23/02/2018

# ARM-Cortex M0 programming with lpc1114FN28 - an overview

This is a migrated version of my Wordpress post, written on : 27 February 2015

## What is it?

The lpc1114FN28 is a low cost, low power 32 bit MCU designed in a 28dip package, it is breadboard friendly and very easy to set up for those who are new to ARM programming (like me). Some features :

• An ARM cortex M0 processor, can run at the frequency up to 50 Hhz.
• Built-in Nested Vectored Interrupt Controller (NVIC)
• 32 kb on chip flash programming memory and 4kb of RAM
• In-System Programming (ISP) and In-Application Programming (IAP)
• UART, I2C, SPI, 10 bits ADC
• Up to 22pins GPIO
• And more..

It is designed mainly for micro-controller stuffs (applications), and can be easily programmed with a few more components. In fact, i'm just ancomputer scientist guy who is new to the MCU (ARM) world and that simplicity is a good point for me. I've bought some of them from Ebayand started to learn how to program it.

## Where to start ?

The MCU can be programmed using the tools and libraries provided by the vendor and maybe it's a good choice for you. But for me, i'm a big fan on open-source things, so i really want to know how i can use the GNU toolchain to program it. I've searched around from the internet and found some good tutorials to start with, so i just post the linkshere :

These tutorials can help you set up the environment and technically program the chip, but to understand how things work, you need to knowthe chip's specification. TheUM10398: LPC111x/LPC11Cxx User manualis a good source of documentation, here you can find all the registers description and the manuals of how to power on thechip's feaures (like GPIO,ADC,PWM, UART,etc.).

## A minimum set up of development environment

There are many options ofhardware/software configuration for programming the chip. Here is an possible one.

### Hardware

Basically,the chip comes with a DIP 28 package and has a boot-loader pre-installed, so program it is very easy and straightforward. It requires zero supporting components. Unlike other ARM chips which require a JTAG programmer, the boot-loader on the LPC1114FN28 supports the UART ISP (In System programming), so you don't need afancy development kit to test your code. All you need are a breadboard, the chip and a USB to serial (USB to TTL) adapter as programmer. Here is the wiring :

