处理 OUT 报告端点(USB HID)
Handling OUT report endpoint (USB HID)
我已经将 LPC11U14 微控制器编程为 USB HID 键盘。它工作得很好,但我无法让 LED 工作。我已经创建了适当的描述符,而且我还可以(通过 USBlyzer)看到主机发送了 OUT 控制传输。我只是不知道在哪里以及如何处理 OUT 报告。
我可以在按下 Caps Lock、Num Lock 或 Scroll Lock 时打开和关闭 LED,但无论我按下三个按钮中的哪一个,它们都会亮起。就好像我没有收到按下哪个按钮的值,而只收到按下 a 按钮的值。
这是我的 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 安装程序包时,none 的变量发生了变化。无论我按下哪个按钮,它们都具有相同的值。 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;
关于在何处以及如何正确读取端点的任何建议?
经过大量调试和 register/memory 检查,我发现控制端点(和其他东西)保存在
extern Int8U USB_PacketMemory[2048];
通过读取字节 128,我可以获得 LED 的状态,然后创建一个函数将它们相应地变为 on/off。
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;
}
}
我已经将 LPC11U14 微控制器编程为 USB HID 键盘。它工作得很好,但我无法让 LED 工作。我已经创建了适当的描述符,而且我还可以(通过 USBlyzer)看到主机发送了 OUT 控制传输。我只是不知道在哪里以及如何处理 OUT 报告。
我可以在按下 Caps Lock、Num Lock 或 Scroll Lock 时打开和关闭 LED,但无论我按下三个按钮中的哪一个,它们都会亮起。就好像我没有收到按下哪个按钮的值,而只收到按下 a 按钮的值。
这是我的 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 安装程序包时,none 的变量发生了变化。无论我按下哪个按钮,它们都具有相同的值。 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;
关于在何处以及如何正确读取端点的任何建议?
经过大量调试和 register/memory 检查,我发现控制端点(和其他东西)保存在
extern Int8U USB_PacketMemory[2048];
通过读取字节 128,我可以获得 LED 的状态,然后创建一个函数将它们相应地变为 on/off。
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;
}
}