Hi everyone!
I've read lots of threads on this forum (with lot of Tsuneo Chinzei's really interesting posts) about this issue, but I'm still stuck with a problem. I'm using an NXP LPC1788. I've tested the USBHID demo with HIDClient.exe on the PC side. Everything works fine. I've wrote a simple C++ console program that made a single write/read operation, based on HIDClient.exe code, and everything is fine again. Now, I need to send/receive 8 bytes instead of a single one. I've started modifying firmware and sofware, following hints on this forum, and at the end I'm able to output 8 bytes, but not to get 8 byte in input.
I've changed the HID_ReportDescriptor structure like this:
const uint8_t HID_ReportDescriptor[] = { HID_UsagePageVendor(0x00), HID_Usage(0x01), HID_Collection(HID_Application), HID_UsagePage(HID_USAGE_PAGE_DEV_CONTROLS), HID_LogicalMin(0), HID_LogicalMax(255), HID_ReportCount(8), HID_ReportSize(8), HID_Usage(1), HID_Input(HID_Data | HID_Variable | HID_Absolute), HID_UsagePage(HID_USAGE_PAGE_DEV_CONTROLS), HID_Usage(1), HID_LogicalMin(0), HID_LogicalMax(255), HID_ReportCount(8), HID_ReportSize(8), HID_Output(HID_Data | HID_Variable | HID_Absolute), HID_EndCollection, };
I've redefined the InReport and OutReport variables as arrays of size 8, that will be copied/pasted on the EP0Buf array using a for loop (in single byte mode it's a simple assignation). I didn't change the wMaxPacketSize in the USB_ConfigDescriptor (so it's set to 4), because changing the value causes error in the output process, too.
Here is the source of the C++ console application that perform a single write/read:
#define MSG_SIZE 9 #include <windows.h> #include <stdio.h> #include "HID.h" int main() { BYTE outReport[MSG_SIZE]; BYTE inReport[IN_MSG_SIZE]; DWORD cnt; int totDevices; char buf[256]; outReport[0] = 0; inReport [0] = 0; // Check for all connected devices HID_Init(); totDevices = HID_FindDevices(); printf("%d Devices found\n", totDevices); if(totDevices < 1) { return 1; } for(int i = 0; i < totDevices; i++) { if (!HID_GetName(i, buf, sizeof(buf))) { sprintf(buf, "Device %d", i); } printf("%d: %s\n", i, buf); } // Open the first device printf("Open device 0..."); if(!HID_Open(0)) { printf("Can't open device 0\n"); return 2; } printf("OK\n"); // Perform a write test printf("Write test..."); outReport[1] = 0; if(!HID_Write(outReport, MSG_SIZE*sizeof(BYTE), &cnt)) { printf("write error\n"); return 3; } printf("OK\n"); // Perform a read test printf("Read test..."); if(!HID_Read(inReport, IN_MSG_SIZE*sizeof(BYTE), &cnt)) { printf("read error\n"); return 4; } printf("OK\n"); // Close device printf("Close device..."); HID_Close(); HID_UnInit(); printf("OK"); return 0; }
Write process goes well. The software get locked during the read process.
I've tested the firmware with the SimpleHIDWrite.exe tool and it works fine. So it seems more a software problem than a firmware one.
What could be worng? Is there someone that was able to tx/rx more that a single byte using a C++ interface? And is it correct to use arrays of size FIRMWARE_SIZE+1 on the software side? (HIDClient.exe uses arrays of size 2 to tx/rx a single byte. If I define arrays of size 8, write and read process fails, but didn't lock)
Thank to everyone! Massimo