Category Archives: ARM microcontrollers

Abour ARM7, LPC2000, ADuC microcontrollers.

32 bit microcontrollers from ATMEL with ARM7 core

Somehow I’ve been sticked to NXP LPC2xxx series microcontrollers and left other brands behind. There are many major manufacturers of ARM microcontrollers. One of them that is worth to pay attention is Atmel with its AT91SAM7 (Smart ARM7) series. SAM7 series of microcontrollers have built in Flash memory and data memory as well. Core is powered with 1.8V while peripherals need 3.3V. Core voltage is converted inside the chip so you don’t have to bother about this and only apply stabile 3.3V voltage. SAM7 microcontrollers are based on ARM7 core so they have very good performance characteristics. SAM7 microcontrollers differ from other brands with their ability to access memory directly (DMA), so each microcontroller peripheral have distinct two channel controller. LPC series only have AMBA bridge between AHB and LHB.

Main characteristics of AT91SAM7 series:

  • very good ratio between performance and poer consumption;

  • performance up to 60MIPS;

  • ARM/THUM command support;

  • 32 byte data bus;

  • programmable external 8/16/32 byte data bus;

  • multiple channel DMA;

  • SPI interface – four CS(Chip Select) pins;

  • TWI interface;

  • Built-in RC generator and PLL;

  • Expanded clock generator and power consumption control;

  • 4 external clock sources;

  • Interrupt controller with extended functions;

  • Debugging interface;

  • RTC with distinct interrupts;

  • 2 or 3 32bit timer/counters;

  • Watch Dog Timer (WDT);

  • Power supply from 3.0V to 3.6V;

  • 5V tolerant I/O;

  • power down modes;

  • built in Power-On reset and Brown-Out Detector;

  • Built in boot-loader for loading Flash via UART or USB port;

  • Memory contents protection from reading.

Chips have built in boot-loader that allow downloading firmware to Flash memory via UART or USB. So you can program memory by using simple cable.

For all current list of AT91SAM visit Atmel’s site.

In order to upload program to microcontroller there is flash utility called SAM-BA used which can be found in AT91SAM community site www.at91.com.

New ARM7 Microcontrollers from NXP with LCD support

New microcontroller LPC2478 from NXP company is based on ARM7 core with built in Flash memory and have built in LCD interface. LPC2470 has no Flash memory.

LPC24 series have two high speed buses AHB to ensure independent work of peripherals like LCD, 10/100 Ethernet, USB and two channels of CAN. LPC24xx have reasonable low prices that allow these MCU to be used in industries like various gadgets, home appliances, medical equipment where LCD is required and also connection to the internet.

LPC54xx_LCD.JPG

 

LCD displays are part of our life starting from cell phones, media players and car navigation systems GPS. LCD takes important part in medical environment. Where visual information may be critical. So LPC2478 and LPC2470 goes in front of non expensive and low requirements for LCD interfacing.

LPC2478 and LPC2470 supports most of statical LCD displays up to 1024×768 pixels monochrome with fifteen gray levels and color 24bit/pixel TFT panels. Designers of embedded systems have to program LCD functions inside the chip what allows to avoid various conflicts that would occur with external interfacing. LPC2478 comes with 512kB fast internal flash memory with built in error correction to ensure maximum reliability of performance.

LPC2478 and LPC2470 only need to be powered from 3.3Valso there is a real time module (RTC) with separate power supply and internal 2kB battery RAM memory.

Microcontrollers come with wide range of peripherals including two CAN, four UART, three I2C, two input and two output I2S interfaces, SPI, SSP, RTC, ADC/DAC, memory car interface for CD/MMC, external interface for SRAM, SDRAM and NOR Flash.

LPC2478 and LPC2470 are cased in 208 pin TFBGA and LQFP packages what makes them powerful and flexible tools.

 

Programming microcontrollers AduC70xx using boot-loader and ARMWSD utility

Firmware for AduC70xx ARM microcontrollers can be uploaded using built in boot-loader. To work with boot-loader Analog Devices offer to use small free program ARMWSD working under windows system. Program doesn’t require installation. ARMWSD communicates with AduC70xx via COM-port. Simple programming steps looks like this:

  • Connect target board to PC COM port;

  • Go to Configure->Parts and select AduC part:

