本帖最后由 gentleman 于 2023-9-4 08:37 编辑
注意本文使用了微软360手柄的PID VID ,仅供交流学习使用。
本文使用设备描述符 等信息均来自互联网
基于试验箱usb鼠标例程修改。
先更换设备描述符
- char code DEVICEDESC[18] =
- {
- // 0x12, //bLength(18);
- // 0x01, //bDescriptorType(Device);
- // 0x00,0x02, //bcdUSB(2.00);
- // 0x00, //bDeviceClass(0);
- // 0x00, //bDeviceSubClass0);
- // 0x00, //bDeviceProtocol(0);
- // 0x40, //bMaxPacketSize0(64);
- // 0xbf,0x34, //idVendor(34BF);
- // 0x04,0xff, //idProduct(FF04);
- // 0x00,0x01, //bcdDevice(1.00);
- // 0x01, //iManufacturer(1);
- // 0x02, //iProduct(2);
- // 0x00, //iSerialNumber(0);
- // 0x01, //bNumConfigurations(1);
-
- 0x12, // bLength(18);
- 0x01, // bDescriptorType(Device);
- 0x00, 0x02, // bcdUSB(2.00);
- 0xFF, // bDeviceClass(0);
- 0xFF, // bDeviceSubClass0);
- 0xFF, // bDeviceProtocol(0);
- 0x40, // bMaxPacketSize0(64);
- 0x5e, 0x04, // idVendor(34BF);
- 0x8e, 0x02, // idProduct(FF04);
- 0x14, 0x01, // bcdDevice(1.00);
- 0x01, // iManufacturer(1);
- 0x02, // iProduct(2);
- 0x03, // iSerialNumber(0);
- 0x01, // bNumConfigurations(1);
- };
复制代码
配置描述符
- char code CONFIGDESC[153]=
- {
- 0x09, // bLength(9);
- 0x02, // bDescriptorType(Configuration);
- 0x99, 0x00, // wTotalLength(41);
- 0x04, // bNumInterfaces(1);
- 0x01, // bConfigurationValue(1);
- 0x00, // iConfiguration(0);
- 0xa0, // bmAttributes(BUSPower);
- 0xfa, // MaxPower(100mA);
-
- /* ---------------------------------------------------- */
- // Interface 0: Control Data
- 0x09, // bLength
- 0x04, // bDescriptorType (INTERFACE)
- 0x00, // bInterfaceNumber
- 0x00, // bAlternateSetting
- 0x02, // bNumEndpoints
- 0xFF, // bInterfaceClass
- 0x5D, // bInterfaceSubClass
- 0x01, // bInterfaceProtocol
- 0x00, // iInterface
- // Unknown Descriptor (If0)
- 0x11, // bLength
- 0x21, // bDescriptorType
- 0x00, 0x01, 0x01, 0x25, // ???
- 0x81, // bEndpointAddress (IN, 1)
- 0x14, // bMaxDataSize
- 0x00, 0x00, 0x00, 0x00, 0x13, // ???
- 0x01, // bEndpointAddress (OUT, 1)
- 0x08, // bMaxDataSize
- 0x00, 0x00, // ???
- // Endpoint 1: Control Surface Send
- 0x07, // bLength
- 0x05, // bDescriptorType (ENDPOINT)
- 0x81, // bEndpointAddress (IN, 1)
- 0x03, // bmAttributes
- 0x20, 0x00, // wMaxPacketSize
- 0x04, // bInterval
- // Endpoint 1: Control Surface Receive
- 0x07, // bLength
- 0x05, // bDescriptorType (ENDPOINT)
- 0x01, // bEndpointAddress (OUT, 1)
- 0x03, // bmAttributes
- 0x20, 0x00, // wMaxPacketSize
- 0x08, // bInterval
- /* ---------------------------------------------------- */
- // Interface 1: Headset (and Expansion Port?)
- 0x09, // bLength
- 0x04, // bDescriptorType (INTERFACE)
- 0x01, // bInterfaceNumber
- 0x00, // bAlternateSetting
- 0x04, // bNumEndpoints
- 0xFF, // bInterfaceClass
- 0x5D, // bInterfaceSubClass
- 0x03, // bInterfaceProtocol
- 0x00, // iInterface
- // Unknown Descriptor (If1)
- 0x1B, // bLength
- 0x21, // bDescriptorType
- 0x00, 0x01, 0x01, 0x01, // ???
- 0x82, // bEndpointAddress (IN, 2)
- 0x40, // bMaxDataSize
- 0x01, // ???
- 0x02, // bEndpointAddress (OUT, 2)
- 0x20, // bMaxDataSize
- 0x16, // ???
- 0x83, // bEndpointAddress (IN, 3)
- 0x00, // bMaxDataSize
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, // ???
- 0x03, // bEndpointAddress (OUT, 3)
- 0x00, // bMaxDataSize
- 0x00, 0x00, 0x00, 0x00, 0x00, // ???
- // Endpoint 2: Microphone Data Send
- 0x07, // bLength
- 0x05, // bDescriptorType (ENDPOINT)
- 0x82, // bEndpointAddress (IN, 2)
- 0x03, // bmAttributes
- 0x20, 0x00, // wMaxPacketSize
- 0x02, // bInterval
- // Endpoint 2: Headset Audio Receive
- 0x07, // bLength
- 0x05, // bDescriptorType (ENDPOINT)
- 0x02, // bEndpointAddress (OUT, 2)
- 0x03, // bmAttributes
- 0x20, 0x00, // wMaxPacketSize
- 0x04, // bInterval
- // Endpoint 3: Unknown, Send
- 0x07, // bLength
- 0x05, // bDescriptorType (ENDPOINT)
- 0x83, // bEndpointAddress (IN, 3)
- 0x03, // bmAttributes
- 0x20, 0x00, // wMaxPacketSize
- 0x40, // bInterval
- // Endpoint 3: Unknown, Receive
- 0x07, // bLength
- 0x05, // bDescriptorType (ENDPOINT)
- 0x03, // bEndpointAddress (OUT, 3)
- 0x03, // bmAttributes
- 0x20, 0x00, // wMaxPacketSize
- 0x10, // bInterval
- /* ---------------------------------------------------- */
- // Interface 2: Unknown
- 0x09, // bLength
- 0x04, // bDescriptorType (INTERFACE)
- 0x02, // bInterfaceNumber
- 0x00, // bAlternateSetting
- 0x01, // bNumEndpoints
- 0xFF, // bInterfaceClass
- 0x5D, // bInterfaceSubClass
- 0x02, // bInterfaceProtocol
- 0x00, // iInterface
- // Unknown Descriptor (If2)
- 0x09, // bLength
- 0x21, // bDescriptorType
- 0x00, 0x01, 0x01, 0x22, // ???
- 0x84, // bEndpointAddress (IN, 4)
- 0x07, // bMaxDataSize
- 0x00, // ???
- // Endpoint 4: Unknown, Send
- 0x07, // bLength
- 0x05, // bDescriptorType (ENDPOINT)
- 0x84, // bEndpointAddress (IN, 4)
- 0x03, // bmAttributes
- 0x20, 0x00, // wMaxPacketSize
- 0x10, // bInterval
- /* ---------------------------------------------------- */
- // Interface 3: Security Method
- 0x09, // bLength
- 0x04, // bDescriptorType (INTERFACE)
- 0x03, // bInterfaceNumber
- 0x00, // bAlternateSetting
- 0x00, // bNumEndpoints
- 0xFF, // bInterfaceClass
- 0xFD, // bInterfaceSubClass
- 0x13, // bInterfaceProtocol
- 0x04, // iInterface
- // Unknown Descriptor (If3)
- 0x06, // bLength
- 0x41, // bDescriptorType
- 0x00, 0x01, 0x01, 0x03, // ???
- };
复制代码
在usb_req_class.c 中添加测试数据
- BYTE test[] = {0x00, 0x14,
- 0x0f, // 第一组按键 R L SE ST RI LE DO UP
- 0xf0, // 第二组按键 Y X B A NOP ME RB LB
- 0xff, // LT
- 0xff, // RT
- 0xff, // LX 双字
- 0xff, // LX2
- 0x00, // LY
- 0x00, // LY2
- 0xff, // RX
- 0xff, // RX2
- 0x78, // RY
- 0x00, // RY2
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
复制代码
和手柄按键/轴 有关的 是2~13 字节
已经写了注释
修改原程序扫描键码后发送数据的 函数 void usb_class_in()
- void usb_class_in()
- {
- BYTE button[3];
- BYTE i;
-
- if (DeviceState != DEVSTATE_CONFIGURED)
- return;
-
- if (!UsbInBusy && fKeyOK) {
- fKeyOK = 0;
-
- button[0] = 0;
- button[1] = 0;
- button[2] = 0;
-
- switch (bKeyCode) {
- case 0xfe:
- button[0] = 0x01;
- break;
- case 0xfd:
- button[0] = 0x04;
- break;
- case 0xfb:
- button[0] = 0x02;
- break;
- case 0xef:
- button[1] = 0xfc;
- break;
- case 0xdf:
- button[1] = 0x04;
- break;
- case 0xbf:
- button[2] = 0xfc;
- break;
- case 0x7f:
- button[2] = 0x04;
- break;
- }
-
- IE2 &= ~0x80; // EUSB = 0;
- UsbInBusy = 1;
- usb_write_reg(INDEX, 1);
- // for (i = 0; i < 3; i++) {
- // // usb_write_reg(FIFO1, button[i]);
- // //usb_write_fifo(FIFO1, test7, 7);
- // }
-
- usb_write_fifo(FIFO1, test, 20);
-
- usb_write_reg(INCSR1, INIPRDY);
-
- IE2 |= 0x80; // EUSB = 1;
- }
- }
复制代码
测试效果
按下试验箱矩阵键盘任意键
可以看到 ABXY 四个按键被成功按下
证明通信正常
第一步就先到这里,后面再去修改矩阵键盘的扫描,让他实现不同的功能
|