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

How to workwith more endpoints

Hi All,
I am working with a project which requires 4 IN Endpoints. I took Keil USB HID example for LPC214X as reference.. Any one knows how can i use more endpoints in that example???

Parents
  • "Does HID Interrupt class has any limitation which doesn't allow use of many endpoints???

    Single HID interface holds
    one interrupt IN endpoint (mandatory)
    one interrupt OUT endpoint (optional)

    Then, you need multiple HID interfaces to support more endpoints on single device.
    That is, composite device.

    Unfortunately, Keil Apnt195 doesn't explain about nothing about composite device.

    I posted a brief summary and examples about composite device to SiLabs forum.
    The example on a composite device withe three HID interfaces will help you.
    This example is written for SiLabs '51 chip, but you'll find how to write the descriptors, how to implement requests handling on composite device.

    "USB composite device"
    www.cygnal.org/.../001050.html

    Tsuneo

Reply
  • "Does HID Interrupt class has any limitation which doesn't allow use of many endpoints???

    Single HID interface holds
    one interrupt IN endpoint (mandatory)
    one interrupt OUT endpoint (optional)

    Then, you need multiple HID interfaces to support more endpoints on single device.
    That is, composite device.

    Unfortunately, Keil Apnt195 doesn't explain about nothing about composite device.

    I posted a brief summary and examples about composite device to SiLabs forum.
    The example on a composite device withe three HID interfaces will help you.
    This example is written for SiLabs '51 chip, but you'll find how to write the descriptors, how to implement requests handling on composite device.

    "USB composite device"
    www.cygnal.org/.../001050.html

    Tsuneo