armwsd_mcu_select.JPG

 

  • Then go to Configure->Comms and select serial port and baud rate:

  armwsd_baud_select.JPG

 

  • Select other settings if needed (Mass erase, Program, Verify, Protect) in Configure->Flash menu;

  • Press OK to get to main window again. Browse for hex file – only hex files are supported in this program. When you are set, then press Start button – Program starts waiting for boot-loader action:

  armwsd_ready_to_program.JPG

 

  • Now you have to start boot-loader on your target board. As you know entering boot-loader needs some procedure to be done. Manually you have to press button “Download” connected to BM pin, then power on board and rapidly press and release “Reset” button and then release “Download” button. After this AduC70xx enters boot-loading mode and downloads hex file.

  ADuC70xx_programming.PNG

Program is simple but it does the job.

Using LPC2000 flash ISP utility to program LPC2148

As I earlier was writing about my home made ARM7-Base development board for LPC2148

ARM_Developement_board.jpg

It is time to write few words on how to use LPC2000 flash ISP utility.

LPC2000 flash utility is a software which is used to program LPC2000 series ARM microcontrollers:

LPC2101, LPC2102, LPC2103, LPC2104, LPC2106, LPC2106, LPC2114, LPC2114, LPC2119, LPC2124, LPC2129, LPC2131, LPC2132, LPC2134, LPC2136, LPC2138, LPC2141, LPC2142, LPC2144, LPC2146, LPC2148, LPC2194.

Programming is done through serial port. As you probably know, the LPC2000 series microcontrollers comes with boot-loader built in. This bootloader provides ISP interface for programming Flash or Ram memories and other operations like erasing. Bootloader is located in upper 8kB flash memory.

Bootloader has an algorithm which detects incoming ISP connection, detects baud rate automatically.

When starting ISP after reset P0.14 has to be pulled down what means that microcontroller is ready to accept ISP commands. Otherwise keep P0.14 pin pulled high to avoid unintended ISP entry.

Lets take a look at main screen of LPC2000 flash utility:

LPC2000_screen.JPG

The program has very intuitive screen. First thing what you have to do is to power up your target board, connect serial cable to your computer. Then in a screen select COM port number and baud rate. If you use automatic ISP entry mode, then check DTR/RTS checkbox – in a board DTR and RTS lines has to control P0.14 pin and RESET pin. Otherwise use manual entry mode.

If “execute code after upload ” is selected, then after programming completes – an extra reset pulse is sent to reset microcontroller.

Next step you have to enter crystal frequency in kilohertz’s. After this press “Read Device ID” to make sure that device is detected correctly. Part ID and boot-loader ID is detected. If successful you can now start programming you microcontroller.

Open hex file and press “upload to flash” to send code to microcontroller. “Compare flash” button is used to compare original hex file contents with uploaded. This operation is possible if checksum is part of hex file already.

Checksum can be generated as follows:

Open buffer menu and select “Flash buffer operations”:

LPC2000_Flash.png

Press “load hex file” and select hex file you need to upload to microcontroller.

Press “Vector Calc” to generate checksum which will be located at the address 0×14. You will notice how this area updates after you press this button. Now you can save hex file back to its location by pressing “Save Hex File”.

Now press “Download Flash” to download hex data fro mmicrocontroller.

In a main window press “Compare flash” to compare flash contents and original hex file.

There is also SRAM buffer operations available – pretty same as flash buffer. You can download microcontroller RAM contents, modify and send back to microcontroller.

You can also run program code from selected address location, fill buffer with some values and so on.

Other types of ARM microcontrollers like LPC2220/2210/2290 are not supported by this utility as these microcontrollres don’t have inner flash memory. But utility can be used because it can send ISP still can access SRAM memory, read device ID. Just ignore Error message and go ahead.

ARM Development Tools

Building embedded software using algorithm flow charts

Embedded software consists of various functions performing particular tasks. Before writing any ASM or C code it is good to draw algorithm flow chart. Flow charts are visual method of representing inner algorithm. It is easer analyze the algorithm and write the code according to diagram.

The main parts of diagram:

image001.gif

Fig 1. Simple series instructions

image002.gif

Fig 2. Parallel instructions

image003.gif

Fig 3. if-then-else structure

image004.gif

Fig 4. while (for) structure

image005.gif

Fig 5. do until structure

image006.gif

Fig 6. case structure

For each function or procedure make separate algorithm flow charts – this enables easer integration of them in to main function.

Sample how program flow chart may look.

image007.png
Fig 7. Sample program Flow Chart

RTC example on ARM7 LPC2148 using WinARM

Finally got my LPC2148 RTC working on my development board. arm7 base development board for lpc2148

I am quite new to ARM microcontrollers, so I managed to make few tests using them by driving some peripherals and writing some test routines. First code I tried was simple LED blink program first lpc2148 arm7 microcontroller test led blink

