由于项目需要,使用了stm32f107的芯片,移植了STM32_USB-Host-Device_Lib_V2.2.0 官方usb固件库,在UCOSII上运行,刚开始使用的是STM32_USB-FS-Device_Lib_V2.3.0的库,这个库网上资源较多,但是在使用的时候发现这个库和UCOSII的延时函数有冲突,导致ucos操作系统不能正常运行,经过调试没有发现原因,调试期间在st官网找到了最新的固件库STM32_USB-Host-Device_Lib_V2.2.0,于是移植过来使用,发现UCOS操作系统正常运行,官方提供的例程使用了端点1作为数据输入输出,我想改成端点1输入,端点2输出,通过查看 官网的库用户文档CD00289278.pdf找到了修改方法,因为我是使用的 customhid的例程,所以以下的修改适用于customhid例程,修改注意这些文件
usbd_conf.h , usb_conf.h , usbd_customhid_core.c
其中 usbd_conf.h 修改 如下宏定义
#define HID_IN_EP 0x81 设备->主机 0x8x 表示IN端点x
#define HID_OUT_EP 0x02 主机->设备 0x0x 表示OUT端点x
#define HID_IN_PACKET 64 IN包长度
#define HID_OUT_PACKET 64 OUT包长度
usb_conf.h 修改 如下宏定义
#define RX_FIFO_FS_SIZE 128 接收FIFO长度
#define TX0_FIFO_FS_SIZE 64 发送端点0FIFO长度
#define TX1_FIFO_FS_SIZE 64 发送端点1FIFO长度
#define TX2_FIFO_FS_SIZE 64 发送端点2FIFO长度
#define TX3_FIFO_FS_SIZE 64 发送端点3FIFO长度
usbd_customhid_core.c修改
1:修改配置描述符,如果要实现自定义双向通信还要修改报告描述符(参考了圈圈的书)
下面是我实现双向通信的配置描述符和报告描述符
配置描述符:
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /* bLength: Configuration Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
USB_CUSTOM_HID_CONFIG_DESC_SIZ,
/* wTotalLength: Bytes returned */
0x00,
0x01, /*bNumInterfaces: 1 interface*/
0x01, /*bConfigurationValue: Configuration value*/
0x00, /*iConfiguration: Index of string descriptor describing
the configuration*/
0xC0, /*bmAttributes: bus powered and Support Remote Wake-up */
0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
/************** Descriptor of Custom HID interface ****************/
/* 09 */
0x09, /*bLength: Interface Descriptor size*/
USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
0x00, /*bInterfaceNumber: Number of Interface*/
0x00, /*bAlternateSetting: Alternate setting*/
0x02, /*bNumEndpoints*/
0x03, /*bInterfaceClass: HID*/
0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0, /*iInterface: Index of string descriptor*/
/******************** Descriptor of Custom HID ********************/
/* 18 */
0x09, /*bLength: HID Descriptor size*/
CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
0x11, /*bcdHID: HID Class Spec release number*/
0x01,
0x00, /*bCountryCode: Hardware target country*/
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
0x22, /*bDescriptorType*/
USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
0x00,
/******************** Descriptor of Custom HID endpoints ***********/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
HID_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_IN_PACKET, /* wMaxPacketSize: 64 Bytes max */
0x00,
0x01, /* bInterval: Polling Interval (32 ms) */
/* 34 */
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
/* Endpoint descriptor type */
HID_OUT_EP, /* bEndpointAddress: */
/* Endpoint Address (OUT) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_OUT_PACKET, /* wMaxPacketSize: 64 Bytes max */
0x00,
0x01, /* bInterval: Polling Interval (20 ms) */
/* 41 */
} ;
报告描述符:
static uint8_t CustomHID_ReportDesc[USBD_CUSTOM_HID_REPORT_DESC_SIZE] =
{
0x06,0x00,0xff,/* USAGE_PAGE */
0x05, 0x8c, /* USAGE_PAGE (ST Page) */
0x09, 0x01, /* USAGE (Demo Kit) */
0xa1, 0x01, /* COLLECTION (Application) */
// The Input report
0x09,0x03, // USAGE ID - Vendor defined
0x15,0x00, // LOGICAL_MINIMUM (0)
0x26,0x00, 0xFF, // LOGICAL_MAXIMUM (255)
0x75,0x08, // REPORT_SIZE (8bit)
0x95,0x40, // REPORT_COUNT (64Byte)
0x81,0x02, // INPUT (Data,Var,Abs)
// The Output report
0x09,0x04, // USAGE ID - Vendor defined
0x15,0x00, // LOGICAL_MINIMUM (0)
0x26,0x00,0xFF, // LOGICAL_MAXIMUM (255)
0x75,0x08, // REPORT_SIZE (8bit)
0x95,0x40, // REPORT_COUNT (64Byte)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0xc0 /* END_COLLECTION */
}; /* CustomHID_ReportDescriptor */
2:修改端点初始化函数:
static uint8_t USBD_CUSTOM_HID_Init (void *pdev,
uint8_t cfgidx)
{
/* Open EP IN */
DCD_EP_Open(pdev,
HID_IN_EP,
HID_IN_PACKET,
USB_OTG_EP_INT);
/* Open EP OUT */
DCD_EP_Open(pdev,
HID_OUT_EP,
HID_OUT_PACKET,
USB_OTG_EP_INT);
return USBD_OK;
}
static uint8_t USBD_CUSTOM_HID_DeInit (void *pdev,
uint8_t cfgidx)
{
/* Close HID EPs */
DCD_EP_Close (pdev , HID_IN_EP);
DCD_EP_Close (pdev , HID_OUT_EP);
return USBD_OK;
}
完成了上面的修改,下一步就是如何接收数据和发送数据:
发送数据使用
uint8_t USBD_CUSTOM_HID_SendReport (USB_OTG_CORE_HANDLE *pdev,
uint8_t *report,
uint16_t len)
{
if (pdev->dev.device_status == USB_OTG_CONFIGURED )
{
DCD_EP_Tx (pdev, HID_IN_EP, report, len);
}
return USBD_OK;
}
函数,这里有个要注意的地方就是在usbd_customhid_core.c中有一个发送中断回调函数,如果想把IN端口改为其他的端点,需要将if (epnum == 1) PrevXferDone = 1中的epnum修改为对应的端点,否则会发送不出去数据,回调函数原型如下
static uint8_t USBD_CUSTOM_HID_DataIn (void *pdev,
uint8_t epnum)
{
/* Ensure that the FIFO is empty before a new transfer, this condition could
be caused by a new transfer before the end of the previous transfer */
DCD_EP_Flush(pdev, HID_IN_EP);
if (epnum == 1) PrevXferDone = 1;
return USBD_OK;
}
接收数据使用如下回调函数
uint8_t USBD_CUSTOM_HID_DataOut (void *pdev,
uint8_t epnum)
{
return USBD_OK;
}
调用 uint32_t DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev,
uint8_t ep_addr,
uint8_t *pbuf,
uint16_t buf_len) 函数;