Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
USB
USB OTG
对ST fullspeed usb otg(dual role)实现的探索
发布于 2020-05-03 15:45:29 浏览:1272
订阅该版
像安卓手机连接PC时,手机就当做设备,当使用OTG线连接时,手机就当做主机使用。 类似上述功能在ST的cubemx并没有看到实现 ![dual.png](https://oss-club.rt-thread.org/uploads/202005/02/230814aonepptnv5n5znnv.png) **STSW-STM32046**里面有USB_Host_Device_Examples,但并没有通过ID触发实现主从切换。 通过阅读ST LL库关于USB这块代码,在USB_DevInit和USB_HostInit中都有这么一句代码: ```c /* Disable all interrupts. */ USBx->GINTMSK = 0U; ``` 然后只开启相关部分中断,并没有开启OTG的CIDSCHGM中断,当然就没法使用ID触发主从切换。 好吧,还是仿写个LL USB库算了。 ```c struct rt_st_fsusb { USB_OTG_GlobalTypeDef* global_register; USB_OTG_HostTypeDef* host_register; volatile rt_uint32_t* host_port_register; USB_OTG_HostChannelTypeDef* host_channel_registers[32]; USB_OTG_DeviceTypeDef* peripheral_register; USB_OTG_INEndpointTypeDef* peripheral_inendpoint_registers[16]; USB_OTG_OUTEndpointTypeDef* peripheral_outendpoint_registers[16]; volatile rt_uint32_t* fifo_start_address; volatile rt_uint32_t* power_clock_register; rt_uint32_t peripheral_endpoint_count; rt_uint32_t host_channel_count; }; typedef struct rt_st_fsusb* rt_st_fsusb_t; ``` ```c rt_err_t rt_st_fsusb_register_init(rt_st_fsusb_t st_fsusb, int peripheral_endpoint_count, int host_channel_count); rt_err_t rt_st_fsusb_core_reset(rt_st_fsusb_t st_fsusb); void rt_st_fsusb_set_fullspeed_transceiver(rt_st_fsusb_t st_fsusb); void rt_st_fsusb_enable_vbus_sensing(rt_st_fsusb_t st_fsusb, rt_bool_t is_true); rt_err_t rt_st_fsusb_enable_output_vbus(rt_st_fsusb_t st_fsusb, rt_bool_t is_true); rt_uint32_t rt_st_fsusb_get_current_mode(rt_st_fsusb_t st_fsusb); void rt_st_fsusb_enable_global_interrupts(rt_st_fsusb_t st_fsusb, rt_bool_t is_true); void rt_st_fsusb_set_global_interrupts(rt_st_fsusb_t st_fsusb, rt_uint32_t value); rt_uint32_t rt_st_fsusb_read_global_interrupts_state(rt_st_fsusb_t st_fsusb); void rt_st_fsusb_clear_global_interrupts_state(rt_st_fsusb_t st_fsusb, rt_uint32_t value); rt_err_t rt_st_fsusb_write_packet_in_tx_fifo(rt_st_fsusb_t st_fsusb, rt_uint8_t channel_endpoint_number, rt_uint8_t* packet_buffer, rt_uint16_t packet_size); void rt_st_fsusb_read_packet_in_rx_fifo(rt_st_fsusb_t st_fsusb, rt_uint8_t* packet_buffer, rt_uint16_t size); rt_err_t rt_st_fsusb_flush_tx_fifo(rt_st_fsusb_t st_fsusb, rt_uint32_t number); rt_err_t rt_st_fsusb_flush_rx_fifo(rt_st_fsusb_t st_fsusb); rt_err_t rt_st_fsusb_peripheral_create(rt_st_fsusb_t st_fsusb); rt_err_t rt_st_fsusb_peripheral_destroy(rt_st_fsusb_t st_fsusb); void rt_st_fsusb_peripheral_enable_connect(rt_st_fsusb_t st_fsusb, rt_bool_t is_true); rt_err_t rt_st_fsusb_host_create(rt_st_fsusb_t st_fsusb); rt_err_t rt_st_fsusb_host_destroy(rt_st_fsusb_t st_fsusb); ``` 初始化USB OTG,关全局中断-->phy core 复位-->"activate the transceiver in transmission/reception"-->取消vbus检测-->设置开启的中断。 ```c static void rt_hw_usb_init() { GPIO_InitTypeDef GPIO_InitStruct = { 0 }; GPIO_InitTypeDef GPIO_InitStruct_ID = { 0 }; rt_st_fsusb_register_init(&stm32_otg, 4, 8); __HAL_RCC_GPIOA_CLK_ENABLE() ; /**USB_OTG_FS GPIO Configuration PA11 ------> USB_OTG_FS_DM PA12 ------> USB_OTG_FS_DP */ GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct_ID.Pin = GPIO_PIN_10; GPIO_InitStruct_ID.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct_ID.Pull = GPIO_PULLUP; GPIO_InitStruct_ID.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct_ID.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct_ID); /* Peripheral clock enable */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE() ; /* USB_OTG_FS interrupt Init */ HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0); HAL_NVIC_EnableIRQ(OTG_FS_IRQn); rt_st_fsusb_enable_global_interrupts(&stm32_otg, RT_FALSE); rt_st_fsusb_core_reset(&stm32_otg); rt_st_fsusb_set_fullspeed_transceiver(&stm32_otg); rt_st_fsusb_enable_vbus_sensing(&stm32_otg, RT_FALSE); rt_st_fsusb_set_global_interrupts(&stm32_otg, (common_interrup_mask | host_interrup_mask | device_interrupt_mask)); } ``` 开启的中断: ```c static const rt_uint32_t common_interrup_mask = USB_OTG_GINTMSK_WUIM | USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_CIDSCHGM | USB_OTG_GINTMSK_RXFLVLM | /*USB_OTG_GINTMSK_SOFM |*/ USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM; static const rt_uint32_t host_interrup_mask = /*USB_OTG_GINTMSK_PTXFEM |*/ USB_OTG_GINTMSK_HCIM | USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_PXFRM_IISOOXFRM; /*USB_OTG_GINTMSK_NPTXFEM |*/ static const rt_uint32_t device_interrupt_mask = USB_OTG_GINTMSK_DISCINT | USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_IISOIXFRM | USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT | /*USB_OTG_GINTMSK_EOPFM |*/ USB_OTG_GINTMSK_ISOODRPM | USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_ESUSPM | USB_OTG_GINTMSK_GONAKEFFM | USB_OTG_GINTMSK_GINAKEFFM; ``` 剩下的就是中断处理了。rt-thread现有的USB框架没有实现主从切换,尝试先实现一个otg_controller: ```c struct rt_usb_otg_controller { struct rt_usb_slave_controller slave_controller; struct rt_usb_host_controller host_controller; void (*process_interrupt_role_change)(struct rt_usb_otg_controller* controller, rt_usb_data_role_type_t type); }; typedef struct rt_usb_otg_controller* rt_usb_otg_controller_t;``````static void process_interrupt_role_change(rt_usb_otg_controller_t controller, rt_usb_data_role_type_t type) { if (type == RT_USB_DATA_ROLE_TYPE_HOST) { rt_kprintf("usb role change: host mode.
"); controller->slave_controller.stop_role_instance(&controller->slave_controller); controller->host_controller.start_role_instance(&controller->host_controller); } else { rt_kprintf("usb role change: slave mode
"); controller->host_controller.stop_role_instance(&controller->host_controller); controller->slave_controller.start_role_instance(&controller->slave_controller); } } ``` ID触发中断处理: ```c if (USB_OTG_GINTSTS_CIDSCHG & global_interrupt) { rt_st_fsusb_clear_global_interrupts_state(&stm32_otg, USB_OTG_GINTSTS_CIDSCHG); if (stm32_otg.global_register->GOTGCTL & USB_OTG_GOTGCTL_CIDSTS) { // device mode otg_controller.process_interrupt_role_change(&otg_controller, RT_USB_DATA_ROLE_TYPE_SLAVE); } else { //host mode otg_controller.process_interrupt_role_change(&otg_controller, RT_USB_DATA_ROLE_TYPE_HOST); } } ``` 串口输出: ``` \ | / - RT - Thread Operating System / | \ 4.0.2 build May 3 2020 2006 - 2019 Copyright by rt-thread team boot rtusb dev version: v0.05. comm interrupt srq usb role change: slave mode msh >device interrupt usb reset. device interrupt enum done. device interrupt epnum = 0, size = 8, datapid = 0, packet type = 6 80 06 00 01 00 00 40 00 device interrupt epnum = 0, size = 0, datapid = 0, packet type = 4 device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. comm interrupt usb role change: host mode. comm interrupt usb role change: slave mode device interrupt usb early suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. device interrupt usb early suspend. device interrupt usb suspend. comm interrupt usb role change: host mode. host interrupt new host port host interrupt port disconnect ```
查看更多
0
个回答
默认排序
按发布时间排序
暂无答案,快来添加答案吧
撰写答案
登录
注册新账号
关注者
0
被浏览
1.3k
关于作者
charlown.cai
这家伙很懒,什么也没写!
提问
12
回答
53
被采纳
0
关注TA
发私信
相关问题
1
请教USB Host
2
STM32F4调试USB 读卡器(Slave)提示格式化
3
急求 STM32F4 USB Device MSC+SD 的相关问题
4
USB 框架问题
5
USB键盘
6
LPC17xx 如何添加USB HOST设备
7
RT-Thread目前支持USB HOST了吗?
8
USB HOST的支持问题
9
RTT 2.0.1 USB存储设备问题,枚举到USBREQ_GET_MAX_LUN后复位
10
USB库已经很久没更新了
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
基于STM32H750和Rt-Thread的CANFD通信实现的记录(一)
2
freemodbus主机在freertos的适配,参考rtthread例程
3
开源共生 商业共赢 | RT-Thread 2024开发者大会议程正式发布!
4
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
5
RT-Thread EtherKit开源以太网硬件正式发布
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部