Children
  • Thanks a lot for your kind help...

    I higly appreciate that.

    Well, My descriptor tables are designed in this way.

    HID_Report descriptor
    { ............ ............
    }

    HID_ConfigurationDescriptor
    { config descriptor.... .........

    Interface 0 descriptor...... .........

    HID Class Descriptor..... .........

    Endpoint Descriptor...... .........
    }

    String Descriptor
    { ............. .............
    }

    Since I have to make now two interfaces, i require two report, Interface, Class, Endpoint descriptors.

    Where should i add these descriptor.
    For reference you can take Keil HID example..

  • I'll show the outline of a composite device of two HID interfaces.
    - It defines two sets of report descriptor, two sets of Interface-HID class-Endpoint descriptor block.
    - If two report descriptors are identical, you can reduce them to single.

    HID_Report descriptor 0
    { ............ ............
    }
    
    HID_Report descriptor 1
    { ............ ............
    }
    
    HID_ConfigurationDescriptor
    {
       config descriptor      ...... .........
    
       Interface 0 descriptor ...... .........
       HID Class Descriptor 0 ...... .........
       Endpoint Descriptor 1  ...... .........
    
       Interface 1 descriptor ...... .........
       HID Class Descriptor 1 ...... .........
       Endpoint Descriptor 2  ...... .........
    
    }
    
    String Descriptor
    { ............. .............
    }
    

    Copy the interface block and modify it as follows.

    Tsuneo

    http://www.keil.com/download/docs/306.asp
    LPC2148_USBHID.ZIP
    usbdesc.c

    /* HID Report Descriptor */
    const BYTE HID_ReportDescriptor0[] = {
      ...
    };
    
    const BYTE HID_ReportDescriptor1[] = {
      ...
    };
    
    const WORD HID_ReportDescSize0 = sizeof(HID_ReportDescriptor0);
    const WORD HID_ReportDescSize1 = sizeof(HID_ReportDescriptor1);
    
    /* USB Configuration Descriptor */
    /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
    const BYTE USB_ConfigDescriptor[] = {
    /* Configuration 1 */
      USB_CONFIGUARTION_DESC_SIZE,       /* bLength */
      USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
      WBVAL(                             /* wTotalLength */
        USB_CONFIGUARTION_DESC_SIZE +
        USB_INTERFACE_DESC_SIZE     +
        HID_DESC_SIZE               +
        USB_ENDPOINT_DESC_SIZE      +
        USB_INTERFACE_DESC_SIZE     +
        HID_DESC_SIZE               +
        USB_ENDPOINT_DESC_SIZE
      ),
      0x02,                              /* bNumInterfaces */
      0x01,                              /* bConfigurationValue */
      0x00,                              /* iConfiguration */
      USB_CONFIG_BUS_POWERED /*|*/       /* bmAttributes */
    /*USB_CONFIG_REMOTE_WAKEUP*/,
      USB_CONFIG_POWER_MA(100),          /* bMaxPower */
    
    /* Interface 0, Alternate Setting none, HID Class */
      USB_INTERFACE_DESC_SIZE,           /* bLength */
      USB_INTERFACE_DESCRIPTOR_TYPE,     /* bDescriptorType */
      0x00,                              /* bInterfaceNumber */
      0x00,                              /* bAlternateSetting */
      0x01,                              /* bNumEndpoints */
      USB_DEVICE_CLASS_HUMAN_INTERFACE,  /* bInterfaceClass */
      HID_SUBCLASS_NONE,                 /* bInterfaceSubClass */
      HID_PROTOCOL_NONE,                 /* bInterfaceProtocol */
      0x5C,                              /* 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(sizeof(HID_ReportDescriptor0)),      /* 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(0x0004),                     /* wMaxPacketSize */
      0x20,          /* 32ms */          /* bInterval */
    
    /* Interface 1, Alternate Setting none, HID Class */
      USB_INTERFACE_DESC_SIZE,           /* bLength */
      USB_INTERFACE_DESCRIPTOR_TYPE,     /* bDescriptorType */
      0x01,                              /* bInterfaceNumber */
      0x00,                              /* bAlternateSetting */
      0x01,                              /* bNumEndpoints */
      USB_DEVICE_CLASS_HUMAN_INTERFACE,  /* bInterfaceClass */
      HID_SUBCLASS_NONE,                 /* bInterfaceSubClass */
      HID_PROTOCOL_NONE,                 /* bInterfaceProtocol */
      0x5C,                              /* 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(sizeof(HID_ReportDescriptor1)),      /* wDescriptorLength */
    /* Endpoint, HID Interrupt In */
      USB_ENDPOINT_DESC_SIZE,            /* bLength */
      USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
      USB_ENDPOINT_IN(4),                /* bEndpointAddress */
      USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
      WBVAL(0x0004),                     /* wMaxPacketSize */
      0x20,          /* 32ms */          /* bInterval */
    
    /* Terminator */
      0                                  /* bLength */
    };
    

  • Thanks a lot Tsuneo.
    you are of a great help....

    Well, do we have to make any changes in "usbcore.h", __inline BOOL USB_SetConfiguration (void) function too or any where else?

    I highly appreciate your help.

    Thanks

  • Add support for the additional interface(s) to GetDescriptor and class-specific request handler.
    I didn't show #define's like USB_HID_IF_NUM0.
    These values are easily determined according to the original source code.

    usbcfg.h
    #define USB_EP_EVENT        0x0013   // set the bits of the endpoints in use
    
    usbcore.c
    
    /*
     *  Get Descriptor USB Request
     *    Parameters:      None (global SetupPacket)
     *    Return Value:    TRUE - Success, FALSE - Error
     */
    
    __inline BOOL USB_GetDescriptor (void) {
      ...
      switch (SetupPacket.bmRequestType.BM.Recipient) {
        ...
        case REQUEST_TO_INTERFACE:
          switch (SetupPacket.wValue.WB.H) {
    #if USB_HID
            case HID_HID_DESCRIPTOR_TYPE:
              len = HID_DESC_SIZE;
              if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM0) {
                EP0Data.pData = (BYTE *)USB_ConfigDescriptor + HID_DESC_OFFSET0;
              } else
              if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM1) {
                EP0Data.pData = (BYTE *)USB_ConfigDescriptor + HID_DESC_OFFSET1;
              } else
                return (FALSE);    /* Multiple HID Interfaces are supported */
              break;
            case HID_REPORT_DESCRIPTOR_TYPE:
              len = HID_ReportDescSize;
              if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM0) {
                EP0Data.pData = (BYTE *)HID_ReportDescriptor0;
              } else
              if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM1) {
                EP0Data.pData = (BYTE *)HID_ReportDescriptor1;
              } else
                return (FALSE);    /* Only Single HID Interface is supported */
              break;
            case HID_PHYSICAL_DESCRIPTOR_TYPE:
              return (FALSE);      /* HID Physical Descriptor is not supported */
    #endif
        ...
    }
    
    /*
     *  USB Endpoint 0 Event Callback
     *    Parameter:       event
     */
    
    void USB_EndPoint0 (DWORD event) {
        ...
        ...
            case REQUEST_CLASS:
            ...
    #if USB_HID
                  if ( (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM0)
                    || (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM1) ) {
        ...
        ...
        case USB_EVT_OUT:
        ...
    #if USB_HID
                        if ( (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM0)
                          || (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM1) ) {
    

    demo.c - GetInReport(), SetOutReport()
    Dispatch these handlers depending on the interface number in SetupPacket.wIndex.WB.L

    usbuser.c - USB_EndPoint4() (and other additional endpoints)
    Copy USB_EndPoint1() and modify it to fit to the endpoint.

    usbuser.c - USB_Configure_Event()
    Put the initial data to the additional endpoint(s)
    If you don't handle the endpoints in the USB ISR, like this post, this initial data is not required.
    "HID Mouse keeps sending unneeded data!"
    http://www.keil.com/forum/docs/thread11531.asp

    Tsuneo

  • Hi Tsuneo...
    I heartly express my thanks to you... but a bit dipressed..
    I did as you asked me to do but still things are not working...

    I don't know how to proceed.. i went through the full code but couldn't find any other place to modify...

    need your expert help badly.

  • Hi Tsuneo.....
    It started working.... YES!!!!!!!
    I didn't know i have to uninstall the driver first... After uninstalling, the things started working very fine....

    Thanks a lot for your help....

  • Thanks from me too Tsuneo! I had a similar requirement and you saved me a ton of time.