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 Device - Bulk - Double buffering packet help

Part Number: TM4C123GE6PM

Hello,

While reading the datasheet about the USB controller in device mode I noticed there is 4k of ram/fifo allotted to the endpoints as well as a single buffering/double buffering mode.  I'm attempting to use bulk transfers to use the maximum allowable amount of free bandwidth when the bus isn't busy for data transfers.  This yields increased throughput for packets as bulk transfers can send more than a single 64 byte packet per frame.  So long story short I want to use bulk so I can get the best throughput on the MCU for USB 2.0 device mode.

With all that said I've become concerned and have a few questions.

1. The datasheet/UG states there is 4k of fifo space allotted for endpoints.  Does this mean all active endpoints will share this ram or each endpoint can have its own 4k buffer if desired?

2. The double-buffering mode as described in section 18.3.1.2 and beyond implies that you can only load 2x packets (two 64 byte chunks) into the endpoint buffer.  Does this mean I'm bandwidth limited to sending 2x bulk packets per frame?  This seems quite poor as the purpose of bulk is to send (I think) around 19 packets if there is enough unused bandwidth in the frame?  I feel like I'm missing something as this would only really be throughput improvement of 2x HID which is quite slow.  

3. Depending on question #2 above - is there a way to load many packets into an endpoint fifo so max utilization of bulk is possible (of course depending on the bus)?  My understanding, from the host side, is that if there is space the host will continue to grab more packets for the current transfer and the device must make sure those packets are immediately available.  This is important because (I think) the MCU is unable to get in interrupt to fetch the extra data for that frame if there is available space - from my research it seems like the additional packets must be in the fifo.

Any help is greatly appreciated!

