经验分享
• admin 发表了文章 • 3 个评论 • 11121 次浏览 • 2015-01-14 16:40
• 来自相关话题
转自国外一篇博客(纯英文),记录万一以后用到呢 O(∩_∩)O~
This writing is only foucs on the process basing on the ST32F4 HAL 1.10 driver (now is 1.30), not including any knowledge of USB protocol explaining.
There are some software you have to prepare at fist:
STM32CubeF4, MDK or EWARM, USB HID Tools
1.Use STM32CubeF4 gernerates the code at first. (Please reference the STM32CubeF4 manual)
2.Open the project with MDK
3.Open “usbd_hid.c”
4.change the like below:
...
static uint8_t USBD_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
...
USBD_ClassTypeDef USBD_HID =
{
USBD_HID_Init,
USBD_HID_DeInit,
USBD_HID_Setup,
NULL, /[i]EP0_TxSent[/i]/
NULL, /[i]EP0_RxReady[/i]/
USBD_HID_DataIn, /[i]DataIn[/i]/
USBD_HID_DataOut, /[i]DataOut[/i]/
NULL, /[i]SOF [/i]/
NULL,
NULL,
USBD_HID_GetCfgDesc,
USBD_HID_GetCfgDesc,
USBD_HID_GetCfgDesc,
USBD_HID_GetDeviceQualifierDesc,
};
__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /[i] bLength: Configuration Descriptor size [/i]/
USB_DESC_TYPE_CONFIGURATION, /[i] bDescriptorType: Configuration [/i]/
USB_HID_CONFIG_DESC_SIZ,
/[i] wTotalLength: Bytes returned [/i]/
0x00,
0x01, /[i]bNumInterfaces: 1 interface[/i]/
0x01, /[i]bConfigurationValue: Configuration value[/i]/
0x00, /*iConfiguration: Index of string descriptor describing
the configuration*/
0xE0, /[i]bmAttributes: bus powered and Support Remote Wake-up [/i]/
0x32, /[i]MaxPower 100 mA: this current is used for detecting Vbus[/i]/
/[b][i][b][/i][i][b][/i][i][b][/i] Descriptor of Joystick Mouse interface [/b][/b][/b][/b]********/
/[i] 09 [/i]/
0x09, /[i]bLength: Interface Descriptor size[/i]/
USB_DESC_TYPE_INTERFACE,/[i]bDescriptorType: Interface descriptor type[/i]/
0x00, /[i]bInterfaceNumber: Number of Interface[/i]/
0x00, /[i]bAlternateSetting: Alternate setting[/i]/
0x02, /[i]bNumEndpoints[/i]/
0x03, /[i]bInterfaceClass: HID[/i]/
0x01, /[i]bInterfaceSubClass : 1=BOOT, 0=no boot[/i]/
0x01, /[i]nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse[/i]/
0, /[i]iInterface: Index of string descriptor[/i]/
/[i][b][/i][i][b][/i][i][b][/i][i][b][/i][i][b][/i] Descriptor of Joystick Mouse HID [/b][/b][/b][/b][/b]**********/
/[i] 18 [/i]/
0x09, /[i]bLength: HID Descriptor size[/i]/
HID_DESCRIPTOR_TYPE, /[i]bDescriptorType: HID[/i]/
0x11, /[i]bcdHID: HID Class Spec release number[/i]/
0x01,
0x21, /[i]bCountryCode: Hardware target country[/i]/
0x01, /[i]bNumDescriptors: Number of HID class descriptors to follow[/i]/
0x22, /[i]bDescriptorType[/i]/
HID_MOUSE_REPORT_DESC_SIZE,/[i]wItemLength: Total length of Report descriptor[/i]/
0x00,
/[i][b][/i][i][b][/i][i][b][/i][i][b][/i][i][b][/i] Descriptor of Mouse endpoint [/b][/b][/b][/b][/b]**********/
/[i] 27 [/i]/
0x07, /[i]bLength: Endpoint Descriptor size[/i]/
USB_DESC_TYPE_ENDPOINT, /[i]bDescriptorType:[/i]/
HID_EPIN_ADDR, /[i]bEndpointAddress: Endpoint Address (IN)[/i]/
0x03, /[i]bmAttributes: Interrupt endpoint[/i]/
HID_EPIN_SIZE, /[i]wMaxPacketSize: 8 Byte max [/i]/
0x00,
0x0A, /[i]bInterval: Polling Interval (10 ms)[/i]/
/[i] 34 [/i]/
0x07, /[i]bLength: Endpoint Descriptor size[/i]/
USB_DESC_TYPE_ENDPOINT, /[i]bDescriptorType:[/i]/
HID_EPOUT_ADDR, /[i]bEndpointAddress: Endpoint Address (OUT)[/i]/
0x03, /[i]bmAttributes: Interrupt endpoint[/i]/
HID_EPOUT_SIZE, /[i]wMaxPacketSize: 1 Byte max [/i]/
0x00,
0x0A, /[i]bInterval: Polling Interval (10 ms)[/i]/
/[i] 41 [/i]/
} ;
...
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END ={
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE_PAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x01, // INPUT (Cnst,Ary,Abs)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x06, // REPORT_COUNT (6)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x03, // USAGE_MAXIMUM (Scroll Lock)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x03, // REPORT_COUNT (3)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x75, 0x05, // REPORT_SIZE (5)
0x95, 0x01, // REPORT_COUNT (1)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
0xc0 // END_COLLECTION
};
...
static uint8_t rx_buf;
static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
uint8_t cfgidx)
{
uint8_t ret = 0;
/[i] Open EP IN [/i]/
USBD_LL_OpenEP(pdev,
HID_EPIN_ADDR,
USBD_EP_TYPE_INTR,
HID_EPIN_SIZE);
/[i] Open EP OUT [/i]/
USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE);
pdev->pClassData = USBD_malloc(sizeof (USBD_HID_HandleTypeDef));
//set EP_OUT 1 prepared to received the data
USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR, &rx_buf, 1);
if(pdev->pClassData == NULL)
{
ret = 1;
}
else
{
((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE;
}
return ret;
}
...
static uint8_t USBD_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum){
HAL_PCD_EP_Receive(hUsbDeviceFS.pData, HID_EPOUT_ADDR, &rx_buf, 1);
if (rx_buf & 0x01){
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);
}
else{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
}
if (rx_buf & 0x02){
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
}
else{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
}
if (rx_buf & 0x04){
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
}
else{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);
}
return USBD_OK;
}
5.now update the usbd_hid.h
#define HID_EPIN_ADDR 0x81
//#define HID_EPIN_SIZE 0x04
#define HID_EPIN_SIZE 0x08
//define the OUT Endpoint
#define HID_EPOUT_ADDR 0x01
#define HID_EPOUT_SIZE 0x01
//#define USB_HID_CONFIG_DESC_SIZ 34
#define USB_HID_CONFIG_DESC_SIZ 41
#define USB_HID_DESC_SIZ 9
//#define HID_MOUSE_REPORT_DESC_SIZE 74
#define HID_MOUSE_REPORT_DESC_SIZE 65
#define HID_DESCRIPTOR_TYPE 0x21
#define HID_REPORT_DESC 0x22
Now let us take a look how it works:
Add a callback process at first.
...
static uint8_t USBD_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
...
USBD_ClassTypeDef USBD_HID =
{
...
/[i]When the data out (from host) callback this process DataOut[/i]/
USBD_HID_DataOut,
...
};
Open the OUT Endpoint when initializing the USB and prepare to receive the data.
Lots of people miss the “USBD_LL_PrepareReceive(…);”, so there is no callback trigger.
static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
uint8_t cfgidx)
{
...
USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE);
//set EP_OUT 1 prepared to received the data
USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR, &rx_buf, 1);
...
}
And following thing is dealing with the callback process ^_^
本文转自:http://eemodule.com/?p=86 查看全部
转自国外一篇博客(纯英文),记录万一以后用到呢 O(∩_∩)O~
This writing is only foucs on the process basing on the ST32F4 HAL 1.10 driver (now is 1.30), not including any knowledge of USB protocol explaining.
There are some software you have to prepare at fist:
STM32CubeF4, MDK or EWARM, USB HID Tools
1.Use STM32CubeF4 gernerates the code at first. (Please reference the STM32CubeF4 manual)
2.Open the project with MDK
3.Open “usbd_hid.c”
4.change the like below:
...
static uint8_t USBD_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
...
USBD_ClassTypeDef USBD_HID =
{
USBD_HID_Init,
USBD_HID_DeInit,
USBD_HID_Setup,
NULL, /[i]EP0_TxSent[/i]/
NULL, /[i]EP0_RxReady[/i]/
USBD_HID_DataIn, /[i]DataIn[/i]/
USBD_HID_DataOut, /[i]DataOut[/i]/
NULL, /[i]SOF [/i]/
NULL,
NULL,
USBD_HID_GetCfgDesc,
USBD_HID_GetCfgDesc,
USBD_HID_GetCfgDesc,
USBD_HID_GetDeviceQualifierDesc,
};
__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
{
0x09, /[i] bLength: Configuration Descriptor size [/i]/
USB_DESC_TYPE_CONFIGURATION, /[i] bDescriptorType: Configuration [/i]/
USB_HID_CONFIG_DESC_SIZ,
/[i] wTotalLength: Bytes returned [/i]/
0x00,
0x01, /[i]bNumInterfaces: 1 interface[/i]/
0x01, /[i]bConfigurationValue: Configuration value[/i]/
0x00, /*iConfiguration: Index of string descriptor describing
the configuration*/
0xE0, /[i]bmAttributes: bus powered and Support Remote Wake-up [/i]/
0x32, /[i]MaxPower 100 mA: this current is used for detecting Vbus[/i]/
/[b][i][b][/i][i][b][/i][i][b][/i] Descriptor of Joystick Mouse interface [/b][/b][/b][/b]********/
/[i] 09 [/i]/
0x09, /[i]bLength: Interface Descriptor size[/i]/
USB_DESC_TYPE_INTERFACE,/[i]bDescriptorType: Interface descriptor type[/i]/
0x00, /[i]bInterfaceNumber: Number of Interface[/i]/
0x00, /[i]bAlternateSetting: Alternate setting[/i]/
0x02, /[i]bNumEndpoints[/i]/
0x03, /[i]bInterfaceClass: HID[/i]/
0x01, /[i]bInterfaceSubClass : 1=BOOT, 0=no boot[/i]/
0x01, /[i]nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse[/i]/
0, /[i]iInterface: Index of string descriptor[/i]/
/[i][b][/i][i][b][/i][i][b][/i][i][b][/i][i][b][/i] Descriptor of Joystick Mouse HID [/b][/b][/b][/b][/b]**********/
/[i] 18 [/i]/
0x09, /[i]bLength: HID Descriptor size[/i]/
HID_DESCRIPTOR_TYPE, /[i]bDescriptorType: HID[/i]/
0x11, /[i]bcdHID: HID Class Spec release number[/i]/
0x01,
0x21, /[i]bCountryCode: Hardware target country[/i]/
0x01, /[i]bNumDescriptors: Number of HID class descriptors to follow[/i]/
0x22, /[i]bDescriptorType[/i]/
HID_MOUSE_REPORT_DESC_SIZE,/[i]wItemLength: Total length of Report descriptor[/i]/
0x00,
/[i][b][/i][i][b][/i][i][b][/i][i][b][/i][i][b][/i] Descriptor of Mouse endpoint [/b][/b][/b][/b][/b]**********/
/[i] 27 [/i]/
0x07, /[i]bLength: Endpoint Descriptor size[/i]/
USB_DESC_TYPE_ENDPOINT, /[i]bDescriptorType:[/i]/
HID_EPIN_ADDR, /[i]bEndpointAddress: Endpoint Address (IN)[/i]/
0x03, /[i]bmAttributes: Interrupt endpoint[/i]/
HID_EPIN_SIZE, /[i]wMaxPacketSize: 8 Byte max [/i]/
0x00,
0x0A, /[i]bInterval: Polling Interval (10 ms)[/i]/
/[i] 34 [/i]/
0x07, /[i]bLength: Endpoint Descriptor size[/i]/
USB_DESC_TYPE_ENDPOINT, /[i]bDescriptorType:[/i]/
HID_EPOUT_ADDR, /[i]bEndpointAddress: Endpoint Address (OUT)[/i]/
0x03, /[i]bmAttributes: Interrupt endpoint[/i]/
HID_EPOUT_SIZE, /[i]wMaxPacketSize: 1 Byte max [/i]/
0x00,
0x0A, /[i]bInterval: Polling Interval (10 ms)[/i]/
/[i] 41 [/i]/
} ;
...
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END ={
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE_PAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x01, // INPUT (Cnst,Ary,Abs)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x06, // REPORT_COUNT (6)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x03, // USAGE_MAXIMUM (Scroll Lock)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x03, // REPORT_COUNT (3)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x75, 0x05, // REPORT_SIZE (5)
0x95, 0x01, // REPORT_COUNT (1)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
0xc0 // END_COLLECTION
};
...
static uint8_t rx_buf;
static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
uint8_t cfgidx)
{
uint8_t ret = 0;
/[i] Open EP IN [/i]/
USBD_LL_OpenEP(pdev,
HID_EPIN_ADDR,
USBD_EP_TYPE_INTR,
HID_EPIN_SIZE);
/[i] Open EP OUT [/i]/
USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE);
pdev->pClassData = USBD_malloc(sizeof (USBD_HID_HandleTypeDef));
//set EP_OUT 1 prepared to received the data
USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR, &rx_buf, 1);
if(pdev->pClassData == NULL)
{
ret = 1;
}
else
{
((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE;
}
return ret;
}
...
static uint8_t USBD_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum){
HAL_PCD_EP_Receive(hUsbDeviceFS.pData, HID_EPOUT_ADDR, &rx_buf, 1);
if (rx_buf & 0x01){
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);
}
else{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
}
if (rx_buf & 0x02){
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
}
else{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
}
if (rx_buf & 0x04){
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
}
else{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);
}
return USBD_OK;
}
5.now update the usbd_hid.h
#define HID_EPIN_ADDR 0x81
//#define HID_EPIN_SIZE 0x04
#define HID_EPIN_SIZE 0x08
//define the OUT Endpoint
#define HID_EPOUT_ADDR 0x01
#define HID_EPOUT_SIZE 0x01
//#define USB_HID_CONFIG_DESC_SIZ 34
#define USB_HID_CONFIG_DESC_SIZ 41
#define USB_HID_DESC_SIZ 9
//#define HID_MOUSE_REPORT_DESC_SIZE 74
#define HID_MOUSE_REPORT_DESC_SIZE 65
#define HID_DESCRIPTOR_TYPE 0x21
#define HID_REPORT_DESC 0x22
Now let us take a look how it works:
Add a callback process at first.
...
static uint8_t USBD_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
...
USBD_ClassTypeDef USBD_HID =
{
...
/[i]When the data out (from host) callback this process DataOut[/i]/
USBD_HID_DataOut,
...
};
Open the OUT Endpoint when initializing the USB and prepare to receive the data.
Lots of people miss the “USBD_LL_PrepareReceive(…);”, so there is no callback trigger.
static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
uint8_t cfgidx)
{
...
USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE);
//set EP_OUT 1 prepared to received the data
USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR, &rx_buf, 1);
...
}
And following thing is dealing with the callback process ^_^