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.

TM4C123GH6PM: Tiva C UART not receiving data

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL, UNIFLASH

I am trying to interface Tiva C with FTDI using UART. I am able to send data from Tiva and receive in FTDI, but unable to read data in Tiva from FTDI. I am using below configuration:

115200 bps, 8 data bits, 1 stop bit, no parity

My hardware connections are:

TX (FTDI), with RX - PC4 (Tiva)
RX (FTDI), with TX - PC5 (Tiva)

ground pins of both connected to each other.

I have tested FTDI with ESP32 using UART, and it works. Please help me resolve the issue. I have attached code in case of misconfigured software.

#include <string.h>
#include "color_generator.h"
#include "inc/hw_ints.h"
#include "driverlib/uart.h"
#include "driverlib/interrupt.h"

#define MAX_SIZE 17
#define BAUD_RATE 115200
#define DELAY 50000000

char received_message[MAX_SIZE];
uint8_t loop_var = 0;
uint32_t len = 0;
const char* messages[] = {"WiFi started", "HTTP started", "WiFi connected"};
const char* text = "Received message: ";
const char* clear_screen = "\033[2J";
const char* newline_carriage_return = "\n\r";
const char* acknowledgement = "Indicating status...";

void uart_setup()
{
    // enable interrupts
    IntEnable(INT_UART4_TM4C123);

    // logging
    // enable gpio port A
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA))
    {
        // wait till peripheral is ready
    }
    GPIOPinConfigure(GPIO_PA0_U0RX | GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    // enable UART0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_UART0))
    {
        // wait till peripheral is ready
    }
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), BAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
    UARTEnable(UART0_BASE);

    // communication with FTDI
    // enable gpio port C
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOC))
    {
        // wait till peripheral is ready
    }
    GPIOPinConfigure(GPIO_PC4_U4RX | GPIO_PC5_U4TX);
    GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_5);

    // enable UART4
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_UART4))
    {
        // wait till peripheral is ready
    }
    UARTIntEnable(UART4_BASE, UART_INT_RT);
    // UARTLoopbackEnable(UART4_BASE);
    UARTConfigSetExpClk(UART4_BASE, SysCtlClockGet(), BAUD_RATE, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
    UARTEnable(UART4_BASE);
}

void debug_led()
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF))
    {
        // wait till peripheral is ready
    }
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3, 0);
}

void uart_handler()
{
    UARTIntClear(UART4_BASE, UART_INT_RT);

    loop_var = 0;

    while (UARTCharsAvail(UART4_BASE) && loop_var < MAX_SIZE)
    {
        // GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
        int32_t ch = UARTCharGet(UART4_BASE);
        // log_to_uart(&ch);
        received_message[loop_var] = ch;
        loop_var++;
    }

    // write received text to console
    log_to_uart(newline_carriage_return);
    log_to_uart(text);
    // GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
    log_to_uart(received_message);

    write_to_uart(acknowledgement);
}

void write_to_uart(const char* text)
{
    len = strlen(text);
    for (loop_var = 0; loop_var < len; loop_var++)
    {
        UARTCharPut(UART4_BASE, text[loop_var]);
        while (UARTBusy(UART4_BASE))
        {
            // wait till transmit FIFO is empty
        }
    }
}

void log_to_uart(const char* text)
{
    len = strlen(text);
    for (loop_var = 0; loop_var < len; loop_var++)
    {
        UARTCharPut(UART0_BASE, text[loop_var]);
        while (UARTBusy(UART0_BASE))
        {
            // wait till transmit FIFO is empty
        }
    }
}

