你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32f405 USB CDC

[复制链接]
zhongfj1688 提问时间:2015-9-29 20:30 /
Hi 各位大神,
项目上使用 STM32F405的芯片,并且通过虚拟串口, VCP与主机进行通讯。
开发上,直接基于stm32_f105-07_f2_f4_usb-host-device_lib进行修改。
ARM向主机发送数据的时候,直接调用的了DCD_EP_Tx。由于数据量比较大,经常发生上次数据还未发送完成,就被新数据覆盖的问题。

不知使用DCD_EP_Tx时候,有没有什么条件可以判断是否可以调用DCD_EP_Tx,以保证这次数据不会覆盖上次数据。

目前我的实现方式,但是不能满足要求。
void USB_send_packet(uint8_t * buf, uint16_t len)

{   
       int i = 0;
       while(DCD_GetTxFifoStatus(&USB_OTG_dev, CDC_IN_EP & 0x7F) < 128); // 判断EP1 剩余的FIFO长度大于512 byte
       while(g_tx_completed == 0); // EP1 TX FIFO EMPTY中断里面 设置为1

       __disable_irq;
       g_tx_completed = 0;
       __enable_irq;

        memset(ep_in_buf, 0, sizeof(ep_in_buf)); // ep_in_buf为长度固定为512的一个全局数组
        memcpy(ep_in_buf, buf, len);
        DCD_EP_Tx(&USB_OTG_dev, CDC_IN_EP, ep_in_buf, len); // len 固定为 512
}

非常感谢,
/Jaret
收藏 1 评论9 发布时间:2015-9-29 20:30

举报

9个回答
creep 回答时间:2015-9-29 23:18:33
本次发送完成后会有发送完成中断的。首先会进入下面的中断函数:
1.png
中断中调用的处理函数也就是下面的结构体中的一个函数:
2.png
也就下面的函数,在这个函数中做个标记可以用于指示上一次数据已经传送完成。
3.png
zhongfj1688 回答时间:2015-9-29 20:52:00

由于需要通过vcp发送的数据量很大,不是通过uart进来了。而且对速度要求比较高。
在stm32f103上,使用usb_sil.c可以这样实现
    if (GetEPTxStatus(ENDP1) == EP_TX_NAK)
    {
        USB_SIL_Write(EP1_IN, InReport, 64);
        SetEPTxCount((EP1_IN & 0x7F), 64);
        SetEPTxValid(ENDP1);
        return 1;
    }

切换到stm32f405上,想使用高速usb,有没有类似的实现方法?

/Jaret
zhongfj1688 回答时间:2015-9-30 09:39:23
Hi Creep,
非常感谢你的回答。

我改成这样实现EP1中断处理函数函数。但貌似数据还是会出现覆盖的情况。顺便说一下,我编译的时候,采用了USB_OTG_HS_DEDICATED_EP1_ENABLED
uint8_t g_tx_completed = 1;
uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
{

  USB_OTG_DIEPINTn_TypeDef  diepint;
  uint32_t fifoemptymsk, msk, emp;
  
  msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK);
  emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
  msk |= ((emp >> 1 ) & 0x1) << 7;
  diepint.d32  = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk;  
  
  if ( diepint.b.xfercompl )
  {
    fifoemptymsk = 0x1 << 1;
    USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
    CLEAR_IN_EP_INTR(1, xfercompl);
    /* TX COMPLETE */
    g_tx_completed = 1;

    //USBD_DCD_INT_fops->DataInStage(pdev , 1);
  }
  if ( diepint.b.epdisabled )
  {
    CLEAR_IN_EP_INTR(1, epdisabled);
  }  
  if ( diepint.b.timeout )
  {
    CLEAR_IN_EP_INTR(1, timeout);
  }
  if (diepint.b.intktxfemp)
  {
    CLEAR_IN_EP_INTR(1, intktxfemp);
  }
  if (diepint.b.inepnakeff)
  {
    CLEAR_IN_EP_INTR(1, inepnakeff);
  }
  if (diepint.b.emptyintr)
  {
    DCD_WriteEmptyTxFifo(pdev , 1);
    CLEAR_IN_EP_INTR(1, emptyintr);
  }
  
  return 1;
}

想请教一下,这个传输完成中断 是指传完一帧数据 (USB高速为512 Byte),还是指TX FIFO里面的数据全部传完啊?

我在调试的时候,曾经试着在TX complete里面设置断点,然后在bus hound里面看什么时候才接收完一帧数据。发现TX complete中断要进很多次,bus hound上才能看到接收完一帧数据。

/Jaret


你好我好大家好! 回答时间:2015-9-30 20:30:26
帮顶               
zhongfj1688 回答时间:2015-10-9 10:08:15
求关注
zhongfj1688 回答时间:2015-10-13 10:00:47
Creep的解答是正解。数据Crash的原因是我PC工具组帧造成的。通过Bus hound抓取数据分析,ARM上发的数据没有问题。
非常感谢Creep。问题解决。
microcomput 回答时间:2015-10-13 11:00:15
不懂,帮顶  
OPOD 回答时间:2015-12-28 17:11:53
顶一下
Riaaaaa 回答时间:2017-8-18 12:03:10
你好楼主!我在这个帖子(https://www.stmcu.org.cn/module/forum/thread-603430-1-1.html)看到你的问题。觉得和我现在遇到的问题有点相似。我现在是在校学生。目前做的项目是在stm32f405rgt6上做一个usb虚拟串口。我想请问您是怎么根据stm32_f105-07_f2_f4_usb-host-device_lib进行修改的……我是stm32的新手。。您介意给我看看您的代码吗?万分感谢!
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版