This one is running microcontrollers real time clock (RTC) and generating interrupts every second. When Interrupt occurs microcontroller sends particular message to UART that I could see via Terminal program.

The main program:

/******************************************************************************

*

* WinARM RTC application

*

* – UART0 send in Interrupt-Mode

* – Sends message every seccond.

* – RTC interupt every second

******************************************************************************/

#include “types.h”

#include “LPC214x.h”

#include “config.h”

#include “armVIC.h”

#include “uart.h”

uint32_t time_toggle=0;

static void rtc0(void) __attribute__ ((interrupt (“IRQ”)));

static void lowInit(void)

{

// set PLL multiplier & divisor.

// values computed from config.h

PLLCFG = PLLCFG_MSEL | PLLCFG_PSEL;

// enable PLL

PLLCON = PLLCON_PLLE;

PLLFEED = 0xAA; // Make it happen. These two updates

PLLFEED = 0×55; // MUST occur in sequence.

// setup the parallel port pin

IO0CLR = PIO0_ZERO_BITS; // clear the ZEROs output

IO0SET = PIO0_ONE_BITS; // set the ONEs output

IO0DIR = PIO0_OUTPUT_BITS; // set the output bit direction

IO1CLR = PIO1_ZERO_BITS; // clear the ZEROs output

IO1SET = PIO1_ONE_BITS; // set the ONEs output

IO1DIR = PIO1_OUTPUT_BITS; // set the output bit direction

// wait for PLL lock

while (!(PLLSTAT & PLLSTAT_LOCK))

continue;

// enable & connect PLL

PLLCON = PLLCON_PLLE | PLLCON_PLLC;

PLLFEED = 0xAA; // Make it happen. These two updates

PLLFEED = 0×55; // MUST occur in sequence.

// setup & enable the MAM

MAMTIM = MAMTIM_CYCLES;

MAMCR = MAMCR_FULL;

// set the peripheral bus speed

// value computed from config.h

VPBDIV = VPBDIV_VALUE; // set the peripheral bus clock speed

}

static void sysInit(void)

{

lowInit(); // setup clocks and processor port pins

// set the interrupt controller defaults

#if defined(RAM_RUN)

MEMMAP = MEMMAP_SRAM; // map interrupt vectors space into SRAM

#elif defined(ROM_RUN)

MEMMAP = MEMMAP_FLASH; // map interrupt vectors space into FLASH

#else

#error RUN_MODE not defined!

#endif

VICIntEnClear = 0xFFFFFFFF; // clear all interrupts

VICIntSelect = 0×00000000; // clear all FIQ selections

VICDefVectAddr = (uint32_t)reset; // point unvectored IRQs to reset()

// wdtInit(); // initialize the watchdog timer

initSysTime(); // initialize the system timer

uart0Init(UART_BAUD(HOST_BAUD), UART_8N1, UART_FIFO_8); // setup the UART

}

/*************************************************************/

void rtc0(void)

{

if (time_toggle==0)

{

uart0Puts(“\n\rTic\r\n”);//Tic Tac output to UART0

time_toggle=1;

}

else

{

uart0Puts(“\n\rTac\r\n”);

time_toggle=0;

}

ILR |= 1; // Clear interrupt flag

VICVectAddr = 0; // Acknowledge Interrupt

PCON = 1; // IDLE mode

}

void init_rtc(void)

{

ILR = 3; // Disable 32’768 interrupt

CCR = 0×11; // Clock enable + 32’767Hz quartz enable

CIIR = 0×01; // Interupt every second

VICVectAddr1 = (unsigned long)rtc0; // set interrupt vector in 1

VICVectCntl1 = 0x0000002D; // use it for RTC Interrupt

VICIntEnable = 0×00002000; // Enable RTC Interrupt

}

void set_time(void)

{

YEAR = 2006; // Year

MONTH = 5; // Month

DOM = 23; // Day of month

DOY = 38; // Day of year

DOW = 143; // Day of week

HOUR = 23; // Hours

MIN = 14; // Minutes

SEC = 30; // Seconds

}

int main(void)

{

uint32_t startTime;

sysInit();

#if defined(UART0_TX_INT_MODE) || defined(UART0_RX_INT_MODE)

enableIRQ();

#endif

uart0Puts(“\n\rRTC interupts every second\r\n”);

startTime = getSysTICs();

init_rtc();

set_time();

for (;;) {

} // for

return 0;

}

And zipped project files:RTC clock example on ERM7 LPC2148 using WinARM

Microcontroller eats too much of RAM

