This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123GE6PM: USB Endpoints - how to implement more

Part Number: TM4C123GE6PM
Other Parts Discussed in Thread: EK-TM4C123GXL

Hello,

I have a hid data pipe device up and and running and I am trying to figure out if it is possible to use the other endpoints in the part to transfer data.  I think HID is generally 1 IN and 1 OUT and 1 CONFIG, but since the datapipe device is customizable is it possible to employ the other endpoints in the device?  I ask, because it looks like you can add additional endpoint descriptors to the USB interface/device I already have working.

I'm just a little unsure of the following.

1. is it possible to mod the USB HID descriptors in such a way that one hid device can utilize all 8 endpoints in the Tiva MCU?

2. If so, how does the driver lib figure out which pipe to use - I'm using the call USBDHIDReportWrite() call right now and I just pass it a 64 byte buffer.  If I attempted to enumerate my device with more endpoint descriptors how do you tell the driver lib which endpoint to send the data/buffer out of?

3. If there is no way to customize HID, does anyone know what the next best option might be?

Ideally I would like to update my existing system to utilize the remaining unused endpoint buffers available in the device.  

Thanks for any help!

  • Hi Robert,

      I'm not a USB expert. I believe per USB protocol you can specify multiple endpoints per interface. In another word, specifying 8 endpoints for one interface is possible. However, as you are already aware, the current HID class in the TivaWare USB library is designed for 3 endpoints (1 Interrupt IN,  1 Interrupt OUT and 1 Endpoint0). If you need to use more endpoints,  I think you need to get down to the USB Device API level. The examples we have are abstracted by the Device Class Driver API. We don't have any examples to show application directly interfacing with USB Device API. You will need to go through the USB library user's guide (section 2.23) to get a feel on how to use USB Device API directly from your application. I think the drivers on the host side may need to be adapted to utilize different endpoints. This may become a custom driver that you need to take care of too. 

    2.2.2 USB Library Device API
    The USB Library Device API offers a group of functions specifically intended to allow development
    of fully-featured USB device applications with as much of the class-independent code as possible
    contained in the USB Library. The API supports device enumeration via standard requests from the
    host and handles the endpoint zero state machine on behalf of the application.

    An application using this interface provides the descriptors that it wishes to publish to the host during
    initialization and these provide the information that the USB Device API requires to configure the
    hardware. Asynchronous events relating to the USB device are notified to the application by means
    of a collection of callback functions also provided to the USB Device API on initialization.
    This API is used in the development of USB device class drivers and can also be used directly
    by applications which want to provide USB functionality not supported by an existing class driver.
    Examples of such devices would be those requiring complex alternate interface settings.
    The USB Device API can be thought of as a set of high level device extensions to the USB DriverLib
    API rather than a wrapper over it. When developing to the USB Device API, some calls to the
    underlying USB DriverLib API are still necessary.
    The header file for the USB Device API is device/usbdevice.h.

    2.23 Using the USB Device API
    If an existing USB Device Class Driver is not suitable for your application, you may choose to
    develop your device using the lower-level USB Device API instead. This offers greater flexibility but
    involves somewhat more work. Creating a device application using the USB Device API involves
    several steps:
    - Build device, configuration, interface and endpoint descriptor structures to describe your device.

    - Write handlers for each of the USB events your device is interested in receiving from the USB
    library.
    - Call the USB Device API to connect the device to the bus and manage standard host interaction
    on your behalf.


    The following sections walk through each of these steps offering code examples to illustrate the
    process. Working examples illustrating use of the library can also be found in the DriverLib release
    for your USB-capable evaluation kit.
    The term “device code” used in the following sections describes all class specific code written
    above the USB Device API to implement a particular USB device application. This may be either
    application code or a USB device class driver.

  • Thank you very much for the response!  You made a good point about the host drivers.  I don't really want to re-invent the wheel if I don't have to on the host or the TI USB driverlib device side.  

    So would you think the best path forward is probably to make the device a "composite" (I think thats correct) and have both a hid and mass storage and just do big data transfers with mass storage.  So to the OS they are two fully supported devices (or interfaces not sure which term is correct here)?

  • Hi Robert,

      You will need to check if the host side  HID drivers can already support multiple endpoints. If it can, you may not need to rewrite the host drivers. 

      A composite device supporting both HID and MSC will be another option. 

  • Hey Charles,

    The MSC is pretty appealing because it can use additional bandwidth.  In reading the spec it sounds like rather than 1 64 byte packet per mS it can (if the bus isn't busy) can send multiple 64 byte packets per 1 mS.  Do you know how that is handled with the driver though.  As a device do you use the write data call on one end point and if there is bandwidth the host pulls multiple 64byte blocks out of one endpoint or do you need to use endpoints in parallel to capitalize on the ability for MSC to utilize the unused bandwidth.

    Ive been reading the usbdriverlib documentation but it isn't clear how to use the API such that MSC will take advantage of extra bandwidth.  I'm guessing you just keep one endpoint (4k buffer in my part) full and the protocol figures it out?  

  • Hi Robert,

    The MSC is pretty appealing because it can use additional bandwidth.  In reading the spec it sounds like rather than 1 64 byte packet per mS it can (if the bus isn't busy) can send multiple 64 byte packets per 1 mS.

      That is also my understanding.  MSC uses bulk transfer type (not interrupt or isochronous). Therefore, for full-speed endpoints, If the bus is idle, multiple Bulk Transfers can take place in a single 1ms frame (Interrupt and Isochronous Transfers are limited to a maximum of one packet per frame). In theory, you may be able to reach 1Mbytes per second throughput using BULK transfers but in reality I think it will be a lot less than that. Full speed has maximum throughput of 12Mbps which is 1.5MBps. As you know there is overhead for each transfer (e.g. token, endpoint address, CRC, ACK and etc). The overhead is 13 bytes for BULK transfers. If your data payload is 64 bytes then it means 13/(13+64) = 17% is associated with the overheads. There is also some bit stuffing per USB protocol and 10% of bandwidth needs to be reserved. This leaves you with maximum 1MBps. 

      We do have a MSC example. You can find it in C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\dk-tm4c129x\usb_dev_msc. Although this example is for TM4C129, I think you can reference it and adapt for TM4C123. The USB library is common for both devices. I'm not sure what your application is. If you are looking for maximum bandwidth, you can also consider the C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c123gxl\usb_dev_bulk example which uses BULK transfers. 

  • Thanks Charles you are a huge help!  I really appreciate your time!