Computing stuff tied to the physical world

Re-flashing an ARM chip

The process has been used in these articles for some time now, but let’s look into what exactly is going on when using a serial connection to upload firmware into an ARM µC. Note that this applies not only to the LPC8xx series chips – other vendors provide more or less the same mechanism for uploading, although each using their own protocol.

When an LPC8xx is powered up or comes “out of reset” for any reason, this is what it’ll do:

Lpc8xx boot logic

The key decision here is “ENTER ISP MODE?”. If a specific pin on the µC is pulled low as it starts up, it’ll launch the ROM-based serial boot loader. If left unconnected or high, the normal startup process will simply execute what’s stored in flash.

There is some code protection and a check that there is in fact code present and we’re not powering up a chip which has never been programmed before, but that’s less important.

The boot loader waits for an incoming “?” character. This is the hex code 0x3F which is a conveniently simple bit pattern and from that, it determines what baud rate is being used.

After a bit more basic handshake logic, the boot loader will now listen to commands to report the chip type, load some data into memory, erase/program a section of flash, etc. Unlike the Arduino boot loader, once entered, this ROM-based boot loader doesn’t ever time out: it’ll sit there waiting patiently for commands. Unless the chip is reset, of course.

On the modified BUB FTDI interface, 4 pins carry I/O signals, plus ground and power:

Ftdi

Note the cross-over of RX/TXD and TX/RXD: one side sends a signal, the other receives.

There are several points of potential confusion:

  • the convention is to use 3.3V signalling levels, but the LPC8xx also tolerates 5V
  • logic levels are inverted: “high” means no RESET, no ISP mode, and RX/TX idle
  • “send” and “receive” are relative to each party, it’s ridiculously easy to mix ’em up
  • for this same reason, it’s meaningless to tag any wire as being “send” or “receive”
  • some boards use “RTS” (Request To Send) instead of “DTR” (Data Terminal Ready)
  • most FTDI boards have a “CTS” pin, not the “RTS” used on the modified BUB
  • CTS is an input, originally intended for hardware flow-control
  • … but it’s rarely ever used as such nowadays, and in fact just ignored

With all these details out of the way, here’s how an upload takes place:

Ftdi upload

RTS is pulled low, so that each DTR pulse will (try to) launch the ROM boot loader. A check is made that the boot loader is indeed active. If not, the reset may be retried. Once the boot loader is active, the RTS pin is released again.

The upload protocol takes over, the firmware is re-flashed, and then a final pulse (with the RTS pin high this time) is sent to reset the µC. After that, the uploaded application code starts running and can use the serial connection if it wants to.

[Back to article index]