找回密码
 立即注册
查看: 1109|回复: 5

USB-HID 手柄制作 (一)

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-9-4 08:35:10 | 显示全部楼层 |阅读模式
本帖最后由 gentleman 于 2023-9-4 08:37 编辑

注意本文使用了微软360手柄的PID VID ,仅供交流学习使用。


本文使用设备描述符 等信息均来自互联网


       基于试验箱usb鼠标例程修改。


       先更换设备描述符
      
      
  1. char code DEVICEDESC[18] =
  2.     {
  3.         // 0x12,                   //bLength(18);
  4.         // 0x01,                   //bDescriptorType(Device);
  5.         // 0x00,0x02,              //bcdUSB(2.00);
  6.         // 0x00,                   //bDeviceClass(0);
  7.         // 0x00,                   //bDeviceSubClass0);
  8.         // 0x00,                   //bDeviceProtocol(0);
  9.         // 0x40,                   //bMaxPacketSize0(64);
  10.         // 0xbf,0x34,              //idVendor(34BF);
  11.         // 0x04,0xff,              //idProduct(FF04);
  12.         // 0x00,0x01,              //bcdDevice(1.00);
  13.         // 0x01,                   //iManufacturer(1);
  14.         // 0x02,                   //iProduct(2);
  15.         // 0x00,                   //iSerialNumber(0);
  16.         // 0x01,                   //bNumConfigurations(1);
  17.         0x12,       // bLength(18);
  18.         0x01,       // bDescriptorType(Device);
  19.         0x00, 0x02, // bcdUSB(2.00);
  20.         0xFF,       // bDeviceClass(0);
  21.         0xFF,       // bDeviceSubClass0);
  22.         0xFF,       // bDeviceProtocol(0);
  23.         0x40,       // bMaxPacketSize0(64);
  24.         0x5e, 0x04, // idVendor(34BF);
  25.         0x8e, 0x02, // idProduct(FF04);
  26.         0x14, 0x01, // bcdDevice(1.00);
  27.         0x01,       // iManufacturer(1);
  28.         0x02,       // iProduct(2);
  29.         0x03,       // iSerialNumber(0);
  30.         0x01,       // bNumConfigurations(1);
  31. };
