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.

MSP432-RTOS: Multibyte receive issue on UART using TI-RTOS

Part Number: MSP432-RTOS
Other Parts Discussed in Thread: CC3200

Hi Team,

In my project I have connected the UART (UARTA2) to pulser unit to get the samples from pulser. This is required as that is the only way this pulser unit is able to transmit data from itself.

Certain commands sent to pulser send one byte information back. but there are couple of commands sent to pulser which sends 4 byte and 1024 byte of data back.

I have been trying this out since over a week now but not able to get a solution for the problem.

When pulser sends 1 byte of information the MSP432 UART is able to receive without any issue.

However, when the pulser sends 4 bytes or the 1024 bytes of data the MSP432 is not able to capture that data.

I am using the "simplelink_msp432_sdk_1_40_00_28" version and have built the code based on RTOS where UART write is called continuously and the UART read is interrupt based using the Read Callback concept.

If I try to copy the bytes received in the UART read callback function into an array so as to free the RXBUF the interrupt never occurs and I don't receive anything in the receive buffer than afterwards.

The reason why I am copying into buffer is as I also get overrun flag triggered when the pulser sends more than 1 byte of data.

Please provide your guidance.

Thank you

Vikram

  • Hello Vikram,
    Can you slow down the UART to see if this resolves the issue?

    Regards,
    Chris
  • Hi Chris,

    The baud rate is the lowest possible I have kept and it is 9600.

    Won't be possible to go below that.

    Thank you

    Vikram

  • Then it looks like something in your code is programmed the wrong way - at 9600 baud, the MSP432 should be bored as hell if you do not run the processor at almost DC clock frequency (I guess it will be a few MHz, isn't it?) or if other, higher priority interrupts do not block your system.
  • Pulser to MSP432 RTOS based wokrking.zipYou might be correct Dennis in saying that something is incorrectly programmed but it is not definitely the priority issue. As I have my UART task running on highest priority and the another task is on priority lower than the UART task.

    I am attaching the project if you get time can you please have a look and suggest where I might be going wrong.

    This code is working but if I add a statement in the UART read callback function which is "uartReceiveFinished" for collecting the data received in RXBUF the interrupt never occurs and the execution does not goes into that piece of code.

    And in this code, I always get an overflow error flag set when the data received is more than 1 byte.

    Thank you for your input.

    Vikram

  • Hi Chris,

    I have managed to resolve that issue which I posted and it was to do with the way I was handling the read callback and always breaking by inserting a break point while the receive was active.

    Another challenge now I am facing is that for each command I am sending to pulser unit, the receive bytes are different. They don't remain constant.

    For some commands I receive 1 byte, for some 2 bytes, for some 4 bytes and one of the command sends 1024 bytes of information back.

    How to handle this variable length of information as the UART_read function need to have the number of bytes that are to be received.

    I am attaching my piece of code that I have written.

    Please provide your input.

    #include <stdint.h>
    #include <stddef.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART.h>
    #include <ti/drivers/dpl/SemaphoreP.h>
    #include <xdc/runtime/System.h>
    #include<string.h>
    
    
    #include <ti/sysbios/BIOS.h>
    /* Example/Board Header files */
    #include "Board.h"
    #include "protocol.h"
    
    SemaphoreP_Handle uartCallbackSemaphore;
    char commandCounter = 0;
    uint8_t *command;
    char getLen = 0;
    uint8_t pcBuffer[4];
    #define BITTIMEVALUE 0x03
    #define ATTVALUE     125
    #define SIGAVGVALUE  31
    #define RGD0VALUE    0x00
    #define RGD1VALUE    0x02
    
    /* Prototype */
    static void uartReceiveFinished(UART_Handle handle, void *uart_rxBuffer, size_t count);
    int readCount = 4;
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        char        input;
        unsigned char commandBuffer[20];
        unsigned char countNum = 0;
        UART_Handle uart;
        UART_Params uartParams;
        /* Call driver init functions */
        GPIO_init();
        UART_init();
    
        /* Turn on user LED */
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_TEXT;
        uartParams.readMode = UART_MODE_CALLBACK;
        uartParams.readDataMode = UART_DATA_TEXT;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.readCallback = uartReceiveFinished;
        uartParams.baudRate = 9600;
        uart = UART_open(Board_UART1, &uartParams);
        if (uart == NULL)
        {
            System_abort("Error opening the UART");
        }
    
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
        GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_OFF);
    
        GPIO_write(Fogwise_LDO1, Fogwise_LDO1_ON);
        /* Loop forever echoing */
        while (1) {
            switch(commandCounter)
            {
                        case 0:
                            commandBuffer[countNum++] = PROBE_STX;
                            commandBuffer[countNum++] = PROBE_SET_BIT_TIME;
                            commandBuffer[countNum++] = PROBE_STX;
                            commandBuffer[countNum++] = 0x01;
                            commandBuffer[countNum++] = BITTIMEVALUE;
                            commandBuffer[countNum++] = PROBE_EOT;
                            commandBuffer[countNum++] = '\0';
                            UART_read(uart, &input, 2);
                            GPIO_toggle(Board_GPIO_LED2);
                            break;
    
                        case 1:
                            commandBuffer[countNum++] = PROBE_STX;
                            commandBuffer[countNum++] = PROBE_GET_BAUD;
                            commandBuffer[countNum++] = '\0';
                            UART_read(uart, &input, 4);
                            break;
    
                        case 2:
                            commandBuffer[countNum++] = PROBE_STX;
                            commandBuffer[countNum++] = PROBE_SET_ATTENUATION;
                            commandBuffer[countNum++] = PROBE_STX;
                            commandBuffer[countNum++] = 0x01;
                            commandBuffer[countNum++] = ATTVALUE;
                            commandBuffer[countNum++] = PROBE_EOT;
                            commandBuffer[countNum++] = PROBE_STX;
                            commandBuffer[countNum++] = PROBE_SET_SIG_AVG;
                            commandBuffer[countNum++] = PROBE_STX;
                            commandBuffer[countNum++] = 0x01;
                            commandBuffer[countNum++] = SIGAVGVALUE;
                            commandBuffer[countNum++] = PROBE_EOT;
                            commandBuffer[countNum++] = '\0';
                            UART_read(uart, &input, 4);
                            GPIO_toggle(Board_GPIO_LED1);
                            break;
    
                        case 3:
                            commandBuffer[countNum++] = PROBE_STX;
                            commandBuffer[countNum++] = PROBE_SET_BAUD;
                            commandBuffer[countNum++] = PROBE_STX;
                            commandBuffer[countNum++] = 0x01;
                            commandBuffer[countNum++] = PROBE_BAUD_9600_CODE;
                            commandBuffer[countNum++] = '\0';
                            UART_read(uart, &input, 1);
                            GPIO_toggle(Board_GPIO_LED3);
                            break;
    
                        default:
                            commandCounter = 0;
                            break;
            }
            commandCounter++;
            countNum = 0;
            UART_write(uart, &commandBuffer, strlen((void*)commandBuffer));
        }
    }
    
    static void uartReceiveFinished(UART_Handle handle, void *uart_rxBuffer, size_t count)
    {
        command = (uint8_t*)uart_rxBuffer;
        memcpy((char*)pcBuffer, (const char*)uart_rxBuffer, 4);
        GPIO_toggle(Board_GPIO_LED0);
    }
    

    Additionally, even though the information seen on the oscilloscope is correct, the value shown at the location pointed by uart_rxBuffer differ for certain commands every now and than making it inconsistent.

    I had probed the UART RX line on the oscilloscope to review the information.

    Please provide some suggestion.

  • Hi Team,

    Please provide some suggestion.
    I even tried accessing the ring buffer at the driver level but not able to find a way to get the value out of the ring buffer as whenever I check for RXBUF getting more than one byte of data I always end up getting the Overrun error and the last byte is observed in the RXBUF.
    How do we access this buffer in the RTOS UARTreceivecallback function.

    Vikram
  • Vikram,
    I am having a little trouble following what you have provided. In the example you attached in the earlier thread I see a ring buffer definiton of 1024 but I still see that in the hw attributes that the ring buffer is still 32. The UART_read will pull from this ring buffer. You may want to check the value returned by UART_read to see if the function is currently busy. Please note that if the ring buffer does not have enough information for the read function, then it will use the ISR to fill the buffer. There is a potential that between successive reads that there may be an overrun, but given the speed I doubt that is likely.

    Are you using the TI-RTOS or the TIDrivers? I am looking at the TIDrivers (v1_30_00_40) but I believe they are similar.

    Regards,
    Chris
  • Thank you Chris for the response.

    I am having a little trouble following what you have provided. In the example you attached in the earlier thread I see a ring buffer definiton of 1024 but I still see that in the hw attributes that the ring buffer is still 32.

    In the example that I had attached in earlier thread I was trying to get the 1024 bytes of data returned from pulser (for a specific command sent by MSP432) at once and hence the ring buffer definition was 1024. But I have changed that in the example that I had attached later since I wanted to begin with simple commands communication between pulser and MSP432.

    The UART_read will pull from this ring buffer. You may want to check the value returned by UART_read to see if the function is currently busy.

    The problem is that the execution some time breaks into the read callback function and some times it does not. can't understand why. So whenever it breaks into the uartReceiveFinished function (callback function) I can view the buffer. How do we check if the function is currently busy if it does not break into it?

    Please note that if the ring buffer does not have enough information for the read function, then it will use the ISR to fill the buffer.

    This is what I don't understand where it says in the UARTMSP432.c driver file.

    "

    /*
    * ======== readTaskCallback ========
    * This function is called the first time by the UART_read task and tries to
    * get all the data it can get from the ringBuffer. If it finished, it will
    * perform the user supplied callback. If it didn't finish, the ISR must handle
    * the remaining data. By setting the drainByISR flag, the UART_read function
    * handed over the responsibility to get the remaining data to the ISR.
    */

    Here it refers to ISR. Is it that we have to create a seperate ISR routine or the callback itself is the ISR?

    There is a potential that between successive reads that there may be an overrun, but given the speed I doubt that is likely.

    Are you using the TI-RTOS or the TIDrivers? I am looking at the TIDrivers (v1_30_00_40) but I believe they are similar.

    I am using the TI-RTOS "SimpleLink MSP432 SDK"

    I hope this gives a better idea of what issue I am facing.

    Vikram

  • /*
     *  ======== uartecho.c ========
     */
    #include <stdint.h>
    #include <stddef.h>
    #include <unistd.h>
    
    /* BIOS module Headers */
    #include <ti/sysbios/BIOS.h>
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART.h>
    #include <ti/drivers/dpl/SemaphoreP.h>
    #include <xdc/runtime/System.h>
    #include<string.h>
    
    #include <ti/sysbios/BIOS.h>
    /* Example/Board Header files */
    #include "Board.h"
    #include "protocol.h"
    
    SemaphoreP_Handle uartCallbackSemaphore;
    char commandCounter = 0;
    uint8_t *command;
    int getLen = 0;
    uint8_t pcBuffer[1028];
    #define BITTIMEVALUE 0x03
    #define ATTVALUE     125
    #define SIGAVGVALUE  31
    #define RGD0VALUE    0x00
    #define RGD1VALUE    0x02
    
    UART_Handle uart;
    
    /* Prototype */
    void probeSendByte(uint8_t byte);
    static void uartReceiveFinished(UART_Handle handle, void *uart_rxBuffer, size_t count);
    int readCount = 4;
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        char        input[257];
        UART_Params uartParams;
        /* Call driver init functions */
        GPIO_init();
        UART_init();
    
        /* Turn on user LED */
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_TEXT;
        uartParams.readMode = UART_MODE_CALLBACK;
        uartParams.readDataMode = UART_DATA_TEXT;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.readCallback = uartReceiveFinished;
        uartParams.baudRate = 9600;
        uart = UART_open(Board_UART1, &uartParams);
        if (uart == NULL)
        {
            System_abort("Error opening the UART");
        }
    
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
        GPIO_write(Board_GPIO_LED1, Board_GPIO_LED_OFF);
    
        GPIO_write(Fogwise_LDO1, Fogwise_LDO1_ON);
        /* Loop forever echoing */
        while (1) {
            switch(commandCounter)
            {
    //                    case 0:
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(PROBE_SET_BIT_TIME);//commandBuffer[countNum++] = PROBE_SET_BIT_TIME;
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(0x01);//commandBuffer[countNum++] = 0x01;
    //                        probeSendByte(BITTIMEVALUE);//commandBuffer[countNum++] = BITTIMEVALUE;
    //                        probeSendByte(PROBE_EOT);//commandBuffer[countNum++] = PROBE_EOT;
    //                        UART_read(uart, input, sizeof(input));
    //                        GPIO_toggle(Board_GPIO_LED2);
    //                        break;
    
    //                    case 0:
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(PROBE_GET_BAUD);//commandBuffer[countNum++] = PROBE_GET_BAUD;
    //                        UART_read(uart, input, sizeof(input));
    //                        commandCounter = 0;
    //                        break;
    
    //                    case 0:
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(PROBE_SET_ATTENUATION);//commandBuffer[countNum++] = PROBE_SET_ATTENUATION;
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(0x01);//commandBuffer[countNum++] = 0x01;
    //                        probeSendByte(ATTVALUE);//commandBuffer[countNum++] = ATTVALUE;
    //                        probeSendByte(PROBE_EOT);//commandBuffer[countNum++] = PROBE_EOT;
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(PROBE_SET_SIG_AVG);//commandBuffer[countNum++] = PROBE_SET_SIG_AVG;
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(0x01);//commandBuffer[countNum++] = 0x01;
    //                        probeSendByte(SIGAVGVALUE);//commandBuffer[countNum++] = SIGAVGVALUE;
    //                        probeSendByte(PROBE_EOT);//commandBuffer[countNum++] = PROBE_EOT;
    //                        UART_read(uart, input, sizeof(input));
    //                        GPIO_toggle(Board_GPIO_LED1);
    //                        commandCounter = 0;
    //                        break;
    
    //                    case 0:
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(PROBE_SET_RANGE_GATE_DELAY0);//commandBuffer[countNum++] = PROBE_SET_ATTENUATION;
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(0x01);//commandBuffer[countNum++] = 0x01;
    //                        probeSendByte(RGD0VALUE);//commandBuffer[countNum++] = ATTVALUE;
    //                        probeSendByte(PROBE_EOT);//commandBuffer[countNum++] = PROBE_EOT;
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(PROBE_SET_RANGE_GATE_DELAY1);//commandBuffer[countNum++] = PROBE_SET_SIG_AVG;
    //                        probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(0x01);//commandBuffer[countNum++] = 0x01;
    //                        probeSendByte(RGD1VALUE);//commandBuffer[countNum++] = SIGAVGVALUE;
    //                        probeSendByte(PROBE_EOT);//commandBuffer[countNum++] = PROBE_EOT;
    //                        UART_read(uart, input, sizeof(input));
    //                        GPIO_toggle(Board_GPIO_LED1);
    //                        commandCounter = 0;
    //                        break;
    
    //                    case 0:
    //                        commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(PROBE_STX);
    //                        commandBuffer[countNum++] = PROBE_SET_BAUD;
    //                        probeSendByte(PROBE_SET_BAUD);
    //                        commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(PROBE_STX);
    //                        commandBuffer[countNum++] = PROBE_STX;
    //                        probeSendByte(PROBE_STX);
    //                        commandBuffer[countNum++] = PROBE_BAUD_9600_CODE;
    //                        probeSendByte(PROBE_BAUD_9600_CODE);
    //                        commandBuffer[countNum++] = '\0';
    //                        UART_read(uart, input, sizeof(input));
    //                        GPIO_toggle(Board_GPIO_LED3);
    //                        commandCounter = 0;
    //                        break;
    
                        case 0:
                            if(getLen == 1028)
                            {
                                GPIO_toggle(Board_GPIO_LED3);
                                getLen = 0;
                            }
                            probeSendByte(PROBE_STX);//commandBuffer[countNum++] = PROBE_STX;
                            probeSendByte(PROBE_START);//commandBuffer[countNum++] = PROBE_GET_BAUD;
                            UART_read(uart, input, sizeof(input));
                            commandCounter = 0;
                            break;
    
                        default:
                            commandCounter = 0;
                            break;
            }
        }
    }
    
    static void uartReceiveFinished(UART_Handle handle, void *uart_rxBuffer, size_t count)
    {
        command = uartMSP432Objects[1].ringBuffer.buffer;
        command = (uint8_t*)uart_rxBuffer;
        memcpy((char*)(pcBuffer + getLen), (const char*)uart_rxBuffer, 257);
        getLen = getLen + 257;
        GPIO_toggle(Board_GPIO_LED0);
    }
    
    void probeSendByte(uint8_t byte) {
    
        UART_write(uart, &byte, 1);
    }
    
    

    Hi Chris,

    I have managed to resolve the issue and the issue used to occur if I executed all commands with the same size buffer for reading the response back from the pulser.

    But when I executed only one command in the switch statement individually and defining the read buffer size equal to the size of the data that is expected back, I did not get any issue.

    Also I used to send the command as a string of characters with '\0' character at the end which the pulser did not recognized as that is not acceptable in its protocol definition.

    So now this leaves to a query.

    Since in my application I have set of commands that need to be sent to pulser and expected a response back from pulser.

    Since all the commands are suppose to receive different count of bytes how do I change the buffer size at run time so that uartReceiveFinished function is executed whenever I receive the entire data for given command.

    I know that when we used CC3200 it has an option for UART_RETURN_PARTIAL when we don't know what is the size of data that is to be received but I don't see such option for MSP432.

    I am attaching the modified piece of code for you to have a look and get an idea on my query.

    In the code, I comment out the cases that I don't want to run and run only one case at any given time.

    Also the size of the char input[size] is always changed depending on what is expected back from the pulser.

    Thank you in advance.

    Vikram

**Attention** This is a public forum