Trying to send an InReport > 64 bytes. Read all threads(thanks Tsuneo) but still not working. That is too say, I'm using SimpleHIDWrite as my tester, 64-byte packets work fine. If I run this code, sending a 65-byte In Report using 2-packets, I get from SimplHIDWrite "Get Report Error: CRC mismatch (17)". Any help much appreciated!
BOOL HID_GetReport (void) { // ReportID = SetupPacket.wValue.WB.L; switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: //We've been asked to report, go get report and send 1st packet GetInReport(); //memcpy(&EP0Buf[0],(u8*)&MyInReport[0],sizeof(MyInReport)); //memcpy(&EP0Buf[0],(u8*)&MyInReport[0],64); break; case HID_REPORT_OUTPUT: return (FALSE); // Not Supported case HID_REPORT_FEATURE: /* EP0Buf[] = ...; */ /* break; */ return (FALSE); // Not Supported } return (TRUE); } ******************************************************************* void GetInReport (void) { // Check if PBINT is pressed if((IOPIN0 & PBINT) == 0) { //just add some data for now MyInReport[0] = 0xC1; MyInReport[1] = 0xD1; MyInReport[63] = 0x63; } else { //just add some data for now MyInReport[0] = 0xC0; MyInReport[1] = 0xD0; MyInReport[63] = 0x63; } VICIntEnClr |= 0x00400000; // Disable USB Interrupt USB_WriteEP(0x81, &MyInReport[0], 64); //Send 1st packet, 64 bytes iNextInPacket = 1; //Set flag for EP1 ISR VICIntEnable |= 0x00400000; // Enable USB Interrupt } *********************************************************************** void USB_EndPoint1 (DWORD event) { switch (event) { case USB_EVT_IN: if(iNextInPacket) { //OK, more data, send second packet (1-byte, total of 65-byte report) iNextInPacket = 0; USB_WriteEP(0x81, &MyInReport[64], 1); } break; } }
You don't touch to your MCU type number, but Keil's USB stack is almost common for various MCUs, except for the low-level routines. Get_Report process is also common. I picked up LPC17xx USBHID code here.
The problem lies in Keil's HID implementation.
USBHID example expects that the input report is loaded in InReport[] in GetInReport(). The report is copied to EP0Buf[] at HID_GetReport(), as follows.
hiduser.c uint32_t HID_GetReport (void) { /* ReportID = SetupPacket.wValue.WB.L; */ switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: GetInReport(); EP0Buf[0] = InReport; break;
In USB_EndPoint0(), The address of EP0Buf[] is registered to EP0Data.pData after HID_GetReport() call. And then, the stack code takes care of the rest, including multi-packets transfer.
usbcore.c void USB_EndPoint0 (uint32_t event) { switch (event) { case USB_EVT_SETUP: USB_SetupStage(); USB_DirCtrlEP(SetupPacket.bmRequestType.BM.Dir); EP0Data.Count = SetupPacket.wLength; /* Number of bytes to transfer */ switch (SetupPacket.bmRequestType.BM.Type) { ... ... #if USB_CLASS case REQUEST_CLASS: switch (SetupPacket.bmRequestType.BM.Recipient) { ... case REQUEST_TO_INTERFACE: #if USB_HID if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) { /* IF number correct? */ switch (SetupPacket.bRequest) { case HID_REQUEST_GET_REPORT: if (HID_GetReport()) { EP0Data.pData = EP0Buf; // <----------- the problem is here USB_DataInStage(); /* send requested data */ goto setup_class_ok; } break;
However, the size of EP0Buf[] is 64 bytes, at most. LPC17xx example sets it to 8.
usbcfg.h #define USB_MAX_PACKET0 8 usbcore.c uint8_t EP0Buf[USB_MAX_PACKET0];
The implementation of Control Transfer process supports multi-packets transfer, successfully. But above HID implementation spoils it. You may improve it as follows.
hiduser.c uint32_t HID_GetReport (void) { /* ReportID = SetupPacket.wValue.WB.L; */ switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: // // fill your_custom_buffer[] with a input report, here // EP0Data.pData = your_custom_buffer; // pass your buffer to the stack
And comment "EP0Data.pData = EP0Buf;" line on USB_EndPoint0()
usbcore.c void USB_EndPoint0 (uint32_t event) { ... case HID_REQUEST_GET_REPORT: if (HID_GetReport()) { // EP0Data.pData = EP0Buf; // comment this line USB_DataInStage(); /* send requested data */
Tsuneo
Thanks, controller is LPC2148. I understand your fix and attempted, still get error from SimpleHIDWrite of "GET REPORT ERROR: Data error (cyclic redundancy error) (17)". We never even get to the HID_GetReport() code. Must be that it errors when attempting to do a GetReport call of > 64 bytes? Anyway, couldn't your fix just be to increase the size of EP0Buf?