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.

TIVA C EK-Tm4C129X UART4 Enable.

Other Parts Discussed in Thread: EK-TM4C1294XL

I am using TIVAC Evaluation kit with TI RTOS for TIVAC series. I saw an example for UART0 Logging and tried to run it. With default ICDI-UART0 this application works fine. 

Now, I want to test this with UART4. I configured JP4 and JP5 for as suggested(verically) to  enable CAN so that ICDI uses UART4 for COM. 
 Also I hav emodified my uartecho.c,BAORD.h, EK_TM4C1294XL.h & EK_TM4C1294XL.c to enable correct GPIO(GAPIOA) for UART TX & RX.  But I am not able to see any logs on my console. Looks like UART4 configurations are not done properly.

Please guide me to get UART4 up for this.

  • Hello  Ravikiran,

    With JP4 and JP5 UART2 is connected to ICDI and not UART4.

    Regards

    Amit

  • Hi Amit,


    Thanks for the reply.
     But, I am slightly confused now.

    Refering to Tiva™ C Series TM4C1294 Connected LaunchPad Evaluation Kit EK-TM4C1294XL User's Guide
    (Yes I am using EVAL Kit EK-Tm4C1294XL), page number 11,17, 19 says UART4 is available for ICDI if CAN is selected in JP5 & JP4. But page 28 of same document says, UART-2 is available for ICDI if CAN is selected in JP4 & JP5. 

    Please can you confirm which one is correct?

    Also my board is EK-TM4C1294XL Rev-C but my document is for REV - 4. I don't see related document available for Rev-C. Please can you share me the one if you have ?

    Thank you.

  • Ravikiran,

       Any luck on this?  I tried this early on with my app but couldn't get it to play along: CAN0+UART4, so I  dropped it for the time being, but would be interested it if you figured it out.  Thanks!

  • Hi Hiowatha,

    Yes there is some progress. We could get UART4 up.

    Since it is UART2 which conflicts with CAN we need not worry about any jumpers. 

    So proper pinmux configuration and interrupt registration for UARt4 device will gives intended  result !

    So,  What Amit said in above post is correct & its the error in documentation which is leading to confusion. 

  • Thanks Ravikiran!

       I finally got back to trying this out on my EK-TM4C1294XL but I can't seem to get anything on the console:

    This is the contents of my UART init function, the top shows when I have UART0 enabled (jumper pins are both horizontal), the bottom is when I am trying to enable UART4 (jumper pins are both vertical).

    //UART0
    // Enable the GPIO Peripheral used by the UART.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
    // Enable UART0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    
    // Configure GPIO Pins for UART mode.
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
    // Initialize the UART for console I/O.
    UARTStdioConfig(0, 115200, g_ui32SysClock);
    
    **********************************************************
    **********************************************************
    **********************************************************
    //UART4
    // Enable the GPIO Peripheral used by the UART.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
    // Enable UART4
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
    
    // Configure GPIO Pins for UART mode.
    GPIOPinConfigure(GPIO_PA2_U4RX);
    GPIOPinConfigure(GPIO_PA3_U4TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3);
    
    
    // Initialize the UART for console I/O.
    UARTStdioConfig(4, 115200, g_ui32SysClock);
    

      In my main code I am repeatedly calling:

    UARTprintf("Hello, world!\n");

    So I was expecting the console to show the hello worlds.  Any idea what I am doing wrong?  BTW, I had to modify the uartstudio.c file to extend it to be able to initialized UART4 (the code only went up to UART2).  I have also tried with with UART2 in case I miss understood the thread, but same result, nothing.

    Any help would be appreciated, just to understand what I am doing wrong.

    Thank you!

  • Hello Hiowatha,

    It is UART-2 which is connected to ICDI via the jumpers? Which UART (UART-2 or UART-4) do you plan to bring to the ICDI? Can you send the data

    1. Modifications file for UARTStdioConfig and UARTprintf

    2. If UART-4 then how are you wiring the jumpers (a snapshot would be good)

    Regards

    Amit

  • Hi Amit,
        So as I understood Ravikiran (and user's guide) above that UART4 is the correct one to setup/use when you switch to using CAN.  The jumpers are vertical, see pic below:


    These are the mods I made to UARTStdio:

    static const uint32_t g_ui32UARTBase[5] =
    {
        UART0_BASE, UART1_BASE, UART2_BASE, UART3_BASE, UART4_BASE
    };
    
    ...
    
    static const uint32_t g_ui32UARTPeriph[5] =
    {
        SYSCTL_PERIPH_UART0, SYSCTL_PERIPH_UART1, SYSCTL_PERIPH_UART2, SYSCTL_PERIPH_UART3, SYSCTL_PERIPH_UART4
    };

    Notice I have added UART3 & UART4 to the original setup array's.

    This is the setup code and usage:

        // Enable the GPIO Peripheral used by the UART.
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        // Enable UART
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
    
        // Configure GPIO Pins for UART mode.
        GPIOPinConfigure(GPIO_PA2_U4RX);
        GPIOPinConfigure(GPIO_PA3_U4TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3);
    
    
        // Initialize the UART for console I/O.
        UARTStdioConfig(4, 115200, g_ui32SysClock);
    
        ... 
     
        UARTprintf("Hello, world!\n");

    I figured this would be straight forward, but I must be forgetting something.

    Thanks again!

  • Hello Hiowatha

    It is UART-2 and not UART-4 on the secondary jumpers. That is what Ravikiran and I have mentioned earlier.

    Regards

    Amit

  • Gotcha, sorry for misunderstanding.  So I just tried this:

    int main(void)
    {
        // Run from the PLL at 120 MHz.
        g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
    
        // Configure the device pins.
        PinoutSet(false, false);
    
        // Enable the GPIO pins for the LED D1 (PN1).
        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1);
    
        // Initialize the UART2::  -->
        // Enable the GPIO Peripheral used by the UART.
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        // Enable UART
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
    
        // Configure GPIO Pins for UART mode.
        GPIOPinConfigure(GPIO_PA6_U2RX);
        GPIOPinConfigure(GPIO_PA7_U2TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    
        // Initialize the UART for console I/O.
        UARTStdioConfig(2, 115200, g_ui32SysClock);
    
        // Delay for a bit.
        SysCtlDelay(g_ui32SysClock / 10  );
    
        // Say Hello!
        UARTprintf("Hello, world!\n");
    
        // We are finished.  Hang around flashing D1.
        while(1)
        {
            // Turn on D1.
            LEDWrite(CLP_D1, 1);
    
            // Delay for a bit.
            SysCtlDelay(g_ui32SysClock / 10  );
    
            // Turn off D1.
            LEDWrite(CLP_D1, 0);
    
            // Delay for a bit.
            SysCtlDelay(g_ui32SysClock / 10 );
    
            // Say Hello!
            UARTprintf("Hello, world!\n");
        }
    }
    

    All else same, I am not seeing anything on the console.  Any other ideas?

    Thanks again.

  • Hello Hiowatha,

    I ran the code and except for the functions like LEDWrite and PinOut which were not defined in your code post, the UART-2 works fine.

    The issue is the missing

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);

    before setting the PN1 as output pin. After making the changes UART-2 works as expected.

    Regards

    Amit

  • Amit,

       The LEDs were working fine, where my trouble lies is in this code:

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "drivers/pinout.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "drivers/buttons.h"
    
    int main(void)
    {
        // Run from the PLL at 120 MHz.
        uint32_t g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
    
        // Enable the GPIO Peripheral used by the UART.
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        // Enable UART
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
    
        // Configure GPIO Pins for UART mode.
        GPIOPinConfigure(GPIO_PA6_U2RX);
        GPIOPinConfigure(GPIO_PA7_U2TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    
        // Initialize the UART for console I/O.
        UARTStdioConfig(2, 115200, g_ui32SysClock);
    
        // Delay for a bit.
        SysCtlDelay(g_ui32SysClock / 10  );
    
        // Say Hello!
        UARTprintf("Hello, world!\n");
    
        // We are finished.  Hang around flashing D1.
        while(1)
        {
            // Delay for a bit.
            SysCtlDelay(g_ui32SysClock / 10 );
    
            // Say Hello!
            UARTprintf("Hello, world!\n");
        }
    }
    

    This is literally all I am running now, NO modifications to anything else and I still don't see anything on the console.  JP5 and JP4 jumpers are ALL vertical.  And the USB debug port is connected to my laptop.  Am I missing something else?  I am using TeraTerm to see the console output, which works great when using UART0 and the jumper pins are horizontal?  I am on the evaluation kit: EK-TM4C1294XL rev A1.

    Any ideas?  Thanks!

  • Hello Hiowatha,

    I think I realized my code was doing UART2 configuration on PD4 and PD5 and not PA6 and PA7.

    The jumpers are meant for PD4 PD5 for UART2. You would need to change the IO Configuration

    Regards

    Amit

  • Hi Amit,

        Are we on the same board?  I am afraid I am still not getting anything on console :-(  I am running on the EK-TM4C1294XL eval board.  Do yo have any other physical connectors that maybe I am not using?  I setup only has the USB connected to the debug port (micro USB furthest from the ethernet jack).

    I am missing something obvious but I am hitting a wall here.  My current code:

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "drivers/pinout.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "drivers/buttons.h"
    
    int main(void)
    {
        // Run from the PLL at 120 MHz.
        uint32_t g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
    
        // Enable the GPIO Peripheral used by the UART.
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    
        // Enable UART
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
    
        // Configure GPIO Pins for UART mode.
        GPIOPinConfigure(GPIO_PD4_U2RX);
        GPIOPinConfigure(GPIO_PD5_U2TX);
        GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    
        // Initialize the UART for console I/O.
        UARTStdioConfig(2, 115200, g_ui32SysClock);
    
        // Delay for a bit.
        SysCtlDelay(g_ui32SysClock / 10  );
    
        // Say Hello!
        UARTprintf("Hello, world!\n");
    
        while(1)
        {
            // Delay for a bit.
            SysCtlDelay(g_ui32SysClock / 10 );
    
            // Say Hello!
            UARTprintf("Hello, world!\n");
        }
    }

    I think the console program works fine, since I am able to see everything when I use UART0, just wondering what else is missing?  I overall intent is to get this working and then introduce CAN0.

    Thanks.

  • Hello Hiowatha,

    My board allows for more configurations on top of EK-TM4C129 (due to other board mods), but in its default configuration is same as EK-TM4C129. At this point I would ask you to send the CCS project zip file, so that I can check the other options for configuration.

    Regards

    Amit

  • Thanks Amit, I appreciate your help!

    I have attached the program I am using to try this.

    8424.hello2.zip

    Thank you.

  • Hello Hiowatha,

    I checked the project folder and the startup_ccs.c is missing in the project.

    Regards

    Amit

  • Wow.  Amit, sorry for all the back and forth.  I am not sure how I missed that.  I think my mistake was creating a new empty project which surprisingly is empty!  (I kid, I should have known better.)  I now seem to have CAN0 enabled along with UART2 for my project, which was my original goal.  Again, thanks for the slap in the head to get me going.

    Will TI eventually update the docs?

    Thank  You.

  • Hello Hiowatha

    Which docs are you talking about? There are quite some we are started working on, that the forum has already highlighted.

    Regards

    Amit

  • Hey Amit,

        I was referring to the EK-TM4C1294XL user's guide which refers to UART4 in several places through out the document.  It's probably already on your (TI) radar so no worries.

    Thanks again!

  • Hello Howitha,

    Yes, it is on the to-do list for documentation, along with a lot of other's.

    Regards

    Amit

  • An interesing topic here.

    I also understood the manual that the jumpers switch to UART4.
    Now in August 2014 the latest manual still contains the error (which confuses developers).
    To support TI, I used the "Submit documentation feedback" link in the manual. So I hope the responsible person will receive the notice.


    Well, for my application I realy need the UART4 port (which isn't connected to ICDI).
    I added a #define switch to the UART echo example.
    In default setting (UART0) it still works fine, but when I switch to UART4, the application crashes.
    (When there is no crash, the LED blinks. If not, there is a crash.)

    UART4 is on Port K, Pins 0 and 1.
    Even after about two hours I can't figure out the problem of the my code.

    I would be happy if someone gives me a notice.

    //*****************************************************************************
    //
    // uart_echo.c - Example for reading data from and writing data to the UART in
    //               an interrupt driven fashion.
    //
    // Copyright (c) 2013-2014 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    // 
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    // 
    // This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    
    #define UART_4
    
    #ifdef UART_4
    	#define UARTX_BASE           UART4_BASE
    	#define SYSCTL_PERIPH_UARTX  SYSCTL_PERIPH_UART4
    	#define GPIO_PXX_UXRX        GPIO_PK0_U4RX
    	#define GPIO_PXX_UXTX        GPIO_PK1_U4TX
    	#define INT_UARTX            INT_UART4
    	#define GPIO_PORTX_BASE      GPIO_PORTK_BASE
    	#define SYSCTL_PERIPH_GPIOX  SYSCTL_PERIPH_GPIOK
    #else
    	#define UARTX_BASE           UART0_BASE
    	#define SYSCTL_PERIPH_UARTX  SYSCTL_PERIPH_UART0
    	#define GPIO_PXX_UXRX        GPIO_PA0_U0RX
    	#define GPIO_PXX_UXTX        GPIO_PA1_U0TX
    	#define INT_UARTX            INT_UART0
    	#define GPIO_PORTX_BASE      GPIO_PORTA_BASE
    	#define SYSCTL_PERIPH_GPIOX  SYSCTL_PERIPH_GPIOA
    #endif
    
    //*****************************************************************************
    //
    //! \addtogroup example_list
    //! <h1>UART Echo (uart_echo)</h1>
    //!
    //! This example application utilizes the UART to echo text.  The first UART
    //! (connected to the USB debug virtual serial port on the evaluation board)
    //! will be configured in 115,200 baud, 8-n-1 mode.  All characters received on
    //! the UART are transmitted back to the UART.
    //
    //*****************************************************************************
    
    //****************************************************************************
    //
    // System clock rate in Hz.
    //
    //****************************************************************************
    uint32_t g_ui32SysClock;
    
    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    //*****************************************************************************
    //
    // The UART interrupt handler.
    //
    //*****************************************************************************
    void
    UARTIntHandler(void)
    {
        uint32_t ui32Status;
    
        //
        // Get the interrrupt status.
        //
        ui32Status = ROM_UARTIntStatus(UARTX_BASE, true);
    //    ui32Status = ROM_UARTIntStatus(UART0_BASE, true);
    
        //
        // Clear the asserted interrupts.
        //
        ROM_UARTIntClear(UARTX_BASE, ui32Status);
    //    ROM_UARTIntClear(UART0_BASE, ui32Status);
    
        //
        // Loop while there are characters in the receive FIFO.
        //
        while(ROM_UARTCharsAvail(UARTX_BASE))
        //while(ROM_UARTCharsAvail(UART0_BASE))
        {
            //
            // Read the next character from the UART and write it back to the UART.
            //
            ROM_UARTCharPutNonBlocking(UARTX_BASE,
                                       ROM_UARTCharGetNonBlocking(UARTX_BASE));
    //        ROM_UARTCharPutNonBlocking(UART0_BASE,
    //                                   ROM_UARTCharGetNonBlocking(UART0_BASE));
    
            //
            // Blink the LED to show a character transfer is occuring.
            //
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
    
            //
            // Delay for 1 millisecond.  Each SysCtlDelay is about 3 clocks.
            //
            SysCtlDelay(g_ui32SysClock / (1000 * 3));
    
            //
            // Turn off the LED
            //
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
        }
    }
    
    //*****************************************************************************
    //
    // Send a string to the UART.
    //
    //*****************************************************************************
    void
    UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count)
    {
        //
        // Loop while there are more characters to send.
        //
        while(ui32Count--)
        {
            //
            // Write the next character to the UART.
            //
            ROM_UARTCharPutNonBlocking(UARTX_BASE, *pui8Buffer++);
    //        ROM_UARTCharPutNonBlocking(UART0_BASE, *pui8Buffer++);
        }
    }
    
    //*****************************************************************************
    //
    // This example demonstrates how to send a string of data to the UART.
    //
    //*****************************************************************************
    int
    main(void)
    {
        //
        // Set the clocking to run directly from the crystal at 120MHz.
        //
        g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_480), 120000000);
        //
        // Enable the GPIO port that is used for the on-board LED.
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
    
        //
        // Enable the GPIO pins for the LED (PN0).
        //
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
    
        //
        // Enable the peripherals used by this example.
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UARTX);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOX);  // UART 4
    //    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    //    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);  // UART 0
    
        //
        // Enable processor interrupts.
        //
        ROM_IntMasterEnable();
    
        //
        // Set GPIO A0 and A1 as UART pins.
        //
        GPIOPinConfigure(GPIO_PXX_UXRX);
        GPIOPinConfigure(GPIO_PXX_UXTX);
    //    GPIOPinConfigure(GPIO_PA0_U0RX);
    //    GPIOPinConfigure(GPIO_PA1_U0TX);
        ROM_GPIOPinTypeUART(GPIO_PORTX_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    //    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Configure the UART for 115,200, 8-N-1 operation.
        //
        ROM_UARTConfigSetExpClk(UARTX_BASE, g_ui32SysClock, 115200,
    //    ROM_UARTConfigSetExpClk(UART0_BASE, g_ui32SysClock, 115200,
                                (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                 UART_CONFIG_PAR_NONE));
    
        //
        // Enable the UART interrupt.
        //
        ROM_IntEnable(INT_UARTX);
        ROM_UARTIntEnable(UARTX_BASE, UART_INT_RX | UART_INT_RT);
    //    ROM_IntEnable(INT_UART0);
    //    ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
    
        //
        // Prompt for text to be entered.
        //
        UARTSend((uint8_t *)"\033[2JEnter text: ", 16);
    
        //
        // Loop forever echoing data through the UART.
        //
        while(1)
        {
    		    // LED test
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
            SysCtlDelay(g_ui32SysClock / (1000 * 3 * 10000));
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
            SysCtlDelay(g_ui32SysClock / (1000 * 3 * 2000));
        }
    }
    

  • Now, one day later,  I checked my code, the eval board circuits, the manual and the posted sources again.

    So I recognised, that UART4 can be applied either to port A (pins 2, 3) or to port K (pins 0, 1).
    For my extension board I use port K, because it's available at the boosterpack connector.

    Additionally I figured out, that the application doesn't crash when I comment out this line:

    ROM_UARTIntEnable(UARTX_BASE, UART_INT_RX | UART_INT_RT);
    
    // note: UARTX_BASE is set to UART4_BASE
    

    Nevertheless I couldn't figure out the bug of my code (based on a TI example for the same eval board).
    Remember: Switching to UART0 doesn't crash.

  • Currently I'm confused about the startup_rvmdk.S files (needed for Keil projects).

    In the TivaWare directory (version 2.1) are 26 examples for the evaluation board EK-TM4C1294XL.
    So it's for the same target hardware, but nearly all startup files are different (especially the vector tables).
    I couldn't find a fitting answer in the internet for more information.

    By comparing the startup files I saw that for the UART echo example are changes related to the interrupt handler of UART 0:

    DCD     UARTIntHandler                 ; UART0 Rx and Tx
    ; ...
    DCD     IntDefaultHandler              ; UART4 Rx and Tx
    

    So I tried to set UART4 to the UART interrupt handler instead.

    DCD     IntDefaultHandler              ; UART0 Rx and Tx
    ; ...
    DCD     UARTIntHandler                 ; UART4 Rx and Tx

    Unfortunately the code still crashes ...

  • Hello Andreas

    Can you send across the Project?

    Regards

    Amit

  • Hi Amit

    thanks for your offer to help me.
    The whole project is attached.


    _____________

    update1: I updated the ZIP file, because there was one bad line

    EK-TM4C1294XL_uart_echo_UART4_update1.zip
  • Hello Andreas,

    I ran the code for UART-4 (attached project) and it works fine

    6052.uart_echo.7z

    The question I have is that how are you connecting UART4 to the PC? Is it a straight wiring or does it have the Level Translator (+Transceiver IC)

    Regards

    Amit

  • Thanks Amit for your time.

    I don't see any code changes in your project. So my C code seems to be fine.

    When I flash your binary output file (uart_echo.bin) to the microcontroller, it works.
    But when I compile your project without any changes, the application crashes.

    When I compared all files, I found an interesting difference in the file uart_echo_uart_echo.dep.

    An include path for the compiler is different.

    // paths in my file:
    ...\Keil_v5\ARM\PACK\ARM\CMSIS\4.1.0\CMSIS\Include
    
    // paths in your file:
    ...\Keil_v5\ARM\PACK\ARM\CMSIS\3.20.4\CMSIS\Include

    I see that path in the Keil project configuration (field "Compiler control string" in tab "C/C++"), but I can't change it.

    Can this be the reason, why YOUR code crashes (only in UART4 configuration), when I recompile it on my computer?
    This is so strange ...

    What I mean with crash:
    Not only the UART communication fails.
    There is a dead lock. If the application runs fine, LED1 is flickering (very quickly).
    When I switch to UART4, either the LED is on or off. Also using the debugger shows, that there is a dead lock.
    I suppose it's something related to the interrupts, because it runs, when I disable UART interrupts.

    Related to your question:
    I use an UART-to-USB cable (type TTL-232R-3V3), which is very nice,
    because you can directly connect it to the microcontroller pins and on the PC you have a virtual COM port.
    http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm
    Using the sweet tool HTerm I can communicate with the UART echo program successfully (when I flash your binary file).

    _______________
    update 1:

    Here I found some information about CMSIS:
    http://www.keil.com/pack/doc/CMSIS/Core/html/index.html

    Here is some information about my Keil IDE version (if needed):

    IDE-Version:
    µVision V5.11.0.0
    
    Tool Version Numbers:
    Toolchain:        MDK-ARM Standard Cortex-M only  Version: 5.11.0.0
    Toolchain Path:    ...\Keil_v5\ARM\ARMCC\bin\
    C Compiler:         Armcc.Exe       V5.04.0.49
    Assembler:          Armasm.Exe       V5.04.0.49
    Linker/Locator:     ArmLink.Exe       V5.04.0.49
    Librarian:             ArmAr.Exe       V5.04.0.49
    Hex Converter:      FromElf.Exe       V5.04.0.49
    CPU DLL:               SARMCM3.DLL       V5.11.0.0
    Dialog DLL:         DCM.DLL       V1.11.0.0
    Target DLL:             lmidk-agdi.dll       V???
    Dialog DLL:         TCM.DLL       V1.14.1.0
    

  • Hello Andreas,

    First of all CMSIS should not have an affect here.

    What I did was take the existing uart_echo example and copy your main code to it and it worked out of the box. When I tried compiling it was giving me errors for FCARM (may be due to version of the IDE I am using), not allowed me to change the driverlib.lib either.

    Following is the information about my IDE (clearly older on the build but compiler/linker versions are the same)

    IDE-Version:
    µVision V5.10.0.2
    Copyright (C) 2014 ARM Ltd and ARM Germany GmbH. All rights reserved.

    Tool Version Numbers:
    Toolchain:        MDK-Lite  Version: 5.10.0.0
    Toolchain Path:    C:\Keil_v5\ARM\ARMCC\bin\
    C Compiler:         Armcc.Exe       V5.04.0.49 [Evaluation]
    Assembler:          Armasm.Exe       V5.04.0.49 [Evaluation]
    Linker/Locator:     ArmLink.Exe       V5.04.0.49 [Evaluation]
    Librarian:             ArmAr.Exe       V5.04.0.49 [Evaluation]
    Hex Converter:      FromElf.Exe       V5.04.0.49 [Evaluation]
    CPU DLL:               SARMCM3.DLL       V5.10.0.0
    Dialog DLL:         DCM.DLL       V1.10.0.0
    Target DLL:             lmidk-agdi.dll       V???
    Dialog DLL:         TCM.DLL       V1.14.1.0

    Regards

    Amit

  • Amit Ashara said:
    What I did was take the existing uart_echo example and copy your main code to it and it worked out of the box.

    I did the same again (original example project + my uart_echo.c file) and it failed.

    Additionally I tried my older Keil 4.54 version, but it failed, too.

    I suppose it's no hardware problem, because when I flash your binary output my board works fine.
    It's seems to be a damn software problem ...

    Which TivaWare version do you use?
    I linked the latest (version 2.1.0.12573), which came together with the used example.

    I also tried it on an other PC (using Keil 4) and it also failed. )-:

  • Hello Andreas

    Yes, I am using 2.1.0.12573 version of TivaWare. A suggestion if you are using Stellaris ICDI: Try using CCS as a back up option.

    Secondly when the code hangs, I am interested in knowing where it hangs? Or does it keep on changing all the time?

    Regards

    Amit

  • By random I found out the problem:

    The deadlock happens, when there is nothing connected to the UART RX pin.
    (Or when the USB-to-UART cable isn't connected to the PC.)

    The UART RX pin needs a high level (3.3V) in idle mode. Otherwise the application crashes.

    Why I didn't get the idea before?
    Because on my older prototype (using the LM4F232 eval board with StellarisWare) didn't crash, when there was nothing connected to the UART connectors.

    My solution: I enabled the internal pull-up resistor of the related pin.
    This prevents a crash when there is nothing connected to the UART RX pin.

    // enable pull-up resitor to prevent crashes if nothing is connected to the UART RX pin (using UART4 on port K)
    GPIOPadConfigSet(GPIO_PORTK_BASE, GPIO_PIN_0, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU); 
    

    Thanks Amit for your time !!

    Here is the source code for using UART 4 with Tiva Connected LaunchPad EK-TM4C1294XL.

    Maybe somebody needs it.
    Keep in mind: If you change the CAN jumpers, UART 2 is connected to ICDI (although UART 4 is written in the manual).
    UART 4 you only need for custom cases.

    //*****************************************************************************
    //
    // uart_echo.c - Example for reading data from and writing data to the UART in
    //               an interrupt driven fashion.
    //
    // Copyright (c) 2013-2014 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    // 
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    // 
    // This is part of revision 2.1.0.12573 of the EK-TM4C1294XL Firmware Package.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    
    #define UART_4  // comment out this line will switch back to UART 0 (default)
    
    #ifdef UART_4
      // using UART4 on port K, pins 0+1  (NOT port A, pins 2+3)
    	#define UARTX_BASE           UART4_BASE
    	#define SYSCTL_PERIPH_UARTX  SYSCTL_PERIPH_UART4
    	#define GPIO_PXX_UXRX        GPIO_PK0_U4RX
    	#define GPIO_PXX_UXTX        GPIO_PK1_U4TX
    	#define GPIO_PIN_UART_RX     GPIO_PIN_0
    	#define INT_UARTX            INT_UART4
    	#define GPIO_PORTX_BASE      GPIO_PORTK_BASE
    	#define SYSCTL_PERIPH_GPIOX  SYSCTL_PERIPH_GPIOK
    #else
    	#define UARTX_BASE           UART0_BASE
    	#define SYSCTL_PERIPH_UARTX  SYSCTL_PERIPH_UART0
    	#define GPIO_PXX_UXRX        GPIO_PA0_U0RX
    	#define GPIO_PXX_UXTX        GPIO_PA1_U0TX
    	#define INT_UARTX            INT_UART0
    	#define GPIO_PORTX_BASE      GPIO_PORTA_BASE
    	#define SYSCTL_PERIPH_GPIOX  SYSCTL_PERIPH_GPIOA
    #endif
    
    //*****************************************************************************
    //
    //! \addtogroup example_list
    //! <h1>UART Echo (uart_echo)</h1>
    //!
    //! This example application utilizes the UART to echo text.  The first UART
    //! (connected to the USB debug virtual serial port on the evaluation board)
    //! will be configured in 115,200 baud, 8-n-1 mode.  All characters received on
    //! the UART are transmitted back to the UART.
    //
    //*****************************************************************************
    
    //****************************************************************************
    //
    // System clock rate in Hz.
    //
    //****************************************************************************
    uint32_t g_ui32SysClock;
    
    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    //*****************************************************************************
    //
    // The UART interrupt handler.
    //
    //*****************************************************************************
    void
    UARTIntHandler(void)
    {
        uint32_t ui32Status;
    
        //
        // Get the interrrupt status.
        //
        ui32Status = ROM_UARTIntStatus(UARTX_BASE, true);
    
        //
        // Clear the asserted interrupts.
        //
        ROM_UARTIntClear(UARTX_BASE, ui32Status);
    
        //
        // Loop while there are characters in the receive FIFO.
        //
        while(ROM_UARTCharsAvail(UARTX_BASE))
        {
            //
            // Read the next character from the UART and write it back to the UART.
            //
            ROM_UARTCharPutNonBlocking(UARTX_BASE,
                                       ROM_UARTCharGetNonBlocking(UARTX_BASE));
    
            //
            // Blink the LED to show a character transfer is occuring.
            //
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
    
            //
            // Delay for 1 millisecond.  Each SysCtlDelay is about 3 clocks.
            //
            SysCtlDelay(g_ui32SysClock / (1000 * 3));
    
            //
            // Turn off the LED
            //
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
        }
    }
    
    //*****************************************************************************
    //
    // Send a string to the UART.
    //
    //*****************************************************************************
    void
    UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count)
    {
        //
        // Loop while there are more characters to send.
        //
        while(ui32Count--)
        {
            //
            // Write the next character to the UART.
            //
            ROM_UARTCharPutNonBlocking(UARTX_BASE, *pui8Buffer++);
        }
    }
    
    //*****************************************************************************
    //
    // This example demonstrates how to send a string of data to the UART.
    //
    //*****************************************************************************
    int
    main(void)
    {
        //
        // Set the clocking to run directly from the crystal at 120MHz.
        //
        g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_480), 120000000);
        //
        // Enable the GPIO port that is used for the on-board LED.
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
    
        //
        // Enable the GPIO pins for the LED (PN0).
        //
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
    
        //
        // Enable the peripherals used by this example.
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UARTX);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOX);  // UART 4
    
        //
        // Enable processor interrupts.
        //
        ROM_IntMasterEnable();
    
        //
        // Set GPIO A0 and A1 as UART pins.
        //
        GPIOPinConfigure(GPIO_PXX_UXRX);
        GPIOPinConfigure(GPIO_PXX_UXTX);
        ROM_GPIOPinTypeUART(GPIO_PORTX_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
    #ifdef UART_4
        GPIOPadConfigSet(GPIO_PORTX_BASE, GPIO_PIN_UART_RX, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU);
    #endif
    
        //
        // Configure the UART for 115,200, 8-N-1 operation.
        //
        ROM_UARTConfigSetExpClk(UARTX_BASE, g_ui32SysClock, 115200,
                                (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                 UART_CONFIG_PAR_NONE));
    
        //
        // Enable the UART interrupt.
        //
        ROM_IntEnable(INT_UARTX);
        ROM_UARTIntEnable(UARTX_BASE, UART_INT_RX | UART_INT_RT); // _RT = Receive Timeout Interrupt Mask
    
        //
        // Prompt for text to be entered.
        //
        UARTSend((uint8_t *)"\033[2JEnter text: ", 16);
    
        //
        // Loop forever echoing data through the UART.
        //
        while(1)
        {
    		    // LED test
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, GPIO_PIN_0);
            SysCtlDelay(g_ui32SysClock / (1000 * 3 * 10000));
            GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
            SysCtlDelay(g_ui32SysClock / (1000 * 3 * 2000));
        }
    }
    

  • Hello Andreas

    Then why did my bin file work at all!!!

    Regards

    Amit

  • hiowatha said:
    BTW, I had to modify the uartstudio.c file to extend it to be able to initialized UART4 (the code only went up to UART2). 

    What changes did you make to permit UART 3 and higher to be used ?

    In the UARTStdioConfig function, I tried commenting out the first ASSERT line to no avail

    void
    UARTStdioConfig(uint32_t ui32PortNum, uint32_t ui32Baud, uint32_t ui32SrcClock)
    {
        //
        // Check the arguments.
        //
        ASSERT((ui32PortNum == 0) || (ui32PortNum == 1) || (ui32PortNum == 2));
    

    I also need to do this as UARTPrintf is so handy compared to just the UARTCharPut function.    Why would UARTStdioConfig not permit initialising ports 3 or higher by design ?  It seems unnecessarily limiting.

  • What changes must I make to UARTStdioConfig and UARTPrintf to cope with UART port numbers 3 or higher ?

  • Peter John said:
    What changes must I make to UARTStdioConfig and UARTPrintf to cope with UART port numbers 3 or higher ?

    OK I decided to figure it out myself.  Crazy limitation if you ask me as it isn't unusual to have more than 3 UARTS on an MCU.  Now whenever I update my TIVA library I have to remember to make these mods to uartstdio.c

    //*****************************************************************************
    //
    // The list of possible base addresses for the console UART.
    //
    //*****************************************************************************
    static const uint32_t g_ui32UARTBase[5] =
    {
        UART0_BASE, UART1_BASE, UART2_BASE, UART3_BASE, UART4_BASE  //added UART4_BASE and UART5_BASE
    };
    
    #ifdef UART_BUFFERED
    //*****************************************************************************
    //
    // The list of possible interrupts for the console UART.
    //
    //*****************************************************************************
    static const uint32_t g_ui32UARTInt[5] =  //was [3]
    {
        INT_UART0, INT_UART1, INT_UART2, INT_UART3, INT_UART4  //added two more UARTS
    };
    
    //*****************************************************************************
    //
    // The port number in use.
    //
    //*****************************************************************************
    static uint32_t g_ui32PortNum;
    #endif
    
    //*****************************************************************************
    //
    // The list of UART peripherals.
    //
    //*****************************************************************************
    static const uint32_t g_ui32UARTPeriph[5] =  //was [3]
    {
        SYSCTL_PERIPH_UART0, SYSCTL_PERIPH_UART1, SYSCTL_PERIPH_UART2, SYSCTL_PERIPH_UART3, SYSCTL_PERIPH_UART4  //added two more UARTS
    };
    

  • Hello Peter,

    As a start, you can search for UART2 and add the other UART's, which will ensure that all UART related variables like base address, interrupt and clock/reset enables are correct.

    Secondly if you are using DEBUG define then do make sure that ASSERT is corrected for additional port numbers.

    Regards

    Amit

  • hi Peter,

       You did exactly what I ended up doing to uartstdio.c  Sorry for my slow reply.

    -hiowatha

  • hiowatha said:
    You did exactly what I ended up doing to uartstdio.c  Sorry for my slow reply.

    -hiowatha

     

    Thanks for confirming !  Now it would be great if TI rolled these changes in to the next tivaware release.  The limitation seems so unnecessary, not to mention unobvious unless one reads the UG (or source code). UARTPrintf is so much more useful than the UART putchar function.

  • This i wrote on Monday, but it's outdated now:

    I tried it again and I'm totally confused.

    For following cases nothing is attached to the UART4 pins and no pull-up resistor is activated.

    When I compile the project on my main PC I had problems last week.
    Today it works on my main PC.

    But when I compile the same project on my second PC, the same crashes happens.
    (The crash can be prevented if connecting the UART cable or enable the pull-up resistor.)

    I don't understand, why the same source code sometimes creates "good binaries" and sometimes "bad binaries".

    For the case that you want to reproduce to problem, I attached you the created binary files (*.bin and *.axf).
    Two files works fine (your TI PC and my main PC today) and two files have problems with non-connected UART4 pins (my main PC last week and my second PC).

    Amit Ashara said:

    Secondly when the code hangs, I am interested in knowing where it hangs? Or does it keep on changing all the time?

    ......... ?? .......

    Now, a few days later I added this:

    I was so confused and made further tests again and compared files.

    So I found out, that the reason for crashing is the missing high level on RX pin AND a configuration in the assember file startup_rvmdk.S.

    In the UART echo example (using UART 0), for UART0 the UARTIntHandler was enabled and for the unused UART4 the IntDefaultHandler.
    For this configuration there will be a crash when using UART 4 (without high input level).

    But it doesn't crash when I set the UARTIntHandler for the UART 4 port instead.

    How tricky ...

    uart_echo__bin_files.zip
  • Please excuse the intrusion

    But the above code does not work for me. Looking at the schematic I can see that the D port pins 4 and 5 are really connected to ICDI when modifying jumpers 4 and 5

    this code works for me (modifing a preexisten example)

    int main(void)
    {
    ui32SysClkFreq = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480), 120000000);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    GPIOPinConfigure(GPIO_PD4_U2RX );
    GPIOPinConfigure(GPIO_PD5_U2TX);
    GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);

    UARTConfigSetExpClk(UART2_BASE, ui32SysClkFreq, 115200,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    UARTCharPut(UART2_BASE, 'E');
    UARTCharPut(UART2_BASE, 'n');
    UARTCharPut(UART2_BASE, 't');
    UARTCharPut(UART2_BASE, 'e');
    UARTCharPut(UART2_BASE, 'r');
    UARTCharPut(UART2_BASE, ' ');
    UARTCharPut(UART2_BASE, 'T');
    UARTCharPut(UART2_BASE, 'e');
    UARTCharPut(UART2_BASE, 'x');
    UARTCharPut(UART2_BASE, 't');
    UARTCharPut(UART2_BASE, ':');
    UARTCharPut(UART2_BASE, ' ');

    while (1)
    {
    if (UARTCharsAvail(UART2_BASE)) UARTCharPut(UART2_BASE, UARTCharGet(UART2_BASE));
    }
    }

  • Hello Daniel

    Yes, that is correct.

    Regards
    Amit