We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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
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?
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); }