在萬利學習板自帶的演示例程中,有幾個USB的例程。如果我們想實現一個USB功能,可以拿里面的例子來改。
那么具體要改哪些地方呢?首先要改各種描述符,然后是具體的數據處理。我們拿USB搖桿鼠標范例來修改,把它改成USB鍵盤。該范例在目錄ManleyEKBoardEKSTM32FUSBDemo(8Mosc)USBDemoUSBLibdemosJoyStickMous下,將JoyStickMouse復制一份,改名為USBKeyboard,以用來修改。
描述符修改
描述符在文件usb_desc.c中。第一個要改的是設備描述符。設備描述符的結構都標準的,長度也是固定的。范例中的USB設備描述符如下:
/* USB Standard Device Descriptor */
const u8 Joystick_DeviceDescriptor[JOYSTICK_SIZ_DEVICE_DESC]=
{
0x12, /*bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
0x00, /*bcdUSB */
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
0x40, /*bMaxPacketSize40*/
0x83, /*idVendor (0x0483)*/
0x04,
0x10, /*idProduct = 0x5710*/
0x57,
0x00, /*bcdDevice rel. 2.00*/
0x02,
1, /*Index of string descriptor describing
manufacturer */
2, /*Index of string descriptor describing
product*/
3, /*Index of string descriptor describing the
device serial number */
0x01 /*bNumConfigurations*/
}; /* Joystick_DeviceDescriptor */
我們只需要修改這里的idVendor(即VID)和idProduct(即PID)即可。它們是用來供電腦端識別設備以加載驅動用的,所以必須不能跟現有的設備相沖突。VID和PID都是兩字節,低字節在前,高字節在后。例如這里的VID為0x0483,寫在里面就是0x83,0x04。我們將VID改成0x1234,將PID改成0x4321,即: 0x34, 0x12, 0x21, 0x43。
然后再修改配置描述符集合。配置描述符集合包括配置描述符、接口描述符、類特殊描述符(這里是HID描述符)、以及端點描述符。如果你需要增加端點,那么在最后增加就行了,注意要記得修改JOYSTICK_SIZ_CONFIG_DESC的值為配置描述符集合的長度。第一部分為配置描述符。通常這里不需要修改,除非你要改成該配置有多個接口(USB復合設備),那么應該修改bNumInterfaces,需要多少個就改成多少個,這里只有一個接口,所以值為1。第二部分為接口描述符,在接口描述符中決定該接口所實現的功能,例如HID設備,或者是大容量存儲設備等等。其中bInterfaceNumber為該接口的編號,從0開始。這里只有一個接口,所以它的值為0,如果又更多的接口,則依次編號。注意一個接口完整結束(包括該接口下的類特殊描述符和端點描述符)后,才開始一個新的接口。bNumEndpoints為該接口所使用的端點數目(不包括端點0),原來的程序是實現鼠標功能的,所以只有一個輸入端點。我們這里增加一個輸出端點,用來控制LED(鍵盤上有大寫字母鎖定、小鍵盤數字鍵鎖定等指示燈),因此將bNumEndpoints改為2。bInterfaceClass為接口所使用的類,這里指定為HID設備,USB鍵盤和鼠標都是HID設備,這里不用修改,如果你要實現其它設備,請根據USB協議所規定的類來修改。bInterfaceSubClass為接口所使用的子類,在HID設備類下規定了兩種子類,系統引導時能用的和不能用的,這里為1,表示系統引導時能使用。bInterfaceProtocol為接口的協議,原來為鼠標,這里改為1,鍵盤。第三部分為HID描述符,只有HID設備才有,如果你要修改成其它設備,則用其它設備的類特殊描述符代替或者沒有,在這里不用做修改。第四部分為輸入端點1的端點描述符,原來代碼中,設置的端點最大包長度(wMaxPacketSize)為4字節,我們將其改成8字節。另外,我們再增加一個輸出端點1,將最后的輸入端點1描述符復制一份,然后修改地址(bEndpointAddress)為0x01,這表示該端點為輸出端點,地址為1。由bEndpointAddress的最高位表示方向,1為輸入,0為輸出,最后4位表示地址。最后,要記得在usb_desc.h文件中修改JOYSTICK_SIZ_CONFIG_DESC的長度為41,因為我們增加了7字節。實際修改好的配置描述符集合如下:
/* USB Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const u8 Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] =
{
//以下為配置描述符
0x09, /* bLength: Configuation Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
JOYSTICK_SIZ_CONFIG_DESC,
/* wTotalLength: Bytes returned */
0x00,
0x01, /*bNumInterfaces: 1 interface*/
0x01, /*bConfigurationValue: Configuration value*/
0x00, /*iConfiguration: Index of string descriptor describing
the configuration*/
0xC0, /*bmAttributes: self powered */
0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
//以下為接口描述符
/************** Descriptor of Joystick Mouse 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*/
0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x01, /*bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
0, /*iInterface: Index of string descriptor*/
//以下為HID描述符
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /*bLength: HID Descriptor size*/
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
0x00, /*bcdHID: HID Class Spec release number*/
0x01,
0x00, /*bCountryCode: Hardware target country*/
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
0x22, /*bDescriptorType*/
JOYSTICK_SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor*/
0x00,
//以下為輸入端點1描述符
/******************** Descriptor of Joystick Mouse endpoint ********************/
/* 27 */
0x07, /*bLength: Endpoint Descriptor size*/
USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
0x81, /*bEndpointAddress: Endpoint Address (IN)*/
0x03, /*bmAttributes: Interrupt endpoint*/
0x08, /*wMaxPacketSize: 8 Byte max */
0x00,
0x20, /*bInterval: Polling Interval (32 ms)*/
//以下為輸出端但1描述符
/* 34 */
0x07, /*bLength: Endpoint Descriptor size*/
USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
0x01, /*bEndpointAddress: Endpoint Address (OUT)*/
0x03, /*bmAttributes: Interrupt endpoint*/
0x08, /*wMaxPacketSize: 8 Byte max */
0x00,
0x20, /*bInterval: Polling Interval (32 ms)*/
評論
查看更多