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.

USB bulk transfers

I have a basic question on USB transfers/ drivers.
Lets say a host wants to read data from the device (TIVA) and it performs a transfer IN, where(in which part of the device SW driver) the device should process the answer?

The routine  RxHandler is for the data the device receives from the host while TxHandler is the data the device transmits to the host...so If the HOST start a transfer IN...where I am going to see that  in the device sw driver(so I can process the information and answer)?


Right now I am writing data (transfer OUT) from the host  to communicate to the device which data to send in the next Transfer IN request...so I manage the answer in the RxHandler..it does not look to me the correct way to do it.


Thanks.

  • Hi,

    you shouldn't touch the drivers that TI furnish.

    -RXhandler, is a interrupt when Data is sent from the Host

    -TXhandler, is a interrupt when a complete data transfer has been made with the host.

    The last part of your question is unclear, can you specify?
  • Thanks for taking the time to answer.
    I am not touching the driver, this is the last thing I want to do. I try to explain better my point.

    I am using libusb on HOST side and TI driver on DEVICE side. The software is working well but sometime I have some errors (mainly TIMEOUT).
    In my HOST application the HOST submits a OUT-transfer and just after that an IN-transfer. The OUT-transfer is used to tell the device which data to use when the HOST will submit the IN-transfer. The loop works well. My question is... is it possible to perform only the IN-Transfer? If so, where in the SW driver (device) I should implement the part that takes the data and write it on the TX_Buffer? At the moment this is managed in the RXhandler. Right now every time I want to do a read from HOST...I do a WRITE before....not sure that is the way it is supposed to work.

    I know this is a basic question but I spent hours looking for an answer and I still don't have it. If somebody has also some links with documentation regarding these things...
    Thanks a lot for the support.
  • Hi,
    what do you mean by In transfer? You mean Host --->device transfer?
  • The transfers are initiated always by the HOST.

    With IN-TRANSFER I mean...the HOST requires data from the DEVICE(read). OUT-TRANSFER the HOST sends data to the Device(write).

    G.

  • Hello Gianluca,

    What is the size of the bulk transfer being requested by the HOST? Did you check if a STALL is being issued by the Device?

    Regards
    Amit
  • I print all the error codes and I do not have that condition. Sometimes I have some TIMEOUT(most recurrent)...that I do not understand...sometimes some error. When I say sometimes I mean...like 5-10 in 1 hour.
    I am trying to understand if I use the bulkOUT/bulkIN in the correct sequence. Do I need a bulkOUT before a Bulk-in to read a specific data buffer from a device?

    I made few changes to avoid transfers overlaps(HOST LAPTOP)...it is a kind of semaphore....so I am sure there are not tranfers pending when I initiate new transfers.

    At he moment I ma sending DEVICE->HOST 400bytes in 3ms.

    Every time a request the data with a bulkOUT/bulkIN, and in the RxHandler I prepare send the data back with the TXBuffer.

    G.
  • Hello Gianluca,

    A site I refer to a lot for USB. AFAIK, you do not need a bulk out for a bulk in, as it is very centric to the application.

    www.beyondlogic.org/.../usb4.shtml

    Regards
    Amit
  • I took a look already there and that is the reason why I started to have doubt about the way I was managing the bulk transfers.
    The problem is ..if I just do a BulkIN...then in the TIVA Driver where should I prepare the answer to the HOST? I enter in RXhandler only for a bulkOUT...and I enter in TXhandler only when a transfer-IN is completed...I don't know if I have explained the point well. I need a kind of callback to prepare teh data to send to the HOST when it requires a bulkIN...
  • Hello Gianluca,

    I think you have explained the condition well. if your application knows what to do on a BulkIN, then it can prepare the data in advance and then use the TXhandler to send the same.

    Regards
    Amit
  • OK, I put a break point in the TXHandler...and I enter there only when I send the data out....which is what I would like to do in the TXhandler.
    I do not enter in TXHandler when the HOST requires a BulkIN...that is my issue.
  • Hello Gianluca,

    OK, I am confused. Did you mean to say that currently the application is entering the TxHandler when a BulkIN is requested by the host or you want the application to enter the TxHandler when a BulkIN is requested?

    If you look at the code then TxHandler is called during a BulkIn and you can use the Callback function to prepare the next set of data.

    Regards
    Amit
  • The application does not enter in the TxHandler when the HOST (laptop) request a BulkIN.
    The application enters in TXHandler only when the DEVICE write the TXBuffer.
  • Hi,
    sure, as I mentionned earlier, TXhandler is an interrupt when a complete transfer has been made with the Host. For your application, you need to implement a protocol. As an example, if you send 0xFF (it is arbitary) to the MCU, than you can programm in your MCU that when you read 0xFF from the host, the MCU will sent data back to the Host.
  • Hello Gianluca

    And you can use this to prepare the next buffer with the first buffer already prepared in the main function.

    Regards
    Amit
  • YES, this is what I am doing already, but to send the "0xFF (it is arbitary)" I use a BulkOUT with first byte of the buffer = 0xFF. So, we are back to my point ...before a BulkIN i have to do a BulkOUT with the 0xFF. IF this is the way I am ok with that.
  • Gianluca Allegretto said:
    My question is... is it possible to perform only the IN-Transfer?

    Yes, IN and OUT endpoints work independently each other, even if they share the same endpoint number (except for the default endpoint, EP0).

    I need a kind of callback to prepare teh data to send to the HOST when it requires a bulkIN...

    Sound like you are working either on usb_dev_bulk or on usb_dev_(c)serial example (and not on usb_dev_msc).

    Both of usb_dev_bulk and usb_dev_(c)serial examples assign a ring buffer (g_sTxBuffer object) over the bulk IN endpoint. To fill data into this TX buffer, you'll call either of these APIs.

    A) USBBufferWrite()
    A simple API, which takes a ring buffer object, source buffer and the size to be written.

    USBBufferWrite((tUSBBuffer *)&g_sTxBuffer, (uint8_t *)&ui8Char, 1);

    B) USBBufferDataWritten()
    Firstly, your code writes to the TX buffer, taking care of buffer wrap around.
    And then, USBBufferDataWritten() is called to pass the number of written bytes.
    A typical usage is seen in usb_dev_bulk example.

    \TivaWare_C_Series-2.1.1.71\examples\boards\dk-tm4c123g\usb_dev_bulk\usb_dev_bulk.c

    static uint32_t
    EchoNewDataToHost(tUSBDBulkDevice *psDevice, uint8_t *pi8Data,
                      uint_fast32_t ui32NumBytes)
    {
        uint_fast32_t ui32Space, ui32WriteIndex;
        tUSBRingBufObject sTxRing;

        //
        // Get the current buffer information to allow us to write directly to
        // the transmit buffer (we already have enough information from the
        // parameters to access the receive buffer directly).
        //
        USBBufferInfoGet(&g_sTxBuffer, &sTxRing);

        //
        // How much space is there in the transmit buffer?
        //
        ui32Space = USBBufferSpaceAvailable(&g_sTxBuffer);

        ui32WriteIndex = sTxRing.ui32WriteIndex;
        for (...) {
            g_pui8USBTxBuffer[ui32WriteIndex] = *your_data_pointer++;
            //
            // Move to the next character taking care to adjust the pointer for
            // the buffer wrap if necessary.
            //
            ui32WriteIndex++;
            ui32WriteIndex =
                (ui32WriteIndex == BULK_BUFFER_SIZE) ? 0 : ui32WriteIndex;
        }
        //
        // We've processed the data in place so now send the processed data
        // back to the host.
        //
        USBBufferDataWritten(&g_sTxBuffer, ui32Count);

    You may call these APIs at any place on your code, either in interrupts of some peripherals or in main loop.


    Sometimes I have some TIMEOUT


    When TIMEOUT occurs on the host,
    a) How many bytes does your firmware sends?
    b) How many bytes does the host request in libusb_bulk_transfer() (libusb 1.0) or usb_bulk_read() (libusb 0.1)?

    As the default, TivaWare doesn't send ZLP over the bulk IN EP.
    When {a) < b)} AND {a) is a multiple of 64 bytes}, you need to enable ZLP appendage using USBBufferZeroLengthPacketInsert()

    Tsuneo

  • Thanks for joining,

    yes, I have started my application from the usb_dev_bulk example and I use USBBufferWrite() in the rxHandler.

    I understand I can call the APIs at any place in the code but I would like to do that when the HOST perform a bulk-IN transfer, is there any interrupt I can use to catch this event?

    Regarding the TIMEOUT, a) 380 b) 380, I should not need to use USBBufferZeroLengthPacketInsert(), right?
  • OK I have few more information to share .
    I added some debug to have statistics about what is happening and I would really appreciate your feedback.

    As I wrote the main communication between HOST/DEVICE is implemented as request of data BULK-OUT and just after that a BULK-IN to get the data. The data is a buffer of 380 bytes. I wanted to monitor what is happening , these are the results from the HOST.


    REQ_MSG_RECEIVED :
    OK 365007 (each is 380 bytes) it is like 18minuts test.
    TIMEOUT 31
    BAD ID 24
    GENERIC ERROR 0

    I have breaks points in the device to make sure BUfferWrite return the correct number(it never fails).

    I don't know is 31 timeouts on 365007 frames is a normal number for a bulk communication..I do not have experience with that.
    The BAD ID (24) happens when there is a TIMEOUT (but sometimes there is timeout without bad ID). BAD ID means the data received by the HOST does not have the correct information...I am sending always 0x55 and receiving 0x00).
    There are not other errors in the HOST,I am monitoring also :

    "LIBUSB_TRANSFER_CANCELLED request message";
    "LIBUSB_TRANSFER_STALL request message";
    "LIBUSB_TRANSFER_NO_DEVICE request message";
    "LIBUSB_TRANSFER_OVERFLOW request message


    On the Device side I have added counter for all error cases in RxHandler and TXHandler...but I do not have any error.