int main(int argc, char const *argv[])
{
    // set system clock frequency to 16 MHz
    SysCtlClockSet(SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    // setup
    uart_setup();

    log_to_uart(clear_screen);
    
    debug_led();    // debug

    while (true)
    {
        // listen for input
        // write_to_uart("loopback");
        // SysCtlDelay(DELAY);
    }
       
    return 0;
}

  • Hi,

     Sorry, I'm currently out of office until 8/3. I will look into your question when I get back tomorrow. 

  • HI,

      - Can you show either the scope or logic analyzer capture of the TX and RX pins for UART4? Do you see the expected data on RX pin from FTDI?

      - Do you have the same problem running your code on the LaunchPad?

      - If you put a breakpoint on uart_handler(), does the processor stop there?

  • Hi Charles, 

    I don't have access to a scope or logic analyzer, so I couldn't check the Tx and Rx levels. However,

    1. FTDI receive is working fine with Tiva C since I am able to send data to it and the data is displaying in the serial monitor connected to FTDI.

    2. I also tried loopback on Tiva C and I'm able to transmit and receive data in UART4. 

    3. uart_handler() is entering only once after reset and the "Received message:" text is getting printed in the serial monitor. It's not entering thereafter.

    4. When connected to FTDI, no data is received and the framing error and break error bits are set.

  • Hi,

      All you have demonstrated is that UART4 can send data to the terminal and the terminal can display the characters. Without the scope it will be hard to debug what is sent on the RX pin. You have also said that you are getting a break and frame error. A scope will be handy to debug this type of problem. 

      Looking at your code I only see you enable UART_INT_RT for Receive Timeout interrupt. You did not enable UART_INT_RX for Receive interrupt. This is likely the problem that you do not receive data. You need to first fix this. 

      I will suggest you run the C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c123gxl\uart_echo example first. You will need to modify this example for UART4. Can you get this example to work? If this example works, then it means there is something wrong with your code. 

  • Hi Charles,

    The Rx line is held high. No bits are being received when I enter data. Verified this with the example UART echo program.

  • Hi Dyutinmoy,

      The uart_echo is a very basic example that is proven to work from the software standpoint. If Rx is held high then you need to debug the FTDI you have. You need to find out why FTDI is outputting high on RX line. 

    - Do you have another FTDI USB to UART converter to try? Not that I'm endorsing any converter, I use something like this product to connect to LaunchPad when I need to try out a different UART port. https://www.amazon.com/DSD-TECH-SH-U09C5-Converter-Support/dp/B07WX2DSVB/ref=sr_1_4?crid=3F3MP1VQP3SV9&keywords=usb+to+uart+converter&qid=1691158413&sprefix=usb+to+uart%2Caps%2C148&sr=8-4

    - I will also suggest that you modify your program from UART4 to UART0 so you can try it out on the LaunchPad board. The LaunchPad board has a built-in USB to UART converter that is part of the ICDI debug probe. However, the ICDI debug probe only takes UART0 for COM port enumeration.  

  • My main aim was to interface Tiva C with ESP32 pico. Since that wasn't working I tried ESP32 with FTDI and that actually worked. Then, when I tried to interface Tiva with FTDI it failed. That's why I suspect it's an issue with Tiva C.

  • If you interface Tiva with ESP32 then it does not involve FTDI. You just connect between the two using UARTTX and UARTRX pins. What is not working? Again, without a scope or logic analyzer it will be much harder to debug the problem. I think the equipment is worth investing but that is your call. 

  • Hi Charles,

    I got a logic analyzer and tried to read in PC4 after connecting to the Tx pin of my ESP32 and I am able to read the data sent from ESP. However, when I open serial monitor connected to UART0, no data is shown. I have attached logic analyzer output. Please suggest if anything'slogic analyzer output wrong with my code or otherwise.

  • Hi,

      First of all, you don't show label for what each channel is on the logic analyzer capture? So which channel is UART0TX, UART0RX, UART4TX and UART4RX. Secondly, they are all flat line, no activities as far as these waveforms are showing. You either need to zoom out or this is actually what is received on UART4RX. If that is the case, as far as Tiva MCU, it does not receive any data. 

      Why don't you do some simple experiments.

      - Are you using a custom board? Do you have FTDI for UART0 if you are going to send data to the terminal on the PC?

      - Modify your code to call log_to_uart() and send one character. Can you see that on UART0TX pin? Does the terminal display the character? Note you must have a FTDI if you are using your own custom board. If you are using a LaunchPad then you don't need FTDI. run this experiment on both LaunchPad and your own custom board.

      - Modify your code to call write_to_uart() and send one character. Can you see that on UART4TX pin? Does ESP receive this character?

      - Put a breakpoint on uart_handler. Does the processor enter uart_handler when it receives a character from ESP. You will need to do some single stepping to debug your system. 

  • Hi Charles,

    - I am using https://www.ti.com/tool/EK-TM4C123GXL board. I am not using FTDI with UART0 to communicate with board.

    - I am able to view characters when I call log_to_uart().

    - I am able to see the character on UART4TX pin when I call write_to_uart(). I can also see this character in ESP32 serial console, which means it is receiving it.

    - Code does not enter uart_handler() when receiving data from ESP32 at all.

  • - Code does not enter uart_handler() when receiving data from ESP32 at all.

    In my reply to you six days ago, I wrote the below. Did you enable UART_INT_RX to generate a receive interrupt?

      Looking at your code I only see you enable UART_INT_RT for Receive Timeout interrupt. You did not enable UART_INT_RX for Receive interrupt. This is likely the problem that you do not receive data. You need to first fix this. 

  • I did. Still doesn't enter.

  • Several things for you to check. 

    - Do you see UART4RX activities on your logic analyzer? There must be a high to low transition on RX pin to indicate a valid START bit per UART protocol to recognize as the start of a frame.

    - Do you see RXRIS bit set in UARTRIS bit? See below. 

     - Show the entire UART4 dump. See below from CCS. 

    - Show your startup_ccs.c file. Do you have uart_handler mapped to UART4 in the interrupt vector table? See below example. 

  • I am using VSCode on Debian, flashing through Uniflash software. Can you please suggest based on that? I have added uart_handler against "UART4 Rx and Tx" in startup file (startup_gcc.c), and the RXRIS is not getting set.

  • You haven't answered my first question. What does UART4RX show on logic analyzer? Do you see any activities? If RXRIS bit is never set then it means it did not receive any data. RXRIS is a raw flag indicating that a character is receive. If RXIM bit in UARTIM register is set then it means the interrupt RX receive is enabled. You will also see RXMIS bit set in UARTMIS register if both RXRIS and RXIM are high. 

    Another thing for you to check if ESP is configured for the same baud rate as Tiva and the same number of stop bits and parity check setting. They must all match to each other. 

    Also check if you are getting any error by checking UARTSR register. If you are getting errors then you need to investigate why these errors are detected. First thing is to show your UART4RX pin. 

  • Attaching logic analyzer capture for UART4 Rx pin :

  • Hi,

      Ok, there is data on UART4RX. Can you show the full register dump for UART4 as I requested earlier?

      Do you have the FIFO enabled? I don't see in our code enabling FIFO. Is that correct? If you had enabled FIFO then you would have needed to wait for the FIFO to be at least half-full (8 bytes) before it will generate an interrupt. Check the FEN bit in UARTLCRH register. By default after reset, FEN is 0. 

  • Hi Charles,

    I have decided to follow a different approach for my requirement. Thanks for your time and help.