打印
[STM32F4]

STM32F4Cube库CDC类试用手记(含USB全速/高速和VC测试程序)

[复制链接]
楼主: 碧云天书
手机看帖
扫描二维码
随时随地手机跟帖
161
lb342| | 2015-9-24 17:09 | 只看该作者 回帖奖励 |倒序浏览
真的感谢楼主的无私奉献和热忱解答。
也许这个在某些自诩高人的眼里很不屑,但对于大众的初学者来说,却很宝贵。
比那些发上一堆效果图,让人们羡慕称赞有没有一点帮助和启发的帖子要强过百倍。

使用特权

评论回复
162
cl1217982730| | 2015-10-2 17:36 | 只看该作者
上位机是怎么弄的?利用串口空间么?有程序么?

使用特权

评论回复
163
0406445| | 2015-10-4 17:33 | 只看该作者
感谢lz的教程,请问有实现过赚多串口吗,要改哪些部分,我的是STMF302,想在linux下运行的,关于驱动部分怎么改,有什么可以建议下的

使用特权

评论回复
164
cl1217982730| | 2015-10-8 15:44 | 只看该作者
碧云天书 发表于 2014-10-9 14:08
试过,失败了,原因没细究

我也失败了。。。也是这个大感叹号!无尽的胸闷!

使用特权

评论回复
165
碧云天书|  楼主 | 2015-10-16 15:32 | 只看该作者
cl1217982730 发表于 2015-10-2 17:36
上位机是怎么弄的?利用串口空间么?有程序么?

有上位机源码的,都在前面的压缩包里了。

使用特权

评论回复
166
碧云天书|  楼主 | 2015-10-16 15:39 | 只看该作者
0406445 发表于 2015-10-4 17:33
感谢lz的教程,请问有实现过赚多串口吗,要改哪些部分,我的是STMF302,想在linux下运行的,关于驱动部分怎 ...

没做过多串口。F302带的USB全速设备IP与F103一样,但与F4不同。我没有试过F3的Cube库,所以没法回答你的问题了,抱歉。

使用特权

评论回复
167
碧云天书|  楼主 | 2015-10-16 15:41 | 只看该作者
本帖最后由 碧云天书 于 2015-10-18 01:10 编辑
cl1217982730 发表于 2015-10-8 15:44
我也失败了。。。也是这个大感叹号!无尽的胸闷!

后来发现在startup_stm32fxxx.s文件中加大Heap_Size到0x0800,感叹号就没有了。

使用特权

评论回复
168
碧云天书|  楼主 | 2015-10-16 15:43 | 只看该作者
lb342 发表于 2015-9-24 17:09
真的感谢楼主的无私奉献和热忱解答。
也许这个在某些自诩高人的眼里很不屑,但对于大众的初学者来说,却很 ...

谢谢鼓励!你们的支持是我将来继续开源的最大动力。

使用特权

评论回复
169
hanyafeng| | 2015-10-22 15:50 | 只看该作者
lz的原理图看过了,除了对reset pin 处理方式少有差异(我直接接地了,根据pdf文档)。不清楚是不是没有进行真正的reset操作(根据红龙demo版代码——只是初始化gpio然后对gpio清零——应该不是reset没有实质0 1 0 翻转操作的原因)导致usb3300的PLL不工作,进而CLKOUT没有输出。

我测试了stm324xG_eval 配套的vcp代码(运行mdk),发现在 OTG_HS_CoreReset 函数里 csrst位 = 1 后,仿真器长时间等待,之后观察 global 寄存器 device 寄存器 数值全部乱掉了。这个现象,我始终没法解释。

不清楚别人是否也出现过相同类型的问题?

使用特权

评论回复
170
碧云天书|  楼主 | 2015-10-22 16:49 | 只看该作者
hanyafeng 发表于 2015-10-22 15:50
lz的原理图看过了,除了对reset pin 处理方式少有差异(我直接接地了,根据pdf文档)。不清楚是不是没有进 ...

