This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

HelloWorld on LM3S6911

Hi there:

A newbie question... I was able to use the HelloWorld example that was provided with the Keil for ARM compiler. I am now trying to do the same thing, only this time, instead of using LPC2106 I am trying to use LM3S6911 from Luminary Micro. Unfortunately, the way to do this, from what I can tell, is very different.

This is my code so far:

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "utils/uartstdio.h"

//*****************************************************************************
//
//! \addtogroup example_list
//! <h1>Hello World (hello)</h1>
//!
//! A very simple ''hello world'' example.  It simply displays ''hello world''
//! on the UART and is a starting point for more complicated applications.
//!
//! UART0, connected to the FTDI virtual COM port and running at 115,200,
//! 8-N-1, is used to display messages from this application.
//
//*****************************************************************************

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



int main(void)
{

    //
    // Set the system clock to run at 8 MHz from the main oscillator.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC |
                   SYSCTL_XTAL_8MHZ | SYSCTL_OSC_MAIN);

    //
    // Enable the peripherals used by this example.
    //
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        //SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);


    //
    // UART0: Set GPIO A0 and A1 as UART.
    //
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);


    //
    // Initialize UART0 as a console for text I/O.
    //
    UARTStdioInit(0);

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

        UARTwrite("test",4);



    //
    // Print hello message to user.
    //
        while(1)
        {
            UARTprintf( "\nHello, world!\n" );
                //printf("change!\n");
        }

}

Now, this compiles, links and executes without any error or warning, but I don't have any IO being shown. I am using the simulator (that is all I have for now).

I tried to SLOG >> out.txt, opened up all the UART windows, but the data does not seem to go anywhere, yet when I am executing under the control of the debugger, it seems to work fine.

I have several questions, many of which could be newbies:

1- I noticed that I am not including lm3s6911.h anywhere in there, yet it compiles fine. The defines in that header do not seem to be used anywhere. Is this normal?

2- Could it be that the simulator cannot do a HelloWorld program but the board could?

3- I am using all the latest StellarisWare includes and libraries.

If someone out there knows something about this and why I am failing, please let me know! I really gave it my best shot, and keep failing.

Steve

Parents
  • I am starting on a lm3s811 as well, and one thing I learned today is that all peripherals are turned off upon reset and you have to pipe clock to them to turn them through the rcgc registers.

    because of that it took me a while to get a simple blinky to run.

    I don't use Luminary's library but I would imagine that you need to that before using uart0. from your code (with no actual knowledge about its functionality), you seem to have commented out the enable uart0 call. so maybe you will check into that?

Reply
  • I am starting on a lm3s811 as well, and one thing I learned today is that all peripherals are turned off upon reset and you have to pipe clock to them to turn them through the rcgc registers.

    because of that it took me a while to get a simple blinky to run.

    I don't use Luminary's library but I would imagine that you need to that before using uart0. from your code (with no actual knowledge about its functionality), you seem to have commented out the enable uart0 call. so maybe you will check into that?

