[APM32E1] 【APM32E103xE测评】+USB键盘鼠标Gamepad手柄一体复合设备

[复制链接]
 楼主| WoodData 发表于 2022-5-16 10:20 | 显示全部楼层 |阅读模式
继上次实现了USB的Gamepad手柄之后,见贴(https://bbs.21ic.com/icview-3220444-1-1.html)。本次实现了键盘鼠标手柄一体的复合设备。

效果如下:
1.png
板上的2个按键模拟了3个设备发送数据。

下面简单说下实现过程:
首先修改增加配置描述符:
  1. const uint8_t g_hidConfigDescriptor[] =
  2. {
  3. // configuration_descriptor hid_configuration_descriptor
  4.    0x09,                               // Length
  5.    0x02,                               // Type
  6.    HID_CONFIG_DESCRIPTOR_SIZE&0xff,HID_CONFIG_DESCRIPTOR_SIZE>>8,// Totallength (= 9+9+9+7+7)
  7.    0x03,                               // NumInterfaces          ?????
  8.    0x01,                               // bConfigurationValue
  9.    0x00,                               // iConfiguration ??????????
  10.    0x80,                               // bmAttributes
  11.    0xc0,                               // MaxPower (in 2mA units)

  12. // interface_descriptor hid_interface_descriptor
  13.    0x09,                               // bLength
  14.    0x04,                               // bDescriptorType
  15.    0x00,                               // bInterfaceNumber        ???,???????????
  16.    0x00,                               // bAlternateSetting        ???????
  17.    0x02,                               // bNumEndpoints                 ??????????,?0?????????0
  18.    0x03,                               // bInterfaceClass (3 = HID)
  19.    0x00,                               // bInterfaceSubClass
  20.    0x00,                               // bInterfaceProcotol
  21.    0x04,                               // iInterface Index of string descriptor
  22. // class_descriptor hid_descriptor
  23.    0x09,                               // bLength
  24.    0x21,                               // bDescriptorType
  25.    0x01,0x01,                          // bcdHID
  26.    0x00,                               // bCountryCode
  27.    0x01,                               // bNumDescriptors
  28.    0x22,                               // bDescriptorType
  29.    HID_GAMEPAD_REPORT_DESCRIPTOR_SIZE,0X00,                   // wItemLength (tot. len. of report descriptor)
  30. // IN endpoint (mandatory for HID)
  31. // endpoint1_descriptor hid_endpoint_in_descriptor
  32.    0x07,                               // bLength
  33.    0x05,                               // bDescriptorType
  34.    0x81,                               // bEndpointAddress
  35.    0x03,                               // bmAttributes        00-????,01-????,10-???,11-????
  36.    0x40,0x00,                                    // MaxPacketSize (LITTLE ENDIAN)
  37.    10,                               // bInterval
  38. // OUT endpoint (optional for HID)
  39. // endpoint1_descriptor hid_endpoint_out_descriptor
  40.    0x07,                               // bLength
  41.    0x05,                               // bDescriptorType
  42.    0x01,                               // bEndpointAddress
  43.    0x03,                               // bmAttributes
  44.    0x40,0x00,                                   // MaxPacketSize (LITTLE ENDIAN)
  45.    10,                               // bInterval


  46. // interface_descriptor hid_interface_descriptor        222222222222222222222222222222
  47.    0x09,                               // bLength
  48.    0x04,                               // bDescriptorType
  49.    0x01,                               // bInterfaceNumber        ???,???????????
  50.    0x00,                               // bAlternateSetting        ???????
  51.    0x02,                               // bNumEndpoints                 ??????????,?0?????????0
  52.    0x03,                               // bInterfaceClass (3 = HID)
  53.    0x01,                               // bInterfaceSubClass  0-nosub,1-bootclass,2-reserved
  54.    0x01,                               // bInterfaceProcotol  0-No,1-keyboard,2-mouse,
  55.    0x05,                               // iInterface Index of string descriptor
  56. // class_descriptor hid_descriptor
  57.    0x09,                               // bLength
  58.    0x21,                               // bDescriptorType
  59.    0x01,0x01,                          // bcdHID
  60.    0x00,                               // bCountryCode
  61.    0x01,                               // bNumDescriptors
  62.    0x22,                               // bDescriptorType
  63.    HID_KEYBOARD_REPORT_DESCRIPTOR_SIZE,0x00,// wItemLength (tot. len. of report descriptor)
  64. // IN endpoint (mandatory for HID)
  65. // endpoint1_descriptor hid_endpoint_in_descriptor
  66.    0x07,                               // bLength
  67.    0x05,                               // bDescriptorType
  68.    0x82,                               // bEndpointAddress
  69.    0x03,                               // bmAttributes        00-????,01-????,10-???,11-????
  70.    0x40,0x00,                                    // MaxPacketSize (LITTLE ENDIAN)
  71.    0x0a,                               // bInterval
  72. // OUT endpoint (optional for HID)
  73. // endpoint1_descriptor hid_endpoint_out_descriptor
  74.    0x07,                               // bLength
  75.    0x05,                               // bDescriptorType
  76.    0x02,                               // bEndpointAddress
  77.    0x03,                               // bmAttributes
  78.    0x40,0x00,                                   // MaxPacketSize (LITTLE ENDIAN)
  79.    0x0a,                                // bInterval

  80.   /************** Descriptor of Mouse HID interface ****************/
  81.   /* 09 */
  82.   0x09,         /*bLength: Interface Descriptor size*/
  83.   0x04,                        /*bDescriptorType: Interface descriptor type*/
  84.   0x02,         /*bInterfaceNumber: Number of Interface*/
  85.   0x00,         /*bAlternateSetting: Alternate setting*/
  86.   0x01,         /*bNumEndpoints*/
  87.   0x03,         /*bInterfaceClass: CUSTOM_HID*/
  88.   0x01,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
  89.   0x02,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
  90.   0X06,         /*iInterface: Index of string descriptor*/
  91.   /******************** Descriptor of CUSTOM_HID *************************/
  92.   /* 18 */
  93.   0x09,         /*bLength: CUSTOM_HID Descriptor size*/
  94.   0x21,                 /*bDescriptorType: CUSTOM_HID*/
  95.   0x11,         /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
  96.   0x01,
  97.   0x00,         /*bCountryCode: Hardware target country*/
  98.   0x01,         /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
  99.   0x22,         /*bDescriptorType*/
  100.   HID_MOUSE_REPORT_DESCRIPTOR_SIZE,0x00,/*wItemLength: Total length of Report descriptor*/
  101.   
  102.   /******************** Descriptor of Custom HID endpoints ********************/
  103.   /* 27 */
  104.   0x07,                  /*bLength: Endpoint Descriptor size*/
  105.   0x05,                         /*bDescriptorType:*/  
  106.   0x83,                     /*bEndpointAddress: Endpoint Address (IN)*/
  107.   0x03,                  /*bmAttributes: Interrupt endpoint*/
  108.   0x40,0x00,                /*wMaxPacketSize: 4 Byte max */  
  109.   0x08,                  /*bInterval: Polling Interval (20 ms)*/
  110.   /* 34 */

  111. };
其次就是3个设备的报告描述符
  1. /**
  2. * [url=home.php?mod=space&uid=247401]@brief[/url]   HID report descriptor
  3. */
  4. const uint8_t g_hidGamepadReportDescriptor[] =
  5. {
  6.     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
  7.     0x09, 0x05,                    // USAGE (Game Pad)
  8.     0xa1, 0x01,                    // COLLECTION (Application)
  9.     0x09, 0x01,                    //   USAGE (Pointer)
  10.     0xa1, 0x00,                    //   COLLECTION (Physical)
  11.     0x09, 0x30,                    //     USAGE (X)
  12.     0x09, 0x31,                    //     USAGE (Y)
  13.     0x09, 0x33,                    //     USAGE (RX)
  14.     0x09, 0x34,                    //     USAGE (RY)
  15.     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
  16.     0x25, 0x7f,                        //     LOGICAL_MAXIMUM (127)       
  17.     0x75, 0x08,                    //     REPORT_SIZE (8)
  18.     0x95, 0x04,                    //     REPORT_COUNT (4)
  19.     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
  20.     0xc0,                          //     END_COLLECTION
  21.        
  22.     0x09, 0x36,                    //   USAGE (Silder)
  23.     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
  24.     0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
  25.     0x75, 0x08,                    //   REPORT_SIZE (8)
  26.     0x95, 0x01,                    //   REPORT_COUNT (1)
  27.     0x81, 0x02,                    //   INPUT (Data,Var,Abs)
  28.        
  29.     0x09, 0x39,                    //   USAGE (Hat switch)
  30.     0x15, 0x01,                    //   LOGICAL_MINIMUM (1)
  31.     0x25, 0x08,                    //   LOGICAL_MAXIMUM (8)
  32.     0x75, 0x08,                    //   REPORT_SIZE (8)
  33.     0x95, 0x01,                    //   REPORT_COUNT (1)
  34.     0x81, 0x42,                    //   INPUT (Data,Var,Abs,Null)
  35.        
  36.     0x05, 0x09,                    //   USAGE_PAGE (Button)
  37.     0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
  38.     0x29, 0x10,                    //   USAGE_MAXIMUM (Button 16)
  39.     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
  40.     0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
  41.     0x75, 0x01,                    //   REPORT_SIZE (1)
  42.     0x95, 0x10,                    //   REPORT_COUNT (16)
  43.     0x81, 0x02,                    //   INPUT (Data,Var,Abs)
  44.    
  45.     0x06, 0x00, 0xff,              //   USAGE_PAGE (Vendor Defined Page 1)
  46.     0x09, 0x01,                    //   USAGE (Vendor Usage 1)
  47.     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
  48.     0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
  49.     0x75, 0x08,                    //   REPORT_SIZE (8)
  50.     0x95, 0x04,                    //   REPORT_COUNT (4)
  51.     0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)       
  52.    
  53.     0xc0                           // END_COLLECTION
  54. };
  1. const uint8_t g_hidKeyboardReportDescriptor[]=
  2. {
  3.     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
  4.     0x09, 0x06,                    // USAGE (Keyboard)
  5.     0xa1, 0x01,                    // COLLECTION (Application)
  6.        
  7.     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
  8.     0x19, 0xE0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
  9.     0x29, 0xE7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
  10.     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
  11.     0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
  12.     0x75, 0x01,                    //   REPORT_SIZE (1)
  13.     0x95, 0x08,                    //   REPORT_COUNT (8)
  14.     0x81, 0x02,                    //   INPUT (Data,Var,Abs)
  15.        
  16.     0x95, 0x01,                    //   REPORT_COUNT (1)
  17.     0x75, 0x08,                    //   REPORT_SIZE (8)
  18.     0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)

  19.     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
  20.     0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
  21.     0x29, 0xdd,                    //   USAGE_MAXIMUM (Keyboard Application)
  22.     0x95, 0x06,                    //   REPORT_COUNT (6)
  23.     0x75, 0x08,                    //   REPORT_SIZE (8)
  24.     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
  25.     0x25, 0xdd,                    //   LOGICAL_MAXIMUM (164)       
  26.     0x81, 0x00,                    //   INPUT (Data,Ary,Abs)

  27.     0x05, 0x08,                    //   USAGE_PAGE (LEDs)
  28.     0x19, 0x01,                    //   USAGE_MINIMUM (Num Lock)
  29.     0x29, 0x05,                    //   USAGE_MAXIMUM (Kana)
  30.     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
  31.     0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)       
  32.     0x95, 0x05,                    //   REPORT_COUNT (5)
  33.     0x75, 0x01,                    //   REPORT_SIZE (1)       
  34.     0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
  35.     0x95, 0x01,                    //   REPORT_COUNT (1)
  36.     0x75, 0x03,                    //   REPORT_SIZE (3)
  37.     0x91, 0x03,                    //   OUTPUT (Cnst,Var,Abs)
  38.        
  39.     0xc0                           // END_COLLECTION
  40. };
  1. const uint8_t g_hidMouseReportDescriptor[]=
  2. {
  3.     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
  4.     0x09, 0x02,                    // USAGE (Mouse)
  5.     0xa1, 0x01,                    // COLLECTION (Application)
  6.     0x09, 0x01,                    //   USAGE (Pointer)
  7.     0xa1, 0x00,                    //   COLLECTION (Physical)
  8.        
  9.     0x05, 0x09,                    //     USAGE_PAGE (Button)
  10.     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
  11.     0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
  12.     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
  13.     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
  14.     0x95, 0x03,                    //     REPORT_COUNT (3)
  15.     0x75, 0x01,                    //     REPORT_SIZE (1)
  16.     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
  17.     0x95, 0x01,                    //     REPORT_COUNT (1)
  18.     0x75, 0x05,                    //     REPORT_SIZE (5)
  19.     0x81, 0x01,                    //     INPUT (Cnst,Ary,Abs)
  20.        
  21.     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
  22.     0x09, 0x30,                    //     USAGE (X)
  23.     0x09, 0x31,                    //     USAGE (Y)
  24.     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
  25.     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
  26.     0x75, 0x08,                    //     REPORT_SIZE (8)
  27.     0x95, 0x02,                    //     REPORT_COUNT (2)
  28.     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
  29.        
  30.     0x09, 0x38,                    //     USAGE (Wheel)
  31.     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
  32.     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
  33.     0x75, 0x08,                    //     REPORT_SIZE (8)
  34.     0x95, 0x01,                    //     REPORT_COUNT (1)
  35.     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
  36.        
  37.     0xc0,                          //     END_COLLECTION
  38.        
  39.         0xc0
  40. };
  1. /** Device descriptor */
  2. const USB_Descriptor_T s_deviceDescriptor = {g_hidDeviceDescriptor, HID_DEVICE_DESCRIPTOR_SIZE};
  3. /** Config descriptor */
  4. const USB_Descriptor_T s_configDescriptor = {g_hidConfigDescriptor, HID_CONFIG_DESCRIPTOR_SIZE};
  5. /** String descriptor */
  6. const USB_Descriptor_T s_stringDescriptor[] =
  7. {
  8.     {g_hidLandIDString,     HID_LANGID_STRING_SIZE},
  9.     {g_hidVendorString,     HID_VENDOR_STRING_SIZE},
  10.     {g_hidProductString,    HID_PRODUCT_STRING_SIZE},
  11.     {g_hidSerialString,     HID_SERIAL_STRING_SIZE},
  12.     {g_Class1StringDesc,    16},
  13.     {g_Class2StringDesc,    18},
  14.     {g_Class3StringDesc,    12},
  15. };

  16. const USB_Descriptor_T s_reportDescriptor[] =
  17. {
  18.     {g_hidGamepadReportDescriptor,  HID_GAMEPAD_REPORT_DESCRIPTOR_SIZE},
  19.     {g_hidKeyboardReportDescriptor, HID_KEYBOARD_REPORT_DESCRIPTOR_SIZE},
  20.     {g_hidMouseReportDescriptor,    HID_MOUSE_REPORT_DESCRIPTOR_SIZE},
  21. };
