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.

RTOS/EK-TM4C123GXL: USB Buffering the data when multiple clocks are used

Part Number: EK-TM4C123GXL


Tool/software: TI-RTOS

Hello,

I am coding for a unit that uses TM4C123G Microcontroller multiple UART's (3 UART Channel) to collect the data from 3 modules and transmit the data using USB. The sensor modules are transmitting the data at 1Kbps individually (total 3 Kbps from 3 modules) in the form of 20 bytes in each packet (50 packets in a second). I am using two clocks with a callback function which interrupts at every 4th and 9th milliseconds (say). Now when I am pushing the data via USB, it is buffering the same data continuously. May I know why is this happening? I assume that I am accessing the data a lot faster than I am suppose to, but for 1Kbps the clock I can configure is at each millisecond. I request some one to help me on this, I am also attaching the code with this thread ( I have made changes in USB serial device example). 

Thanks in advance. 

Regards,

Nithin

/* ===================================================================================
 * --------------------------------  INCLUDES  ---------------------------------------
 * ===================================================================================
 */

#include <string.h>
#include <stdbool.h>

/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/IHeap.h>
#include <xdc/runtime/Memory.h>
#include <ti/sysbios/heaps/HeapMem.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>

/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/UART.h>

/* Example/Board Header files */
#include "Board.h"

/* USB Reference Module Header file */
#include "USBCDCD.h"

/* ===================================================================================
 * ------------------------------  DEFINITIONS  --------------------------------------
 * ===================================================================================
 */

#define TASKSTACKSIZE   512
#define DATA_BUFF_SIZE  60

/* ===================================================================================
 * ---------------------------  GLOBAL VARIABLES  ------------------------------------
 * ===================================================================================
 */

Task_Struct task0Struct, task1Struct,task2Struct,task3Struct;
Char task0Stack[TASKSTACKSIZE], task1Stack[TASKSTACKSIZE],task2Stack[TASKSTACKSIZE],task3Stack[TASKSTACKSIZE];
UART_Handle uart, uart1, uart2, uart3, uart4, uart5;
UART_Params uartParams, uartParams1, uartParams2, uartParams3, uartParams4, uartParams5;
static Semaphore_Handle semSerial,sem1Serial;
Clock_Struct clk0Struct,clk1Struct;

unsigned char a[20]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char b[20]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char c[20]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char data[DATA_BUFF_SIZE]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                                    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                                    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint32_t RxBytes=0, RxBytes1=0, RxBytes2=0;

/*
 *  ======== gpioButtonFxn ========
 *  Callback function for the interrupt.
 */

Void gpioButtonFxn(UArg arg0)
{
    Semaphore_pend(sem1Serial,BIOS_WAIT_FOREVER);
    //GPIO_write(Board_LED0, 1);
    RxBytes1 = UART_read(uart1, b, sizeof(b));

}


/*
 *  ======== gpioButtonFxn1 ========
 *  Callback function for the interrupt.
 */
Void gpioButtonFxn1(UArg arg0)
{
    Semaphore_pend(semSerial,BIOS_WAIT_FOREVER);
    //GPIO_write(Board_LED0, 1);
    RxBytes2 = UART_read(uart4, c, sizeof(c));

}


/* ====================================================================================
 * --------------------------  PUBLIC FUNCTIONS  --------------------------------------
 * ====================================================================================
 */

