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.

LAUNCHXL-CC1310: UART echo using callback stops working after external MCU resets

Part Number: LAUNCHXL-CC1310
Other Parts Discussed in Thread: CC1310

Hi,

I have been trying to fix a bug in the radio we developed around CC1310. The problem is boiled down to a simple test setup:

STM32F091RC <==> CC1310

Another MCU, STM32F091RC is connected to two pins on CC1310(IO2 as UART RX, IO3 as UART TX) plus shared GND. CC1310 is flashed with UART echo example from API documentation, also attached below.

STM32F091RC sends some dummy bytes to CC1310 periodically and expects CC1310 sends back whatever are sent to it. If new firmware is flash into STM32F091RC, I will have to reset CC1310 to get uart echo to work. In our customized board, I also observed that after a cold start during which both STM32F091RC and CC1310 get power from the same 3.3V rail at the same time, I also have to reset CC1310 to get uart echo to work. Meanwhile, in our customized PCB, data sent from CC1310 to external host MCU will continue to work even after host MCU is reset. So the problem is just somehow CC1310 cannot receive data from external host MCU if host MCU is reset.

On the other hand, if I just keep CC1310 connected to debug tool on launchpad, send dummy bytes from computer, I always see echo after I reset launchpad. I don't remember we had such problem when the external MCU is one from MSP430 family.

So the problem seems like a compatibility issue. Is there anything else except resetting CC1310 to make sure UART communication between CC1310 and other MCUs such as those from ST to work?

Thanks.

#define MAX_NUM_RX_BYTES    1000   // Maximum RX bytes to receive in one go
#define MAX_NUM_TX_BYTES    1000   // Maximum TX bytes to send in one go
uint32_t wantedRxBytes;            // Number of bytes received so far
uint8_t rxBuf[MAX_NUM_RX_BYTES];   // Receive buffer
uint8_t txBuf[MAX_NUM_TX_BYTES];   // Transmit buffer
// Read callback function
static void readCallback(UART_Handle handle, void *rxBuf, size_t size)
{
    // Make sure we received all expected bytes
    if (size == wantedRxBytes) {
        // Copy bytes from RX buffer to TX buffer
    	size_t i = 0;
       for(i = 0; i < size; i++)
           txBuf[i] = ((uint8_t*)rxBuf)[i];
       // Echo the bytes received back to transmitter
       UART_write(handle, txBuf, size);
       // Start another read, with size the same as it was during first call to
       // UART_read()
       UART_read(handle, rxBuf, wantedRxBytes);
    }
    else {
        // Handle error or call to UART_readCancel()
    }
}

// Write callback function
static void writeCallback(UART_Handle handle, void *rxBuf, size_t size)
{
    // Do nothing
}

