Hi everybody I'm trying to migrate from AT91SAM7S256 to SAM3S8B Micro controller. I applied some necessary changes in my project and everything works well. But I have a problem: In previous project we use HID sample code for AT91SAM7S in \Keil\ARM\Boards\Atmel\AT91SAM7S-EK\USB\HID. I replaced USB source code with related HID sample codes for SAM3S in \Keil\ARM\Boards\Atmel\SAM3S-EK\USBHID and USB communication performance significantly decreased. For example reading 2 bytes from our new hid device takes more than 1 second but in old hid device this takes about 40 milliseconds. Our descriptor for old project is:
#include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbdesc.h" #include "hid.h" /* HID Report Descriptor */ const BYTE HID_ReportDescriptor[] = { HID_UsagePageVendor(0xFF), HID_Usage(0xFF), HID_Collection(HID_Application), HID_Usage(0xFF), HID_ReportCount(64), HID_ReportSize(8), HID_LogicalMin(-128), HID_LogicalMax(127), HID_Input(0), HID_Usage(0xFF), HID_ReportCount(64), HID_ReportSize(8), HID_LogicalMin(-128), HID_LogicalMax(127), HID_Output(0), HID_EndCollection, }; /* USB Standard Device Descriptor */ BYTE USBHID_DeviceDescriptor[] = { USB_DEVICE_DESC_SIZE, USB_DEVICE_DESCRIPTOR_TYPE, WBVAL(0x0110), /* 1.10 */ 0x00, 0x00, 0x00, USB_MAX_PACKET0, WBVAL(0xF6B5), WBVAL(0xBD60), WBVAL(0xFFFF), 0x04, 0x1C, 0x42, 0x01 }; const WORD HID_ReportDescSize = sizeof(HID_ReportDescriptor); /* USB Configuration Descriptor */ /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ const BYTE USBHID_ConfigDescriptor[] = { /* Configuration 1 */ USB_CONFIGUARTION_DESC_SIZE, USB_CONFIGURATION_DESCRIPTOR_TYPE, WBVAL( 1*USB_CONFIGUARTION_DESC_SIZE + 1*USB_INTERFACE_DESC_SIZE + HID_DESC_SIZE + 2*USB_ENDPOINT_DESC_SIZE ), 0x01, 0x01, 0x00, USB_CONFIG_BUS_POWERED /*|*/ /*USB_CONFIG_REMOTE_WAKEUP*/, USB_CONFIG_POWER_MA(100), /* Interface 0, Alternate Setting 0, HID Class */ USB_INTERFACE_DESC_SIZE, USB_INTERFACE_DESCRIPTOR_TYPE, 0x00, 0x00, 0x02, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE, 0x92, /* HID Class Descriptor */ /* HID_DESC_OFFSET = 0x0012 */ HID_DESC_SIZE, HID_HID_DESCRIPTOR_TYPE, WBVAL(0x0100), /* 1.00 */ 0x00, 0x01, HID_REPORT_DESCRIPTOR_TYPE, WBVAL(HID_REPORT_DESC_SIZE), /* Endpoint, HID Interrupt In */ USB_ENDPOINT_DESC_SIZE, USB_ENDPOINT_DESCRIPTOR_TYPE, USB_ENDPOINT_IN(2), USB_ENDPOINT_TYPE_INTERRUPT, WBVAL(0x0040), 0x1, /* 1ms */ /* Endpoint, HID Interrupt out */ USB_ENDPOINT_DESC_SIZE, USB_ENDPOINT_DESCRIPTOR_TYPE, USB_ENDPOINT_OUT(3), USB_ENDPOINT_TYPE_INTERRUPT, WBVAL(0x0040), 0x1, /* 1ms */ /* Terminator */ 0 };
And our descriptor for new one is:
#include "type.h" #include "usb.h" #include "usbcfg.h" #include "usbdesc.h" #include "hid.h" #define HID_INPUT_REPORT_BYTES 64 #define HID_OUTPUT_REPORT_BYTES 64 #define HID_FEATURE_REPORT_BYTES 1 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); /* USB Standard Device Descriptor */ const U8 USB_DeviceDescriptor[] = { USB_DEVICE_DESC_SIZE, USB_DEVICE_DESCRIPTOR_TYPE, WBVAL(0x0110), /* 1.10 */ // WBVAL(0x0200), /* 2.00 */ 0x00, 0x00, 0x00, USB_MAX_PACKET0, WBVAL(0xF6B5), WBVAL(0xBD60), WBVAL(0x0100), /* 1.00 */ 0x01, 0x02, 0x03, 0x01 }; /* USB Configuration Descriptor */ /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor) */ const U8 USB_ConfigDescriptor[] = { /* Configuration 1 */ USB_CONFIGUARTION_DESC_SIZE, USB_CONFIGURATION_DESCRIPTOR_TYPE, WBVAL( USB_CONFIGUARTION_DESC_SIZE + USB_INTERFACE_DESC_SIZE + HID_DESC_SIZE + 2*USB_ENDPOINT_DESC_SIZE ), 0x01, 0x01, 0x00, USB_CONFIG_BUS_POWERED /*|*/ // USB_CONFIG_SELF_POWERED /*USB_CONFIG_REMOTE_WAKEUP*/, USB_CONFIG_POWER_MA(100), /* Interface 0, Alternate Setting 0, HID Class */ USB_INTERFACE_DESC_SIZE, USB_INTERFACE_DESCRIPTOR_TYPE, 0x00, 0x00, 0x02, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE, 0x04, /* HID Class Descriptor */ /* HID_DESC_OFFSET = 0x0012 */ HID_DESC_SIZE, HID_HID_DESCRIPTOR_TYPE, WBVAL(0x0100), /* 1.00 */ 0x00, 0x01, HID_REPORT_DESCRIPTOR_TYPE, WBVAL(HID_REPORT_DESC_SIZE), /* Endpoint, HID Interrupt In */ USB_ENDPOINT_DESC_SIZE, USB_ENDPOINT_DESCRIPTOR_TYPE, USB_ENDPOINT_IN(1), USB_ENDPOINT_TYPE_INTERRUPT, WBVAL(0x0040), 0x01, /* 1ms */ /* Endpoint, HID Interrupt Out */ USB_ENDPOINT_DESC_SIZE, USB_ENDPOINT_DESCRIPTOR_TYPE, USB_ENDPOINT_OUT(2), USB_ENDPOINT_TYPE_INTERRUPT, WBVAL(0x0040), 0x01, /* 1ms */ /* Terminator */ 0 };
As you see, we use 64byte endpoint in both projects and 1 millisecond time interval for hid device. Any idea why does this problem?
> We use the same application to measure time
Then, the difference should be caused by the device side.
Measure the performance on the firmware, using SysTick, as follows.
usbuser.c uint32_t g_timing[3]; void USB_EndPoint2 (U32 event) { // EP2 (interrupt OUT) handler // when a packet comes from host, this routine is called g_timing[0] = SysTick->VAL; // capture SysTick value USB_ReadEP( ... ); // read a packet from OUT EP, and parse the command on the packet ... USB_WriteEP( ... ); // put a packet to the IN EP g_timing[1] = SysTick->VAL; // capture SysTick value } void USB_EndPoint1 (U32 event) { // EP1 (interrupt IN) handler // when the packet completes to send, this routine is called g_timing[2] = SysTick->VAL; // capture SysTick value }
After putting "get input" command, puase the firmware execution on the debugger, and read g_timing[] values using the debugger. Which one causes so long delay?
Tsuneo