static void uart_multiple_init()
{
     //Create a UART with data processing off.
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;
    uart = UART_open(Board_UART0, &uartParams);

    if (uart == NULL) {
        System_printf("NOT opened");
        System_flush();
         //Turn on user LED
        GPIO_write(Board_LED0, Board_LED_ON);
        System_abort("Error opening the UART");
    }

    UART_Params_init(&uartParams1);
    uartParams1.writeDataMode = UART_DATA_BINARY;
    uartParams1.readDataMode = UART_DATA_BINARY;
    uartParams1.readReturnMode = UART_RETURN_FULL;
    uartParams1.readEcho = UART_ECHO_OFF;
    uartParams1.baudRate = 115200;
    uart1 = UART_open(Board_UART1, &uartParams1);

    if (uart1 == NULL) {
        System_printf("UART1 NOT OPEN");
        System_flush();
        // Turn on user LED
        GPIO_write(Board_LED0, Board_LED_ON);
        System_abort("Error opening the UART");
    }

    UART_Params_init(&uartParams2);
    uartParams2.writeDataMode = UART_DATA_BINARY;
    uartParams2.readDataMode = UART_DATA_BINARY;
    uartParams2.readReturnMode = UART_RETURN_FULL;
    uartParams2.readEcho = UART_ECHO_OFF;
    uartParams2.baudRate = 115200;
    uart2 = UART_open(Board_UART2, &uartParams2);

    if (uart2 == NULL) {
        System_printf("UART2 NOT OPEN");
        System_flush();
         //Turn on user LED
        GPIO_write(Board_LED0, Board_LED_ON);
        System_abort("Error opening the UART");
    }

    UART_Params_init(&uartParams3);
    uartParams3.writeDataMode = UART_DATA_BINARY;
    uartParams3.readDataMode = UART_DATA_BINARY;
    uartParams3.readReturnMode = UART_RETURN_FULL;
    uartParams3.readEcho = UART_ECHO_OFF;
    uartParams3.baudRate = 115200;
    uart3 = UART_open(Board_UART3, &uartParams3);

    if (uart3 == NULL) {
        System_printf("UART3 NOT OPEN");
        System_flush();
         //Turn on user LED
        GPIO_write(Board_LED0, Board_LED_ON);
        System_abort("Error opening the UART");
    }

    UART_Params_init(&uartParams4);
    uartParams4.writeDataMode = UART_DATA_BINARY;
    uartParams4.readDataMode = UART_DATA_BINARY;
    uartParams4.readReturnMode = UART_RETURN_FULL;
    uartParams4.readEcho = UART_ECHO_OFF;
    uartParams4.baudRate = 115200;
    uart4 = UART_open(Board_UART4, &uartParams4);

    if (uart4 == NULL) {
        System_printf("UART4 NOT OPEN");
        System_flush();
         //Turn on user LED
        GPIO_write(Board_LED0, Board_LED_ON);
        System_abort("Error opening the UART");
    }

    UART_Params_init(&uartParams5);
    uartParams5.writeDataMode = UART_DATA_BINARY;
    uartParams5.readDataMode = UART_DATA_BINARY;
    uartParams5.readReturnMode = UART_RETURN_FULL;
    uartParams5.readEcho = UART_ECHO_OFF;
    uartParams5.baudRate = 115200;
    uart5 = UART_open(Board_UART5, &uartParams5);

    if (uart5 == NULL) {
        System_printf("UART5 NOT OPEN");
        System_flush();
         //Turn on user LED
        GPIO_write(Board_LED0, Board_LED_ON);
        System_abort("Error opening the UART");
    }

}

/* ===================================================================================
 * ------------------------------  TASK FUNCTIONS  --------------------------------------
 * ===================================================================================
 */

/*
 *  ======== transmitFxn ========
 *  Task to receive serial data.
 *
 *  This task will transmit data when data is available and block while the
 *  device is not connected to the USB host or if no data was received.
 */

Void transmitFxn(UArg arg0, UArg arg1)
{

    while (true) {
       /* if ((semSerial !=NULL) && (count==0))
        {
            USBCDCD_sendData(data, sizeof(data), BIOS_WAIT_FOREVER);
            Semaphore_post(semSerial);
        }count++;
        if (count >0)
        {*/
            //Semaphore_pend(sem1Serial,BIOS_WAIT_FOREVER);
            // Block while the device is NOT connected to the USB
             USBCDCD_waitForConnect(BIOS_WAIT_FOREVER);

            USBCDCD_sendData(data, (RxBytes+RxBytes1+RxBytes1), BIOS_WAIT_FOREVER);

            // Semaphore_post(semSerial);
            Task_sleep(1);
      //  }



   }
}


/*
 *  ======== receiveFxn ========
 *  Task to receive serial data.
 *
 *  This task will receive data when data is available and block while the
 *  device is not connected to the USB host or if no data was received.
 */
Void receiveFxn(UArg arg0, UArg arg1)
{
    uart_multiple_init();
    while (true) {

        RxBytes  = UART_read(uart5, a, sizeof(a));


        memcpy(data, a, RxBytes);
        memcpy((data+RxBytes), b, RxBytes1);
        memcpy((data+RxBytes+RxBytes1), c, RxBytes2);
        if((RxBytes+RxBytes1+RxBytes2)== 60)
        {
            USBCDCD_waitForConnect(BIOS_WAIT_FOREVER);
            USBCDCD_receiveData(data, (RxBytes+RxBytes1+RxBytes2), BIOS_WAIT_FOREVER);
        }
        }

}

