Good day to all,
I am using MCB1760 board.
I want to use EP1 for OUT EP in my application.
As a start I have modified the RTX_HID code as below.
The device is detecting.
When I run the HID_Client on the PC I can select the device.
But after selecting the device it is getting struct.
Changes are made as given below: USB_ConfigDescriptor in usbdesc.c: Added EP1 output descriptor. USB_EndPoint1 task of usbuser.c: Added USB_EVT_OUT functionality.
Please suggest
const U8 USB_ConfigDescriptor[] = { /* Configuration 1 */ USB_CONFIGUARTION_DESC_SIZE, /* bLength */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL( /* wTotalLength */ 1*USB_CONFIGUARTION_DESC_SIZE + 1*USB_INTERFACE_DESC_SIZE + 1*HID_DESC_SIZE + 2*USB_ENDPOINT_DESC_SIZE //Updated on 09-11-11 ), 0x01, /* bNumInterfaces */ 0x01, /* bConfigurationValue: 0x01 is used to select this configuration */ 0x00, /* iConfiguration: no string to describe this configuration */ USB_CONFIG_BUS_POWERED /*|*/ /* bmAttributes */ /*USB_CONFIG_REMOTE_WAKEUP*/, USB_CONFIG_POWER_MA(100), /* bMaxPower, device power consumption is 100 mA */
/* Interface 0, Alternate Setting 0, HID Class */ USB_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x00, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x02, /* bNumEndpoints */ //Updated to 2 on 09-11-11 USB_DEVICE_CLASS_HUMAN_INTERFACE, /* bInterfaceClass */ HID_SUBCLASS_NONE, /* bInterfaceSubClass */ HID_PROTOCOL_NONE, /* bInterfaceProtocol */ 0x04, /* iInterface */ /* HID Class Descriptor */ /* HID_DESC_OFFSET = 0x0012 */ HID_DESC_SIZE, /* bLength */ HID_HID_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(0x0100), /* 1.00 */ /* bcdHID */ 0x00, /* bCountryCode */ 0x01, /* bNumDescriptors */ HID_REPORT_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(HID_REPORT_DESC_SIZE), /* wDescriptorLength */ /* Endpoint, HID Interrupt In */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(1), /* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ WBVAL(0x0040), /* wMaxPacketSize */ 0x20, /* 32ms */ /* bInterval */ /* Endpoint, HID Interrupt Out */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_OUT(1), /* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ WBVAL(0x0040), /* wMaxPacketSize */ 0x20, /* 32ms */ /* bInterval */ /* Terminator */ 0 /* bLength */ };
#if (USB_EP_EVENT & (1 << 1)) __task void USB_EndPoint1 (void) { U16 evt;
for (;;) { os_evt_wait_or(0xFFFF, 0xFFFF); /* Wait for an Event */ evt = os_evt_get(); /* Get Event Flags */
if (evt & USB_EVT_IN) { GetInReport(); USB_WriteEP(HID_EP_IN, &InReport, sizeof(InReport)); } if (evt & USB_EVT_OUT) { USB_ReadEP(HID_EP_IN, &OutReport); SetOutReport(); } } } #endif
Hi,
I have modified my code to receive or transmit more than 64 bytes according to the suggestions posted in the forum. If I run the SimpleHIDwrite on the PC it is detecting. SetReport and GetReport are woring. When I click on the "Write", it is showing error as Access Violation at address at 00000000. Read of address 00000000.
The size of the descriptor modified and the code modified is given below. Please suggest.
#define HID_INPUT_REPORT_BYTES 64 /* size of report in Bytes */ #define HID_OUTPUT_REPORT_BYTES 64 /* size of report in Bytes */ #define HID_FEATURE_REPORT_BYTES 64 /* size of report in Bytes */ const U8 HID_ReportDescriptor[] = { HID_UsagePageVendor( 0x00 ), HID_Usage ( 0x01 ), HID_Collection ( HID_Application ), HID_LogicalMin ( 0 ), /* value range: 0 - 0xFF */ HID_LogicalMaxS ( 0xFF ), HID_ReportSize ( 8 ), /* 8 bits */ HID_ReportCount ( HID_INPUT_REPORT_BYTES ), HID_Usage ( 0x01 ), HID_Input ( HID_Data | HID_Variable | HID_Absolute ), HID_ReportCount ( HID_OUTPUT_REPORT_BYTES ), HID_Usage ( 0x01 ), HID_Output ( HID_Data | HID_Variable | HID_Absolute ), HID_ReportCount ( HID_FEATURE_REPORT_BYTES ), HID_Usage ( 0x01 ), HID_Feature ( HID_Data | HID_Variable | HID_Absolute ), HID_EndCollection, }; const U16 HID_ReportDescSize = sizeof(HID_ReportDescriptor); #if (USB_EP_EVENT & (1 << 1)) __task void USB_EndPoint1 (void) { U16 evt; static U32 out_report_size = 0; static U32 in_report_size = 0; static U32 in_index=0; U32 in_send_size=0; U32 i=0; for (;;) { os_evt_wait_or(0xFFFF, 0xFFFF); /* Wait for an Event */ evt = os_evt_get(); /* Get Event Flags */ if (evt & USB_EVT_IN) { if ( in_report_size == 0 ) { // this interrupt is caused by the last packet? os_sem_send( USB_IN_EP1_Semaphore ); // IN EP1 is free } else { // there remains bytes to be sent in_send_size = HID_IN_EP_MAXPACKET_SIZE; // pick up a packet size if ( in_report_size < HID_IN_EP_MAXPACKET_SIZE ) { in_send_size = in_report_size; } // pass it to the endpoint USB_WriteEP( HID_EP_IN, &InReport[in_index], in_send_size ); in_report_size -= in_send_size; // move counter and index by sent size in_index += in_send_size; } } if (evt & USB_EVT_OUT) { out_report_size += USB_ReadEP( HID_EP_OUT, &OutReport[out_report_size] ); if(out_report_size == HID_OUTPUT_REPORT_BYTES) { os_sem_wait( USB_IN_EP1_Semaphore, 0xffff );// wait until IN EP is available for(i=0;i<out_report_size;i++) { InReport[i] = OutReport[i]; } in_report_size = out_report_size; in_index = 0; out_report_size = 0; // force EP1 IN interrupt manually LPC_USB->USBEpIntSet = 1 << EPAdr(HID_EP_IN); } } } } #endif
Hi Tsuneo,
I am in the deadline crisis. Any help at the earliest possible will be appreciated. Please suggest.
Lingaraju
Seems (almost) fine. You've taken the code form this topic, and modified a little. http://www.keil.com/forum/19729/
Did you modify USB_Core() task for USB_Configuration event, too?
The original Keil RTX_HID continuously sends input report. To start this sequential reports, it puts the first report at USB_Configuration handler in USB_Core() task. But your modification sends the input report just when an output report completes, for loop back. The first report in USB_Configuration event is deleted.
usbuser.c U32 out_report_size = 0; U32 in_report_size = 0; U32 in_index = 0; OS_SEM USB_IN_EP1_Semaphore; __task void USB_Core (void) { ... ... #if USB_CONFIGURE_EVENT if (evt & USB_EVT_SET_CFG) { if (USB_Configuration) { /* Check if USB is configured */ // <--- comment these two lines // GetInReport(); // USB_WriteEP(HID_EP_IN, &InReport, sizeof(InReport)); // <--- add these three lines out_report_size = 0; in_report_size = 0; in_index = 0; os_sem_init( USB_IN_EP1_Semaphore, 1 ); } } #endif
To speed up the response, set bInterval value on the endpoint descriptors to 1 ms.
Tsuneo
Thanks for the reply.
I changed the code asper your suggestion and checked, but still it is giving the same error.
According to me, with the earlier code also the device was not sending the inrport array repeatedly since the in_report_size variable value will be '0'(zero) untill the USB_EVT_OUT gets the data and loads it to the inreport array.
I think the problem is something else.
Please suggest.
regards Lingaraju
> SimpleHIDWrite: Violation at address at 00000000. Read of address 00000000
Umm.. It seems a bug of SimpleHIDWrite, which appears when 64 bytes or more is assigned. Confirmed with this firmware on Olimex LPC1766-STK. www.8052.com/.../MCB1760_RTX_HID_64BytesOver_loopback.zip This firmware works fine, but SimpleHIDWrite causes above error.
Test your firmware on another test bench, for example, Jan Axelson's HID page http://www.lvr.com/hidpage.htm generic_hid_cs_50 www.lvr.com/.../generic_hid_cs_50.zip
It is working fine with generic_hid_50 software. It really helped me to find the problem.