Thanks!

  • Hi,

    1. The datasheet/UG states there is 4k of fifo space allotted for endpoints.  Does this mean all active endpoints will share this ram or each endpoint can have its own 4k buffer if desired?

    That is correct. All active endpoints share the same 4k FIFO memory. 

    2. The double-buffering mode as described in section 18.3.1.2 and beyond implies that you can only load 2x packets (two 64 byte chunks) into the endpoint buffer.  Does this mean I'm bandwidth limited to sending 2x bulk packets per frame?  This seems quite poor as the purpose of bulk is to send (I think) around 19 packets if there is enough unused bandwidth in the frame?  I feel like I'm missing something as this would only really be throughput improvement of 2x HID which is quite slow.

    For bulk transactions, the maximum packet size is 64 bytes for full speed. This is actually per USB spec. If you have kilobytes of data to transfer then they will be broken into multiple 64-bytes of transactions which constitute a USB transfer. Please refer to this link for details about bulk transfers. 

    https://www.beyondlogic.org/usbnutshell/usb4.shtml#Bulk

    3. Depending on question #2 above - is there a way to load many packets into an endpoint fifo so max utilization of bulk is possible (of course depending on the bus)?  My understanding, from the host side, is that if there is space the host will continue to grab more packets for the current transfer and the device must make sure those packets are immediately available.  This is important because (I think) the MCU is unable to get in interrupt to fetch the extra data for that frame if there is available space - from my research it seems like the additional packets must be in the fifo.

    If bulk transfers is not interrupted by higher priority transfers such as isochronous or interrupt transfers then it will transfer as many packets (64bytes per packet) as possible to utilize the bandwidth. Below is about bulk transfers from the above link I share. 

    Bulk Transfers

    Bulk transfers can be used for large bursty data. Such examples could include a print-job sent to a printer or an image generated from a scanner. Bulk transfers provide error correction in the form of a CRC16 field on the data payload and error detection/re-transmission mechanisms ensuring data is transmitted and received without error.

    Bulk transfers will use spare un-allocated bandwidth on the bus after all other transactions have been allocated. If the bus is busy with isochronous and/or interrupt then bulk data may slowly trickle over the bus. As a result Bulk transfers should only be used for time insensitive communication as there is no guarantee of latency.

    Bulk Transfers

          • Used to transfer large bursty data.
          • Error detection via CRC, with guarantee of delivery.
          • No guarantee of bandwidth or minimum latency.
          • Stream Pipe - Unidirectional
          • Full & high speed modes only.

    Bulk transfers are only supported by full and high speed devices. For full speed endpoints, the maximum bulk packet size is either 8, 16, 32 or 64 bytes long. For high speed endpoints, the maximum packet size can be up to 512 bytes long. If the data payload falls short of the maximum packet size, it doesn't need to be padded with zeros. A bulk transfer is considered complete when it has transferred the exact amount of data requested, transferred a packet less than the maximum endpoint size, or transferred a zero-length packet.

  • Hi Charles,

    Thank you for the response.  Long story short I'm wondering if you can load more than two 64 byte packets into the endpoint fifo for USB full speed bulk transfers?  The data sheet double buffering description makes me think you can't.  This is important because I think the data needs to be in the endpoint FIFO for the host to pull out multiple packets.  So if I transfer say 100 megabytes I want to keep the endpoint buffer full so the host always has a lot of packets it can pull out if space in that frame allows.  Not sure if that is super clear but my concern is that I would be unable to load/send say 10 packets when possible because the MCU only suppoerts loading two packets per endpoint from the double buffering section.

  • Hi Robert,

      The FIFO is meant to buffer the new data while the USB transaction is sent to the bus. If you have 10 packets to send then it will buffer two packets at a time while the prior packets is sent to the bus. There is no need to buffer 10 packets of data. It is not possible to buffer N packets all at once as the FIFO or any memory is limited. 

  • Ok but the issue here is that the benefit of bulk is that you send more than 2 packets per transaction.  So if at the end of the day the MCU can only feed 2 packets at a time per transaction you're not getting much out of a bulk transfer.  I am just struggling to see, with this architecture, how the tiva can utilize the potential of bulk if it can only send two packets at a time for the bulk endpoint.

  • Hi Robert,

      I think we need to clarify what is a transaction. A 'transaction' consists of a token packet, data packet and a handshake packet.  Please refer to the USB link I refer. In this transaction, the data packet is 64bytes for bulk transfer configuration. If you have 10 packets to transfer then this USB transfer consists of 10 transactions.  You are going to see on USB bus 10 transactions of 64bytes of data packets back to back if you only have one endpoint configured for bulk transfers. Of course, if you have other endpoints that are configured for isochronous or interrupt transfers then they can interrupt this bulk transfer because isochronous transfers have guaranteed bandwidth per USB protocol. 

  • Just to make sure we are on the same page. If you think that a transaction can consist of 2 or more data packets then that is not how USB protocol works per my understanding. For example, if you think a USB transaction consists of a token packet -> 10 data packets (10 x 64 = 640 bytes) -> handshake packet then this is not what a USB protocol is defined. 

    USB Protocol

    USB is a polled bus, where the host initiates all data exchanges.

    Transactions

    Data is transferred in so called transactions. Normally, they consist of three packets:

    1. The token packetis the header defining the transaction type and direction, the device address, and the endpoint.
    2. Data is transferred in a data packet.
    3. The final status of the transaction is acknowledges in the handshake packet.

    Pipe Model

    In a transaction, data is transferred either from the USB Host to an USB Device or vice-versa. The transfer direction is specified in the token packet that is sent from the USB Host. Then, the source sends a data packet or indicates it has no data to transfer. In general, the destination responds with a handshake packet indicating whether the transfer was successful.

    Packet Model

    Packets

    Packets could be thought of as the smallest element of data transmission. Each packet transmits an integral number of bytes at the current transmission rate. Packets start with a synchronization pattern, followed by the data bytes of the packet, and concluded with an End-of-Packet (EOP) signal. All USB packet patterns are transmitted least significant bit first. Before and after the packet, the bus is in idle state.

    Start-of-Frame (SOF) Packet

    A special packet is the Start-of-Frame packet (SOF) that splits the USB bus into time segments. Each pipe is allocated a slot in each frame. The Start-of-Frame packet is sent every 1ms on full speed links. At high speed, the 1ms frame is divided into 8 microframes of 125μs each. A Start-of-Frame packet is sent at the beginning of each microframe using the same frame number. The frame number increments every 1ms.

  • Hi Charles,

    I believe my terminology was quite off and causing confusion here.  Let me take a step back and re-evaluate my question after spending more time on the resources you provided.  This is quite helpful and most likely I got confused.  

    Thanks a lot for the help.  I will come back and post after a further review of this. 

  • Hi Charles,

    I think I understand and the good news is that I was confused and the Tiva series will work.  I will elaborate so you can verify I am understanding this correctly.

    I was initially worried about throughput being unnecessarily low because I thought a packet was actually a transaction which was wrong.  Because of this mistake I therefore thought only two packets (should have been using "transaction") would fit in the 1mS polling rate for a "frame".  I thought the 1ms time block was a frame.  Here is a link that seems to be referring to "frame" in the same way I am.

    https://www.usbmadesimple.co.uk/ums_6.htm#frames_and_microframes

    So to sum up my confusion.  I thought the MCU  could only fit 2x USB 2.0 bulk data packets (64 bytes packets) in a frame.  This was incorrect and I believe I see how this works now and the MCU will handle things fine.

    If I understand this correctly, the MCU will load the endpoint buffer with 64 bytes of data to transfer to the host (in the IN example here).  This data becomes a data packet within a transaction on the bus.  As you showed above each transaction has 3x packets.  Once this happens (the  host reads the endpoint) an interrupt will be thrown to reload the endpoint buffer with more data for the next transaction.  The MCU will have time to fetch new 64 byte blocks between data packets in each transaction and transactions will fill up a frame.  

    So long story short, the MCU reloads the endpoint buffer after each transaction and there will be plenty of time for the MCU to stuff the next packet's data into the buffer.  If there is space within the frame the host will continue to issue read transactions and the MCU will keep loading data for these transactions.  

    As for the double buffering, this just allows you to hold an extra data chunk for the next transaction's data packet.  So if double buffering is used and the endpoint holds two packets (data packet data) it basically means two back to back data transactions can be serviced?  If this is true this makes sense now and I was confusing packet with transaction.  

    So the big picture for large data transfers (as efficiently as possible with bulk) is that the MCU just needs to keep servicing (filling) the endpoint buffers with data to support the data transactions.  The host will use as many transactions as it can per frame.  

    If at this point I'm on the right track then my post was due to a misunderstanding on my part thinking that the double buffering meant only two data transactions per frame were possible which I now see isn't the case.  

    Thanks for the support Charles!

  • Hi Robert,

      Your understanding is correct. Glad that everything is clear up for you.