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.

Ek-LM4F120XL UART_1 Configuration Issue

Hi all,

I am a graduate student experimenting with the Stellaris Cortex M4 Launchpad Ek-LM4F120XL on behalf of my advisor, who would like to use this board for his embedded systems class. I am quite new to the Cortex M4 world, so this could potentially be a noob question. I'm trying to use an external USB serial converter to connect to this dev board, so that we can dedicate the USB to the ICDI debug hardware, and then use the external an USB serial converter for UART printf statements. This facilitates concurrent debug and serial output, which is not possible with the on board hardware. This is a very useful for class. 

My starting point for this project was the hello microvision project found in the Stellarisware folder for the Ek-LM4F120XL board. I modified this code to print continuously, and successfully tested the code using UART0. To use UART1, I connected a USB to serial converter to PB0 and PB1 for UART1 RX/TX, as well as a ground connection to my USB serial converter. 

I then changed the following  code in hello.c:::

// ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// ROM_GPIOPinConfigure(GPIO_PA0_U0RX );
// ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
// ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
// UARTStdioInit(0);
//

I modified the above code to the following, to confgure the correct GPIO pins for UART1:::::

//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
//ROM_GPIOPinConfigure(GPIO_PB0_U1RX);
//ROM_GPIOPinConfigure(GPIO_PB1_U1TX);
//ROM_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//UARTStdioInit(1);

