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/TM4C123GH6PM: Send / Recieve USB messages.

Part Number: TM4C123GH6PM

Tool/software: Code Composer Studio

Hello!

I am trying to create a small little application using the TM4C123GH6PM, currently with the launch pad, but I will turn the design into a single PCB one, once the program is finished.

So what I am trying to achive is, send some lines to the board from the PC via USB,  it should recognicse the command, do it job and echo back OK or an Error code. 

Commands look like this: 

  • Rxxx
  • Lxxx
  • Zxxx
  • Txxx
  • etc..

Where the X-s are representating number, it's always 3 digits. 

What I have managed to do so far is to modify the usb_dev_bulk, I have changed the part  "EchoNewDataToHost"

static uint32_t
EchoNewDataToHost(tUSBDBulkDevice *psDevice, uint8_t *pui8Data,
                  uint32_t ui32NumBytes)
{
    uint32_t ui32Loop, ui32Space, ui32Count;
    uint32_t ui32ReadIndex;
    uint32_t 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);

    //
    // How many characters can we process this time round?
    //
    ui32Loop = (ui32Space < ui32NumBytes) ? ui32Space : ui32NumBytes;
    ui32Count = ui32Loop;

    //
    // Update our receive counter.
    //
    g_ui32RxCount += ui32NumBytes;

    //
    // Dump a debug message.
    //
    DEBUG_PRINT("Received %d bytes\n", ui32NumBytes);

    //
    // Set up to process the characters by directly accessing the USB buffers.
    //
    ui32ReadIndex = (uint32_t)(pui8Data - g_pui8USBRxBuffer);
    ui32WriteIndex = sTxRing.ui32WriteIndex;

    while(ui32Loop)
    {
        //
        // Copy from the receive buffer to the transmit buffer converting
        // character case on the way.
        //

        //
        // Is this a lower case character?
        //
        if((g_pui8USBRxBuffer[ui32ReadIndex] == 'L'))
        {
            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3);
            UARTprintf("LEFT" );

        }
        else if((g_pui8USBRxBuffer[ui32ReadIndex] == 'R'))
        {
            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
            UARTprintf(" RIGHT " );

        }
        else
        {

            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0);
            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
            //
            // Is this an upper case character?
            //
            if((g_pui8USBRxBuffer[ui32ReadIndex] >= 'A') &&
               (g_pui8USBRxBuffer[ui32ReadIndex] <= 'Z'))
            {
                //
                // Convert to lower case and write to the transmit buffer.
                //
                g_pui8USBTxBuffer[ui32WriteIndex] =
                    (g_pui8USBRxBuffer[ui32ReadIndex] - 'Z') + 'z';
            }
            else
            {
                //
                // Copy the received character to the transmit buffer.
                //
                g_pui8USBTxBuffer[ui32WriteIndex] =
                    g_pui8USBRxBuffer[ui32ReadIndex];
            }
        }

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

        ui32ReadIndex++;
        ui32ReadIndex = (ui32ReadIndex == BULK_BUFFER_SIZE) ?
                        0 : ui32ReadIndex;

        ui32Loop--;
    }

    //
    // We've processed the data in place so now send the processed data
    // back to the host.
    //
    USBBufferDataWritten(&g_sTxBuffer, ui32Count);

    DEBUG_PRINT("Wrote %d bytes\n", ui32Count);

    //
    // We processed as much data as we can directly from the receive buffer so
    // we need to return the number of bytes to allow the lower layer to
    // update its read pointer appropriately.
    //
    return(ui32Count);
}

So now I know the program separates the first 2 commands, but I would like to ask for your help on :

  • how to get the next 3 digits after the command
  • how to get these 3 digits as numbers (int s)
  • how to echo back strings easily (something UARTprintf or something)

Thank you for helping me!

  • You questions are pretty generic C questions. To access the three digits sent after the letter, you can simply increment the index into the receive buffer. There are several ways to convert the three ASCII digits into a number. You can use sscanf(), or atoi().

    #include <stdlib.h>
    

            if((g_pui8USBRxBuffer[ui32ReadIndex] == 'L'))
                   {
                       GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3);
                       UARTprintf("LEFT" );
                       value = atoi((char *)g_pui8USBRxBuffer+ui32ReadIndex+1u);
    
                   }
    

    You can use sprintf() to create a string to send back.

  • Hello Bob!

    Thanks for your entry, I am not so professional in C, to be honest with you while I was waiting for the topic to be opened by an administrator i whore the following snipet:

            if((g_pui8USBRxBuffer[ui32ReadIndex] == 'L'))
            {
                ui32ReadIndex++;
                ui32ReadIndex = (ui32ReadIndex == BULK_BUFFER_SIZE) ?
                                0 : ui32ReadIndex;
                GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3);
                UARTprintf("LEFT" );
                char buffer[3];
                uint32_t i;
                for(i = 0; i<3; i++){
                	buffer[i] = g_pui8USBRxBuffer[ui32ReadIndex];
                    ui32ReadIndex++;
                    ui32ReadIndex = (ui32ReadIndex == BULK_BUFFER_SIZE) ?
                                    0 : ui32ReadIndex;
                }
                number = atoi((char *)buffer);
                UARTprintf("\n %i", number);
                for(i = 0; i < sizeof(buffer); i++ )
                {
                	g_pui8USBTxBuffer[ui32WriteIndex] = buffer[i];
                    ui32WriteIndex++;
                    ui32WriteIndex = (ui32WriteIndex == BULK_BUFFER_SIZE) ?
                                     0 : ui32WriteIndex;
                }
    
    
    
            }

    This basically does the same. 

    I have tried your tip with sprintf the following happens:

    The code: 

    if((g_pui8USBRxBuffer[ui32ReadIndex] == 'C'))
            {
    
                GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
                UARTprintf(" COMMAND " );
                uint32_t value;
                valueC = atoi((char *)g_pui8USBRxBuffer+ui32ReadIndex+1u);
                UARTprintf("\n %i", valueC);
    
                switch(valueC){
                	case 100:
                		//TODO
                		sprintf(g_pui8USBTxBuffer, "COMMAND OK");
                		break;
    
                	default:
                		sprintf(g_pui8USBTxBuffer, "INVALID COMMAND");
                		break;
    
                }
    
    
    
            }

    I send the following message via the sample usb applicaiton: "C101" I get the response of: "I101" ?!?!?!

    So I have got suspicious that maybe the remaining part of the original code makes some changes there and that couses this problem.

    So now I receive the messages in 4 character long senctions

    C101 - > "INVA"  - INVALID COMMAND

    C100 -> "AND "  - COMMAND OK

    C101 -> "COMM" - INVALID COMMAND

    What would be the workaround for this? 

    Flushing the TX buffer every time and send the whole buffer. I guess.

        //
        // We've processed the data in place so now send the processed data
        // back to the host.
        //
        USBBufferDataWritten(&g_sTxBuffer, ui32Count);

    And replace the ui32Count with the buffer length..., but the following did not work:

        //
        // We've processed the data in place so now send the processed data
        // back to the host.
        //
        USBBufferDataWritten(&g_sTxBuffer, sizeof(g_pui8USBTxBuffer[BULK_BUFFER_SIZE]));

    Maybe I am asking stupid questions form a C program point of view but the other side of this communication is gonna be in C# which makes thing way easier.

  • Az I have mentioned here e2e.ti.com/.../2258704 sending back messages has some errors. "use sprintf()" is not a solution in my opinion.