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.

TI RTOS cannot set HSE for High Speed UART

Other Parts Discussed in Thread: TM4C1290NCPDT

TM4C1290NCPDT

TI-RTOS forces HSE bit to zero in UART_CTRL (UART Control register). It suppose to set HSE bit for higher baud rate like 3Mbps and higher.

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 = 460800;
uartParams.baudRate = 3000000;
uart = UART_open(Board_UART0, &uartParams);

ROM_UARTConfigSetExpClk(UART0_BASE, ui32SysClock, 3000000, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

after UART_open the UART_CTRL register does not set the HSE bit.
while without TI-RTOS with Peripheral Driver Library API it able to set HSE bit for 3Mbps UART baud rate

Is there a bug in TI-RTOS ?

  • Hi Nirav,

    A call to UART_open ultimately calls TivaWare's UARTConfigSetExpClk() to configure the baud rate; which should set the HSE bit for you if its supposed to.

    What version of TI-RTOS are you using?

    I just took a look at some (perhaps old) TivaWare code. You may want to check at what CPU frequency SYS/BIOS thinks you are running. UART_open asks SYS/BIOS for the current system (SYSCLK) frequency. Perhaps the reference frequency is off. Can you see what frequency BIOS_getCpuFreq() will return?

    void
    UARTConfigSetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk,
                        uint32_t ui32Baud, uint32_t ui32Config)
    {
        uint32_t ui32Div;
    
        //
        // Check the arguments.
        //
        ASSERT(_UARTBaseValid(ui32Base));
        ASSERT(ui32Baud != 0);
        ASSERT(ui32UARTClk >= (ui32Baud * UART_CLK_DIVIDER));
    
        //
        // Stop the UART.
        //
        UARTDisable(ui32Base);
    
        //
        // Is the required baud rate greater than the maximum rate supported
        // without the use of high speed mode?
        //
        if((ui32Baud * 16) > ui32UARTClk)
        {
            //
            // Enable high speed mode.
            //
            HWREG(ui32Base + UART_O_CTL) |= UART_CTL_HSE;
    
            //
            // Half the supplied baud rate to compensate for enabling high speed
            // mode.  This allows the following code to be common to both cases.
            //
            ui32Baud /= 2;
        }
        else
        {
            //
            // Disable high speed mode.
            //
            HWREG(ui32Base + UART_O_CTL) &= ~(UART_CTL_HSE);
        }

  • Hi Tom,

    Thanks for the detailed information. Yes you are correct UART_Open ultimately calls the same API library function and HSE bit selection is based on the SYSCLK frequency.

    I have checked,  BIOS_getCpuFreq() returns cpuFreq.lo = 0x04C4B400 // 80MHz, I am using tirtos_1_21_00_09.

    But my problem is different, First I thought that UART is not working because HSE bit is not set.

    But then I realise that with TI RTOS I am not able to receive many bytes (i.e 200 - 500) bytes together.I can see from the debug some missing bytes. also when I send 512 bytes I only able to receive around 250 bytes and that also not correct.(with the default SYSTEM CLOCK - 80Mhz)

    I also tried by changing the SYSCLOCK using inside main()

    	 cpuFreq.hi = 0;
    	 cpuFreq.lo = 0x07270E00; //120Mhz
    
    	BIOS_setCpuFreq(&cpuFreq);
    	Clock_tickReconfig();
    

    But it receives all junk bytes.... and not complete 512 bytes also.

    Could you please provide some pointer why I am not able to receive correctly 512 bytes using RTOS but I can receive correctly without using TI RTOS (example code).

    THanks.

     

     

     

     

     

  • Nirav,

    a few things here.

    1. BIOS_setCpuFreq() only tells BIOS at what frequency the CPU/System is running; generally when you change the CPU frequency at runtime. If you use the "Boot" module via the graphical configuration pages, it can configure the PLL for you and let SYS/BIOS know of the new frequency (without any runtime code).
    2. Running a UART baud rate at 3MHz isn't a typical standard baudrate that we test for. I'm suspecting that the non-RTOS might be running at a higher CPU frequency that would allow for a good UART sampling rate. Can you check the non-RTOS' CPU frequency and reconfigure the TI-RTOS application to match that (via the Boot module)?
    3. Another suggestion: Try using the NonInstrumented UART libraries as they don't have Log_print statements in them allowing the UART driver to execute faster. Add this into your .cfg file.
    var UART = xdc.useModule('ti.drivers.UART');
    UART.libType = UART.LibType_NonInstrumented;

  • Thanks Tom,

    After changing UART libraries to NonInstrumented it's working. However to be on safer side I also increased PLL to max i.e 120MHz.

    Earlier  RTOS and  without RTOS both running at same frequency - 80Mhz. But  with instrumented mode enabled in RTOS causes missing bytes in UART_read().

     

  • Nirav,

    I'm suspecting that you UART RX FIFO is being overrun when you use the instrumented libraries. Can you try switching back to the instrumented UART library, changing the CPU freq back to 80Mhz, and reconfiguring the FIFO trigger level after the call to UART_open(). Note, you need to #include some header files for this.

    #include <inc/hw_memmap.h>
    #include <inc/hw_ints.h>
    #include <inc/hw_types.h>
    #include <driverlib/uart.h>
    
    UART_open(...);
    UARTFIFOLevelSet(UART0_BASE, UART_FIFO_TX1_8, UART_FIFO_RX1_8);

    I'd like to know if we allow the hardware to trigger an UART RX interrupt sooner (with less data in the FIFO) if it would help avoiding dropped incoming UART data. The UART driver sets it to 7/8 full to reduce the number of interrupts generated, but that might not be a good configuration at your baudrate.