ORBTrace for flashing FPGAs

ORBTrace isn’t just good for CPUs, it can wiggle anything with a JTAG interface. For illustration, here’s how to use it to bootstrap another ORBTrace device using openFPGAloader.

openFPGAloader, as its name implies, programs FPGAs. Fortuitously it supports ORBTrace as one of its programming interfaces, so we can use the pins on the right hand side of it to reprogram another ORBTrace device from scratch. It’s worth noting that in reality you wouldn’t normally need to do this, you can normally use dfu…but since we’ve got dogfood, we’d best demonstrate we can eat it.

If you’ve got an uncased ORBTrace mini you’ll see the Gnd/TMS/TCK/TDI/TDO pins that are connected to the FPGA towards the lower left hand side of the board. You can connect those to the corresponding programming pins on the ORBTrace you’re going to use for programming. Overall, the setup will look something like this (I’m using a pogo-pin adapter to avoid needing to solder to the pins);

Once it’s wired up, we can check it’s possible to detect the target device FPGA as a first step. Power up the target and then let’s start by turning power on to the FPGA interface on the ORBTrace we’ll use for programming (otherwise there’s no drive to the pins);

>orbtrace -p vtref,3.3 -e vtref,on

OK, now let’s find the target;

>openFPGALoader -c orbtrace --detect
Found 1 compatible device:
	0x1209 0x3443 Orbtrace
index 0:
	idcode 0x1112043
	manufacturer lattice
	family ECP5
	model  LFE5UM-45
	irlength 8

If you run openFPGAloader with the –list-fpga argument you’ll see a list of all the devices it recognizes. The specific device your run reports might vary depending on exactly which FPGA is installed in your target (The first batch are LFE5U-25s and will report an ID of 0x41111043), but the principle holds.

Before we start programming, we need to take a quick detour into how ORBTrace boots, otherwise things won’t make too much sense. When the ECP5 FPGA wakes up it initially loads a boot gateware from the start of the flash. If it doesn’t see the programming button held down this gateware will then try to boot the ‘production’ gateware from a displacement of 0x1000000. If the programming button is held down it’ll go into dfu mode so new programming can be loaded via the usb port. In normal use that dfu interface is quite sufficient, but that wouldn’t be a very good demo of reprogramming using openFPGAloader, so we’re going to ignore that.

Assuming you’ve got the boot gateware built (refer to the orbtrace github repository for more info on how to do that) we can burn that directly into the flash at zero displacement, and then verify that it made it there safely and in good order;

>openFPGALoader -c orbtrace -o 0x0 --bitstream build/orbtrace_mini_dfu/gateware/orbtrace_mini.bit --fpga-part LFE5UM-45 --verify -f
write to flash
Found 1 compatible device:
	0x1209 0x3443 Orbtrace
Open file DONE
Parse file DONE
Enable configuration: DONE
SRAM erase: DONE
Detail: 
Jedec ID          : 01
memory type       : 60
memory capacity   : 17
EDID + CFD length : ff
EDID              : ffff
CFD               : 
flash chip unknown: use basic protection detection
Erasing: [==================================================] 100.00%
Done
Writing: [==================================================] 100.00%
Done
Verifying write (May take time)
Read flash : [==================================================] 100.00%
Done

Once this is complete you’ll see the Status LED of your target device flashing Red and Yellow. That’s because the FPGA is loading the boot gateware and then trying to load the production gateware immediately afterwards…but that doesn’t exist yet, so it enters a boot loop (You might get a displayReadReg error at the end of the programming sequence above because the chip is automatically rebooting…you can safely ignore it).

If you press the programming button during this loop the device will enter dfu mode, but don’t do that, we’ll load the production gateware using the JTAG interface too. You will need to have built that using the instructions in the github repository, then (note the subtly different path to the gateware file);

>openFPGALoader -c orbtrace -o 0x1000000 --bitstream build/orbtrace_mini/gateware/orbtrace_mini.bit --fpga-part LFE5UM-45 --verify -f
write to flash
Found 1 compatible device:
	0x1209 0x3443 Orbtrace
Open file DONE
Parse file DONE
Enable configuration: DONE
SRAM erase: DONE
Detail: 
Jedec ID          : 01
memory type       : 60
memory capacity   : 17
EDID + CFD length : ff
EDID              : ffff
CFD               : 
flash chip unknown: use basic protection detection
Erasing: [==================================================] 100.00%
Done
Writing: [==================================================] 100.00%
Done
Verifying write (May take time)
Read flash : [==================================================] 100.00%
Done
Refresh: DONE

At the end of this step the Status LED will turn solid green. Congratulations, you’ve just programmed an ORBTrace from the bare state.

openFPGAloader is pretty flexible, and supports a wide range of FPGAs. For us, the key is to include the -c orbtrace option on it’s command line, then ORBTrace is a fully functional FPGA interface for use with it.

You thought you were getting a JTAG/SWD/TRACE interface, but you got a FPGA programmer for free too.