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.

Tiva Bulk - Speed up

Hi,

right now I modify the Tiva/Stella Bulk example and achieve to get a bit/rate of 4.5 mb/s.

In the USB spec sheet, the full speed can go up  to 12 mb/s. For my application, I would like to go around 10 mb/s.

Any tips/ideas to increase the data rate?

Regards.

Mathieu

  • Hello Mathieu,

    I think you would need to go through the USB specification. The data rates of 10 mbps is not possible if you check the USB specification on data rates of different transfer types.

    Regards
    Amit
  • Hello,

    10 megabits/s cannot be achieve with a bulk device?

    Regards
    Mathieu
  • Hello Mathieu,

    From the USB1.1 Specification...

    Regards

    Amit

  • Hi, okay I get that the max rate is 9.728 mb/s. I got 2 questions than:

    1. How can I increase my speed? It isn t a hardline spec the 10 mb/s, right how they use a FTDI chip and we just want something better that, I already out perf the chip

    2. Tivaware isn't using USB 2.0 ?
  • Hello Mathieu,

    TM4C123 supports upto 15Mbps (originally called the USB1.1) and TM4C129 supports upto 480Mbps (called the USB 2.0). The USB 2.0 spec supports LS/FS and HS implementation, but that does not mean that the bandwidth automatically changes as the actual device transfers are restricted by the protocol and its overheads.
    The FTDI chip is a USB HS capable device, so it can go above the requirement of LS/FS.

    Regards
    Amit
  • Hi,

    what is the strategy to increase the rate on a TM4C123 device? We would like to get rid of the FTDI chip on the final PCB.

    Regards

    Mathieu

  • Hello Mathieu,

    Which FTDI chip are you using?

    Regards
    Amit
  • Hi we are currently using a FTDI chip FT232.

    But do you have any tips for the Tiva C programming. The main goal is to get rid of any chips and use the MCU at his full potential,

    Regards

    Mathieu

  • Hello Mathieu,

    The FT232 device is surely a FS device. I think to get the MCU at full potential a low level bare metal example with minimal software overhead is required. Unfortunately, we do not have such an example and even with the low level implementation the max data throughput will still get capped at ~9Mbps.

    Regards
    Amit
  • Hi,
    thanks for the reply, I will try to check my coworker the USB code. The usb code is a long term goal, for now we will go with a better ftdi chip. Mainly, because when we merge some code with end up with a 32.2 kb file and Keil cannot compile that in free mode.
  • Hi Mathieu and Amit

    what is the strategy to increase the rate on a TM4C123 device?

    I think to get the MCU at full potential a low level bare metal example with minimal software overhead is required.


    A little modification of TivaWare code would be enough to get better speed of bulk transfers, without low-level bare-metal approach ;-)
    A) Endpoint double buffer
    B) Overhead of ring buffer

    A) Endpoint double buffer
    TM4C123 has endpoint double buffer, which gives more chance for the device to respond to host. This double buffer mechanism is "transparent"; even when the double buffer is enabled, you don't need to change other code around the endpoint. And then, you may easily test the performance of double buffer.

    To enable double buffer on an endpoint,
    1) assign twice buffer size to the endpoint
    2) set corresponding bit of USBRXDPKTBUFDIS or USBTXDPKTBUFDIS for the endpoint
    The modification of the TivaWare is,


    \TivaWare_C_Series-2.1.1.71\usblib\device\usbdconfig.c

    bool
    USBDeviceConfig(tDCDInstance *psDevInst, const tConfigHeader *psConfig)
    {

    line 352:
        ui32Count = MAX_PACKET_SIZE_EP0;
        for(ui32Loop = 1; ui32Loop < NUM_USB_EP; ui32Loop++)
        {
            //
            // Configure the IN endpoint at this index if it is referred to
            // anywhere.
            //
            if(psEPInfo[ui32Loop - 1].pui32Size[EP_INFO_IN])
            {
                //
                // What FIFO size flag do we use for this endpoint?
                //
                ui32MaxPkt = GetEndpointFIFOSize(
                                    psEPInfo[ui32Loop - 1].pui32Size[EP_INFO_IN] * 2, // <--- 1)
                                    &ui32BytesUsed);

                //
                // The FIFO space could not be allocated.
                //
                if(ui32BytesUsed == 0)
                {
                    return(false);
                }

                //
                // Now actually configure the FIFO for this endpoint.
                //
                USBFIFOConfigSet(USB0_BASE, IndexToUSBEP(ui32Loop), ui32Count,
                                 ui32MaxPkt, USB_EP_DEV_IN);
                ui32Count += ui32BytesUsed;

                HWREGB(ui32Base + USB_O_TXDPKTBUFDIS) |= (1 << ui32Loop);    // <--- 2)
            }

            //
            // Configure the OUT endpoint at this index.
            //
            if(psEPInfo[ui32Loop - 1].pui32Size[EP_INFO_OUT])
            {
                //
                // What FIFO size flag do we use for this endpoint?
                //
                ui32MaxPkt = GetEndpointFIFOSize(
                                    psEPInfo[ui32Loop - 1].pui32Size[EP_INFO_OUT] * 2, // <--- 1)
                                    &ui32BytesUsed);

                //
                // The FIFO space could not be allocated.
                //
                if(ui32BytesUsed == 0)
                {
                    return(false);
                }

                //
                // Now actually configure the FIFO for this endpoint.
                //
                USBFIFOConfigSet(USB0_BASE, IndexToUSBEP(ui32Loop), ui32Count,
                                 ui32MaxPkt, USB_EP_DEV_OUT);
                ui32Count += ui32BytesUsed;

                HWREGB(ui32Base + USB_O_RXDPKTBUFDIS) |= (1 << ui32Loop);    // <--- 2)
            }

        }


    B) Overhead of ring buffer
    If you don't get better performance by double buffer, overhead of ring buffer would be the bottle neck of the performance. You have to customize the ring buffer, or you would directly exchange data between your own buffer and the endpoint buffer. The implementation depends on your data provider/consumer. To discuss on this implementation, more information about your data provider/consumer is required.

    Tsuneo

  • Hello Tsuneo,

    Tsuneo Chinzei said:
    You have to customize the ring buffer, or you would directly exchange data between your own buffer and the endpoint buffer.

    Thanks for the inputs. While I agree with your Double Buffer Approach, it is the software overhead of the state machines that is going to run delays into the transfers

    Regards

    Amit

  • HI Amit,
    can you please explain a bit more about the "software overhead of the state machines that is going to run delays into the transfers" ?

    Thanks
  • Hello Gianluca,

    if you look at the function call for the USB device, there is a state machine in the usblib that tracks the state based on the interrupt and the number of function calls in each API. That is the software overhead.

    Regards
    Amit
  • Hello Amit,

    Thanks a lot for your feedback. I spent  some time on the driver today  to understand a bit more and follow your indication.

    I have found a state machine in the function:

    uint32_t USBBufferEventCallback(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData)

    I measured with the oscilloscope the time I spend in this function and it is 100us. I can't understand where the other 900us (total 1ms) are coming from.

    The thing that makes me thinking is that the time is exactly 1ms...no1.1 or 0.95...it is just 1ms. Perhaps I am looking  the wrong part of the code..

    My application works well except for this issue with the timing...so if you can give me some more direction/advise it would be great.

    Thanks

    G.

  • If you'll pardon an interjection by someone who knows nothing about the topic. Isn't there a polling period on the Bus near that time frame?

    Robert
  • Hi, your observation is more than welcomed. Having exactly 1ms between two transfers make me think that that time is not just the result of my transmission but it is a fix time based on some "polling period" or I don't know what else. I don't know more than you about the topic (USB communication) but I am trying to go more in deep and reuse the nice code TI has provided for the bulk transfers. This USB is a 12Mbit/s so I think there should be a way to speed up the driver. I don't know if the operative system (windows7 in my case) plays also a big role...perhaps adding time..not sure.

    G.
  • I believe 1ms usually corresponds to the SOF packet interval. I would try instrumenting one of the internal TickHandlers in usblib to see if that matches the interval you are seeing.
  • Yes Jon, you are right, it seems that 1ms is the SOF packet interval for fulls-peed USB. I think the only way to speed up the data transfer is to transfer bigger sizes or start a transfer before the the completion of the previous one. I don't like both but I don't see other possibility at this time...If somebody has a third option...

    Thanks

    G.

  • Hello Ginaluca,

    IMHO Bigger Size packet would be the best solution.

    Regards
    Amit
  • I am going to do that , hopefully it will work fine, then I will post some updates.
    Thanks
  • Hi, I finaly got the time to implement that, but your code is missing part USB_O_RXDPKTBUFDIS is undefined