(Image from (http://eleceng.dit.ie/frank/arm/BareMetalLPC1114/lpc1114ISP.png))

Note that the TX/RX pins on the adapter need to be connected to the RX/TX (dp15/dp16) on the chip respectively.This simple configuration allows you to program the chip via the serial port, it does not allow you to debug the software however. Here is how the programming works :

• First, we need to tell the chip to enter the ISP mode by putting the ISP mode pin (dp 24) to low (0). The chip is now listening for instructions.
• On the software side, we run the programmer software (we'll talk about it later) to send the program to the chip, it will wait for the chip to accept.
• Put the reset line on the chip (dp23) to low (0) for an interval then high (1) to enable the programming, the chip will get programmed.
• Disable the ISP (put high to dp24) and reset (put low then high to dp23) the chip to start the program.

The reset and ISP mode lines can be activated manually by using two buttons or automatically by software (you'll need a custom hardware programmer though). I've successfully automatically programmed the chip using the Raspberry Pi A+.

### Software

#### LpC21ISP

You will need a software programmer to send your compiled code(in hex or bin format) to the chip via the ISP mode we've set up above. There are also different options as you'll see in the tutorial links above. Personally, i use the lpc21isp (it's also open-source). You can found the code and installation instructionhere. Let's assume that you have a hex file name blink.hex, and in thehost computer, your USB to serial device is /dev/ttyAMA0 (it depends on your host OS, mine is on the Raspberry Pi with raspbian). Here is the command used to program the chip:

    lpc21isp -hex blink.hex /dev/ttyAMA0 115200 48000


The -hex option tells the command that it is a hex file, if you use the binary format, the option should be -bin. Here, the serial baud-rate is set to 115200. You can just type lpc21isp -hfor more options and informations.

#### The gnu toolchain

So far so good, now we need a compiler to compile (and debug) our code (in C/C++ or assembly). There are of-course many software tool chains for ARMdevelopment like the Keil MDK, but we wont talk about it here since it's a commercial product and hence out of scope of the post (every thing is open-source here).

The chosen compiler here is the GCC ARM, a specific version of the famous GCC for ARM chips. You can find all the source code and instructions here, and here is the build and installation process. You will also need to install the make system (Makefile) to create automatic build script for your application.

#### Libraries

If you use the vendor tool or other tool to develop, you need to stick with the libraries provided by these tool. You may also want to learn to use the CMSIS programming template, the CMSIS is an effort of ARM to standardise the development process on different vendor's chips. The programs that use the CMSIS template is more standard and easier to port between different chips. We dont use the CMSIS here. In this post i just talk about the minimumrequirement to successfully write and compile a program with the GNU toolchain. Those whose want to use the CMSIS can find more here.

All my projects on the lpc1114fn28 is strongly rely on the header file found on this site, you can get it here. Now let's figure out what we need for a very basic application:

    ./
|-- Makefile
|-- nit.c
|-- lpc111x.h
|-- main.c


First of all, the lpc111x.h that defines all registers described on theUM10398 user manual.By accessing to these registers we can configure the chip to power on its features, or read its internal states (gpio state, ADC value, etc)...

The linker_script.ld defines where the interrupt vector, code, data as well as the top of the stack will be mapped to the chip memory (flash, sram,etc). The compiler will need this in its linkageprocess.

The init.c is the startup code of the Cortex M0 processor which specifies the interrupt vector, the stack pointer, copies data section from the flash to RAM, configures the system clock, etc. We will modify this file when dealing with the interrupt.

The main.c is our application's code, and the Makefile define the build command for the application. All these files can be found in the example section.

### Put it all together - the hello world example

Ok now it's time to light up some LED, the simple example below shows how to put all things together, with a breadboard, a LED and some wires, you are ready to go. Here is the wiring :

The led is connected to the PIO0_9 (dp2) pin on the chip

The LED is connected to the PIO_09 on the lpc114FN28, we will use this pin to toggle the led on and off. Here is the main.c file,for now, you don't need to understand all the code, all you need to know is it turns the PIO_09 (dp2) pin on and off for a interval of time, and so onthe led (which connectsto it).

/*The LED is connected to the dp2 of the chip (PIO0_9)*/
#include "lpc111x.h"

int main()
{
// Turn on clock for GPIO, IOCON
SYSAHBCLKCTRL |= BIT6  + BIT16;
// power on GPIO function on PIO0_9
IOCON_PIO0_9 &= ~(0x7);
// configure PIO0_9 as output
GPIO0DIR |= (1<<9);
// turn of the PIO0_9
GPIO0DATA &= ~(1<<9);

int n;
while(1)
{
// turn on the led
GPIO0DATA |= (1<<9);
n=1000000; while(--n);
//turn off the led
GPIO0DATA &= ~(1<<9);
n=1000000; while(--n);
}
}


So let'scompileit using the GNU tool chain, the compilation is doneontwo files: init.c and main.c:

    arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -g -c init.c -o init.o
arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -g -c main.c -o main.o


The -mcpu option tells the compiler that its target CPU is ARM cortex M0 and the -mthumbmakes sure that the compiler will use the ARM Thumb instruction set (16 bits instruction set, whichhelp reduce the code size), since cortex M0 only supports the Thumb, this option is mandatory.

Once you have the files compiled without errors, you need to link the outputs (init.o, main.o) together to make the final program

arm-none-eabi-ld init.o main.o -L /your/path/to/lib/gcc/arm-none-eabi/4.9.3/armv6-m \
-lgcc -T linker_script.ld --cref -Map main.map -nostartfiles -o main.elf


This command will combine the outputs and all the libraries necessary to produce the main.elf file. It need indeed the linker_script.ld file and the libgcclibrary. The last one can be found on your GCC arm-non-eabi installed path (you need to modify this with your own path).

The last thing you need to do is to convert themain.elf to hex format with the arm-none-eabi-objcopy command :

    arm-none-eabi-objcopy -O ihex main.elf main.hex


For simplicity, we can combine all these commands in a single Make file like this :

LD=arm-none-eabi-ld
OBJCP=arm-none-eabi-objcopy
GCC=arm-none-eabi-gcc
LIB=/path/to/gcc-arm-none-eabi-4_9/lib/gcc/arm-none-eabi/4.9.3/armv6-m
all:init.o main.o
$(LD) init.o main.o -L$(LIB) -lgcc -T linker_script.ld --cref -Map \
main.map -nostartfiles -o main.elf
$(OBJCP) -O ihex main.elf main.hex init.o:$(GCC) -mcpu=cortex-m0 -mthumb -g -c init.c -o init.o
main.o:
\$(GCC) -mcpu=cortex-m0 -mthumb -g -c main.c -o main.o
clean:
rm main.o init.o main.map main.elf main.hex


Enter the makecommand and this file will automatically do the compilation task for you. For the next project, you only need to change the main.c file and you're already to go.

Enter the chip to ISP mode by active the ISP line

1. Run the command : lpc21isp -hex main.hex /dev/ttyAMA0 115200 48000.
Note that the /dev/ttyAMA0 device is depend on your system, change it with your own oneNote that the /dev/ttyAMA0 device is depend on your system, change it with your own one.
2. Active the reset line (low then high) to enable the chip to be programmed.
3. Once the chip is programmed, disable the ISP mode by putting high tothe ISP line.
4. Reset the device to run the program by activating the reset line (low then high).

You will get some thing like this when the chip get programmed :

lpc21isp version 1.97
converted to binary format...
image size : 540
Image size : 540
Synchronizing (ESC to abort)........ OK
7
Read part ID: LPC1114.../102, 32 kiB FLASH / 4 kiB SRAM (0x1A40902B)
Will start programming at Sector 1 if possible, and conclude with Sector
0 to ensure that checksum is written last.
Erasing sector 0 first, to invalidate checksum. OK
Sector 0: ..............