接着就是USB端点的初始化。本次要使用端点1,端点2的输入输出端点,端点3的输入端点。
初始化如下:
  1. void HidMouse_Reset(void)
  2. {
  3.     uint8_t i;

  4.     s_usbConfigStatus = 0;  //usb not config,disable send data
  5.    
  6.     USBD_SetBufferTable(USB_BUFFER_TABLE_ADDR);
  7.     //endpoint 0 init
  8.     USBD_ResetEPKind(USBD_EP_0);
  9.    
  10.     USBD_SetEPType(USBD_EP_0, USBD_EP_TYPE_CONTROL);
  11.     USBD_SetEPTxStatus(USBD_EP_0, USBD_EP_STATUS_STALL);
  12.     USBD_SetEPTxAddr(USBD_EP_0, USB_EP0_TX_ADDR);
  13.    
  14.     USBD_SetEPRxStatus(USBD_EP_0, USBD_EP_STATUS_VALID);   
  15.     USBD_SetEPRxAddr(USBD_EP_0, USB_EP0_RX_ADDR);
  16.     USBD_SetEPRxCnt(USBD_EP_0, USB_EP_PACKET_SIZE);

  17. //ep1 gamepad
  18.     USBD_SetEPType(USBD_EP_1, USBD_EP_TYPE_INTERRUPT);
  19.     USBD_SetEPTxAddr(USBD_EP_1, USB_EP1_TX_ADDR);
  20.     USBD_SetEPTxCnt(USBD_EP_1, 8);
  21.     USBD_SetEPRxAddr(USBD_EP_1, USB_EP1_RX_ADDR);
  22.     USBD_SetEPRxCnt(USBD_EP_1, 4);
  23.     USBD_SetEPRxTxStatus(USBD_EP_1, USBD_EP_STATUS_VALID, USBD_EP_STATUS_VALID);
  24. //EP2 keyboard
  25.     USBD_SetEPType(USBD_EP_2, USBD_EP_TYPE_INTERRUPT);
  26.     USBD_SetEPTxAddr(USBD_EP_2, USB_EP2_TX_ADDR);
  27.     USBD_SetEPTxCnt(USBD_EP_2, 8);
  28.     USBD_SetEPRxAddr(USBD_EP_2, USB_EP2_RX_ADDR);
  29.     USBD_SetEPRxCnt(USBD_EP_2, 1);
  30.     USBD_SetEPRxTxStatus(USBD_EP_2, USBD_EP_STATUS_VALID, USBD_EP_STATUS_VALID);
  31. //EP3 mouse
  32.     USBD_SetEPType(USBD_EP_3, USBD_EP_TYPE_INTERRUPT);
  33.     USBD_SetEPTxAddr(USBD_EP_3, USB_EP3_TX_ADDR);
  34.     USBD_SetEPTxCnt(USBD_EP_3, 4);
  35.     USBD_SetEPRxAddr(USBD_EP_3, USB_EP3_RX_ADDR);
  36.     USBD_SetEPRxCnt(USBD_EP_3, 8);
  37.     USBD_SetEPRxTxStatus(USBD_EP_3,USBD_EP_STATUS_VALID, USBD_EP_STATUS_DISABLE );
  38.    
  39.     //endpoint addr
  40.     for(i = 0; i < USB_EP_NUM; i++)
  41.     {
  42.         USBD_SetEpAddr((USBD_EP_T)i, i);
  43.     }
  44.    
  45.     USBD_SetDeviceAddr(0);
  46.     USBD_Enable();
  47. }
