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 reports longer than 64 bytes on lpc1768

Hi,

I'm on the board MCB1700.
I took the example of Keil (C:\Keil\ARM\Boards\Keil\MCB1700\RL\USB\RTX_HID)
I modify the code following the instructions in this forum : http://www.keil.com/forum/17770/
It works well with 64 bytes, but when I change to 300 bytes, It does not work.
The device is not well recognized.

This is what I changed.

usbdesc.c

/* 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(0x012c),                     /* wMaxPacketSize */<----- 300 bytes
  0x01,          /* 1ms */          /* bInterval */
        /* Endpoint, HID Interrupt Out */                                                                                                               // rajout EP OUT
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_OUT(1),                /* bEndpointAddress */
  USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
  WBVAL(0x012c),                     /* wMaxPacketSize */<----- 300 bytes
  0x01,          /* 1ms */          /* bInterval */
hid.h

#define HID_ReportCountS(x)      0x96,(x&0xFF),((x>>8)&0xFF) //add to the table HID_ReportDescriptor[]
hiduser.h

/* HID report size (count) */
#define HID_INPUT_REPORT_BYTES       300              /* size of report in Bytes */
#define HID_OUTPUT_REPORT_BYTES      300              /* size of report in Bytes */
#define HID_FEATURE_REPORT_BYTES     300              /* size of report in Bytes */

Here is the configuration on the PC side using the software USB View.

Device Descriptor:
bcdUSB:             0x0200
bDeviceClass:         0x00
bDeviceSubClass:      0x00
bDeviceProtocol:      0x00
bMaxPacketSize0:      0x40 (64)
idVendor:           0xC251
idProduct:          0x2201
bcdDevice:          0x0100
iManufacturer:        0x01
0x0409: "Keil Software"
iProduct:             0x02
0x0409: "Keil MCB1700 HID"
iSerialNumber:        0x03
0x0409: "0001A0000000"
bNumConfigurations:   0x01

ConnectionStatus: DeviceConnected
Current Config Value: 0x00
Device Bus Speed:     Full
Device Address:       0x02
Open Pipes:              0

Configuration Descriptor:
wTotalLength:       0x0029
bNumInterfaces:       0x01
bConfigurationValue:  0x01
iConfiguration:       0x00
bmAttributes:         0x80 (Bus Powered )
MaxPower:             0x32 (100 Ma)

Interface Descriptor:
bInterfaceNumber:     0x00
bAlternateSetting:    0x00
bNumEndpoints:        0x02
bInterfaceClass:      0x03 (HID)
bInterfaceSubClass:   0x00
bInterfaceProtocol:   0x00
iInterface:           0x04
0x0409: "HID"

HID Descriptor:
bcdHID:             0x0100
bCountryCode:         0x00
bNumDescriptors:      0x01
bDescriptorType:      0x22
wDescriptorLength:  0x0024

Endpoint Descriptor:
bEndpointAddress:     0x81  IN
Transfer Type:   Interrupt
wMaxPacketSize:     0x012C (300)
bInterval:            0x01

Endpoint Descriptor:
bEndpointAddress:     0x01  OUT
Transfer Type:   Interrupt
wMaxPacketSize:     0x012C (300)
bInterval:            0x01

And with the software USBlyser, i don't see the "Interface 0 HID Report Descriptor".
(I have an exclamation-mark on the USB)
I searched the forum but I found nothing for my problem.
if someone has an idea? thank you.

Parents
  • > But the function USB_WriteEP() does not cut in blocks of 64?

    No it doesn't.
    USB_WriteEP() sends a packet, up to 64 bytes (wMaxPacketSize).
    Like the OUT endpoint, your firmware has to split the report into 64 bytes packets.
    Each packets is passed to USB_WriteEP() in USB_EVT_IN

    __task void USB_EndPoint1 (void) {
    U16 evt;
    static U32 out_report_size = 0;
    static U32 in_report_size = 0;
           U32 in_index;
           U32 in_send_size;
    
    for (;;) {
      os_evt_wait_or(0xFFFF, 0xFFFF);         /* Wait for an Event */
      evt = os_evt_get();                     /* Get Event Flags */
    
      if (evt & USB_EVT_OUT) {                        // OUT EP1 interrupt comes
                                                      // read out the output report
        out_report_size += USB_ReadEP( HID_EP_OUT, &OutReport[out_report_size] );
    
        if(out_report_size == HID_OUTPUT_REPORT_BYTES)
        {
                                                      // wait until IN EP is available
            os_sem_wait( USB_IN_EP1_Semaphore, 0xffff );
                                                      // now, IN EP and its context is available
            memcpy(InReport, OutReport, out_report_size );
            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);
        }
      }
    
      if (evt&USB_EVT_IN) {                            // IN EP1 interrupt comes
        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;
        }
      }
    }
    

    Tsuneo

Reply
  • > But the function USB_WriteEP() does not cut in blocks of 64?

    No it doesn't.
    USB_WriteEP() sends a packet, up to 64 bytes (wMaxPacketSize).
    Like the OUT endpoint, your firmware has to split the report into 64 bytes packets.
    Each packets is passed to USB_WriteEP() in USB_EVT_IN

    __task void USB_EndPoint1 (void) {
    U16 evt;
    static U32 out_report_size = 0;
    static U32 in_report_size = 0;
           U32 in_index;
           U32 in_send_size;
    
    for (;;) {
      os_evt_wait_or(0xFFFF, 0xFFFF);         /* Wait for an Event */
      evt = os_evt_get();                     /* Get Event Flags */
    
      if (evt & USB_EVT_OUT) {                        // OUT EP1 interrupt comes
                                                      // read out the output report
        out_report_size += USB_ReadEP( HID_EP_OUT, &OutReport[out_report_size] );
    
        if(out_report_size == HID_OUTPUT_REPORT_BYTES)
        {
                                                      // wait until IN EP is available
            os_sem_wait( USB_IN_EP1_Semaphore, 0xffff );
                                                      // now, IN EP and its context is available
            memcpy(InReport, OutReport, out_report_size );
            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);
        }
      }
    
      if (evt&USB_EVT_IN) {                            // IN EP1 interrupt comes
        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;
        }
      }
    }
    

    Tsuneo

Children