处理报告端点(USB HID)

处理报告端点(USB HID),usb,endpoint,hid,descriptor,Usb,Endpoint,Hid,Descriptor,我已经将LPC11U14微控制器编程为USB HID键盘。它工作得很好,但我无法让LED正常工作。我已经创建了适当的描述符,而且我还可以(通过USBlyzer)看到主机发送控制权输出。我只是不知道在哪里以及如何处理这份报告 我可以在按下Caps Lock、Num Lock或Scroll Lock时打开和关闭LED,但无论我按下三个按钮中的哪一个,它们都会亮起。就好像我没有收到哪个按钮被按下的值,而只收到一个按钮被按下的值 以下是我的HID报告描述符: const Int8U HidReportD

我已经将LPC11U14微控制器编程为USB HID键盘。它工作得很好,但我无法让LED正常工作。我已经创建了适当的描述符,而且我还可以(通过USBlyzer)看到主机发送控制权输出。我只是不知道在哪里以及如何处理这份报告

我可以在按下Caps Lock、Num Lock或Scroll Lock时打开和关闭LED,但无论我按下三个按钮中的哪一个,它们都会亮起。就好像我没有收到哪个按钮被按下的值,而只收到一个按钮被按下的值

以下是我的HID报告描述符:

const Int8U HidReportDescriptor[] =
{      
    0x05, 0x01, // Generic dekstop
    0x09, 0x06, // Keyboard
    0xA1, 0x01, // Application

    0x05, 0x07, // Usage Page; Key Codes
    0x19, 0xE0, // Usage minimum; 224
    0x29, 0xE7, // Usage maximum; 231
    0x15, 0x00, // Logical minimum; 0 
    0x25, 0x01, // Logical maximum; 1
    0x75, 0x01, // Report size; 1
    0x95, 0x08, // Report count; 8
    0x81, 0x02, // Input (Data, Variable, Absolute); Modifier byte

    0x95, 0x01, // Report count; 1
    0x75, 0x08, // Report size; 8
    0x81, 0x01, // Input (Constant); Reserved byte
    0x95, 0x03, // Report count; 5
    0x75, 0x01, // Report size; 1
    0x05, 0x08, // Usage page, page # for LED's
    0x19, 0x01, // Usage minimum; 1
    0x29, 0x03, // Usage maximum; 5
    0x91, 0x02, // Output (Data, Variable, Absolute); LED report
    0x95, 0x01, // Report count; 1
    0x75, 0x05, // Report size; 3
    0x91, 0x01, // Output (Constant); LED report padding

    0x95, 0x06, // Report count; 6
    0x75, 0x08, // Report size; 8
    0x15, 0x00, // Logical minimum; 0
    0x26, 0xFF, 0x00, // Logical maximum; 101
    0x05, 0x07, // Usage Page; Key Codes
    0x19, 0x00, // Usage minimum; 0
    0x2A, 0xFF, 0x00, // Usage maximum; 101
    0x81, 0x00, // Input (Data, Array); Key arrays (6 bytes)

    0xC0        // End collection
};
在我的“usb_hooks”文件中,有通过usb进行通信时调用的所有不同函数。当使用断点跟踪我按下Num Lock按钮时使用的函数时,此函数称为:

/*************************************************************************
 * Function Name: USB_CLASS_REQUEST_HOOK
 * Parameters: USB_Endpoint_t EP
 *
 * Return: UsbCommStatus_t
 *
 * Description: Called when class request receiving
 *
 *************************************************************************/
UsbCommStatus_t USB_CLASS_REQUEST_HOOK (pUsbSetupPacket_t pSetup)
{
  //Add code here ...
  return(UsbClassHidRequest(pSetup));
  //return(UsbFault);
}
此外,当检查pSetup安装程序包时,它的所有变量都不会改变。无论我按下哪个按钮,它们都具有相同的值。pSetup包含以下内容:

typedef union _UsbSetupPacket_t
{
  Int8U Data[8];
  struct {
    UsbRequestType_t  mRequestType;
    Int8U             bRequest;
    TwoBytes_t        wValue;
    TwoBytes_t        wIndex;
    TwoBytes_t        wLength;
  };
} UsbSetupPacket_t, * pUsbSetupPacket_t;

有没有关于在何处以及如何正确读取端点的建议

经过大量调试和寄存器/内存检查,我发现控制端点(和其他东西)保存在
extern Int8U USB_PacketMemory[2048]
通过读取字节128,我可以获得LED的状态,然后执行相应的功能来打开/关闭LED

void setLeds(int ledValue) {  
  switch (ledValue) {
  case 0x00:
    GPIOSetBitValue(0, 23, 0); 
    GPIOSetBitValue(1, 13, 0); 
    GPIOSetBitValue(1, 14, 0); 
    break; 
  case 0x01:
    // and so on...
    break;
  }
}

您的报告描述符正常,因此我怀疑有编码问题。另外,您使用的是哪种操作系统?我注意到,最新的Linux版本不会报告LED状态的变化,除非该设备显示为引导键盘。我使用Windows。我用USB分析仪检查过,操作系统将正确的控制传输发送到设备,但我只是不知道如何“读取”:)嗯……我认为你应该用更多的代码将你的代码粘贴到问题更新的问题中。