下面说一下端点Buffer地址设置,这里容易搞错。
/** EP0 Tx address */
#define USB_EP0_TX_ADDR         (0X40)
/** EP0 Rx address */
#define USB_EP0_RX_ADDR         (0X80)
/** EP1 Tx address */
#define USB_EP1_TX_ADDR         (0XC0)
/** EP1 Rx address */
#define USB_EP1_RX_ADDR         (0XD0)
/** EP2 Tx address */
#define USB_EP2_TX_ADDR         (0XE0)
/** EP2 Rx address */
#define USB_EP2_RX_ADDR         (0XF0)
/** EP3 Tx address */
#define USB_EP3_TX_ADDR         (0X100)
/** EP3 Rx address */
#define USB_EP3_RX_ADDR         (0X110)


首先端点buffer地址为什么要从0x40开始,因为这个MCU有8个端点,每个端点又分输入输出。
而且每个端点有buffer起始地址和数据长度空间都占4字节。使用1个输入端点就要增加8字节,1个输出端点也要8字节。
本次使用了端点0,1,2,3。所以地址至少要7*8=56字节即0x38。后面地址就要根据每个端点的数据包长度来修改buffer地址。
2.jpg 3.jpg

最后就是按键模拟,及USB数据发送过程处理
  1. void HidMouse_Proc(void)
  2. {
  3.         
  4.     static  int8_t x = 0;
  5.     static  int8_t y = 0;
  6.     uint8_t buffer[8] = {0, 0, 0, 0};
  7.     uint8_t buffer1[8] = {0, 0, 0, 0};
  8.     uint8_t buffer2[4] = {0, 0, 0, 0};

  9.     if(!s_usbConfigStatus)
  10.     {
  11.         return;
  12.     }
  13.     if(g_time_tick == 0)
  14.         {
  15.         g_time_tick = 10;
  16.         /** Right key */
  17.         if(!GPIO_ReadInputBit(GPIOA, GPIO_PIN_0))
  18.         {
  19.             GPIOE->ODATA ^= GPIO_PIN_5;
  20.             x -= 10;
  21.             buffer[5] = 3;
  22.             buffer[6] |= 0x01;
  23.             buffer1[2] = 0x20;
  24.             buffer2[1] = -5;
  25.         }else
  26.         {
  27.             buffer[6] &= ~0x01;
  28.             buffer1[2] = 0;
  29.             buffer2[1] = 0;
  30.         }
  31.       
  32.         /** Left key */
  33.         if(!GPIO_ReadInputBit(GPIOA, GPIO_PIN_1))
  34.         {
  35.             GPIOE->ODATA ^= GPIO_PIN_6;
  36.             x += 10;
  37.             buffer[5] = 7;
  38.             buffer[6] |= 0x02;
  39.             buffer1[3] = 0x21;
  40.             buffer2[1] = 5;
  41.         }else
  42.         {
  43.             buffer[6] &= ~0x02;
  44.             buffer1[3] = 0;
  45.         }
  46.         
  47.         buffer[0] = x;
  48.         buffer[1] = y;

  49.         if(s_statusEP_in[1])
  50.         {
  51.             s_statusEP_in[1] = 0; //send over flag
  52.             USBD_WriteDataToEP(USBD_EP_1, buffer, sizeof(buffer));  //write data to buffer
  53.             USBD_SetEPTxStatus(USBD_EP_1, USBD_EP_STATUS_VALID);    //send data valid
  54.         }
  55.         
  56.         if(s_statusEP_in[2])
  57.         {
  58.             s_statusEP_in[2] = 0; //send over flag
  59.             USBD_WriteDataToEP(USBD_EP_2, buffer1, sizeof(buffer1));  //write data to buffer
  60.             USBD_SetEPTxStatus(USBD_EP_2, USBD_EP_STATUS_VALID);    //send data valid
  61.         }
  62.         
  63.         if(s_statusEP_in[3])
  64.         {
  65.             s_statusEP_in[3] = 0; //send over flag
  66.             USBD_WriteDataToEP(USBD_EP_3, buffer2, sizeof(buffer2));  //write data to buffer
  67.             USBD_SetEPTxStatus(USBD_EP_3, USBD_EP_STATUS_VALID);    //send data valid
  68.         }        
  69.         
  70.         }


  71. }