复制代码
配置描述符

  1. char code CONFIGDESC[153]=
  2. {
  3.     0x09,       // bLength(9);
  4.         0x02,       // bDescriptorType(Configuration);
  5.         0x99, 0x00, // wTotalLength(41);
  6.         0x04,       // bNumInterfaces(1);
  7.         0x01,       // bConfigurationValue(1);
  8.         0x00,       // iConfiguration(0);
  9.         0xa0,       // bmAttributes(BUSPower);
  10.         0xfa,       // MaxPower(100mA);
  11.         /* ---------------------------------------------------- */
  12.         // Interface 0: Control Data
  13.         0x09, // bLength
  14.         0x04, // bDescriptorType (INTERFACE)
  15.         0x00, // bInterfaceNumber
  16.         0x00, // bAlternateSetting
  17.         0x02, // bNumEndpoints
  18.         0xFF, // bInterfaceClass
  19.         0x5D, // bInterfaceSubClass
  20.         0x01, // bInterfaceProtocol
  21.         0x00, // iInterface
  22.         // Unknown Descriptor (If0)
  23.         0x11,                         // bLength
  24.         0x21,                         // bDescriptorType
  25.         0x00, 0x01, 0x01, 0x25,       // ???
  26.         0x81,                         // bEndpointAddress (IN, 1)
  27.         0x14,                         // bMaxDataSize
  28.         0x00, 0x00, 0x00, 0x00, 0x13, // ???
  29.         0x01,                         // bEndpointAddress (OUT, 1)
  30.         0x08,                         // bMaxDataSize
  31.         0x00, 0x00,                   // ???
  32.         // Endpoint 1: Control Surface Send
  33.         0x07,       // bLength
  34.         0x05,       // bDescriptorType (ENDPOINT)
  35.         0x81,       // bEndpointAddress (IN, 1)
  36.         0x03,       // bmAttributes
  37.         0x20, 0x00, // wMaxPacketSize
  38.         0x04,       // bInterval
  39.         // Endpoint 1: Control Surface Receive
  40.         0x07,       // bLength
  41.         0x05,       // bDescriptorType (ENDPOINT)
  42.         0x01,       // bEndpointAddress (OUT, 1)
  43.         0x03,       // bmAttributes
  44.         0x20, 0x00, // wMaxPacketSize
  45.         0x08,       // bInterval
  46.         /* ---------------------------------------------------- */
  47.         // Interface 1: Headset (and Expansion Port?)
  48.         0x09, // bLength
  49.         0x04, // bDescriptorType (INTERFACE)
  50.         0x01, // bInterfaceNumber
  51.         0x00, // bAlternateSetting
  52.         0x04, // bNumEndpoints
  53.         0xFF, // bInterfaceClass
  54.         0x5D, // bInterfaceSubClass
  55.         0x03, // bInterfaceProtocol
  56.         0x00, // iInterface
  57.         // Unknown Descriptor (If1)
  58.         0x1B,                               // bLength
  59.         0x21,                               // bDescriptorType
  60.         0x00, 0x01, 0x01, 0x01,             // ???
  61.         0x82,                               // bEndpointAddress (IN, 2)
  62.         0x40,                               // bMaxDataSize
  63.         0x01,                               // ???
  64.         0x02,                               // bEndpointAddress (OUT, 2)
  65.         0x20,                               // bMaxDataSize
  66.         0x16,                               // ???
  67.         0x83,                               // bEndpointAddress (IN, 3)
  68.         0x00,                               // bMaxDataSize
  69.         0x00, 0x00, 0x00, 0x00, 0x00, 0x16, // ???
  70.         0x03,                               // bEndpointAddress (OUT, 3)
  71.         0x00,                               // bMaxDataSize
  72.         0x00, 0x00, 0x00, 0x00, 0x00,       // ???
  73.         // Endpoint 2: Microphone Data Send
  74.         0x07,       // bLength
  75.         0x05,       // bDescriptorType (ENDPOINT)
  76.         0x82,       // bEndpointAddress (IN, 2)
  77.         0x03,       // bmAttributes
  78.         0x20, 0x00, // wMaxPacketSize
  79.         0x02,       // bInterval
  80.         // Endpoint 2: Headset Audio Receive
  81.         0x07,       // bLength
  82.         0x05,       // bDescriptorType (ENDPOINT)
  83.         0x02,       // bEndpointAddress (OUT, 2)
  84.         0x03,       // bmAttributes
  85.         0x20, 0x00, // wMaxPacketSize
  86.         0x04,       // bInterval
  87.         // Endpoint 3: Unknown, Send
  88.         0x07,       // bLength
  89.         0x05,       // bDescriptorType (ENDPOINT)
  90.         0x83,       // bEndpointAddress (IN, 3)
  91.         0x03,       // bmAttributes
  92.         0x20, 0x00, // wMaxPacketSize
  93.         0x40,       // bInterval
  94.         // Endpoint 3: Unknown, Receive
  95.         0x07,       // bLength
  96.         0x05,       // bDescriptorType (ENDPOINT)
  97.         0x03,       // bEndpointAddress (OUT, 3)
  98.         0x03,       // bmAttributes
  99.         0x20, 0x00, // wMaxPacketSize
  100.         0x10,       // bInterval
  101.         /* ---------------------------------------------------- */
  102.         // Interface 2: Unknown
  103.         0x09, // bLength
  104.         0x04, // bDescriptorType (INTERFACE)
  105.         0x02, // bInterfaceNumber
  106.         0x00, // bAlternateSetting
  107.         0x01, // bNumEndpoints
  108.         0xFF, // bInterfaceClass
  109.         0x5D, // bInterfaceSubClass
  110.         0x02, // bInterfaceProtocol
  111.         0x00, // iInterface
  112.         // Unknown Descriptor (If2)
  113.         0x09,                   // bLength
  114.         0x21,                   // bDescriptorType
  115.         0x00, 0x01, 0x01, 0x22, // ???
  116.         0x84,                   // bEndpointAddress (IN, 4)
  117.         0x07,                   // bMaxDataSize
  118.         0x00,                   // ???
  119.         // Endpoint 4: Unknown, Send
  120.         0x07,       // bLength
  121.         0x05,       // bDescriptorType (ENDPOINT)
  122.         0x84,       // bEndpointAddress (IN, 4)
  123.         0x03,       // bmAttributes
  124.         0x20, 0x00, // wMaxPacketSize
  125.         0x10,       // bInterval
  126.         /* ---------------------------------------------------- */
  127.         // Interface 3: Security Method
  128.         0x09, // bLength
  129.         0x04, // bDescriptorType (INTERFACE)
  130.         0x03, // bInterfaceNumber
  131.         0x00, // bAlternateSetting
  132.         0x00, // bNumEndpoints
  133.         0xFF, // bInterfaceClass
  134.         0xFD, // bInterfaceSubClass
  135.         0x13, // bInterfaceProtocol
  136.         0x04, // iInterface
  137.         // Unknown Descriptor (If3)
  138.         0x06,                   // bLength
  139.         0x41,                   // bDescriptorType
  140.         0x00, 0x01, 0x01, 0x03, // ???
  141. };
