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.

UART1 at PC4 and PC5

Other Parts Discussed in Thread: TM4C123GH6PGE

Hi

I have configured uart1 using the uart echo example code as given below. But I am getting data at terminal different from the data what I am sending. Could any one suggest me to solve this problem.

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/rom.h"
#include "grlib/grlib.h"
#include "drivers/cfal96x64x16.h"
#include "utils/uartstdio.h"
#include "driverlib/rom_map.h"


//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif

//*****************************************************************************
//
// Send a string to the UART.
//
//*****************************************************************************
void
UARTSend( unsigned char *pucBuffer, unsigned long ulCount)
{
    //
    // Loop while there are more characters to send.
    //
    while(ulCount--)
    {
        //
        // Write the next character to the UART.
        //
        ROM_UARTCharPutNonBlocking(UART1_BASE, *pucBuffer++);


    }
}

//*****************************************************************************
//
// The UART interrupt handler.
//
//*****************************************************************************
unsigned char buf[256] = {0};
unsigned char * pucBuffer = buf;
void
UARTIntHandler(void)
{
    unsigned long ulStatus;

    //UARTprintf("Inside Interrupt Handler\n");
    //
    // Get the interrrupt status.
    //
    ulStatus = ROM_UARTIntStatus(UART1_BASE, true);

    //
    // Clear the asserted interrupts.
    //
    ROM_UARTIntClear(UART1_BASE, ulStatus);
#if 0
    //
    // Loop while there are characters in the receive FIFO.
    //
    while(UARTCharsAvail(UART1_BASE))
        {
            //
            // Read the next character from the UART and write it back to the UART.
            //
        //UARTCharGet(UART0_BASE);
        //UARTCharPut( UART0_BASE,UARTCharGet(UART0_BASE));
        //ROM_UARTCharPutNonBlocking(UART0_BASE,
                                       //ROM_UARTCharGetNonBlocking(UART0_BASE);
        *pucBuffer++= UARTCharGetNonBlocking(UART0_BASE);
        //                               UARTCharPut( UART0_BASE,UARTCharGet(UART0_BASE));
        }
    UARTSend(&buf[0],strlen(buf));
    pucBuffer = buf;
    memset(buf,0x00,sizeof(buf));
#endif
}
//*****************************************************************************
//
// This example demonstrates how to send a string of data to the UART.
//
//*****************************************************************************
int
main(void)
{

    ROM_FPUEnable();
    ROM_FPULazyStackingEnable();
    //
    // Set the clocking to run directly from the crystal.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    // Enable the peripherals used by this example.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    ROM_GPIOPadConfigSet(GPIO_PORTC_BASE,GPIO_PIN_4 | GPIO_PIN_5,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_OD);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);

    ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4);
    ROM_GPIOPinConfigure(GPIO_PC4_U1RX);
    ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_5);
    ROM_GPIOPinConfigure(GPIO_PC5_U1TX);

   ROM_UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(),115200,
                               (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                UART_CONFIG_PAR_NONE));
    //
    // Enable processor interrupts.
    //
    ROM_IntMasterEnable();

 #if 1
    //
    // Enable the UART interrupt.
    //
    ROM_IntEnable(INT_UART1);
 #endif
    ROM_UARTIntEnable(UART1_BASE, UART_INT_RX | UART_INT_RT);

  //
  // Loop forever echoing data through the UART.
    while(1){
        UARTCharPut(UART1_BASE,'A');
      
}

Thank you.

Regards,

