Computing stuff tied to the physical world

The upload conundrum

Uploading plays a central role in embedded computing. Unlike the processor in your laptop or mobile device, where you can simply install an app, or – if you’re a software developer – compile from source code and launch the executable, embedded µC’s have extremely limited resources. No disks, no Ethernet or USB even on the simpler chips, and definitely no room for a software development environment, or even a code editor or command shell.

Instead, we have to use our laptops (or desktops) as “host” to “cross-compile” the code which is to be run on the “target” µC. Going from here to there requires special dance steps.

Let’s assume that the code has been cross-compiled for now, and is ready as a binary “firmware image” to be sent to the µC to try it out.

On AVR chips like the ATmega328 or ATtiny85, we can use an In-System Programming (ISP) connection, which requires 6-pins: 2 for power, plus 4 for RESET and an SPI link (don’t confuse “SPI” and “ISP”). The standard ISP hookup uses a 2×3-pin 0.1″ header:

Avr isp header

All ARM-based chips have either a JTAG or SWD interface. The latter is more popular with small chips, because it requires only two I/O pins. This is usually a 2×5-pin 0.05″ header:

Arm swd header

JTAG and SWD are considerably more than just an upload interface: you can start and stop the µC, and set “tracepoints” and “watchpoints”. These hardware debugging features, which also include single-stepping through the code, can be incredibly useful when chasing some complex bug or trying to understand what the hardware is really doing.

The convention, also in the LPC810, is that ARM µC’s power up with the two SWD I/O pins enabled, but this feature can then be turned off in the code and the pins re-used otherwise. So out of the box, every ARM chip is controllable and debuggable through its SWD pins.

The drawback of using AVR’s ISP or ARM’s SWD pins is that we need special hardware to connect things to our laptop. With working code, all we really want is a way to upload it.

In a way, all this is unavoidable: to power up a chip, you need power pins, and to send data to a chip, you need I/O pins. But power pins get re-used once debugging is over, since power has to be applied anyway. And a few I/O pins are always going to be useful for debugging and testing, as a way for the code in the chip to report what’s going on.

The solution is to re-use the same two I/O pins for uploading code and for communicating serially with a chip when it’s running that code. We might need those pins in our projects, but at least while debugging we really have to have a solid communication mechanism.

It all depends on how many spare pins there are on the chip (as Murphy keeps telling us: never enough!). From the above, the minimum appears to require 4 pins, including power.

Unfortunately, that’s not enough. For control, we also need to be able to reset the chip, if the code is not working properly (and as Murhpy gets his way, that’s often the case!).

On Arduino’s, JeeNodes, and other AVR-based systems the whole uploading dance is indeed based on these three I/O pins. But it requires a trick, in the form of a “boot loader” which is given control whenever the µC starts up after a reset. This boot loader then takes care of the communication and of storing new firmware into permanent flash memory.

But how did that boot loader get there?

Easy: through ISP. Except that now we’re back to square one. On most AVR chips, someone has to install a boot loader on the µC, and then we get the convenience of uploads and serial comms. The boot loader will wait a short time to see if uploading is requested, and otherwise jump to the code currently stored in the remaining flash memory.

With ARM chips, we have one more trick up our sleeve, but it requires the use of one extra I/O pin. Ok, nothing comes for free – but as you’ll see further on, it’s not such a big deal.

The trick is that ARM µC’s include a boot loader in ROM, i.e. built into the chip and delivered ready to go from the factory. It’s always included, and it can’t be broken or lost.

In the case of the LPC810, there’s a “serial” boot loader on the chip, which (surprise!) starts up after a reset, and (surprise!) uses a simple serial protocol on two I/O pins. It depends on one additional convention: a specific “ISP” I/O pin on the chip needs to be low (“0”) when the chip comes out of reset, to activate that serial boot loader. When high (“1”), the code already in flash memory will be started.

So what we need, is a way to control both the RESET pin and the ISP pin.

We’ve now lost 4 I/O pins to get code upload support. The good news is that all those I/O pins can be re-used and re-allocated at will once the µC has started running. The only requirement is that the RESET and ISP pins must start as high during normal power up.

Note that the two SWD pins are still available for hardware debugging if we want ’em. All of the above can be squeezed into an 8-pin DIP chip. Which is exactly what the LPC810 did:

Lpc810 pinout

Pins 3 + 4 are easy to use in a project (disable SWD), then 2 + 8 (no in-circuit uploads), and lastly 1 + 5 (as long as they are high on power-up, perhaps by using them as outputs).

[Back to article index]