Void clk0Fxn(UArg arg0)
{
    Semaphore_post(sem1Serial);
}

Void clk1Fxn(UArg arg0)
{
    Semaphore_post(semSerial);
}

/*
 *  ======== main ========
 */
int main(void)
{
    /* Construct BIOS objects */
    Task_Params taskParams;
    Error_Block eb;
    Semaphore_Params semParams;

    /* Call board init functions */
    Board_initGeneral();
    Board_initGPIO();
    Board_initUSB(Board_USBDEVICE);
    Board_initUART();

    USBCDCD_init();

    /* Construct tx/rx Task threads */
    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    taskParams.priority = 2;
    Task_construct(&task0Struct, (Task_FuncPtr)transmitFxn, &taskParams, NULL);

    taskParams.stack = &task1Stack;
   //                            taskParams.priority = 3;
    Task_construct(&task1Struct, (Task_FuncPtr)receiveFxn, &taskParams, NULL);


    taskParams.stack = &task2Stack;
    Task_construct(&task2Struct, (Task_FuncPtr)gpioButtonFxn, &taskParams, NULL);


    taskParams.stack = &task3Stack;
    Task_construct(&task3Struct, (Task_FuncPtr)gpioButtonFxn1, &taskParams, NULL);


    /* RTOS primitives */
    Semaphore_Params_init(&semParams);
    semParams.mode = Semaphore_Mode_BINARY;
    semSerial = Semaphore_create(0, &semParams, &eb);
    if (semSerial == NULL) {
        System_abort("Can't create semaphore");
    }

    sem1Serial = Semaphore_create(0, &semParams, &eb);
    if (sem1Serial == NULL) {
        System_abort("Can't create RX semaphore");
    }

    /* Construct BIOS Objects */

    Clock_Params clkParams, clkParams1;

    Clock_Params_init(&clkParams);
    clkParams.period = 4 ;
    clkParams.startFlag = TRUE;


    /* Construct a periodic Clock Instance with period = 4ms system time units */

    Clock_construct(&clk0Struct, (Clock_FuncPtr)clk0Fxn, 4 , &clkParams);

    Clock_Params_init(&clkParams1);
    clkParams1.period = 7 ;
    clkParams1.startFlag = TRUE;



    /* Construct a periodic Clock Instance with period = 7ms system time units */
    Clock_construct(&clk1Struct, (Clock_FuncPtr)clk1Fxn, 7 , &clkParams1);

    /* Start BIOS */
    BIOS_start();

    return (0);
}

  • Hi Nitihin,

    Your gpioButtonFxn and gpioButtonFxn1 tasks are running and then terminating (since they fall out of the function). So uart1 and uart4 are only being read once.

    Note: I'd change the name of the functions also. gpioButtonFxn was the name we used for a GPIO Callback that is called in Hwi context. It's a little confusing. I'd use names like uart1Receiver or something like that.

    btw....parameters passed into XXX_open, XXX_create, and XXX_construct do not need to be persistent. So they can be re-used. This will make your application smaller and little easier to read. For example

    static void uart_multiple_init()
    {
    //Create a UART with data processing off.
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;
    uart = UART_open(Board_UART0, &uartParams);

    if (uart == NULL) {
    System_printf("NOT opened");
    System_flush();
    //Turn on user LED
    GPIO_write(Board_LED0, Board_LED_ON);
    System_abort("Error opening the UART");
    }

    // re-using uartParams that was set above.
    uart1 = UART_open(Board_UART1, &uartParams);


    Todd
  • Hello Todd,

    Thank you for suggesting, I have made the necessary changes to callback function. I got to understand the fact that callbacks are running only once, but how am I suppose to run it periodically or put it in a loop?
  • Just put it in a loop.

    Void gpioButtonFxn(UArg arg0)
    {
    while(1) {
    Semaphore_pend(sem1Serial,BIOS_WAIT_FOREVER);
    //GPIO_write(Board_LED0, 1);
    RxBytes1 = UART_read(uart1, b, sizeof(b));
    }