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 using alternate pins on Stellaris Launchpad

Hello,

I've hit a wall trying to modify the UART_echo demo project to work using UART1 on pins PC4 and PC5. Using these pins with the code below I get no activity on PC5 and no response on PC4 (using logic analyzer and oscilloscope). When I use pins PB0 and PB1 as UART1 the demo works perfectly. I'm hoping I have missed a configuration somewhere, but checking the registers GPIO_PCTL and GPIO_AFSEL against the datasheet the configuration looks good. My code below is for trying to use PC4 & PC5. Below that is the change for making it work on PB0 & PB1. Everything else remains constant. UART1 seems to be a popular topic, but I haven't seen one with this problem. Can someone please show me what I am missing?

Thank you for your time. 


#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/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.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

//*****************************************************************************
//
// The UART interrupt handler.
//
//*****************************************************************************
void
UARTIntHandler(void)
{
unsigned long ulStatus;

//
// Get the interrrupt status.
//
ulStatus = UARTIntStatus(UART1_BASE, true);

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

//
// Loop while there are characters in the receive FIFO.
//
while(ROM_UARTCharsAvail(UART1_BASE))
{
//
// Read the next character from the UART and write it back to the UART.
//
ROM_UARTCharPutNonBlocking(UART1_BASE,
ROM_UARTCharGetNonBlocking(UART1_BASE));

//
// Blink the LED to show a character transfer is occuring.
//
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

//
// Delay for 1 millisecond. Each SysCtlDelay is about 3 clocks.
//
SysCtlDelay(SysCtlClockGet() / (1000 * 3));

//
// Turn off the LED
//
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);

}
}

//*****************************************************************************
//
// Send a string to the UART.
//
//*****************************************************************************
void
UARTSend(const 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++);
}
}

//*****************************************************************************
//
// This example demonstrates how to send a string of data to the UART.
//
//*****************************************************************************
int
main(void)
{
//
// Enable lazy stacking for interrupt handlers. This allows floating-point
// instructions to be used within interrupt handlers, but at the expense of
// extra stack usage.
//
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 GPIO port that is used for the on-board LED.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

//
// Enable the GPIO pins for the LED (PF2).
//
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);

//
// Enable the peripherals used by this example.
//
SysCtlPeripheralDisable(SYSCTL_PERIPH_UART0);

//
// Enable Peripheral Clocks
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

//
// Enable port PC4 for UART1 U1RX
//
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_4);
GPIOPinConfigure(GPIO_PC4_U1RX);

//
// Enable port PC5 for UART1 U1TX
//
GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_5);
GPIOPinConfigure(GPIO_PC5_U1TX);
//
// Configure the UART for 115,200, 8-N-1 operation.
//
ROM_UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 115200,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));

//
// Enable the UART interrupt.
//
IntEnable(INT_UART1);
UARTIntDisable(UART1_BASE,UART_INT_TX);
UARTIntEnable(UART1_BASE, UART_INT_RX | UART_INT_RT);

//
// Enable processor interrupts.
//
IntMasterEnable();

//
// Prompt for text to be entered.
//
UARTSend((unsigned char *)"\033[2JEnter text: ", 16);

//
// Loop forever echoing data through the UART.
//
while(1)
{
}
}


//
// Enable Peripheral Clocks
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

//
// Enable port PB0 for UART1 U1RX
//
GPIOPinConfigure(GPIO_PB0_U1RX);
GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0);

