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

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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版