All you know that microcontrollers have limited amount RAM and EEPROM. For instance ATMega128 has 4-Kbytes of RAM, 4-Kbyte of EEPROM. This may seem quite enough for some applications, but more complicated routines require more of RAM. And there is no compiler that can do better optimization on usage of ram than programmer.

The main aim of reaching this is reducing dependence on global data, stack and the heap.

So if your application running in microcontroller eats too much of RAM then you should develop some strategy of using its RAM.

Lets see… if you use constants as global values, why not to move them to EEPROM area? You can easily do this by compiler when you declare your variables by using const keyword:

const uint8_t a=10;

I compiled some code using this declaration and compiler (AVR-GCC) compiled .eep file which can be burned to microcontrollers EEPROM. In this way you can store your constants to your EEPROM memory.

Another factor eating microcontroller RAM is stacks. Try to use us much stack as your program require and leave some reserved space just in case. There are many techniques that can help define requirement of stack memory. One of them is to fill all stack with some specific data and after program execution check how much stack memory left untouched (never been overwritten). Different situation is with real time operation systems (RTOS) as there different task have its own stack. Here you can reduce number of tasks or use separate interrupt task to operate all interrupt service routines.

Using heaps in embedded systems is a pain, because heaps reduce performance increases code size. If it is possible try to use arrays instead.

Minimizing microcontroller code size

Reducing microcontroller code size isn’t ease task, but what if you want resulting code to fit your available memory…

Minimizing microcontroller code size can be done in two ways:

Firs is using compilers optimization feature by code size. This optimization is very dangerous. Your optimized code may not work as supposed to because compiler may eliminate some code like empty loops or adding zeros.

For example compilers like to remove for(int i=0;i<1000;i++) {} by leaving one or several iterations. So don’t think that your optimized code will work as un-optimized.

There are other things you can do to minimize microcontroller code size. One of them is avoiding usage of standard libraries routines. Because these libraries are general and handles all standard possible execution cases. By including them in your design you include a bunch of code you don’t need. If it is possible it is better to write your own routines or modify existing ones to fit your needs.

Also try to use needed variable sizes. If you need unsigned integers use uint type if you need byte sized don’t use int which usually is more than 8 bits (16 or 32). This may significantly reduce your code as there are fewer instructions needed to execute smaller variable types. Sometimes you can use goto statements to remove complicated conditional structures. Just remember – Embedded system development is different than writing PC software. Don’t think general – think narrow when working with concrete hardware as resources of microcontrollers are limited.

Increase microcontroller code efficiency

C compilers are getting more and more advanced, but there is always a trade off made between speed and code size. Compiled code can be faster or smaller but not both. So you have to choose which part is more important speed or code size.

The Increase of microcontroller code efficiency can be done in many ways. Don’t trust compiler optimization features, as they might not bee as effective as you expect. It is better to grab some profiler and inspect what parts of your code takes the most time and size.

It is better to follow some techniques that may reduce code execution time and increase microcontroller code efficiency:

Inline Functions

Use keyword inline to any function you want. This makes compiler not to call a function, but to copy the function code in to desired place. This technique is effective when inline function is called frequently and it contains a few code lines. In other hand bigger functions can fill you code size limit very fast.

Table Lookups

Table lookups are realized by using switch statement. Be smart using switch statement. Put most likely sentences firsts and last likely sentences last. This may reduce execution time.

If there much work to do within switch cases might be it is better to replace switch sentence with table of pointers to functions.

Assembly lines

Assembly is always the best optimized code (well not for all programmers). You can make code efficient as you need. But sometimes C or C++ compilers produce better code than average programmer. So decide is this worth your time to mess up with assembly. But using inline assembly can significantly increase microcontroller code efficiency.

Use register values

Register keyword can be used when declaring variables. This makes compiler to assign variable to a genera purpose register besides a stack. Use this keyword to most frequently used variables.

Consider global variables

In computer software development it is strictly recommended to use local variables to make code more universal and readable. But in embedded systems it is more efficient to use global variables as this eliminates the need to push parameter to stack before function call popup. You increase speed of you code but loose modularity.

Polling vs. Interrupt

In embedded systems interrupt routines are used frequently. So sometimes might be to use polling routines to communicate the hardware. In some cases interrupts my cause latencies. Using polling also leads to less modularity.

Don’t use float point arithmetic

Floating point arithmetic is a killer of microcontroller code efficiency unless your design includes FPU. Otherwise compiler uses software subroutines to simulate floating point arithmetic’s. There are many techniques which let you avoid using floating point operations like byte shift instead divide and so on.

New on WinAVR Tutorial New on WinARM Tutorial