STM 32プロセッサベースのUSB HIDアナログマウスキーボード(1)-USB HIDベース

9991 ワード

HIDはHuman Interface Deviceの略で、HIDデバイスはキーボード、マウス、ゲームレバーなど、人と直接対話するデバイスです.しかし、HIDデバイスは必ずしもヒューマン・インターフェースを必要としない.HIDカテゴリの仕様に合致するデバイスがすべてHIDデバイスである限り.交換されたデータはレポートまたはレポートと呼ばれる構造内に格納され、デバイスのファームウェアはHIDレポートのフォーマットをサポートする必要があります.ホストは、制御および中断転送においてレポートを転送および要求し、データを転送および受信する.レポートのフォーマットは非常に弾力性があり、任意のカテゴリのデータを処理できます.デバイスにはHIDインタフェースのほかに、他のUSBインタフェースも含まれている可能性があります.例えば、映像表示装置は、HIDインタフェースを用いて輝度、コントラスト、更新率のソフトウェア制御を行い、従来の映像インタフェースを用いて表示すべきデータを伝送することができる.USB拡声器はリアルタイム伝送で音声を再生し、HIDインタフェースで音量、振動、低音などを制御します.HIDインタフェースは通常、従来の制御インタフェースよりも安価である.USBプロトコルの紹介は、ネット上のチュートリアルを参照してください.
USBデバイス列挙プロセスの紹介:http://lastnight1034.blog.163.com/blog/static/167118149201211710164820/
USBデバイス記述子:http://blog.csdn.net/saloon_yuan/article/details/7837492
STM 32のUSB機能を使用してHIDデバイスの機能を実現し、ST公式のUSBライブラリを使用して、公式のルーチンで修正することができます.デバイス記述子、構成記述子、インタフェース記述子、HID記述子、エンドポイント記述子、文字列記述子、およびHIDデバイス固有のレポート記述子を変更して、特定の機能を完了します.
レポートおよびレポート記述子の概要リファレンス:http://www.baiheee.com/Documents/081126/081126115257.htm
USB HIDデバイスは、レポートを介してデータを転送し、入力レポートと出力レポートをレポートします.入力レポートはUSBデバイスがホストに送信するもので、例えばUSBマウスはマウスの移動やマウスのクリックなどの情報をパソコンに返し、キーボードはボタンデータをパソコンに返すなどである.出力レポートは、ホストがUSBデバイスに送信するもので、キーボードのデジタルキーボードロックランプや大文字ロックランプなどです.レポートはパケットで、転送するデータが含まれています.入力レポートは入力端点を割り込むことによって入力され、出力レポートは少し異なり、出力端点を割り込まない場合は出力端点0を制御して送信することができ、割り込み出力端点がある場合は出力端点を割り込むことによって発行することができる.レポート記述子は、レポートとレポートの中のデータが何に使われているかを記述します.これにより、USB HOSTはレポートの中のデータが示す意味を分析することができます.これは、入力エンドポイント0の戻りを制御することによって、ホストがレポート記述子の取得コマンドを使用してレポート記述子を取得し、この要求がデバイスではなくインタフェースに送信されることに注意する.1つのレポート記述子は、複数のレポートを記述することができ、異なるレポートは、レポートIDによって識別され、レポートIDは、レポートの先頭、すなわち、最初のバイトである(デバイスが送信した最初のバイトデータは、ホストにレポートのタイプを識別させ、このレポートを解析するためにどのレポート記述子を使用するかを示すレポートIDである).レポート記述子にレポートIDが規定されていない場合、レポートにはIDフィールドがなく、最初はデータである.詳細については、USB HIDプロトコルを参照してください.USBレポート記述子は、HID Descriptor toolを使用して生成することができ、このツールはオンラインでダウンロードすることができます. 
具体的な記述子は次のようになります.
/* 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*/
	0x34,                       /*idVendor (0x1234)*/
	0x12,
	0x21,                       /*idProduct = 0x4321*/
	0x44,
	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 */


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*/
	0x0A,          /*wMaxPacketSize: 10 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*/
	0x0A,          /*wMaxPacketSize: 10 Byte max */
	0x00,
	0x20,          /*bInterval: Polling Interval (32 ms)*/
	/* 41 */
}; /* MOUSE_ConfigDescriptor */

