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 driver delaying its callback

Part Number: CC1352P


Tool/software: TI-RTOS

We are seeing a 250us delay from the end of data being transmitted out the UART to when we receive a write callback.

Here's how we are configuring the uart in the board file:

/*
* =============================== UART ===============================
*/
#include <ti/drivers/UART.h>
#include <ti/drivers/uart/UARTCC26XX.h>

// TODO JCI: Move this defines to the my_ files??
#define ZFR182x_PWB_UART_RING_BUFFER_SIZE 200 // was 32. Could we make this smaller?

UARTCC26XX_Object uartCC26XXObjects[ZFR182x_PWB_UARTCOUNT];

uint8_t uartCC26XXRingBuffer[ZFR182x_PWB_UARTCOUNT][ZFR182x_PWB_UART_RING_BUFFER_SIZE];

const UARTCC26XX_HWAttrsV2 uartCC26XXHWAttrs[ZFR182x_PWB_UARTCOUNT] = {
{
.baseAddr = UART0_BASE,
.powerMngrId = PowerCC26XX_PERIPH_UART0,
.intNum = INT_UART0_COMB,
.intPriority = ~0,
.swiPriority = 0,
.txPin = ZFR182x_PWB_UART0_TX,
.rxPin = ZFR182x_PWB_UART0_RX,
.ctsPin = PIN_UNASSIGNED,
.rtsPin = PIN_UNASSIGNED,
.ringBufPtr = uartCC26XXRingBuffer[ZFR182x_PWB_UART0],
.ringBufSize = sizeof(uartCC26XXRingBuffer[ZFR182x_PWB_UART0]),
.txIntFifoThr = UARTCC26XX_FIFO_THRESHOLD_1_8,
.rxIntFifoThr = UARTCC26XX_FIFO_THRESHOLD_4_8,
.errorFxn = NULL
},

};

const UART_Config UART_config[ZFR182x_PWB_UARTCOUNT] = {
{
.fxnTablePtr = &UARTCC26XX_fxnTable,
.object = &uartCC26XXObjects[ZFR182x_PWB_UART0],
.hwAttrs = &uartCC26XXHWAttrs[ZFR182x_PWB_UART0]
},

};

const uint_least8_t UART_count = ZFR182x_PWB_UARTCOUNT;

 

Here's how we are configuring the uart when it's openned:

params.readMode = UART_MODE_CALLBACK;
params.writeMode = UART_MODE_CALLBACK;
params.readCallback = UartMgr_readCallback;
params.writeCallback = UartMgr_writeCallback;
params.readReturnMode = UART_RETURN_FULL;
params.readDataMode = UART_DATA_BINARY;
params.writeDataMode = UART_DATA_BINARY;
params.readEcho = UART_ECHO_OFF;
params.baudRate = H8_UART_DEFAULT_BAUDRATE;
params.dataLength = UART_LEN_8;
params.stopBits = UART_STOP_ONE;
params.parityType = UART_PAR_NONE;

UartMgr_Handle = UART_open(Board_UART0, &params);

---------------------------

Before the UART_write we are setting a PIN high, and setting it low when the callback is run. 

The packet that we're sending is only around 10 bytes. 

---------------------------

// Enable the 485 transmit
PIN_setOutputValue(TxEn_PinHandle, Board_UART_485_TXEN, Board_UART_485_TXEN_ON);
CPUdelay(16); /* 3 cycles per loop: 16 loop @ 48 Mhz ~= 1 uS */

// Send the data
UART_write(UartMgr_Handle, buf, pktSize);

--------------------------

void UartMgr_writeCallback(UART_Handle handle, void *buf, size_t count)
{
// Disable the 485 transmit
PIN_setOutputValue(TxEn_PinHandle, Board_UART_485_TXEN, Board_UART_485_TXEN_OFF);

// Signal the event handler in the processing loop that the transmit is done
UartMgrTss->events |= EVT_TRANSMIT_DONE;
Semaphore_post(UartMgrTss->semHandle);
}

---------------------------

 Using a scope, we can see that there is a 250uS delay from the end of the last byte to the when the pin is set low.

We also tried this as a blocking function with the same results.

---------------------------

// Enable the 485 transmit
PIN_setOutputValue(TxEn_PinHandle, Board_UART_485_TXEN, Board_UART_485_TXEN_ON);
CPUdelay(16); /* 3 cycles per loop: 16 loop @ 48 Mhz ~= 1 uS */

// Write the data
UART_write(UartMgr_Handle, buf, pktSize);  // Blocks here

// Disable the 485 transmit
PIN_setOutputValue(TxEn_PinHandle, Board_UART_485_TXEN, Board_UART_485_TXEN_OFF);

---------------------------

Since it dithers very little from 250us, it doesn't appear to be getting blocked by other tasks. There is also much less delay from when we set the pin high to when the first byte begins to transmit.

The UART task is the highest priority of the tasks that we are creating at priority 5.  

It's a concern to us because we need to stop driving the RS-485 bus as soon as possible to allow other devices to transmit without errors.

Is there some setting in the driver that we can adjust to control this delay or change the priorities in the board file (.intPriority or .swiPriority)?

Thanks,

- Bill

  • Hi,

    Thank you for providing details on the issue.

    In the UART driver (UARTCC26XX.c), it looks like a timer is used to ensure sufficient time for the TX FIFO to empty.
    We'll investigate further.


    Regards,
    Toby
  • The delay is most likely due to startTxFifoEmptyClk. It might be possible to optimize this for a specific use case, but we do not have any guidelines as to how to do this.

    BR

    Siri
  • Thank you for the response.

    I see the line of code in UARTCC26XX.c/startTxFifoEmptyClk() that calculates this delay.

    unsigned int writeTimeoutUs = (numOfDataInFifo*(1+5+(object->dataLength)+(object->stopBits+1))*1000000)/object->baudRate + 100;

    If we could simply remove the arbitrary 100uS margin tacked on at the end, it would satisfy our use case.

    So my question now is, how do we modify this function? 

    Can I change it in the SDK, and will it re-compile and become part of the drivers_cc13x2.aem4f driver? (That doesn't seem to work)

    Can I add this function to my code to override the one in the library? (That doesn't seem to work either)

    Any suggestions would be helpful.

    Thanks,

    - Bill

  • You can simply add the UARTCC26XX.c file to your project ("ADd Files...") and then:

    Do the changes you want to do, the re-compile.

    BR

    Siri

  • That works. 

    Thanks.

    - Bill