程序:
游客,如果您要查看本帖隐藏内容请回复


评论

回复才能看隐藏内容,感谢分享!  发表于 2022-12-10 00:21
Fanexs168 发表于 2022-5-25 16:49 | 显示全部楼层
Mark一下,后面自己抽空再搞搞~
olivem55arlowe 发表于 2022-5-28 12:44 | 显示全部楼层
支持otg吗?
houjiakai 发表于 2022-5-28 13:12 | 显示全部楼层
支持和pc端的通信吗?
sesefadou 发表于 2022-5-28 13:32 | 显示全部楼层
USB速度可以到多少?
jonas222 发表于 2022-5-28 13:58 | 显示全部楼层
Gamepad手柄怎么驱动呢  
soodesyt 发表于 2022-5-28 14:47 | 显示全部楼层
买过一个最小板子,看着还不错的。   
geraldbetty 发表于 2022-5-28 15:26 | 显示全部楼层
这个支持usb吗?  
phoenixwhite 发表于 2022-5-28 16:34 | 显示全部楼层
可以读取ps2的键盘吗?
gxliu08 发表于 2022-5-28 21:19 | 显示全部楼层
感谢分享,学习学习
发条陈 发表于 2022-6-28 22:49 | 显示全部楼层
支持
everyrobin 发表于 2022-7-9 13:22 | 显示全部楼层
这个hid设备吗?  
burgessmaggie 发表于 2022-7-9 13:41 | 显示全部楼层
资料很棒,感谢分享。  
nomomy 发表于 2022-7-9 14:20 | 显示全部楼层
不知道刷新的速度怎么样   
mickit 发表于 2022-7-9 15:20 | 显示全部楼层
这个驱动怎么样   
gaokosen 发表于 2022-9-15 16:43 | 显示全部楼层
mark 参考
海洋无限 发表于 2022-9-16 12:44 | 显示全部楼层
求教,这个评测的板子能拿到
Stahan 发表于 2022-10-4 20:12 | 显示全部楼层
支持pc通信吗?
luobeihai 发表于 2022-12-10 00:18 | 显示全部楼层
需要回复才能看,回复学习一下,感谢分享!
Undshing 发表于 2023-1-3 15:36 | 显示全部楼层
刷新的速度怎么样  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

127

主题

4778

帖子

28

粉丝
快速回复 在线客服 返回列表 返回顶部