stm32 usb hid 移植时出现的问题及解决办法(记录)

由于项目需要,使用了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) 函数;

 

 

 

 

你可能感兴趣的:(stm32,USB)