本帖最后由 lvben5d 于 2019-2-18 09:46 编辑
2019年2月2号今天开始,把自己开发GD32E103 USB做设备模式的一些卡顿和解决办法 与君共勉。
1. 自建工程模版,需要在OPTION->C/C++ misc control 栏 输入 --c99 因为天杀的这库文件编写人员,初始化了一些东东 是按照c99来的,默认你建立的工程编译后,会一直出现error: #29: expected an expression ...
2. 建议使用者建立工程的时候,学习STM32一样,分core区和application interface组, 内核区我们基本不会去修改。 应用区才是我们自己EP和功能修改所在,这样清晰。 GD32E103提供的delay_us和ms函数是坑爹的,用了定时器0,而且是阻塞模式,个人建议不如用软延迟,自己注意指令时钟来推算大概的软延迟就好。
3. 利用好usbd_config.h函数 做我们自己应用的头函数,把GD32E103官网示例里各类应用的定义 COPY进这个函数,然后用usbfs.C 作为放置我们自己应用相关的方方面面。
4. GD32E103 USB的控制端口(所有USB标准都是端口0作为控制端口) 发送函数usbd_status_enum usbd_ctltx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len)
控制端口0 接收函数 usbd_status_enum usbd_ctlrx (usb_core_handle_struct *pudev, uint8_t *pbuf, uint16_t len)
5. [吐槽] GD32E103 CDC只有KEIL4的USB工程,对于用KEIL5而电脑没安装KEIL4的兄弟来说,找个变量都要CTRL+SHFIT+F 很麻烦! 6. [我的理解不一定对 大家注意!]有关端点IN OUT的理解,最开始学习STM32F103手册写 有8个双向,16个单向端点, 而USB标准协议本身, 所有端点都是单向的,厂家描述成8个双向单点,意思只是说,某1个双向单点可以配置成2个单相端点,但你实际要么IN 要么OUT,比如EP2 就没有EP2_IN和EP2_OUT一起使用的,只是允许你要么EP2_IN 要么 EP2_OUT。 这个问题的理解一直困扰我,我看例程后,感觉是这样。
7. [牛] USB2.0标准协议中,由于WINDOWS等保存unicode字符都是2个字节,而我们单片机大家用的时候,很少中文,英文一起存吧? 存字符串的时候,大家是不是 string[]="abcdefg" 了呢? 在GD32的内存中,每个字符是占用1个字节内存的,但由于WINDOWS 保存字符可以unicodex的形式(好处大家百度)那么1个字符就会占用了2个内存单元,于是,我们USB设备上传描述符的时候,大家看到了这样的奇怪现象 ‘a’, ' ', 'b', ' ' ,'c', '',‘d’, ' ', 'e', ' ' ,'f', '' ,'g', '' , 多了很多内容为0的空字符。 STM32为了在USB枚举后提交设备描述符的时候,处理这个unicode使用了const数组。我发现GD32的库文件编写人员C99水平高,使用的是这样的
usbd_std.H文件里
#define WIDE_STRING(string) _WIDE_STRING(string)
#define _WIDE_STRING(string) L##string
#define USBD_STRING_DESC(string) \
(uint8_t *)&(struct { \
uint8_t _len; \
uint8_t _type; \
wchar_t _data[sizeof(string)]; \
}) { \
sizeof(WIDE_STRING(string)) + 2U - 2U, \
USB_DESCTYPE_STRING, \
WIDE_STRING(string) \
}
.c文件里
__ALIGN_BEGIN uint8_t* usbd_strings[] __ALIGN_END =
{
[0] = (uint8_t *)&usbd_language_id_desc,
[USBD_MFC_STR_IDX] = USBD_STRING_DESC("Luck7Box"),
[USBD_PRODUCT_STR_IDX] = USBD_STRING_DESC("SpecialMiniHTPC"),
[3] = USBD_STRING_DESC("LvMagic0000000001")
}; 8. GD32 USB FS内核下 设备模式时,我们一般喜欢用1个IO加外围电路来控制DP+的上拉使能和禁能
发现GD32居然有1个设备控制寄存器 (USBFS_DCTL)
1 SD 软断开
软件可实现USB总线上的软断开,在置1该位后,关掉DP线上的上拉电阻,从而引起主机检测设备的断开。
USB_SOFT_DISCONNECT_DISABLE(); ??? 是否意味着我只需在DP+ 上拉1个1.5K电阻是3.3V就可以了,而不需要IO口去控制??
PS: 虽然占用了内存,但是用户修改自己喜欢的产品啊,制造描述符的时候 就所见即所得! 是C99的高级编程方式,学到。 这个是KEIL5编译器的 #define _WIDE_STRING(string) L##string L表示string是Unicode!、
|