Anand

  • Devil in the detail - but you are close!  Examine this:

    while(UARTCharsAvail(UART1_BASE))
            {
                //
                // Read the next character from the UART and write it back to the UART.
                //
            //UARTCharGet(UART0_BASE);
            //UARTCharPut( UART0_BASE,UARTCharGet(UART0_BASE));
            //ROM_UARTCharPutNonBlocking(UART0_BASE,
                                           //ROM_UARTCharGetNonBlocking(UART0_BASE);
            *pucBuffer++= UARTCharGetNonBlocking(UART0_BASE);
            //                               UARTCharPut( UART0_BASE,UARTCharGet(UART0_BASE));

    Note that PC4/5 - assuming yours is an LX4F device (you did not identify) - may be config'ed as either UART1 or UART4.

    Too rapid "cut/paste" leads to such inconsistencies...

    You may do well to check the "real(inner) workings of, "GPIOPinTypeUART" - this may save your addition of, "GPIOPadConfigSet" - which should not place a UART pin into Open Drain mode (as you've done)...  (far easier for you to find/review the "non-ROM" version of these functions - your IDE should "find" via a "search w/in files")

  • Dear cb1_mobile,

    The portion which you are suspecting, I have included in conditional directive #if  0 which will not be executed. Even if I remove GPIOPadConfigSet(), I am unable to get the proper results.

    One more problem is while debugging UARTCharPut() is not updating the UART data register UARTDR. Please let me know what is the problem.

    Thank you.

    Regards,

    Anand

  • Mon ami - my belief continues - that even if the "changed code" is conditional - the "blend" of UARTs will not serve to your satisfaction.  Our group always strives for simplicity - and adding extra complexity - at this early stage while you're not succeeding - seems risky/unwise...

    Not all Stellaris may utilize, "GPIOPinConfigure()" - and you are silent as regards your chosen MCU.  You can "unlock" this mystery via SW-DRL-UG - keying upon that instruction w/in GPIO chapter.  Kindly ID - and confirm if that function is allowed...

    Best to start there - before further digging into code.   And kindly confirm that you are able to get proper results from one or more UARTs.

  • Dear cb1_mobile,

    Thanks for your reply.

    I confirmed that my device is belongs to Blizzard class. As per SW-DR L-UG "GPIOPinConfigure()" is supported for this class. I am getting garbage data instead of data what I am sending. The configuration look for me. This is my latest code below,

    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/fpu.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/rom.h"
    #include "grlib/grlib.h"
    #include "drivers/cfal96x64x16.h"
    #include "utils/uartstdio.h"
    #include "driverlib/rom_map.h"
    #include "lm4f232h5qd.h"
    //*****************************************************************************
    //
    //! \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.
    //
    //*****************************************************************************

    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, unsigned long ulLine)
    {
    }
    #endif

    //*****************************************************************************
    //
    // Send a string to the UART.
    //
    //*****************************************************************************
    void
    UARTSend( unsigned char *pucBuffer, unsigned long ulCount)
    {
        //
        // Loop while there are more characters to send.
        //
        while(ulCount--)
        {
            //
            // Write the next character to the UART.
            //
            ROM_UARTCharPutNonBlocking(UART1_BASE, *pucBuffer++);


        }
    }

    //*****************************************************************************
    //
    // The UART interrupt handler.
    //
    //*****************************************************************************
    unsigned char buf[256] = {0};
    unsigned char * pucBuffer = buf;
    void
    UARTIntHandler(void)
    {
        unsigned long ulStatus;

        //UARTprintf("Inside Interrupt Handler\n");
        //
        // Get the interrrupt status.
        //
        ulStatus = ROM_UARTIntStatus(UART1_BASE, true);

        //
        // Clear the asserted interrupts.
        //
        ROM_UARTIntClear(UART1_BASE, ulStatus);

    }
    //*****************************************************************************
    //
    // This example demonstrates how to send a string of data to the UART.
    //
    //*****************************************************************************
    int
    main(void)
    {
        unsigned long ulBaud = 0, ulConfig =0;
        ROM_FPUEnable();
        ROM_FPULazyStackingEnable();
        //
        // Set the clocking to run directly from the crystal.
        //
        ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                           SYSCTL_XTAL_16MHZ);

        // Enable the peripherals used by this example.
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);

        ROM_GPIOPinConfigure(GPIO_PC4_U1RX);
        ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4);
        ROM_GPIOPinConfigure(GPIO_PC5_U1TX);
        ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_5);


       ROM_UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(),115200,
                                   (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                                    UART_CONFIG_PAR_NONE));
       ROM_UARTEnable(UART1_BASE);
       ROM_UARTConfigGetExpClk(UART1_BASE, ROM_SysCtlClockGet(), &ulBaud,  &ulConfig);
       //
        // Enable processor interrupts.
       ROM_IntMasterEnable();



        while(1){
            while(ROM_UARTBusy(UART1_BASE));
            ROM_UARTCharPut(UART1_BASE,'B');

       }

    }

     

    Thank you

    Regads,

    Anand

  • Hi Anand,

       I assume you are using EK-LM4F232, since you put "lm4f232h5qd.h" in your includes. You intend to modify the uart_echo project to use UART 1 instead of UART 0. cb1 has already pointed out mistakes on your first code posting. But on your second code posting, you are missing out the part that you want to "echo back" characters at your UARTIntHandler(). Also, make sure that your PC hyperterminal has the same UART settings as your microcontroller.

    -Kel

  • Hi Markel,

    Thank you for your reply.

    In fact, My intention is to send data through  UART1 TX, I am not intended to echo any char read from the keyboard.  

  • Hi Markel or anyone who can help,

    I am trying to use UART1 (PC4 to receive & PC5 to transmit) instead of UART0 from the sample code uart_echo.c.

    I am using LM4F232.

    Below is the portion of the code but is not working (as in no transmission in PC5):

    *****************************************************************************

    //Enable the peripherals

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOPC);

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);

    //Set GPIO PC4 & PC5

    ROM_GPIOPinConfigure(GPIO_PC4_U1RX);

    ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4);

    ROM_GPIOPinConfigure(GPIO_PC4_U1TX);

    ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_5);

    ROM_IntMasterEnable();

    ***********************************************************************************

     

     

     

     

  • Hi John,

         Are you sure you have made all the necessary changes, including UARTIntHandler()? 

    -kel

  • And - as always - these boards provide USB to UART connection only upon the routed connections - ICDI chip to target MCU.  Unless you hack the board - and re-route to the newly chosen UART - suspect this may well be the issue.

    Unfortunate that this (essential) connection info is most always absent from such, "I changed the UART posts." 

    Should the MCU's UART ever connect to "real" RS232 source - line driver ICs must be in place to protect the MCU's UART_RX.

  • Dear all,

    I read the previous post and change the UART from 1 to 4 using PC4 & PC5.

    However, there's still no transmission. I am not doing echoing back but just probing through oscilloscope.

    Must I make any changes in the CCS start up file (assuming I used the copied startup_ccs.c from the uart_echo program)?

  • John Chan1 said:

    ROM_IntMasterEnable();

    While necessary - this function is insufficient to cause UARTx to fully/properly bring about its interrrupt.

    Examples abound showing the additional interrupt set-ups/configs. Two quickly, "come to mind:"

        IntEnable(INT_UARTx);
        UARTIntEnable(UARTx_BASE, UART_INT_RX | UART_INT_RT);

    You must further read - understand - and then apply to best match your requirements...

    And - might you experiment, "interrupt-free?"   So much simpler/faster - establishes that all other set-up/config is proper...   (i.e. StellarisWare\examples\peripherals\uart\uart_polled.c)  This method removes your being held "hostage" to the demands enforced by interrupts - assures that "all else" is proper.  After this victory - movement to interrupts has far better chance of success...

    BTW: you state UART4 - yet your code lists UART1.  (devil always in such detail)  Note that your LX4F (and ours) may employ either UART4 or UART1 via PC4/PC5 - but I have long been wary of PC4/PC5 as UART1 as all other UARTs are activated via, "selection matrix = 1" - UART1 is the only one requiring "selection matrix = 2."  Suggest you switch to UART4 as "safest" via PC4/PC5...  (when navigating a new "plain" - either silicon or Serengeti - best to, "stick close to the herd" - i.e. choose matrix = 1)

  • Thank you guys & cb1_mobile,

    UART4 is working.

  • Hi John,

    For the record, the prime suspect in your failure to get UART 1 fully functioning is that you did not map the C5 pin (you mapped the C4 pin twice):

    //Set GPIO PC4 & PC5

    ROM_GPIOPinConfigure(GPIO_PC4_U1RX);

    ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4);

    ROM_GPIOPinConfigure(GPIO_PC4_U1TX);

    ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_5);

    I suggest you give UART1 another try and report back - others may have been unjustly dissuaded by your experience...

    Regards,

    Dave

  • @ Source/Dave,

    Good eyes - however iirc - others have reported similar UART1 issue when employing PC4/PC5.

    As no pins are lost - and UART4 has now multiple records of success (across several LX4 & rebrand MCUs) - and as those "bound/determined" to use UART1 may employ PB0/PB1 to that end - bit difficult to justify such effort...

    Does not the fact that UART1 - via PC4/PC5 - stands as "sole" UART accessed via selection matrix 2 - cause any concern?

  • Hello,

    I am pleased to report that UART1 works in both TX and RX on my LM4F232 development board (refitted with a TM4C123GH6PGE).  I had been using UART6 via PD4 and PD5.  By changing the UART/GPIO/INTVEC entries, everything works normally through PC4 and PC5.  I cannot comment on similar functionality on the pre-brand part numbers;-)

    Regards,

    Dave

  • Good to know - although utility/benefit remains somewhat questionable.

    PC4/PC5 support UART4 as well - and on our 64 pin M4 - that is the sole appearance of UART4. 

    UART1 appears on both PB0/PB1 and PC4/PC5 - thus such use will cost the user a UART - which seems bit less than, "stellar."

  • A scenario to consider based on the TM4C123GH6PGE datasheet:

    Designer wants full-featured USB capability AND a UART with modem-flow control. 

    The USB0ID and USB0VBUS pins may only be accessed on PB0/PB1 (pins 97 & 98), respectively.  Since UART1 is the only one with modem-flow control capability, it must get mapped to PC4/PC5 to avoid conflict.

    I can attest that even with the Tiva PinMux tool, I took a fair bit of time pining-out an LQFP-64 to access all the peripherals I needed and to optimize trace routing.  It helped to have multiple choices.

    For the record, I'm not using USB OR modem-flow control...

     

    Regards,

    Dave

  • Well described - potential use of PB0/PB1 as USB - or UART1's unique ability to provide, "flow control" - as you list - very much dissolves earlier objection...  And - do much appreciate your making time/effort to so clearly report - thanks...

    The uniqueness of UART1's capability indeed may justify its use of a selection matrix value "outside" all other UARTs.

    This concerned as it is w/in the realm of possibility that such "uniqueness" may require a variation in critical MCU pre/post wafer tests, and/or may enforce different path lengths/geometry @ wafer level.    (we've noted such weakness in other maker's ARM MCUs - thus our desire to stay as much as possible w/in "normal/customary" bounds.  i.e. do not "court" potential trouble/complication...)

    So - suspect "method/madness" - your side and mine - are now fully detailed.