const u8 Joystick_ReportDescriptor[JOYSTICK_SIZ_REPORT_DESC] =
{
	/************************USB¼üÅ̲¿·Ö±¨¸æÃèÊö·û**********************/
	/*******************************************************************/
	0x05, 0x01, // USAGE_PAGE (Generic Desktop)
	0x09, 0x06, // USAGE (Keyboard)
	0xa1, 0x01, // COLLECTION (Application)
	0x85, 0x01, // Report ID (1)
	0x05, 0x07, // USAGE_PAGE (Keyboard/Keypad)
	0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
	0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
	0x15, 0x00, // LOGICAL_MINIMUM (0)
	0x25, 0x01, // LOGICAL_MAXIMUM (1)
	0x95, 0x08, // REPORT_COUNT (8)
	0x75, 0x01, // REPORT_SIZE (1)
	0x81, 0x02, // INPUT (Data,Var,Abs)
	0x95, 0x01, // REPORT_COUNT (1)
	0x75, 0x08, // REPORT_SIZE (8)
	0x81, 0x03, // INPUT (Cnst,Var,Abs)
	0x95, 0x06, // REPORT_COUNT (6)
	0x75, 0x08, // REPORT_SIZE (8)
	0x15, 0x00, // LOGICAL_MINIMUM (0)
	0x25, 0xFF, // LOGICAL_MAXIMUM (255)
	0x05, 0x07, // USAGE_PAGE (Keyboard/Keypad)
	0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
	0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
	0x81, 0x00, // INPUT (Data,Ary,Abs)
	0x25, 0x01, // LOGICAL_MAXIMUM (1) 
	0x95, 0x05, // REPORT_COUNT (5)
	0x75, 0x01, // REPORT_SIZE (1)
	0x05, 0x08, // USAGE_PAGE (LEDs)
	0x19, 0x01, // USAGE_MINIMUM (Num Lock)
	0x29, 0x05, // USAGE_MAXIMUM (Kana)
	0x91, 0x02, // OUTPUT (Data,Var,Abs)
	0x95, 0x01, // REPORT_COUNT (1)		 
	0x75, 0x03, // REPORT_SIZE (3)
	//3¸öbitÀ´´Õ³ÉÒ»×Ö½Ú¡£										
	0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
	0xc0,		// END_COLLECTION

	/************************USBÊó±ê²¿·Ö±¨¸æÃèÊö·û**********************/
	/*******************************************************************/
	0x05, 0x01, // USAGE_PAGE (Generic Desktop)
	0x09, 0x02, // USAGE (Mouse)
	0xa1, 0x01, // COLLECTION (Application)
	0x85, 0x02, // Report ID (2)
	0x09, 0x01, // USAGE (Pointer)
	0xa1, 0x00, // COLLECTION (Physical)
	0x05, 0x09, // USAGE_PAGE (Button)
	0x19, 0x01, // USAGE_MINIMUM (Button 1)
	0x29, 0x03, // USAGE_MAXIMUM (Button 3)						  
	0x15, 0x00, // LOGICAL_MINIMUM (0)
	0x25, 0x01, // LOGICAL_MAXIMUM (1)
	0x95, 0x03, // REPORT_COUNT (3)
	0x75, 0x01, // REPORT_SIZE (1)
	0x81, 0x02, // INPUT (Data,Var,Abs)
	0x95, 0x01, // REPORT_COUNT (1)
	0x75, 0x05, // REPORT_SIZE (5)
	0x81, 0x03, // INPUT (Cnst,Var,Abs)
	0x05, 0x01, // USAGE_PAGE (Generic Desktop)
	0x09, 0x30, // USAGE (X)
	0x09, 0x31, // USAGE (Y)
	0x09, 0x38, // USAGE (Wheel)
	0x15, 0x81, // LOGICAL_MINIMUM (-127)
	0x25, 0x7f, // LOGICAL_MAXIMUM (127)
	0x75, 0x08, // REPORT_SIZE (8)
	0x95, 0x03, // REPORT_COUNT (3)
	0x81, 0x06, // INPUT (Data,Var,Rel)
	0xc0,       // END_COLLECTION
	0xc0        // END_COLLECTION
};

/* USB String Descriptors (optional) */
const u8 Joystick_StringLangID[JOYSTICK_SIZ_STRING_LANGID] =
{
	JOYSTICK_SIZ_STRING_LANGID,
	USB_STRING_DESCRIPTOR_TYPE,
	0x09,
	0x04
}; /* LangID = 0x0409: U.S. English */

const u8 Joystick_StringVendor[JOYSTICK_SIZ_STRING_VENDOR] =
{
	JOYSTICK_SIZ_STRING_VENDOR, /* Size of Vendor string */
	USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType*/
	/* Manufacturer: "STMicroelectronics" */
	'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
	'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
	'c', 0, 's', 0
};

const u8 Joystick_StringProduct[JOYSTICK_SIZ_STRING_PRODUCT] =
{
	JOYSTICK_SIZ_STRING_PRODUCT,          /* bLength */
	USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
	'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'J', 0,
	'o', 0, 'y', 0, 's', 0, 't', 0, 'i', 0, 'c', 0, 'k', 0
};

u8 Joystick_StringSerial[JOYSTICK_SIZ_STRING_SERIAL] =
{
	JOYSTICK_SIZ_STRING_SERIAL,           /* bLength */
	USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
	'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0
};

以下、主に上記のいくつかの記述子を紹介します.次の図は、各記述子のタイプ値です.
1、デバイス記述子DeviceDesciptor
2、構成記述子コンフィギュレーションDescriptor
3、インタフェースディスクリプタInterfaceDescriptor
4、HIDディスクリプタHIDDescriptor
HIDデバイス固有の記述子で、HIDデバイスのプロパティとレポート記述子のサイズを構成します.
5、端点記述子EndpointDescriptor
エンドポイント記述子は、エンドポイント番号およびエンドポイントを構成するための入出力です.
6、レポート記述子ReportDescriptor
報告記述子は、HIDデバイス固有の記述子であり、送信されたデータを記述するフォーマットに適しており、ホストにマシンから送信されたデータをどのように解析するかを示すために使用される.
7、文字列記述子StringDescriptor