Programming the LPC processor

The microcontroller can be flashed from UART or USB. It will allow programming when there is no valid binary image or when PIO0_1 is sensed low when reset goes inactive. The pin is also called PRG*.

To this aim, J1 makes available GND, PRG and RST (as written on the silk screen). You can easily force programming mode with tweezers or two buttons connected through Dupont wires.

At this point, if VBUS is present, it will allow USB flashing; if VBUS is low, it will enter UART programming. In the TDC board, Vbus is connected to the USB-mini socket: if USB is connected, it will allow USB-flashing. If not (i.e. if you power the device otherwise) it will allow UART-flashing.

Flashing from USB

When in ``USB programming mode'', the microcontroller will enumerate as a storage USB device. You should overwrite firmware.bin with the new binary image (i.e. neopixel.bin or otherwise).

Unfortunately, the internal ROM of the microcontroller only accepts sequential writes. If you reprogram under Linux, you can't mount the device to copy the file, because the OS will rearrange writes as it sees fit. It might work if you use "dd bs=512 oflags=sync" but I didn't try. Under Windows, which doesn't optimize disk access, any kind of copy will work; MacOS is Unix, so normal copies are expected to fail.

Please note that the "failure" in copying is because of the limitation of the internal ROM in the microcontroller (which in turn is dictated by the underlying hardware). The "contract" offered by the LPC device is "you can write in my FAT simulation, but only sequentially", which is different from "I am a FAT storage device".

For this reason, the suggested tool to flash the device is mcopy, part of mtools; a set of user-space programs designed to access "msdos" floppy disks without mounting. mcopy (= msdos copy) reads and writes sequentially on the raw device. The default configuration for mtools, set forth in /etc/mtools.conf is made for floppy disks. Here, on the contrary, we need to access a "real hard disk". If you have one disk, the microcontroller will appear as /dev/sdb, if you have two disks, the microcontroller will be /dev/sdc, and so on. Thus, you should create mtools names for them, but writing in either /etc/mtools.conf or .mtoolsrc in your home directory ("rc" means "run command", it is commonly used to name initialization procedures, or configuration files).

I use the following lines:

   drive b: file="/dev/sdb" exclusive
   drive c: file="/dev/sdc" exclusive
   drive d: file="/dev/sdd" exclusive
   drive e: file="/dev/sde" exclusive
   drive f: file="/dev/sdf" exclusive

You can check in /proc/partitions what is the disk name (it is the only disk which is 34kB big). Example:

   laptopo% cat /proc/partitions
   major minor  #blocks  name
      8        0  125034840 sda
      8        1   14647296 sda1
      8        2   12695552 sda2
      8        3   48828416 sda3
      8        4   48862208 sda4
      8       16  488386584 sdb
      8       17   11534336 sdb1
      8       18  278670360 sdb2
      8       19  198180864 sdb3
      8       32         34 sdc
So here the microcontroller is sdc and I'll use c: as mtools name:
   mcopy tests-lpc/neopixel.bin c:firmware.bin

mcopy asks if you want to overwrite the existing firmware.bin, and you must confirm this. My own version accepts -o for ``overwrite'', but I heard some other version does not, please check before using -o.

Finally, most likely you'll need to run the command as administrator, unless you already have permission to access /dev/sdc. So please use "sudo mcopy ..." (sudo means "super user do"). There is no risk in playing (as administrator) with mcopy, because the tool will only access FAT-formatted devices, so you can't damage your system if you make mistakes in your drive letters.

Flashing from the serial port (UART)

To write firmware using the serial port please use tools/progrom (whereas tools/program is for binaries to be exectuted directly in RAM, if you choose CONFIG_RAM_RUNNING). The tool assumes the target is on /dev/ttyUSB0. If you need to use a different UART port, please export LPC_PORT in your environment. For example:

   export LPC_PORT=/dev/ttyUSB1
   ./tools/progrom micosi.bin

The programming tool goes on listening to the serial port after programming, so you'll see any messages printed by the microcontroller if you press reset while progrom is still running. Otherwise, please kill progrom with ctrl-C (control-C doesn't mean "copy"; the ASCII standard says it means "end of text", so it was a sane choice to kill a program reading "text" from stdin).

This is a sample run of progrom (for bigger programs the output is longer):

   laptopo% ./tools/progrom ./tests-lpc/neopixel.bin
   Opening serial port /dev/ttyUSB0
   Forcing boot loader mode
   Syncronizing... done
   Identifying... done
   part number: 2988402b
   LPC1124, 32kB Flash, 6kB RAM
   ISP Boot loader: 7.4
   size is 884 (xfer 900)
   W 268436480 900
   0
   ....................OK
   U 23130
   position 0x00000, size 900:
   P 0 0
      prepare: 0
   E 0 0
      erase: 0
   P 0 0
      prepare: 0
   C 0 268436480 4096
      copy: 0

Vendor tools

If you prefer to use other tools you find on the net, that's fine, if they work for you. A quick search I did recently didn't find anything easy: most vendors want to ship their hardware programmers instead, to be driven by their secret applications. Bah. . This is what I use and make available, but I won't be surprised if something better exists.


Alessandro Rubini
Last modified: April 2021