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.

MSP432E401Y: UART Echo Mode Breaks UART_WRITE Functionality

Part Number: MSP432E401Y


Found a potential bug. When I enable the UART in text mode, non-blocking with tx and rx callback functions. If echo mode is enabled, it will only print text to my terminal with uart_write if I have a function that manipulates the read buffer in some way (which could just be undefined behavior). Notably, my code works 100% perfectly fine when echo mode is disabled. Attached is the code used. I commented out a for loop in the RX callback function. When echo mode is on it does not print anything when uart_write is used. when echo mode is off it does. if echo mode is on and the for loop printf statements are uncommented it will work.

I would like to figure out why this odd behavior occurs so that I can remove that for loop and avoid undefined behavior like this.

/*
 *  ======== empty.c ========
 */

/* For usleep() */
#include <unistd.h>
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>

/* Driver Header files */
#include <ti/drivers/GPIO.h>
// #include <ti/drivers/I2C.h>
// #include <ti/drivers/SPI.h>
#include <ti/drivers/UART.h>
// #include <ti/drivers/Watchdog.h>

/* Driver configuration */
#include "ti_drivers_config.h"

#define MAX_CLI_LENGTH  (8)
unsigned char rxBuffer[MAX_CLI_LENGTH];

/*
 *  ======== mainThread ========
 */
void txCallback(UART_Handle handle, char *buf, size_t count) {}
void rxCallback(UART_Handle handle, char *buf, size_t count);

void *mainThread(void *arg0)
{
    const char  echoPrompt[] = "Echoing characters:\r\n";
    UART_Handle uart;
    UART_Params uartParams;

    /* 1 second delay */
    uint32_t time = 1;

    /* Call driver init functions */
    GPIO_init();
    // I2C_init();
    // SPI_init();
    UART_init();
    // Watchdog_init();

    /* Configure the LED pin */
    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    /* Turn on user LED */
    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.baudRate = 115200;
    uartParams.readEcho = UART_ECHO_ON;
    uartParams.readMode = UART_MODE_CALLBACK;
    uartParams.readDataMode = UART_DATA_TEXT;
    uartParams.readReturnMode = UART_RETURN_NEWLINE;
    uartParams.readCallback = (UART_Callback)&rxCallback;
    uartParams.writeDataMode = UART_DATA_TEXT;
    uartParams.writeMode = UART_MODE_CALLBACK;
    uartParams.writeCallback = (UART_Callback)&txCallback;

    uart = UART_open(CONFIG_UART_0, &uartParams);

    if (uart == NULL) {
        /* UART_open() failed */
        while (1);
    }

    UART_write(uart, echoPrompt, sizeof(echoPrompt));
    UART_read(uart,&rxBuffer,sizeof(rxBuffer));

    while (1) {
        sleep(time);

        GPIO_toggle(CONFIG_GPIO_LED_0);
    }
}

void rxCallback(UART_Handle handle, char *buf, size_t count) {

//    printf("Read %i = ", count);
//    int i;
//    for(i = 0; i < MAX_CLI_LENGTH; i++) {
//        printf("%d ", (int)(*((buf + i))));
//    }

    char infoMSG[] = "NOT A VALID COMMAND\r\n";
    UART_write(handle, infoMSG, sizeof(infoMSG));

    UART_read(handle,buf,MAX_CLI_LENGTH);
}

  • Hi Dylan,

    I'd have to read into how echo mode is intended to work once back from the holidays next week.

    I'm curious though that if your code is working fine without echo mode, why you think that adding echo mode without changing anything else in your code would also be operational? Without looking into the details, my gut feel is there would be different handling for echo versus non-echo modes and so you'd have to change your callback accordingly.

    Best Regards,

    Ralph Jacobi

  • Hi Ralph,

    The only information I could find so far on the echo mode is in the header file, which I followed what it said to do. Both write and read were set to text mode with non-blocking callback and the UART should not be receiving any inputs during the callback. Another obvious thing someone here may try to point out is the use of the uart_write during a non-blocking callback, but I have a longer version of the code which just runs uart write after the semaphore and before the GPIO toggle and it behaves the same.

    /*!
     *  @brief      UART echo settings
     *
     *  This enumeration defines if the driver will echo data when uses in
     *  #UART_DATA_TEXT mode. This only applies to data received by the UART.
     *
     *  #UART_ECHO_ON will echo back characters it received while in #UART_DATA_TEXT
     *  mode.
     *  #UART_ECHO_OFF will not echo back characters it received in #UART_DATA_TEXT
     *  mode.
     *
     *  @pre        UART driver must be used in #UART_DATA_TEXT mode.
     */
    typedef enum {
        UART_ECHO_OFF = 0,  /*!< Data is not echoed */
        UART_ECHO_ON = 1    /*!< Data is echoed */
    } UART_Echo;
    
    ....
    
     *  Options for the readEcho parameter are #UART_ECHO_OFF and #UART_ECHO_ON.
     *  This parameter determines whether the driver echoes data back to the
     *  UART.  When echo is turned on, each character that is read by the target
     *  is written back, independent of any write operations.  If data is
     *  received in the middle of a write and echo is turned on, the echoed
     *  characters will be mixed in with the write data.
     ...