When I look at the corresponding serial output on my PC terminal, characters are displayed, but they essentially look like garbage, as if the Baud rate is incorrect. I checked the uartstdio.c, and according to this, the Baud rate should be 115200, which is what I selected in the terminal program. I also changed it to other baud rates within the terminal program, and it still doesn't change the serial output to anything recognizable.I also used the UARTStdioInitExpClk() function to explicitly set the baud rate. This worked for the UART0 case, but produced the same incorrect results for the UART1 connection. Any suggestions? Thanks in advance!

  • Appears you have failed to, "ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);"  Code list you show is necessary - but not sufficient to properly set-up/config UART1.   ARM MCUs are quite demanding as regards to all required clocks being enabled.... (and of course - all comment marks must depart)

    You - among many others - have fallen into the trap caused by Port A's "automatic default" into UART mode - thus this function is hidden - copy/paste of UART0 not proper for any other UART!  (not the best example design - imho...)

    Further - suggest that you consider a UART - Serial Enabled, multi-row Lcd as alternative to external USB-Serial converter.  In this manner - students gain even further, "real-world" tech usage skills - likely more helpful in securing tech employment...  (USB to Uart converter - not so much...)

    One last point - don't know how much longer that particular board will remain available.  (some part re-branding in play - this vendor)  MCU on your board is very stripped-down version - believe that a very similar, yet newer board has more intense MCU (w/PWM Generators) at similar cost.  Alas - as this forum reveals - some "hiccup" in SW migration between these two MCUs - even though "rebrand/improvement" is little beyond "paint job..."

  • Thanks for your help! So I added the code you suggested, and I am still getting the same results. I am wondering now if it is some issue with the uartstdio.c file in the hello project, perhaps something is hardcoded in this file specifically for UART0 that needs to be configured differently for UART1?

  • Max Bezold said:
    perhaps something is hardcoded in this file specifically for UART0

    Looking @ uartstdio.c - in some detail - is exactly what I'd do.  Look especially to see if:

    ROM_UARTConfigSetExpClk(UART1_BASE, ...) is included w/in uartstdio.c.  (this is required by the non - uartstdio.c UART function)

    Or switch to the standard, "ROM_UARTCharPut(UART1_BASE, '\r');" and similar Get functions...  These are well detailed w/in SW-DRL-UGxxxx - should become your/students' constant companion.

    Your very brief code-snippet does not reveal use of UART Interrupt - if used - this must change from UART0 to UART1 and be so reflected w/in your "start-up" file.  Have you done this?

    Our group always remains suspicious of any/all "add-ons" - in your case that's USB converter.  How have you confirmed that it is good? 

    Further - by transmitting a series of 0x55 - it should be easy for you to observe the alternating (1-0) bit pattern on a scope - and easily measure the bit width along with the formation of the UART's output byte.  The more information gleaned - faster/easier the solution...

    And indeed - the necessity to clock UART1 (or UARTn) always remains...  (and is good practice even for those Ports which default (even by accident) into your chosen mode)

  • Considering further - while you report checking/attempting multiple baud-rate settings on the inter-connected PC - did you also check/insure that data width (8 bits), Start, Stop, Parity all matched (PC & MCU) - and that neither SW (Xon/Xoff) nor HW "handshakes" were expected - by the PC?

    Upon very quick scan of uartstdio.c - my sense is that Uarts 0-2 are supported.

    If you're unlucky - and USB-Serial converter was economy version - always best to dial down baud-rate to 9600 - and repeat your tests.

    It must be that a custom "cable" was created - so that UART1 signals could be harvested (MCU board) - then routed to (assumed) 9 pin Serial "D" style connector - resident most such converters.  Any time/attention given to the thorough verification of this interconnect?

    Really - solution at this point "cries out" for simple scope measure of suggested 0x55 Uart byte (alternating 1-0 bit pattern).

    Dawns further - 4 lunchpad MCU pins have "unusual" (to be kind) forced interconnect.  Board schematic reveals - insure that your UART1 pins were not so honored...

  • The UART1 Module does have hardware handshaking/flow control etc, upon further review. Connecting to a scope showed the expected 0-3.3 Volt shifts, looks a lot like UART! I've tried this with a couple of different USB to Serial Converters, and using Putty as a terminal program. Parity/Start/Stop all matched up. 

    Not knowing much about 'flow control', and not having the knowledge (at the time) or inclination to map out the HW handshake pins, I decide to switch over to UART2 (which doesn't have handshaking/flow control etc), I've included my configuration code, just for fun. This didn't work, and I couldn't see any output on the scope. 

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    ROM_GPIOPinConfigure(GPIO_PD6_U2RX);
    ROM_GPIOPinConfigure(GPIO_PD7_U2TX);
    ROM_GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    UARTStdioInit(2);

    I've since tried going back to UART1, and disabling the flow control. This doesn't seem to be permitted using the ROM_API functions, and so I attempted a workaround by writing to the register directly. Keil now keeps crashing, I'm luck if I can flash code 1 out of every 10 times I try. Think I am going to revisit this tomorrow. I've spent sometime reviewing a lot of the documentation, so I have a better handle on how the hardware works. Checking the interconnects seems like a logical next step, but I'm still puzzled by the UART2 configuration. No output on the scope pretty much takes everything out out of the equation except software on the MCU and perhaps the possibility of screwy boards. 

  • Your "instinct" for choosing different Ports - and Pins - not too good.  Attempt to use PD7 - as explained in MCU manual - is doomed w/out first "unlocking" - as PD7 is one of two pins defaulting into NMI Status.

    Part of the equation you've missed - is more thorough review of MCU manual - focused especially upon the Ports/Pins you've chosen.  While you could not have been expected to "know" this NMI default condition existed - always wise to review descriptions of Ports/Pins - you've chosen.

    When you can find the time to review PD7 - and its unlock procedure - Serial transfer may commence...

    Writing directly to registers - as you've described - demands even further/harder MCU manual study - I'd stay far away @ this your early stage.  Repurpose PD7 - review earlier working UART0 code - modify into UART2 format - and try that. (perhaps prior to another week's passage...)

  • Thanks for your help. I hadn't had a chance to touch this project this week due to other demands on my schedule. When I picked it back up today, it became apparent to me that it was time to thoroughly read the manual, which I have started to do. As far as my 'instinct' or lack thereof goes, the PD7 was a quick attempt at fixing it. I realize that it might seem idiotic/reckless to someone with more familiarity with the MCU, but at the time it seemed worth a shot, as the code change and verification to approximately 5 minutes. And trying it teased out this NMI issue, thanks for that, so I think it was worth it. I think after some more experimentation and manual reading, my instincts for this specific type of TI Cortex processor should be pretty good. 

    The advice about the external serial converters is much appreciated. As a classroom tool, that makes a lot of sense. The use of terminal programs and serial converters by folks in our lab has a lot to do with the ability to log i/o, as well as a lack of LCDs appropriate to the old development boards we previously used. The booster packs look like a good option that I will evaluate. 

    Rather than messing with unlocking the NMI for PD7, I might look at other pins. I'll do a more thorough look thru the manual before I do that. 

    Thanks again, you've given me plenty to think about!

  • No doubt you're making progress - these devices are complex - many (surely this reporter) have stumbled during start-up.  (key clients "pushed us" from comfort zone of Philips enhanced 8051 (and all our code + development systems investment) - into ARM about 10 years past.)  Did you know that every commercial (i.e. "real" cell phone) has employed ARM - not a single Intel MCU.  (perhaps w/latest Intel releases - such may change...)

    Have you considered the design/development of small pcb - which includes an RS232 level converter and/or UART to USB chip?  (FTDI, Cypress etc.)  This will greatly enhance your UART to "outside world" efforts - and should prove lower cost than commercial devices.  We like this small, external pcb idea as you may further include I2C EEProm (ease I2C test/evaluation) and several small pots (likewise ease ADC test...)  Believe such multi-purpose boards - covering these vital basics - will prove a very sound investment - enable students to focus upon SW - not unseemly interconnects...

    Trap you've encountered sure to beckon (and well accommodate) multitude of students - not thrilled w/1200+ pg. MCU manual.  Suggest that small warning card - alerting to "unpleasant" results via use of PF0, PD7 and PC0-PC3 (das ist verboten! JTAG!) be placed prominently (and indelibly) w/each every Stellaris/rebrand board!  (we regularly engage student interns - these cards have saved us hundreds of lost hours/dollars...)

     

  • So I finally was able to get back to this project yesterday, and the PD7 and NMI unlocking totally did the trick (after I figured out how to do it, ha.) I'm attaching my working code in response, as to help others. I really like your suggestions about fabricating the board, this is definitely an option for us. We currently develop dev boards for early stages of projects, and we always put on a USB-UART bridge (CP2110 from SiLabs) to make this part fairly seamless. I believe the plan is to procure launchpads for student use, so I think that will help greatly with reducing the amount of time required chasing down interconnect issues. 

    I think some cards in the lab are a good idea as well. I made some obvious mistakes in the process (I forgot to enable the peripheral leading to a repeated hardware fault whenever I tried to write to the Port D registers. After doing a forum search, I learned I'm hardly the first to make that mistake. Good candidate for a card suggestion.)

    I was interested to hear that you transitioned from an enhanced 8051. Most of my experience in grad school up to now has been with Silicon Labs 8051. It's hard to leave that comfort zone. In particular, I really didn't like the Stellaris API method for configuring the peripherals. That level of abstraction really irked me at first. After spending quite a bit of time reading through the data sheet, spending time the architecture, as well as gaining quite a bit of comfort with the StellarisWare API, it's not all that intimidating to me anymore. I'm definitely interested in continuing to learn more about these processors, it will certainly make me more marketable professionally, as you say, the deployment of ARMs are very widespread. 

    Again, thank you so much for your help! It was truly invaluable!

    ///////////////////////////CODE SNIPPET TO FOLLOW//////////////////////////////////////////////////////////////

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //If this API call isn't made, a hardware fault occurs

    //when we attempt to read/write registers belonging to this
    //port. It enables and routes a clock, etc.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    //Configure the alternate function of GPIO pin

    ROM_GPIOPinConfigure(GPIO_PD7_U2TX);


    //Below is an example of how to modify hardware registers on TI Cortex MCUs
    //Hardware registers are mapped to addresses on the 32 bit memory space.
    //These addresses are given in the TI Manual as a base address and an offset.

    //THIS IS THE CODE WE WILL DISCUSS HERE, IT WILL BE EXECUTED LATER:

    //HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;

    //HWREG() is a macro defined in hw_types.h.
    //It formats a memory address, given as a 32 bit hex value, as a 32 bit unsigned
    //volatile pointer that Keil MDK recognizes as a memory address
    //
    //Note the way the register address is used in the macro. It is a base
    //address plus an offset. This is how they are defined in the TI manual.
    //Every port has a base address, and specific registers for that port are
    //located at some memory offset from this base address.

    //From the TI Manual Stellaris Lm4F120H5QR Microcontrooler manual,
    //Description of the GPIOLOCK register (pp 643)

    // GPIO Lock (GPIOLOCK)
    // GPIO Port A (APB) base: 0x4000.4000
    // GPIO Port A (AHB) base: 0x4005.8000
    // GPIO Port B (APB) base: 0x4000.5000
    // GPIO Port B (AHB) base: 0x4005.9000
    // GPIO Port C (APB) base: 0x4000.6000
    // GPIO Port C (AHB) base: 0x4005.A000
    // GPIO Port D (APB) base: 0x4000.7000
    // GPIO Port D (AHB) base: 0x4005.B000
    // GPIO Port E (APB) base: 0x4002.4000
    // GPIO Port E (AHB) base: 0x4005.C000
    // GPIO Port F (APB) base: 0x4002.5000
    // GPIO Port F (AHB) base: 0x4005.D000
    // Offset 0x520


    //The base address (GPIO_PORTD_BASE) and the offset (GPIO_O_LOCK)
    // added togteher by the HWREG macro. These are defined in
    //hw_memmap.h and hw_gpio.h, respectively.

    //If you trace them back to the header file, you will find that

    //#define GPIO_PORTD_BASE 0x40007000 // GPIO Port D
    //#define GPIO_O_LOCK 0x00000520 // GPIO Lock

    //Compare this with the figure from the manual above, and you will
    //see that they are consistent.

    //Unlock access to the commit register for Port D, so that we can
    //configure Port Pin PD7 as UART module 2 TX line.
    //This is a write to GPIOLOCK register for Port D,
    //UART2 Tx is mapped out to PD7. PD7 is by default also an NMI input port,
    //in order to configure it as UART port, we need to write to two
    //different HW flash registers. The first is GPIOLOCK @ 0x4000.7000 offset
    //0x01, to unlock the register by writing 0x4C4F434B to it.
    //See Stellaris LM4f120H5QR MCU manual pp. 643-644 for more info.

    //After GPIOLOCK is modified, we are then able to set bits 0:7
    //of hardware register GPIOCR to make the configuration registers
    // modifiable.

    HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;

    //Set the commit register for PD7 to allow changing the function
    HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0x80;

    //Enable the alternate function for PD7 (U2TX)
    HWREG(GPIO_PORTD_BASE + GPIO_O_AFSEL) |= 0x80;


    // Turn on the digital enable for PD7
    HWREG(GPIO_PORTD_BASE + GPIO_O_DEN) |= 0x80;


    // Relock the commit register, to prevent further changes
    HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = 0;


    //This function sets the Baudrate, clock source, parity, start and
    //stop bits of UART module 2
    UARTStdioInit(2);

  • Good for you - glad you persisted - now, "Up/Running!"  Your history - discoveries - new understanding - now will prove of immense benefit to your students.

    Some (one hopes useful) follow-on comments:

    a) CP2110 from SiLabs - that may be wise choice - rather than more popular FTDI chip - which may see issues w/FTDI devices upon past Stellaris.

    b) Powering launchpad via USB smt connector.  (we were gifted several - first chip so crippled (no PWM Gen) - little interest)  Beware that at least on "1st incarnation" these boards may have had issue w/less than ideal reflow soldering - and forum reports of USB connector and/or pcb traces, "lifting!"  Never good - especially so in student environment.  And - we never/ever recommend the use of smt connector for extended "make/break" power connections.  (asking for trouble)  You may consider some superior means to power/de-power.

    c) First, "enable the peripherals" - you're far from alone - all w/in our group (especially moi) guilty this charge - more than once!  However - sad to say - hallowed "SW-DRL-UGxxxx is unwilling, "co-conspirator."  (Say What?)  That guide - of course unable to anticipate all possible ports/pins in play - is silent as regards the mandatory prior enabling of "targeted/mated" peripherals!  (this w/in each/every "Code Example" section @ chapter end)   My belief - SW-DRL-UG should add, "Insure that any/all peripherals referenced by these listed functions have first been identified and enabled!"  Examples provided appear most basic - and limited - not too hard for you to have students expand - boosting their understanding in the process...  (then print - or save these new/improved versions - for repeated, ready reference) 

    d) Matrix keypad and multiple Leds always aid GPIO exploration. 

    e) Multiple small yet robust potentiometers best enable ADC investigation.  (avoid MCU temp sense - problemmatic imho)

    f) We find ribbon, IDC style cables - w/strain relief - best able to withstand student use/abuse.  Only these should be used (imho) to serve as MCU board to "accessory/function generation board" interconnect. 

    g) Insure that proper/appropriate power is transferred from MCU board to accessory board.  *** Due to smt connector issue on MCU board - you may consider powering your MCU board via this interconnect cable - with a proper power connector resident upon the accessory board.

    Congrats on your persistence and success - good luck...

  • Hello Max,  one of our forum members brought it to my attention that you are evaluating the launchpad for a course at your university. That is great to hear.  I wanted to make sure you are aware of the TI University Program and the teaching materials that are availble for the Tiva Launchpad in particular.  Please see Larissa's most recent blog post regarding Dr Jon Valvano's teaching materials and textbook series.  Feel free to register for the university program via the regional link on our home page and let us know where you are teaching - it would be great to hear from you.

    best regards,
    Cathy Wicks