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/CC1352P: UART_write not completing

Part Number: CC1352P

Tool/software: TI-RTOS

I'm struggling to debug an application using the UART. It would appear that UART_write does not seem to flush.

I've taken the uartecho.c example and added a PIN callback where I print the id:

/*
 *  ======== uartecho.c ========
 */
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

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

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

PIN_Config pinTable[] =
{
        Board_PIN_BUTTON0 | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP,
        Board_PIN_BUTTON1 | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP,
        PIN_TERMINATE
};

static UART_Handle uart;

void UART_writeint(int val, int base)
{
#if 0 // sprintf causes hangs... why?
        char str[16];

        if (base == 10)
                sprintf(str, "%d", val);
        else
                sprintf(str, "%x", val);
        UART_write(uart, str, strlen(str));
#else
        char buf[32];
        char ascii[] = "0123456789abcdef";
        char *p = &buf[sizeof(buf)-1];
        int i = val;

        *p = 0;
        if (i >= 0) {
                i = -i;
        }
        do {
                p--;
                *p = ascii[abs(i) % base];
                i /= base;
        } while (i && p > buf);
        if (val < 0 && p > buf) {
                p--;
                *p = '-';
        }
        UART_write(uart, p, (int)(&buf[sizeof(buf)] - p) - 1);
#endif
}

static int count=0;
static void Board_keyCallback(PIN_Handle hPin, PIN_Id pinId)
{
        UART_write(uart, "key:", 4);
        UART_writeint(count++, 16);
        UART_write(uart, "\r\n", 2);
}

/*
 *  ======== mainThread ========
 */
void *mainThread(void *arg0)
{
    char        input;
    const char  echoPrompt[] = "Echoing characters:\r\n";
    UART_Params uartParams;
    PIN_State pinState;
    PIN_Handle pinHandle;

    /* Configure Button pins and callback */
    pinHandle = PIN_open(&pinState, pinTable);
    PIN_registerIntCb(pinHandle, Board_keyCallback);
    PIN_setConfig(pinHandle, PIN_BM_IRQ, Board_PIN_BUTTON0 | PIN_IRQ_NEGEDGE);
    PIN_setConfig(pinHandle, PIN_BM_IRQ, Board_PIN_BUTTON1 | PIN_IRQ_NEGEDGE);

    /* Call driver init functions */
    GPIO_init();
    UART_init();

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

    /* 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_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) {
        /* UART_open() failed */
        while (1);
    }

    UART_write(uart, echoPrompt, sizeof(echoPrompt));

    /* Loop forever echoing */
    while (1) {
        UART_read(uart, &input, 1);
        UART_write(uart, &input, 1);
    }
}

When run and BTN1 changes state I see 'key:' and nothing else. The two UART_write's following that never send any characters. This would appear to only occur within a callback... what's going on here?

Additionally as my code states if I use 'sprintf' the app appears to crash.

Ultimately I would like to be able to make System_printf() go over the UART... is there a simple way to do that?

Thanks,

Tim

  • Hi Tim,

    I think the way you try to print in the "int" function is your issue, let's look at the UART_write parameters:

    Assuming "p" points to 2 and that the first address is 0 and the last is 15: UART_write(uart, p (2), (16 - 3) - 1) which would be UART_write(uart, p (2), 12) which as a start should be way more then the "2" you would expect to be pressed.

    I would start with verifying the arguments you pass in to this UART_write call (maybe start by replacing them with a dummy print) and see if these makes sense.
  • I suppose you can use sprintf to format the string and use UART_write to output the format string.
  • It's not the UART_writeint function that's the issue here... there is something wrong with back to back UART_write calls:

    static void Board_keyCallback(PIN_Handle hPin, PIN_Id pinId)
    {
    UART_write(uart, "key:", 4);
    UART_write(uart, "foo", 3);
    UART_write(uart, "\r\n", 2);
    }

    only prints 'key:' every time the key callback is called. If I do a single 'UART_write(uart, "key:foo\r\n", 9);' in the callback it prints everything and this only seems to occur within the callback.

    The code is taken directly from ~/ti/simplelink_cc13x2_sdk_2_30_00_45/examples/rtos/CC1352R1_LAUNCHXL/drivers/uartecho built with gcc with just additions to open/write to the UART.
  • Try to use the following codes

    static void Board_keyCallback(PIN_Handle hPin, PIN_Id pinId)
    {
    const char key[] = "key:";
    const char foo[] = "foo";
    const char rn[] = "\r\n";

    UART_write(uart, key, sizeof(key));
    UART_write(uart, foo, sizeof(foo));
    UART_write(uart, rn, sizeof(rn));
    }

    instead of

    static void Board_keyCallback(PIN_Handle hPin, PIN_Id pinId)
    {
    UART_write(uart, "key:", 4);
    UART_write(uart, "foo", 3);
    UART_write(uart, "\r\n", 2);
    }

  • Hi Tim,

    I should have caught this the first time around, but you are using the UART driver in blocking mode. You are not allowed to perform blocking calls from an ISR context (including most driver callbacks) as this would freeze the system. If you want to use UART_write() from inside a callback, you should operate it in callback mode. This means you would need to re-think how you structure the write as you can't "queue" up writes.
  • Thank you this was exactly the issue. I suspected it had something to do with the callback. I got it working fine by using a static buffer for uart output and a Semaphore used to lock it:

    void UART_writeln(const char *str)
    {
        strcat(uart_txbuf, str);
        /* Data ready to transmit */
        Semaphore_post(semHandle);
    }

    void UART_writeint(const char *pre, int val, int base)
    {
        char str[16];

        if (pre)
            UART_writeln(pre);
        if (base == 10)
            sprintf(str, "%d", val);
        else
            sprintf(str, "%x", val);
        UART_writeln(str);
    }

    void *uartThread(void *arg0)
    {
        UART_setup();
        UART_writeln("rfEcho\r\n");

        while(1) {
            /* Waiting for output */
            Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);
            UART_write(uart, uart_txbuf, strlen(uart_txbuf));
            uart_txbuf[0] = 0;
        }
    }

    Tim