这个例子中没有对USB3300的Reset脚进行操作(实际上是忘记了),将该引脚直接接地是没问题的。

我看了你在其它贴中的代码段,只有GPIO初始化部分。你是否打开了ULPI时钟和OTG HS时钟?你用的是标准库编程,与本贴的差异较大。建议你先将本贴的代码移植到你的硬件上,看能否运行,以此判断是软件问题还是硬件问题。

使用特权

评论回复
171
hanyafeng| | 2015-10-22 18:34 | 只看该作者
我把函数名流程描述调用关系:统一函数入口 USBD_Init(&USB_OTG_dev,
            USB_OTG_HS_CORE_ID,
            &USR_desc,
            &USBD_CDC_cb,
            &USR_cb);
紧接着做了硬件初始化 USB_OTG_BSP_Init(pdev) 我已经根据硬件设计情况做了修改;USBD_DeInit(pdev)这个函数什么都没干,不解释了;接着是指针填充到更大结构体内,便于调用。

DCD_Init 函数有实际意义:USB_OTG_SelectCore 函数 实际是给ram内结构体与寄存器产生映射关系(填写指针);设置EP;USB_OTG_DisableGlobalInt 函数 使用了联合体(int32与位域),清除 gint 位。

USB_OTG_CoreInit 函数 对GUSBCTL设置了一通(还是利用联合体),但是在这一步 usbcfg.b.ulpi_fsls = 0;
    usbcfg.b.ulpi_clk_sus_m = 0;
               
    USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);  
仿真器跟踪结果,反而把数值写错了!?

到这一步 USB_OTG_CoreReset 函数,对csctl 位 set 1,不仅仅导致前面的设置失败,而且还导致众多default 数值全部没有了,还搞的仿真器死掉了!

之后,USB_OTG_SetCurrentMode 函数没啥好说的。

曾经屏蔽掉USB_OTG_CoreReset , 运行函数 USB_OTG_CoreInitDev。
  /* Device configuration register */
  dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);                // DAD = 0x20 默认
  dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80;                                                                                // 对应 PFIVL
  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32 );                // 此刻:DAD = 0 ,出错了

省略一部分代码

  /* Clear all pending Device Interrupts */
  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 );
  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 );
  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );                // OTG_HS_DAINT 只读!写入无效
  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 );

接着省略

USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPCTL, depctl.d32);
    USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPTSIZ, 0);                                       
    USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);                                // 默认数值 0x80 TXFE = 1 写入 FF 失效!

USB_OTG_EnableDevInt(pdev);                                        // 使能相关中断位

最后,USB_OTG_EnableGlobalInt 函数。

感觉这个库写的好像缺点什么。debug过程能看到有些bits没有设置到。

附录:
cdc也是作的很蠢:用usb 的 中断 推动 向 uart 发送;用uart 接收中断 推动 usb 的发送(还得不时检查是不是越界了)。





使用特权

评论回复
172
hanyafeng| | 2015-10-22 18:41 | 只看该作者
还有一点要补充:因为是给rtt添加usb device,将 usbd_init 函数放在 rt_hw_board_init 函数(班级硬件初始化)里,意外发现 NVIC_Configuration 函数中的 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 与 usb_bsp.c 文件中 USB_OTG_BSP_EnableInterrupt 函数里 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1) 的使用产生冲突。

运行2次肯定要使得rtt 崩溃的!但是去除一个还是死机!

使用特权

评论回复
173
hanyafeng| | 2015-10-22 19:00 | 只看该作者
ULPI时钟和OTG HS时钟,例程中设置了,仿真器在rcc寄存器组里检查过了。今天我问 microchip 北京代理的技术支持工程师,说到reset处理方式的不同之处,谈到没有客户这么用到过。

我不清楚PLL电路是否需要 reset 进行enable ,查阅 stm32 自己 clock tree 图,没感觉需要 reset 参与,而且 usb3300 的 功能框图 reset 根本没出现(故意遗漏?)。查阅 ULPI 接口协议文档,只是提到了 ULPI reset 与 硬件的 reset 只是在个别寄存器组的差异。

