This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

USB HID Low performance

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?

Parents
  • > 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

Reply
  • > 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

Children
No data