Children
  • Thank you Ashley, Torsten and Andy... actually, this is what I did:

    1- I tried different examples in the StellarisWare.
    2- The LM3S6965 uart_echo worked out fine
    3- I gradually modified it to suit my needs.

    So, I am not using the stdio from utils at all. I actually modified these so as to use the low-level UARTCharPut(UART0_BASE, pcBuf[uIdx]) in a for loop to print pcBuf.

    And, I am using the following to initialize everything:

    //
        // Set the clocking to run directly from the crystal.
        //
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_8MHZ);
    
        //
        // Enable the peripherals used by this example.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        //
        // Set GPIO A0 and A1 as UART pins.
        //
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
        //
        // Configure the UART for 115,200, 8-N-1 operation.
        //
        UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
                            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                             UART_CONFIG_PAR_NONE));
    

    I found that sometimes the serial data isn't flushed completely, so I am using a few escapes at the end of my prints to flush out everything completely.

    Might not be perfect, but it works.

  • Hi,

    after knowing most of the LMI bugs (*smile*) the core is more or less easy to programm. Just take the Datasheet and programm through the regs.
    The LMI library is good to have a look how they do it, I prefer writing the init code by myself (smaller, quicker).

    1. make sure your pll is running on a clock freq. you know :-) (*)
    2. switch on the peripheral clock for the peripheral you want to use
    3. switch on or off the alternate function if the peripheral use a shared pin (i.e. GPIO / UART).
    4. Go to page <peripheral> in the programmming manual and go through the registers, making the changes you need. Registers you do not need you can leave out. (Defaults are often ok).
    5. last step in registers: enable the peripheral

    .
    (*) Be very careful in PLL settings, because incorrect settings can totally screw up the controller (you can put the core to garbage sometimes...). Never write a ZERO into the clock divider reg, bypass is always a mux-reg.

    .
    A few Hints when starting:

    - put a 1s for(...) __nop(); loop into your main before init starts. This will help you to break into the core when programming incorrect pll settings or you have overwritten the JTAG port

    - add breakpoints to the fault handlers, Hard Fault is often saying that an uninitialized (clock off or clock not ready, too short delay after clk enable) peripheral is accessed

    - on higher level, if you have a UART running (or ITM) add functions with a printf and an endless loop for the fault handlers (like Bluescreens)

    - download the LMI unlock tool, because the Controller likes to lock itselv while programming. This is not always the user's fault, just try to unlock the controller and reprogramm it again with the same code.

    - CMSIS also provides proper init code which you should use, then you do not need the LMI driverLib. It also contains some helper functions for the NVIC peripheral which is a bit complex.

  • Init Code for UART, with Interrupt on every RC char.

    CLK must be defined to the Core Clock frequency.
    UART0_INTBRD = CLK / (16 * 57600);

    
    void UARTIntHandler(void)
    {
        unsigned long status;
    
        // Get the interrrupt status.
        status = UART0_MIS;
    
         // Clear the asserted interrupts.
            UART0_ICR = status;
    
        // See if the transmit interrupt was asserted.
        //if(status & UART_INT_TX)
        //{
        //  ;
        //}
    
            if(status & UART_INT_RX)
        {
                    // read value and fill the software-buffer
                    rxBuffer_putchar(UART0_DATA & 0xff);
    
            }
    }
    
    
    /**
    * \brief Initializes the UART0 \n
    * 57600 8N1
    */
    
    int uart0_init(int baud)
    {
            unsigned int uart_frac=0;
    
            // disable UART
            bit_off(UART0_CTRL, 8);         // disable RX
            bit_off(UART0_CTRL, 9);         // disable TX
            bit_off(UART0_CTRL, 0);         // disable UART
    
            // set PORTA to be UART0
        bit_on(PORTA_AFSEL, 0);             // alternate function to pin1
            bit_on(PORTA_AFSEL, 1);         // alternate function to pin2
    
        // Set the pad(s) for standard push-pull operation.
            bit_on(PORTA_STRENGTH2, 0);
            bit_on(PORTA_STRENGTH2, 1);
            bit_on(PORTA_DEN, 0);
            bit_on(PORTA_DEN, 1);
    
            // set the baudrate
            UART0_INTBRD = CLK / (16 * 57600);
        uart_frac = CLK % (16 * 57600);
        UART0_FRAC = ((((2 * uart_frac * 4) / 57600) + 1) / 2);
    
            // config the UART0
            bit_off(UART0_LCRH, 0);         // no break
            bit_off(UART0_LCRH, 1);         // no parity
            bit_off(UART0_LCRH, 2);         // no parity
            bit_off(UART0_LCRH, 3);         // one stop
            bit_off(UART0_LCRH, 4);         // no FIFO
            bit_on(UART0_LCRH, 5);          // 8 Data Bits
            bit_on(UART0_LCRH, 6);          // 8 Data Bits
            bit_off(UART0_LCRH, 7);         // no parity stick
    
            // Clear the Flags
            UART0_FLAGR = 0x00;
    
            //UARTEnable(UART0_BASE);
            bit_on(UART0_CTRL, 8);          // enable RX
            bit_on(UART0_CTRL, 9);          // enable TX
            bit_on(UART0_CTRL, 0);          // enable UART
    
        // Enable the UART interrupt in NVIC.
            bit_on(N_VIC_EN0, (INT_UART0 - INT_GPIOA));
    
            // Enable the UART interrupt
            bit_on(UART0_INTM, 4);
    
            return(SHELL_RET_NORMAL);
    }
    
    
    
    /**
    * retargets the printf-command
    */
    
    int fputc(int ch, FILE *f)
    {
            if ((char) ch == '\n')
            {
                    while(UART0_FLAGR & (1<<3));
                    UART0_DATA = '\r';
            }
    
            while(UART0_FLAGR & (1<<3));
            UART0_DATA = ch;
    
            return(ch);
    }