- Setting up a cross-compiling toolchain for ARM
- Creating and compiling your first blinky program
- Programming the LPC810 using free and open source tools
Setting up an ARM Toolchain
While most seasoned veterans probably prefer a good old makefile, if you're new to ARM you'll appreciate the hand-holding an IDE can provide. We'll be using NXP's free LPCXpresso IDE in this tutorial, which is based on Eclipse and GCC, and works with all of their recent chips.
Downloading the LPCXpresso IDE
In order to download NXP's free LPCXpresso IDE, you do need to create an account on Code Red's website (who are now owned by NXP), at https://www.lpcware.com/lpcxpresso/download
While registering sucks, LPCXpresso is still the easiest free tool using an open source toolchain, and you can easily break out of it once you're a bit more comfortable with ARM and GCC, creating your own makefile and linker script, and LPCXpresso is just a bit of icing on top of the Eclipse + GCC cake.
An advantage of LPCXpresso is that it includes a relatively easy to use installer for Linux, Windows and Mac OS X, so you're free to use the toolchain and IDE on any major platform.
After registering, you should see a download list similar to the following:
Installing LPCXpresso
The installation process is relatively straight forward, and it should be fairly foolproof. Starting with the welcome screen, just run through the installer, and LPCXpresso will automatically setup all the tools, including the cross-compiling toolchain, Eclipse, etc.Importing a Project Into LPCXpresso
Blinky!
By default, the LPC810_CodeBase you downloaded is setup to run a blinky example on pin 0.2, and it spits out 'Hello, LPC810!' on the default UART pins, which we can see in the 'while(1)' super-loop in main.c, shown below:
while(1) { #if !defined(USE_SWD) /* Turn LED Off by setting the GPIO pin high */ LPC_GPIO_PORT->SET0 = 1 << LED_LOCATION; mrtDelay(500); /* Turn LED On by setting the GPIO pin low */ LPC_GPIO_PORT->CLR0 = 1 << LED_LOCATION; mrtDelay(500); #else /* Just insert a 1 second delay */ mrtDelay(1000); #endif /* Send some text (printf is redirected to UART0) */ printf("Hello, LPC810!\n"); }
Blinky is following by our printf() statement, and by default all printf output is redirect to UART0 on the LPC810.
Before worrying about writing and programs, though, lets build the firmware as-is!
Building Firmware in LPCXpresso
To build a project in LPCXpresso (or Eclipse), you need to right-click on the current project in the project explorer (located on the left-hand side of the IDE by default), and select the 'Build Project' menu item.Programming the LPC810 with Flash Magic
But first ... a bit of wiring is in order! You'll need to hookup a UART to USB adapter, a 3V3 voltage regulator, a couple caps, and a few wires to get everything wired up safely with the LPC810. Just follow the wiring diagram below and you should be good.
The UART cable colors on the right (four wires) match the colors of Adafruit's USB to TTL Serial Cable.
Programming the LPC810
There are two main ways to take advantage of ISP mode to program your MCU:- Use Flash Magic, a free GUI-based tool for Windows
- Use lpc2isp, an open source command-line tool that can be adapted to work on most operating systems, though you may need to build it yourself and add your MCU ID.
Hooking Everything Up
This tutorial will assume that you are using the PL2303-based USB to TTL Serial Cable included with the LPC810 Starter Kit.- Insert the LPC810 into your breadboard as shown, along with the 3.3V voltage regulator, and two decoupling capacitors.
- Connect the white, green, red and black wires on the right-hand side of the diagram to the same colored cables on your USB to TTL serial adapter.
- Connect the ISP pin to GND (the cable shown in gray above), which will cause the chip to enter ISP mode when it comes out of reset
- Connect the other red and black cables on the breadboard which control the power supply to the MCU.
Using Flash Magic
If you haven't already done so, download and install the latest version of the free Flash Magic tool.The tool is relatively straight forward once you have used it once or twice, but this guide will show you everything you need to know to program the LPC810 using the Flash Magic GUI.
Get Your .HEX File Ready
Flash magic uses Intel Hex files to program the MCUs.The LPC810 CodeBase will produce a compatible .hex file from your own code, which we'll learn about later, but you can also find some sample .hex files at the bottom of this tutorial for convenience sake.
Configuring Flash Magic for the LPC810
Before you can program your LPC810, you need to supply some basic information to Flash Magic:- Set the device to 'LPC810M021FN8'
- Set the COM port to whatever COM port your USB to TTL cable is using (you can find this in the Device Manager on Windows, for example)
- Set the Baud Rate to '115200'
- Set the Oscillator to '12'
- Check the 'Erase blocks used by Hex File' checkbox
Checking your Connection
You can make sure that all of your settings are correct, and that everything is connected properly and that the chip is actually in ISP mode by selecting 'ISP > Read Device Signature ...' from the top menu bar:
Programming the Device
After selecting your .hex file in the 'Hex File' textbox, you simply need to click the Start button, and Flash Magic should start programming your device.
You may wish to check the 'Verify After Programming' checkbox before doing this, but it isn't strictly necessary:
Testing Your Firmware
At this point, your device should be programmed. To test your firmware perform the following steps:
- Disconnect the ISP wire on your breadboard (the gray wire in the image above)
- Reset the device ... for example, disconnect then reconnect the red power cable on your USB to TTL adapter
- Once the board is powered up and if the ISP pin is not pulled low the chip will execute code normally
Sample Hex Files
For convenience sake, you can find some pre-compiled sample .hex files for the LPC810 in the '/tools' folder of the LPC810 code base, available on github:-
LPC810_Blinky_P0_2.hex - This hex file will cause an LED on P0.2 to blink at a regular rate. To use this firmware, connect the anode (the larger pin on your LED) to P0.2 on the LPC810, and the cathode (the shorter pin on the LED) to a 1K resistor and to GND, as seen in the following diagram:
OK ... But why the LPC810 at Adafruit?
The DIP8 LPC810 is still somewhat of a challenge to use precisely because it's so small (by ARM standards, anyway): 4KB flash and 1KB SRAM. That doesn't go far, and in reality you only have about 3KB flash to play with once you add in your startup code and get everything setup.
But that's actually part of what I found so fun about this chip! It's a genuine challenge but a fun one to do something creative and interesting with so much performance in such a small space!
'Small is Beautiful'
Warning: Shameless, unadulterated, highly-personal rant!Really ... small is where it's at if you care about writing clean, efficient code and really learning how to do something properly and understanding what you're doing!
I always start my new projects with the smallest chip I can, rather than the biggest one available. Why? Because it forces me to keep size in mind, to try to write better, more efficient code, and to get the most out of the limited resources I have. Why do I always start with ARM chips with 32KB flash and 8-12KB SRAM when I could get something with 512KB flash and 100KB+ SRAM for not much more? Because if I started with those big chips I'd write even sloppier code that took more space than I needed, and I'd be stuck with bigger and more expensive chips and even worse code forever!
One of the biggest difficulties in deeply embedded systems is keeping things lean, without compromising on stability and reliability. That means error checking, data validation, etc., which takes space and time to implement, but you need to keep space in check, so it's an endless series of trade offs, decisions and optimisations.
Deeply embedded development has a lot more in common with mechanical watch-making than it does with traditional SW development: you're always trying to fit an impossible seeming number of gears and components into a ridiculously small package, and everything has to fit in in just the right manner to work at all. To throw some oil on the fire, it also needs to hold up to all manner of abuse and mistreatment that will get thrown at it, and keep smiling back at you day after day!
Something embedded SW engineers understand better than almost anyone else -- except maybe those crazy mechanical watch makers -- is the huge satisfaction in writing clean, concise, efficient code that solves real problems in concrete, elegant, reliable ways. Writing bloated code is easy ... writing elegant code and creating tiny solutions for big ambitions is harder, but also infinitely more satisfying!
Why the LPC810 with it's tiny package, and limited resources? Because it's a fun challenge and a really interesting way to learn ARM!
I really wanted to get this chip in people's hand just to see what people can do with 4KB flash and 1KB SRAM, and a reasonably limited set of peripherals. It's the kind of fun challenge that I enjoy working on, and I'm sure I'm not alone in that!
This guide was first published on May 24, 2013. It was last updated on May 24, 2013.