复制代码




在usb_req_class.c  中添加测试数据

  1. BYTE test[] = {0x00, 0x14,
  2.                0x0f, // 第一组按键  R  L   SE   ST   RI   LE   DO   UP
  3.                0xf0, // 第二组按键  Y  X   B    A    NOP  ME   RB   LB
  4.                0xff, // LT
  5.                0xff, // RT
  6.                0xff, // LX   双字
  7.                0xff, // LX2
  8.                0x00, // LY
  9.                0x00, // LY2
  10.                0xff, // RX
  11.                0xff, // RX2
  12.                0x78, // RY
  13.                0x00, // RY2
  14.                0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
复制代码
和手柄按键/轴 有关的 是2~13 字节
已经写了注释

修改原程序扫描键码后发送数据的 函数  void usb_class_in()


  1. void usb_class_in()
  2. {
  3.     BYTE button[3];
  4.     BYTE i;
  5.     if (DeviceState != DEVSTATE_CONFIGURED)
  6.         return;
  7.     if (!UsbInBusy && fKeyOK) {
  8.         fKeyOK = 0;
  9.         button[0] = 0;
  10.         button[1] = 0;
  11.         button[2] = 0;
  12.         switch (bKeyCode) {
  13.             case 0xfe:
  14.                 button[0] = 0x01;
  15.                 break;
  16.             case 0xfd:
  17.                 button[0] = 0x04;
  18.                 break;
  19.             case 0xfb:
  20.                 button[0] = 0x02;
  21.                 break;
  22.             case 0xef:
  23.                 button[1] = 0xfc;
  24.                 break;
  25.             case 0xdf:
  26.                 button[1] = 0x04;
  27.                 break;
  28.             case 0xbf:
  29.                 button[2] = 0xfc;
  30.                 break;
  31.             case 0x7f:
  32.                 button[2] = 0x04;
  33.                 break;
  34.         }
  35.         IE2 &= ~0x80; // EUSB = 0;
  36.         UsbInBusy = 1;
  37.         usb_write_reg(INDEX, 1);
  38.         // for (i = 0; i < 3; i++) {
  39.         //     // usb_write_reg(FIFO1, button[i]);
  40.         //     //usb_write_fifo(FIFO1, test7, 7);
  41.         // }
  42.         usb_write_fifo(FIFO1, test, 20);
  43.         usb_write_reg(INCSR1, INIPRDY);
  44.         IE2 |= 0x80; // EUSB = 1;
  45.     }
  46. }
复制代码
测试效果

截图202309040826023763.jpg

按下试验箱矩阵键盘任意键
可以看到 ABXY 四个按键被成功按下
证明通信正常

第一步就先到这里,后面再去修改矩阵键盘的扫描,让他实现不同的功能



HID 手柄阶段1.7z

94.53 KB, 下载次数: 127

回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-10 08:37:25

18

主题

95

回帖

513

积分

荣誉版主

积分
513
发表于 2023-9-4 09:35:43 | 显示全部楼层
强烈支持原创
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-9-4 11:23:24 | 显示全部楼层

  水平有限,抛砖引玉。

点评

这么好的帖子怎么能不顶上去呢?  详情 回复 发表于 2023-9-4 14:35
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2025-04-10 08:37:25

18

主题

95

回帖

513

积分

荣誉版主

积分
513
发表于 2023-9-4 14:35:54 | 显示全部楼层
gentl*** 发表于 2023-9-4 11:23
水平有限,抛砖引玉。

这么好的帖子怎么能不顶上去呢?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:98
  • 最近打卡:2025-04-29 07:45:37

3

主题

74

回帖

358

积分

中级会员

积分
358
发表于 2023-9-19 16:43:56 | 显示全部楼层
楼主威武
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-9-19 18:46:20 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 20:56 , Processed in 0.327345 second(s), 85 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表