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.

CCS/TM4C1294NCPDT: Share some sample code to transfer the UDB device bulk using DMA

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL

Tool/software: Code Composer Studio

Hii

1. I need some sample code for transferring the bulk device data using DMA.

My requirement is to read the adc channel at1 KHz sampling frequency. I want to maintain two transmit buffer. In timer ISR,  I will append data in two buffers accordingly.

If one buffer get full ,I will trigger the USB  DMA for this buffer and start writing data in other buffer and vice versa.

I already did this implementation through UART DMA and its working fine . Same I want to do via USB.

2. I want to use USB bulk device communication without ISR(subroutine of Txhandler and Rxhandler), Kindly suggest how to do the implementation.

Thanks & Regard

Anamika

  • Hi,

      We have a USB example using Bulk class. This is something that might come close to what you are looking for. You can find in <TivaWare_Installation>/examples/boards/ek-tm4c1294xl/usb_dev_bulk. 

  • Hii Charles

    I have checked  that usb bulk example and it's working also,there it's receiving and sending data via rx and tx handler.I need some sample code with usb DMA bulk transfer and receiving sending data without subroutine.
    Thanks & Regards
    Anamika
  • Hii Charles

     I  run the timer  of every 500 ms and in timer ISR  and In Timer ISR I am sending 10 bytes of data

    in 10 byte : 4 bytes is sample_no (uint32_t sample_no)

    2 bytes adc channel 1  (as of now 1024 value is fixed)

    2 bytes adc channel 2  (as of now 1024 value is fixed)

    2 bytes adc channel 3  (as of now 1024 value is fixed)

    Below function  I am using, please let me know is there any changes

    void Transfer(void)
    {

    sample_no++;

    uint_fast32_t ui32WriteIndex;
    tUSBRingBufObject sTxRing;

    USBBufferInfoGet(&g_sTxBuffer, &sTxRing);
    ui32WriteIndex = sTxRing.ui32WriteIndex;

    g_pui8USBTxBuffer[ui32WriteIndex++] = sample_no>>24;
    g_pui8USBTxBuffer[ui32WriteIndex++] = sample_no>>16;
    g_pui8USBTxBuffer[ui32WriteIndex++] = sample_no>>8;
    g_pui8USBTxBuffer[ui32WriteIndex++] = sample_no;

    g_pui8USBTxBuffer[ui32WriteIndex++] = 1024>>8;
    g_pui8USBTxBuffer[ui32WriteIndex++] = (uint8_t)(1024);

    g_pui8USBTxBuffer[ui32WriteIndex++] = 1024>>8;
    g_pui8USBTxBuffer[ui32WriteIndex++] = (uint8_t)1024;

    g_pui8USBTxBuffer[ui32WriteIndex++] = 1024>>8;
    g_pui8USBTxBuffer[ui32WriteIndex++] = (uint8_t)1024;

    USBBufferDataWritten(&g_sTxBuffer, 10);

    }

    While receiving data, sometime incremented sample no. is not received and also 1024 value not received.

    I am sharing some images, please go through it 

    Thanks & regard

    Anamika

  • Hii Charles

     I  run the timer  of every 500 ms and in timer ISR  and In Timer ISR I am sending 10 bytes of data

    in 10 byte : 4 bytes is sample_no (uint32_t sample_no)

    2 bytes adc channel 1  (as of now 1024 value is fixed)

    2 bytes adc channel 2  (as of now 1024 value is fixed)

    2 bytes adc channel 3  (as of now 1024 value is fixed)

    Below function  I am using, please let me know is there any changes

    void Transfer(void)
    {

    sample_no++;

    uint_fast32_t ui32WriteIndex;
    tUSBRingBufObject sTxRing;

    USBBufferInfoGet(&g_sTxBuffer, &sTxRing);
    ui32WriteIndex = sTxRing.ui32WriteIndex;

    g_pui8USBTxBuffer[ui32WriteIndex++] = sample_no>>24;
    g_pui8USBTxBuffer[ui32WriteIndex++] = sample_no>>16;
    g_pui8USBTxBuffer[ui32WriteIndex++] = sample_no>>8;
    g_pui8USBTxBuffer[ui32WriteIndex++] = sample_no;

    g_pui8USBTxBuffer[ui32WriteIndex++] = 1024>>8;
    g_pui8USBTxBuffer[ui32WriteIndex++] = (uint8_t)(1024);

    g_pui8USBTxBuffer[ui32WriteIndex++] = 1024>>8;
    g_pui8USBTxBuffer[ui32WriteIndex++] = (uint8_t)1024;

    g_pui8USBTxBuffer[ui32WriteIndex++] = 1024>>8;
    g_pui8USBTxBuffer[ui32WriteIndex++] = (uint8_t)1024;

    USBBufferDataWritten(&g_sTxBuffer, 10);

    }

    While receiving data, sometime incremented sample no. is not received and also 1024 value not received.

    I am sharing some images, please go through it 

    Thanks & regard

    Anamika

  • Hi,

      I'm not a USB expert. However, it seems to me that you are using the ring buffer directly rather than using the USB Buffer in the context of USB data transfer. The USB Buffer data structure makes use of the ring buffer. If you were to use the USB buffer then it would have looked something like below as shown in the usb_bulk_structs.c. 

    Please refer to the USB library user's guide section 5 for detail about the USB buffer and the ring buffer. Here is an excerpt.

    A USB buffer provides a unidirectional buffer for a single endpoint and may be configured for operation
    as either a receive buffer (accepting data from the USB controller and passing it to an
    application) or a transmit buffer (accepting data from the application and passing it to the USB
    controller for transmission). In each case, the buffer handles all packetization or depacketization of
    data and allows the application to read or write arbitrarily-sized blocks of data (subject to the space
    limitations in the buffer, of course) at times suitable to it.


    Each USB buffer makes use of a ring buffer object to store the buffered data. The ring buffer object is
    not USB-specific and does not interact directly with any USB drivers but the API is made available
    since the functionality may be useful to an application in areas outside USB communication, for
    example to buffer data from a UART or other peripheral. If attempting to buffer a USB data stream,
    however, the USB buffer API should be used since it handles the USB driver-side interaction on
    behalf of the application. An application must not mix calls to the two APIs for the same object -
    if using a USB buffer, only APIs of the form USBBufferXxx() should be used to access that buffer
    and, similarly, if using a plain ring buffer, only USBRingBufXxx() calls must be used.

    I think if you wanted to use the ring buffer directly you might want to try USBRingBufWrite() instead of USBBufferDataWritten(). Will that make a difference? Also in the USB library user's guide, it mentions in several places that the client must take care to correctly handle the buffer wrap point if accessing the buffer directly. I think the USBRingBufSize(),USBRingBufUsed(),USBRingBufFull() are API that you can use before you call the USBRingBufWrite.

  • Hii Charles

    In USB bulk example(TivaWare_C_Series-2.1.4.178\examples\boards\ek-tm4c1294xl\usb_dev_bulk), It's using ringbuffer and also using USBBufferDataWritten.

    That's why I try to implement the  same as mentioned in example.

    Kindly go through the attached screen.

    Thanks & Regard

    Anamika

  • Hi Anamika,

      Thanks for the reference. In my earlier reply, I mentioned about the need to take care of the buffer wrap and also making sure there is enough space in the transmit buffer. If you look at the reference code snippet below, it is checking how much space is left in the transmit buffer and also taking care of the ui32WriteIndex pointer adjustment (e.g. resetting the pointer to 0 again). I don't see them in your code. Could that be the reason for the problem you see?

        //
        // How much space is there in the transmit buffer?
        //
        ui32Space = USBBufferSpaceAvailable(&g_sTxBuffer);
    
        //
        // How many characters can we process this time round?
        //
        ui32Loop = (ui32Space < ui32NumBytes) ? ui32Space : ui32NumBytes;
        ui32Count = ui32Loop;

            //
            // 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;