//
// Enable port PB1 for UART1 U1TX
//
GPIOPinConfigure(GPIO_PB1_U1TX);
GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_1);

  • Did you remember to provide for UART1's interrupt handler - w/in your start-up file?  Your name for the handler is too broad (fails to specify UartX) for our taste.

     IntDefaultHandler,                      // UART0 Rx and Tx
     IntDefaultHandler,                      // UART1 Rx and Tx

  • Thank you for your reply.

    I did. My interrupt handler is:

    UARTIntHandler, // UART0 Rx and Tx
    UARTIntHandler, // UART1 Rx and Tx

    I know it's generic. In my actual project it's more specific. This is just the demo project, without the rest of my code to add as noise when reading.

    The part that's really got me hung up is that the code works when UART1 is on PB0 and PB1, but not when using PC4 and PC5. I thought  it could be a case of pins being locked (read about that for other pins somewhere), but I haven't found any information on that for these pins. They don't have another default function, so they can't be locked.

     

  • This is strange - but do thank you (& appreciate) the quickness/depth of your reply.

    Now we have another 64 pin LX4F - and I confirmed your "desire" to employ PC4/5 as Uart1.

    But - looking anew - I see that PC4/5 more "normally" are employed as Uart4!   (most Uarts "belong" in selection column 1 - Uart1 in this case - is w/in column 2!)

    Looking still further - I find NO other Uarts outside of column 1 - thus leaning toward belief that Uart1 listing for PC4/5 is mistaken...

    Quickest/easiest "fix" is for you to substitute Uart4 for Uart1 - almost guarantee (standard 30 day, 30 foot)  - that's instant - magical mystery cure!  (later we can "fix" Uart1 - but try this first...)

  • Thank you, I will try that. The reason I didn't use UART4 at first was because UARTStdioInit() from the demo code cannot use UART4. I did not want to modify uartstdio.c in case I made a mistake, and by keeping it unmodified can use it as a working reference for help.

    By "belong" in selection column 1, is there some sort of preference to using the functions allocated in lower numbered selections? I thought each selection was equivalent, minus the fact that if I don't specify a pin for a function it will default to the pin with the lowest GPIOPCTL value.

  • The fact that Uart1 "stands alone" causes concern.  And you have had difficulty - yet appear (my quick scan) to have done most correctly.

    Your logic for seeking Uart1 is justifiable - but in light of my findings - I'd switch to aforementioned Uart4.

    Standard StellarisWare "normal/customary" UART functions exist in multiple - and place no such restriction (forbidding) upon Uart4...

  • UART4 works perfectly on PC4 and PC5.

    I have also found my problem. I just thought to try against another Stellaris Launchpad, and on this new unit both UART1 and UART4 work perfectly on PC4 and PC5. I don't understand it, it's a very specific failure. I would think the entire GPIO or the entire UART module would fail, not just this one combination of them (UART1 with GPIO PC4 and PC5). I did not think that this would have been a hardware issue, but it seems to be.

    Thank you for your help. I will mark your reply suggesting the use of UART4 as the verified answer.

  • Thank you, Sir - much appreciated.  And yet another bout of "strangeness." 

    That said - is it possible that UART1 did not "make it" properly to board's edge connector?  Multiple reports of header pins being "non standard" (on your board) - causing loss of I/O integrity.

    Suppose - for "real" understanding - focused examination of the GPIO Port C Controlling Registers - just prior to and just after "Pin Config" and "Pin Type" will confirm the correctness of PC4/5 Uart "steering."

  • I'm somewhat relieved that things like this have been seem before. It means I'm not doing anything too wrong. I will check continuity on my board when I get back to my lab.

    I did look at the GPIO_AFSEL and GPIO_PCTL, and the UART control registers. They looked to be configuring properly, with the exception that UART0 was not resetting to 0x0- state. That's why I put in the UART0 disable (I'm sorry I don't have the exact resisters and line from memory. I focused more on the GPIO registers since I thought my problem was there). I will take a much closer investigation of that board and it's registers tonight. For now, I have just marked it as "bad" and removed it from the testing pool.

  • I know these are all 'simple' projects for a complex micro, but I'm at my wits end...  I have three Tiva (TM) C Series LaunchPads.  For the past two days, I have been trying to get something other than UART0 to work with Tera Term.

    I used the code above by magyarm (thank you!), to implement UART1 but reverted to PB0/PB1 as I am at least getting something out of it.  Once the header pins are hooked to my PC through a RS232 DB9 to USB, this is the best I can get out of the code:

    I'm using the GND pin on J2, and PB0 and PB1 on J1.  What am I missing?  I can upload my code, but it is identical to that posted above.

    Thank you.