void *mainThread(void *arg0)
{
    UART_Handle handle;
    UART_Params params;
    // Init UART
    UART_init();
    // Specify non-default parameters
    UART_Params_init(&params);
    params.baudRate      = 115200;
    params.writeMode     = UART_MODE_CALLBACK;
    params.writeDataMode = UART_DATA_BINARY;
    params.writeCallback = writeCallback;
    params.readMode      = UART_MODE_CALLBACK;
    params.readDataMode  = UART_DATA_BINARY;
    params.readCallback  = readCallback;
    // Open the UART and initiate the first read
    handle = UART_open(Board_UART0, &params);
    //UART_control(handle, UARTCC26XX_CMD_RETURN_PARTIAL_ENABLE, NULL);
    wantedRxBytes = 1;
    int rxBytes = UART_read(handle, rxBuf, wantedRxBytes);
    while(true); // Wait forever
}

  • In both cases you describe, you will have a situation where you do not have full control over what is happening on the UART lines, and this is leading to an error that is not handles on the CC1310 side. 

    You can try to monitor the UART lines to see how they behave in a situation both where you flash the STM32F091RC and in the case where you have a reset of both devices.

    For the latter case, I will assume that you are starting to access the UART BEFORE the STM32F091RC is properly reset and initialized.

    You can also try to have the debugger connected to the CC1310 to try to figure out where the code is hanging.

    On the other hand, in you final application, would you ever flash the STM32F091RC while the CC1310 is set up to communicate with it over UART?

    In the case where you reset both devices, can you make sure that the CC1310 Uart driver is not opened before the STM32F091RC is initialized?

    Siri

  • On the other hand, in you final application, would you ever flash the STM32F091RC while the CC1310 is set up to communicate with it over UART?

    Yes, that is the most puzzling part to me.Even in the test setup, after I reset CC1310 launchpad and get uart communication to work, if I reset STM32F091RC or reflash the same firmware into STM32F091RC again while CC1310-launchpad is still connected and running, data sending from STM32F091RC will not be echoed back to it. Meanwhile, in our final application, data from CC1310 to STM32F091RC will continue to work as expected.

    I attached a probe to RX pin on CC1310, then either routed that probe to RX on a USB-UART chip like FT231-xs, the USB-UART chip will have no problem receiving the data. If I connect RX pin on CC1310 to a logic analyzer, I also don't see anything out of line.

  • Also I want to add that if I just flash the UART echo example code from  SimpleLink SDK, the version that uses constant poll, into CC1310, then neither resetting nor reflashing firmware into STM32F091RC will stop UART echo on CC1310 from working.

  • I was able to find the way to add error handling callback function.Not sure if I was doing it wrong, but adding error callback to handle RX error doesn't fix the problem

    // In CC1310_LAUNCHXL.c
    static void uartErrorCallback(UART_Handle uartHandle, uint32_t error)
    {
        if(error == UART_RXERROR_PARITY || error == UART_RXERROR_BREAK || error == UART_RXERROR_FRAMING || error == UART_RXERROR_OVERRUN)
            UART_read(uartHandle, uartCC26XXRingBuffer[CC1310_LAUNCHXL_UARTCOUNT], 1);
    }
    
    const UARTCC26XX_HWAttrsV2 uartCC26XXHWAttrs[CC1310_LAUNCHXL_UARTCOUNT] = {
        {
            .baseAddr       = UART0_BASE,
            .powerMngrId    = PowerCC26XX_PERIPH_UART0,
            .intNum         = INT_UART0_COMB,
            .intPriority    = ~0,
            .swiPriority    = 0,
            .txPin          = CC1310_LAUNCHXL_UART_TX,
            .rxPin          = CC1310_LAUNCHXL_UART_RX,
            .ctsPin         = PIN_UNASSIGNED,
            .rtsPin         = PIN_UNASSIGNED,
            .ringBufPtr     = uartCC26XXRingBuffer[CC1310_LAUNCHXL_UART0],
            .ringBufSize    = sizeof(uartCC26XXRingBuffer[CC1310_LAUNCHXL_UART0]),
            .txIntFifoThr   = UARTCC26XX_FIFO_THRESHOLD_1_8,
            .rxIntFifoThr   = UARTCC26XX_FIFO_THRESHOLD_4_8,
            .errorFxn       = uartErrorCallback
        }
    };

  • I am still not sure I understand why this is an actual problem.

    If you for some reason needs to re-flash one of the devices in your system, I would expect that this would be a good time to restart/reset the complete application?

    If this is not an option, you need to try to figure out where the CC1310 get problem using the debugger, and also see monitor RX, TX, the Reset Line and Power when flashing the STM32F091RC.

    I recommend you to take a look at the uart2callback example for the CC13x2 devices:

    uart2callback (ti.com)

    It uses callback mode in RX but blocking mode in TX. Can you please try this and see how that works?

    Siri

  • I should have the worded the title differently. It is not just after re-flashing host MCU, but whenever host MCU resets after CC1310 is up and running, such as those reset caused by watchdog timer in host MCU. When host MCU has to reset CC1310, if CC1310 is served as a collector, then the whole RF network will be reset, all connected sensor nodes will be forced out and then have to rejoin. There will be a brief disruption of communication between sensor nodes and collector node, and rejoining network is quite expensive in terms of battery life. So it is enough a problem.

    I think the UART echo example you referenced will work even worse than versions in previous SDK. It will stuck in read callback if error happens. Beyond that it is more or less the same as previous version of SDK.

  • Is it required that the host MCU reset the CC1310 when the host resets or is it possible to avoid? 

  • Reset of host MCU itself is infrequent but inevitable. If some problem in other part of the host code (LwIP stack) comes up, it can only be fixed by a controlled reset of host MCU. There is also watchdog, if enough product is running in the field for long enough, watchdog will kick in at some point. I would say reset of host MCU will happen every 2 ~ 12 months.

    The onlyreason host MCU needs to reset CC1310 is, CC1310 stops responding to host MCU after host MCU is reset. I first noticed this whenever I update host firmware during development, later we found that reset of host MCU by watchdog will also stop CC1310 from responding, and reset of CC1310 will make it responsive again.

  • Have you tried the solution I suggested 3 days ago (looking at the callback example from he UART2 driver?)

    Siri