一句话,搞了好几天 ULPI 的 USB 外设 的 初始化。有点想吐的感觉,吃不下饭睡不着觉。

使用特权

评论回复
174
hanyafeng| | 2015-10-22 19:12 | 只看该作者
我为何怀疑 例程的库有问题? 只要把 usbd_init 加上,连 sdram 都失效了。逐个检查 register 逐行检查代码运行结果,真是让我很失望。以前就不是很相信st的库,这次因为初始化的register很多且不熟悉,迎着头皮用库函数,还是出现了死机问题。如果将cdc没用的内容删除,例程也就是剩下usbd_init 函数内容了。

反正我不习惯这种来来回回设置register 的做法,费解!还好,我初始化 sdram 不错, 用的台湾的型号,便宜,性价比高。

使用特权

评论回复
175
hanyafeng| | 2015-10-22 19:14 | 只看该作者
附上我调试的例程,方便大家。

使用特权

评论回复
176
玛尼玛尼哄| | 2015-10-22 20:01 | 只看该作者
比较起以前的USB设备库,HAL库的USB库有诸多改进,看来ST发心还是蛮大的

使用特权

评论回复
177
hanyafeng| | 2015-10-29 18:22 | 只看该作者
自己往rtt里加入三个基本文件:usbd_core.c usbd_ctlreq.c usbd_ioreq.c ,另外也设置了头文件的路径。我发现usbd_core.h 与 usbd_core.c 之间 函数 数量有问题:
/* USBD Low Level Driver */
USBD_StatusTypeDef  USBD_LL_Init (USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef  USBD_LL_DeInit (USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef  USBD_LL_Start(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef  USBD_LL_Stop (USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef  USBD_LL_OpenEP  (USBD_HandleTypeDef *pdev,
                                      uint8_t  ep_addr,                                      
                                      uint8_t  ep_type,
                                      uint16_t ep_mps);

USBD_StatusTypeDef  USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
USBD_StatusTypeDef  USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
USBD_StatusTypeDef  USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
USBD_StatusTypeDef  USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
uint8_t             USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);   
USBD_StatusTypeDef  USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr);   
USBD_StatusTypeDef  USBD_LL_Transmit (USBD_HandleTypeDef *pdev,
                                      uint8_t  ep_addr,                                      
                                      uint8_t  *pbuf,
                                      uint16_t  size);

USBD_StatusTypeDef  USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
                                           uint8_t  ep_addr,                                      
                                           uint8_t  *pbuf,
                                           uint16_t  size);

uint32_t USBD_LL_GetRxDataSize  (USBD_HandleTypeDef *pdev, uint8_t  ep_addr);  
以上函数在usbd_core.c中出现过???????????????

谁知道 这些函数都跑那里去了!求解!!!!!!!!!!!!!

使用特权

评论回复
178
hanyafeng| | 2015-10-29 18:50 | 只看该作者
我在 Drivers\STM32F4xx_HAL_Driver\Src 下面找到一文件 stm32f4xx_ll_usb.c。这个文件和上述函数,USBD_LL_开头的函数有何关系?

stm32f4xx的usb库函数也太绕人了吧?搞了第二个例程了还是缺少必要一些函数体,真是让我伤心了。明白人,给解释解释,这到底是怎么回事。

使用特权

评论回复
179
hanyafeng| | 2015-10-29 19:35 | 只看该作者
找到了,在 usbd_conf.c 文件内。这文件并不是与库函数在一起,usbd_ll_之类的函数为何放在 usbd_conf.c 文件中,而不是在 usbd_core.c中?

使用特权

评论回复
180
734774645| | 2015-10-29 20:35 | 只看该作者
如果要对数据进行繁重的处理,应该在main()函数或工作进程内处理,是的。这样才能使用主时钟的CPU。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则