Bricking and Unbricking a Logomatic

Here’s a story that will hopefully educate and inform, and maybe help anyone out there who had a similar problem to me.

First, a bit about my project: the Rollercoasterometer. I have a Logomatic with the A/Ds connected to a bunch of MEMS sensors, one UART hooked to a GPS, and the other to a SerLCD. Also, (naturally) it is running the Logomatic Kwan firmware, with a couple of features that I haven’t released yet.

For some reason, I felt the intense burning desire to change the bootloader. Mostly it is because it vomits up random katakana on the display whenever the bootloader is running in USB mass storage mode. (Bootloader runs at 115200 baud, display expects 9600 baud) Also, the code could drive the SD card faster so it doesn’t take 90min to download a recording session.

Now on every Logomatic, there are actually three independent programs installed. One is installed by NXP (the manufacturers of the LPC2148), runs automatically every time the chip resets, and is VERY hard (maybe impossible) to change, overwrite, or erase. This program supports In-System Programming (ISP) over UART0, as well as In-Application Programming (IAP, allows user code to change the flash) and a couple of other things. Altogether, it’s a pretty amazing 12kB of code. This is installed in the boot block at the top of flash at 0x7D000 and as I said, runs whenever the chip resets. Normally it just checks if the user code at 0x00000 is valid, and if so, just runs it. We’ll call this program the Boot Block, since that is where it lives.

The second is the Bootloader, installed by Sparkfun at 0x00000. This Bootloader is considered user code by the Boot Block, and this one checks if the USB is plugged in, and if it is, it just acts like a normal thumb drive. If the USB is not plugged in, it checks if there is a file named FW.FSE on the card, and if there is, it installs it at 0x10000 and then deletes FW.FSE. In either case, it then runs the user firmware at 0x10000.

The third one is your firmware, installed by the bootloader. In my case, I added a feature that writes out all 512kiB of flash onto the SD card. I also added a feature that uses the IAP feature of the boot block to copy a file to 0x00000 and overwrite the Sparkfun bootloader. Basically it’s the same feature as the Sparkfun bootloader.

As a test case, I copied the original code at 0x00000 to a file, then copied it back to flash, and it worked. Then I compiled the USB bootloader code on the Sparkfun site and installed it.

That was a mistake.

I’m not sure whether the boot block decided that the boot loader didn’t pass the checksum, or whether the boot loader crashed, but one of them happened, and it doesn’t run my firmware anymore. The part is bricked. :frowning:

So now I have to hook up something to the serial port so I can talk to the boot block, right? Just look up Sparkfun catalog number PGM-00275 for a cable to do it, but:

  1. It’s saturday, and Sparkfun is closed.

  2. I’m cheap.

  3. It’s not USB.

So, I look through my old parts box and find an Arduino Nano. Nice part, has an ATMega168 processor and an FT232 USB chip, acts like a serial port… hey! I have already worked with it and got it to talk to a terminal program on my computer over USB. The problem is that the Arduino processor only has one UART, and the USB chip is plugged into it. So, I figure I have to do some kind of SoftwareSerial to simulate another UART, and use the Arduino to relay stuff from the Logomatic to my terminal program.

After some effort getting a SoftwareSerial port to work not very well, I realize the answer: The hardware UART is on exposed pins 0 and 1, but you can’t use them at the same time you use the USB because the FT232 chip is hooked to those same pins. Therefore, the Tx and Rx pins of the FT232 are exposed as well.

So, I just set up the Arduino processor to listen on both pins, then plug the Tx pin into the Tx of UART0 on the Logomatic, and likewise Rx to Rx. This is different from usual, because the Arduino is marked from the point of view of the processor, not the USB chip. The effect is that the Arduino processor is ignored, and the FT232 is connected directly to the logomatic. So I pull up Hyperterminal, connect it to COM3, set the baud rate to something nice and simple like 1200baud, and have the following deep and meaningful conversation with my beloved departed part:

Tx: ?

Rx: Synchronized

Tx: Synchronized

Rx: OK

We’re in business.

Since the SD card is removable, I removed it, put it in my computer, and set up the LOGCON.txt to re-write the original bootloader. Since my firmware was still in place at 0x10000 in flash, I figured all I needed to do was run it. Unfortunately, the boot block doesn’t set up the PLL, so the chip is running at 12MHz instead of the 60MHz that my firmware expects. As a consequence, this failed and the part remained bricked. Not to worry, I still have serial access to the boot block, so I can push over whatever code I want.

The moral of the story? There are two, I guess.

  1. DON’T try to update the boot loader.

  2. Every Arduino comes with a USB chip which can be hijacked into a USB<->TTL Serial bridge, for any purpose, completely bypassing the processor on the Arduino.

I still haven’t figured out what went wrong, but when I do, I still plan on updating the firmware, violating moral #1 above, but with some confidence, because of moral #2 above.

The reference for all of this is the schematics for the Logomatic and Arduino Nano, and especially the LPC2148 user manual, available from the NXP website. For this adventure I used the chapter on flash and ISP/IAP, but the whole book is an indispensable reference for anyone trying to write their own firmware.

Edit 11 Jan 2010: I just learned a third important thing: Erasing is not optional.

The LPC2148 appears to have NOR flash, which when erased reads all ones. You can program any particular bit to be zero, but to change a bit back to one, you have to erase, which sets all the bits in an entire sector (4kiB or 32kiB) back to one. I had previously ignored this.

When I wrote back an exact copy of the bootloader when it was already there, I didn’t change any bits, so it appeared to work. However, when I wrote a new boot loader, old 1 bits that needed to be changed to 0 were, but old 0 bits that needed to be changed to 1 were not. So it is no wonder that it didn’t work, and even when I wrote back the original bootloader after writing a new bootloader, it didn’t work. I was getting the bitwise AND of the two bootloaders, which definitely isn’t valid code. Once I erased the chip, I could put the original bootloader back on with no problems, and the part is now officially unbricked. :smiley: