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/PROCESSOR-SDK-AM437X: UART driver issue

Part Number: PROCESSOR-SDK-AM437X

Tool/software: TI-RTOS

Hi

I have a problem with using the UART driver, it seems during each callback I am loosing one byte.

1. If I take a look at c:\ti\pdk_am437x_1_0_8\packages\ti\drv\uart\src\v1\UART_v1.c, it does a byte read at the end of the while loop, but if size is 0, this byte gets discarded!

2. In the uart driver layer (csl) UARTCharGetNonBlocking(hwAttrs->baseAddr) returns -1 on no data. This is returned in a int8_t thus it will not be possible to receive any binary data that are 0xFF ???
It seems though that in starterware UARTCharGetNonBlocking() is returning an int (32 bit). So which function is used by the uart driver?

The same problem applies to int8_t UARTCharGet(uint32_t baseAddr).
This IS a bug in csl an should be fixed.

/*
 *  ======== UART_v1_readData ========
 *  Read and process data from the UART.
 */
static inline int32_t UART_v1_readData(UART_Handle handle, int32_t size);   /* for misra warnings*/
static inline int32_t UART_v1_readData(UART_Handle handle, int32_t size)
{
    int32_t             readIn;
    UART_V1_Object     *object;
    UART_HwAttrs const *hwAttrs;

    object = (UART_V1_Object*)handle->object;
    hwAttrs = (UART_HwAttrs*)handle->hwAttrs;
    readIn = (int32_t)UARTCharGetNonBlocking(hwAttrs->baseAddr);

    /* Receive chars until empty or done. */
    while ((size != 0) && (readIn != (int32_t)(-1)))
    {
        /* If data mode is set to TEXT replace return with a newline. */
        if (object->params.readDataMode == UART_DATA_TEXT)
        {
            if ((uint8_t)readIn == ((uint8_t)('\r')))
            {
                /* Echo character if enabled. */
                if (object->params.readEcho)
                {
                    UARTCharPut(hwAttrs->baseAddr, ((uint8_t)('\r')));
                }
                readIn = (int32_t)'\n';
            }
        }

        UART_drv_log2("UART:(0x%x) Read character 0x%x",
                      hwAttrs->baseAddr, (uint8_t)readIn);

        *(uint8_t *)object->readBuf = (uint8_t)readIn;
        object->readBuf = (uint8_t *)object->readBuf + 1;
        object->readCount++;
        size--;

        /* Echo character if enabled. */
        if (object->params.readEcho)
        {
            UARTCharPut(hwAttrs->baseAddr, (uint8_t)readIn);
        }

        /* If read return mode is newline, finish if a newline was received. */
        if ((object->params.readReturnMode == UART_RETURN_NEWLINE) &&
            ((uint8_t)readIn == ((uint8_t)('\n'))))
        {
            UART_drv_log1("UART:(0x%x) Newline character received, ",
                    hwAttrs->baseAddr);
            size = 0;
            break;
        }
        readIn = (int32_t)UARTCharGetNonBlocking(hwAttrs->baseAddr);   // THIS WILL READ EXTRA CHARACTER FROM RX FIFO - IF ONE IS PRESENT! Must skip this if size is 0!
    }

    return (size);
}

  • The RTOS team have been notified. They will respond here.
  • No response yet?

    Besides the errors stated above, I have also found the UART driver to be highly unstable at higher loads. I have an incoming stream of binary data at 230kbaud, receving ~10.000 bytes per second while also sending (much less ~600 bytes per second). I was using EDMA and read & write callback functions.

    I have spent WAY TOO MUCH time on debugging the driver and have finally just written my own (based on UART_v1.c) to only use interrupts (EDMA will come later) and have it working now.
  • Sorry about the delay. I have escalated the request.
  • Hi,

    Sorry for the delay! There is UART_BasicExample_evmAM437x_armTestProject for testing UART, including the UART non-DMA read write test in callback mode.

    In this mode, I entered exact 16 characters and UART received and print to console, I didn't see any missing one character. Can you explain how you find this? The UARTCharGetNonBlocking uses CSL function. I will look into it.

    Regards, Eric

  • Hi Eric

    It is quite easy to see that there is an error in the UART driver, just by reading the code (I added it in my first post - see what is highlighted).

    When the function UART_v1_readData(UART_Handle handle, int32_t size) is called in the UART driver, size gives the amount of data to read.

    If the driver ( UART_v1_readData()) is reading less data than what is inside the UART RX FIFO, one byte will always be discarded. This scenario will probably never happen when you are just entering characters or when you have set up reading of exact the number of characters sent (as is done in the test example).

    TI should improve the test of the UART driver, since this will also show other issues. In it's current state it is more or less useless (except for simple printf and keyboard input). The test should be done with higher load with both sending and receiving asynchronously.
  • Any update on this?
  • Sorry, we are still looking at it.

    Regards, Eric
  • Hi,

    Yes, when the FIFO is empty, the UARTCharGetNonBlocking() from CSL code returns -1 (0xFF). Casting with int32_t and assigning this to readIn, it still 0xFF, not 0xFFFF_FFFF. The while() is true and reads for additional "size" if byte, this is a problem.

    Also, this is a read before the while loop, so totaling size+1 of bytes is read. This is also a problem. We will correct this.

    Regards, Eric
  • Hej Eric

    Thanks.

    You should also know that there is something wrong with the interrupt handling in the UART driver. I have seen the driver lockup and seeing other problems. But this was under load with receiving higher load of data while sending. That was the reason I wrote my own driver (based on TIs) which is stable and a designed more for our use.