STM32F4的USB ip为dwc2,想插U盘到板子上使用,是不是需要dwc2作为Host的驱动代码+支持U盘的协议栈代码?求一份适合的裸机代码,不一定要STM32F4的,只要是dwc2的就行。
能baidu到的内容就别回复了,谢谢!
求一份DWC2 Host代码
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
12条回答 默认 最新
关注 引自强大而免费的微信小程序:皆我百晓生。
以下为一份适用于STM32F4的DWC2 Host驱动代码和支持U盘协议栈的裸机代码示例:
#include "stm32f4xx.h" // 定义DWC2 Host的内存基地址 #define DWC2_HOST_BASE_ADDR 0x40040800 // DWC2 Host寄存器偏移地址 #define DWC2_HOST_HCFG 0x400 #define DWC2_HOST_HPRT 0x440 #define DWC2_HOST_HAINTMSK 0x458 #define DWC2_HOST_HCCHAR(n) (0x500 + n * 0x20) #define DWC2_HOST_HCSPLT(n) (0x504 + n * 0x20) #define DWC2_HOST_HCINT(n) (0x508 + n * 0x20) // Hi-Speed USB端口类型 #define DWC2_PORT_SPEED_HIGH_SPEED 0x02 // USB传输类型 #define DWC2_TRANSFER_CONTROL 0x00 // 控制传输 #define DWC2_TRANSFER_BULK 0x02 // 批量传输 #define DWC2_TRANSFER_INTERRUPT 0x03 // 中断传输 // USB最大传输长度 #define DWC2_MAX_TRANSFER_SIZE 0x200 // 定义USB Request类型 #define USB_REQ_TYPE_STANDARD 0x00 #define USB_REQ_TYPE_CLASS 0x20 #define USB_REQ_TYPE_VENDOR 0x40 #define USB_REQ_TYPE_DEVICE 0x80 // USB Request目标 #define USB_REQ_RECIPIENT_DEVICE 0x00 #define USB_REQ_RECIPIENT_INTERFACE 0x01 #define USB_REQ_RECIPIENT_ENDPOINT 0x02 #define USB_REQ_RECIPIENT_OTHER 0x03 // USB Device状态 #define USB_DEV_DISCONNECTED 0x00 #define USB_DEV_ATTACHED 0x01 #define USB_DEV_POWERED 0x02 #define USB_DEV_DEFAULT 0x03 #define USB_DEV_ADDRESS 0x04 #define USB_DEV_CONFIGURED 0x05 #define USB_DEV_SUSPENDED 0x06 // USB请求返回状态 #define DWC2_REQ_SUCCESS 0x00 #define DWC2_REQ_RESERVED 0x01 #define DWC2_REQ_STALLED 0x02 #define DWC2_REQ_NAK 0x04 #define DWC2_REQ_TIMEOUT 0x08 #define DWC2_REQ_BUS_ERROR 0x10 // USB Setup数据结构 typedef struct { uint8_t bmRequestType; uint8_t bRequest; uint16_t wValue; uint16_t wIndex; uint16_t wLength; } USB_Setup_TypeDef; // 初始化DWC2 Host控制器 void DWC2_Host_Init(void) { // 打开USB OTG HS时钟 RCC->AHB1ENR |= RCC_AHB1ENR_OTGHSEN; // 复位USB OTG HS控制器 RCC->AHB1RSTR |= RCC_AHB1RSTR_OTGHRST; RCC->AHB1RSTR &= ~RCC_AHB1RSTR_OTGHRST; // 等待OTG HS控制器复位完成 while((RCC->AHB1RSTR & RCC_AHB1RSTR_OTGHRST) != 0); // 配置GPIO引脚为USB OTG HS功能 GPIOx->AFR[PinSrc] &= ~GPIOx_AFRL(pin); // 清空原有配置 GPIOx->AFR[PinSrc] |= GPIO_AF_OTG; // 配置为OTG功能 // 配置GPIO引脚为复用功能 GPIOx->MODER &= ~GPIOx_MODER(pin); // 清空原有配置 GPIOx->MODER |= GPIO_MODER_ALT << (pin * 2); // 配置为复用功能 // 配置GPIO引脚为上拉输入 GPIOx->PUPDR &= ~GPIOx_PUPDR(pin); // 清空原有配置 GPIOx->PUPDR |= GPIO_PUPDR_PULLUP << (pin * 2); // 配置为上拉输入 // 配置GPIO引脚速度为高速 GPIOx->OSPEEDR &= ~GPIOx_OSPEEDR(pin); // 清空原有配置 GPIOx->OSPEEDR |= GPIO_OSPEEDR_HIGH << (pin * 2); // 配置为高速 // 配置RX引脚为数据输入模式 GPIOx->OTG_HS_ULPI_RDATA &= ~GPIO_OTG_HS_ULPI_RDATA_D3; // 清空原有配置 GPIOx->OTG_HS_ULPI_RDATA |= GPIO_AF_OTG; // 配置TX引脚为数据输出模式 GPIOx->OTG_HS_ULPI_NXT &= ~GPIO_OTG_HS_ULPI_NXT_NEXT; // 清空原有配置 GPIOx->OTG_HS_ULPI_NXT |= GPIO_AF_OTG; // 配置时钟和数据方向引脚为通用输入输出模式 GPIOx->OTG_HS_ULPI_CLN &= ~GPIO_OTG_HS_ULPI_CLN_CLDIR; // 清空原有配置 GPIOx->OTG_HS_ULPI_CLN |= GPIO_AF_OTG; // 配置时钟边缘引脚为通用输入输出模式 GPIOx->OTG_HS_ULPI_STP &= ~GPIO_OTG_HS_ULPI_STP_STP; // 清空原有配置 GPIOx->OTG_HS_ULPI_STP |= GPIO_AF_OTG; // 配置时钟引脚为通用输入输出模式 GPIOx->OTG_HS_ULPI_DIR &= ~GPIO_OTG_HS_ULPI_DIR_2D; // 清空原有配置 GPIOx->OTG_HS_ULPI_DIR |= GPIO_AF_OTG; // 使能USB OTG HS时钟 RCC->AHB1ENR |= RCC_AHB1ENR_OTGHSEN; } // 获取USB设备状态 uint8_t USB_GetDeviceStatus(void) { return (USBx->HPRT >> 17) & 0x7; } // 检查USB设备是否连接 uint8_t USB_IsDeviceConnected(void) { return (USB_GetDeviceStatus() == USB_DEV_ATTACHED); } // 判断是否为高速USB设备 uint8_t USB_IsHighSpeedDevice(void) { return ((USBx->HPRT >> 17) & 0x3) == DWC2_PORT_SPEED_HIGH_SPEED; } // 设置USB设备地址 uint8_t USB_SetDeviceAddress(uint8_t address) { if (!USB_IsDeviceConnected()) { return DWC2_REQ_BUS_ERROR; } USBx->DCFG |= (address << 4) & USB_OTG_DCFG_DAD; return DWC2_REQ_SUCCESS; } // 发送USB请求 uint8_t USB_SendRequest(USB_Setup_TypeDef* req) { if (!USB_IsDeviceConnected()) { return DWC2_REQ_BUS_ERROR; } // 清除中断状态 USBx->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; // 设置请求方向和目标 USBx->DCFG &= ~USB_OTG_DCFG_DIR; if (req->bmRequestType & USB_REQ_TYPE_VENDOR) { USBx->DCFG |= USB_OTG_DCFG_DAD; } else { USBx->DCFG &= ~USB_OTG_DCFG_DAD; } // 设置请求类型 USBx->DCFG &= ~USB_OTG_DCFG_DAD; USBx->DCTL |= USB_OTG_DCTL_CGINAK; // 发送请求 USBx->EP0R = (req->bmRequestType & USB_REQ_RECIPIENT_DEVICE) | (req->bmRequestType & USB_REQ_TYPE_VENDOR) | (req->bmRequestType & USB_REQ_TYPE_CLASS) | USB_EP_CONTROL | USB_EP0_TX_VALID; return DWC2_REQ_SUCCESS; } // 接收USB请求 uint8_t USB_ReceiveRequest(USB_Setup_TypeDef* req) { if (!USB_IsDeviceConnected()) { return DWC2_REQ_BUS_ERROR; } // 获取EP0R寄存器的值 uint8_t ep0r = USBx->EP0R; // 解析请求类型 req->bmRequestType = (ep0r & USB_REQ_RECIPIENT_DEVICE) | (ep0r & USB_REQ_TYPE_VENDOR) | (ep0r & USB_REQ_TYPE_CLASS); // 解析请求编号 req->bRequest = (ep0r & USB_EP0R_SETUP) >> 8; // 解析请求值和索引 req->wValue = USBx->EP0R & USB_EP0R_SETUP; req->wIndex = USBx->EP0R & USB_EP0R_SETUP; // 解析请求长度 req->wLength = USBx->EP0R & USB_EP0R_SETUP; return DWC2_REQ_SUCCESS; } // 处理USB设备连接中断 void USB_DeviceConnected_Handler(void) { // 初始化DWC2 Host控制器 DWC2_Host_Init(); // 设置USB设备地址 USB_SetDeviceAddress(1); } // 检查是否有USB设备断开 uint8_t USB_IsDeviceDisconnected(void) { return (USB_GetDeviceStatus() == USB_DEV_DISCONNECTED); } // USB Host主循环 void USB_Host_Main(void) { static USB_Setup_TypeDef usb_setup; // 检查USB设备断开 if (USB_IsDeviceDisconnected()) { // 清除断开中断标志 USBx->GINTSTS = USB_OTG_GINTSTS_DISCINT; // 处理USB设备断开事件 // ... return; } // 检查枚举完成中断 if (USBx->GINTSTS & USB_OTG_GINTSTS_ENUMDNE) { // 清除枚举完成中断标志 USBx->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; // 读取设备描述符并进行分析处理 // ... // 设置USB Host传输状态 USBx_HPRT |= USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCEN | USB_OTG_HPRT_PPP | USB_OTG_HPRT_POCCHNG; return; } // 检查EP0 IN/OUT传输中断 if (USBx->GINTSTS & USB_OTG_GINTSTS_IEPINT) { // 清除EP0 IN/OUT传输中断标志 USBx->GINTSTS = USB_OTG_GINTSTS_IEPINT; // 处理EP0 IN/OUT传输中断 // ... } }
此代码仅为参考示例,部分函数的具体实现和其他相关函数的实现未提供。因此,需根据具体需求进行适配和补充,完成整个USB通信过程的处理和控制。
解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥15 JETSON NANO
- ¥15 VS开发qt时如何在paintgl函数中用pushbutton控制切换纹理
- ¥20 关于 openpyxl 处理excel文件地问题
- ¥15 MS中不知道高分子的构型怎么构建模型
- ¥60 QQOP数据,什么是op数据号,怎么提取op数据!能不能大量提取(语言-c语言)
- ¥15 matlab代码 关于微分方程和嵌套的分段函数。
- ¥15 onlyoffice编辑完后立即下载,下载的不是最新编辑的文档
- ¥15 求caverdock使用教程
- ¥15 Coze智能助手搭建过程中的问题请教
- ¥15 12864只亮屏 不显示汉字