week 3: fab isp

This week we learned how to use the Modela (a micro-milling machine), and were tasked with building and programming an in-circuit programmer (ISP), or a chip that can program other chips. This week wasn't about circuit design, so we didn't need to design the board from scratch, just cut it out with the Modela. I decided to use Andy's design, since I really liked the approach of using the board-edge USB connector rather than requiring a separate USB cable. So all I did was download the design images he posted and uploaded them to the Modela.

I taped the provided copper-plated FR1 stock to the machine bed, used the 1/64" mill first to cut the top traces, and kept the default settings in CBA Fab Module.

I then switched to a 1/32" bit to cut out the board.

I then headed upstairs to solder the components onto the board. The pieces were small, but luckily my group has this awesome microscope thing:

I put small balls of solder on one of the pads for each component first, then using a tweezer, soldered each component to the ball to keep it in place, then soldered the remaining pads.

Uploading the firmware to the board was the hardest part. I wasn't sure what software I even had to install on my computer, so I started out by assuming I had everything I needed and tried to upload the firmware directly to the board using the firmware code provided to us. Following the instructions, "make clean" and "make" worked just fine to generate the hex code, but "make fuse" obviously didn't work, complaining that I needed a command line tool called avrdude. I have a Mac and use homebrew to manage packages, so I used brew to install avrdude ("brew install avrdude"). It installed just fine, but upon typing "make fuse" again, it complained that avrdude wasn't compiled with usb support, making me realize I needed to compile it from scratch rather than using homebrew.

Eventually I found this tutorial from LadyAda, which helped me install avr-gcc and avrlibc just fine. Avrdude was still a problem though because even after following the compilation instructions, it still didn't have usb support built in. After some frustration, I eventually figured out the following (which works for Mac users who have homebrew):

I then attempted to uploaded the firmware code again, but got an error that it couldn't find the device called 'usb'. Following the instructions in the comments of the Makefile, I changed this line:

AVRDUDE = avrdude -c avrisp -P usb -p $(DEVICE) # edit this line for your programmer

to this:

AVRDUDE = avrdude -c avrisp -P /dev/tty.usbmodem00006663 -p $(DEVICE) # edit this line for your programmer

which replaced the placeholder "usb" device name with the actual port that my programmer was on. This was progress, but I still couldn't set the fuses on my board with `make fuse`. I kept getting a timeout error, so I used a multimeter to check that there were no shorts on my board, which there weren't. I eventually realized that the programmer I happened to have wasn't an "avrisp" as indicated, but rather an "STK 500", so I knew I had to change out the word "avrisp" in that line in the Makefile for something else representing "STK 500". It was hard to find a list of strings that avrdude accepted for the -c option, but it finally spit this out at me after I typed something that I can only assume it found sufficiently offensive:

Valid programmers are:
c2n232i = serial port banging, reset=dtr sck=!rts mosi=!txd miso=!cts [/usr/local/etc/avrdude.conf:791]
dasa3 = serial port banging, reset=!dtr sck=rts mosi=txd miso=cts [/usr/local/etc/avrdude.conf:778]
dasa = serial port banging, reset=rts sck=dtr mosi=txd miso=cts [/usr/local/etc/avrdude.conf:765]
siprog = Lancos SI-Prog [/usr/local/etc/avrdude.conf:752]
ponyser = design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts [/usr/local/etc/avrdude.conf:739]
pavr = Jason Kyle's pAVR Serial Programmer [/usr/local/etc/avrdude.conf:710]
dragon_pdi = Atmel AVR Dragon in PDI mode [/usr/local/etc/avrdude.conf:703]
dragon_dw = Atmel AVR Dragon in debugWire mode [/usr/local/etc/avrdude.conf:695]
dragon_hvsp = Atmel AVR Dragon in HVSP mode [/usr/local/etc/avrdude.conf:687]
dragon_pp = Atmel AVR Dragon in PP mode [/usr/local/etc/avrdude.conf:679]
dragon_isp = Atmel AVR Dragon in ISP mode [/usr/local/etc/avrdude.conf:671]
dragon_jtag = Atmel AVR Dragon in JTAG mode [/usr/local/etc/avrdude.conf:663]
jtag2pdi = Atmel JTAG ICE mkII PDI mode [/usr/local/etc/avrdude.conf:655]
jtag2avr32 = Atmel JTAG ICE mkII im AVR32 mode [/usr/local/etc/avrdude.conf:647]
jtagmkII_avr32 = Atmel JTAG ICE mkII im AVR32 mode [/usr/local/etc/avrdude.conf:639]
jtag2dw = Atmel JTAG ICE mkII in debugWire mode [/usr/local/etc/avrdude.conf:631]
jtag2isp = Atmel JTAG ICE mkII in ISP mode [/usr/local/etc/avrdude.conf:623]
jtag2 = Atmel JTAG ICE mkII [/usr/local/etc/avrdude.conf:615]
jtag2fast = Atmel JTAG ICE mkII [/usr/local/etc/avrdude.conf:607]
jtag2slow = Atmel JTAG ICE mkII [/usr/local/etc/avrdude.conf:599]
jtagmkII = Atmel JTAG ICE mkII [/usr/local/etc/avrdude.conf:591]
jtag1slow = Atmel JTAG ICE (mkI) [/usr/local/etc/avrdude.conf:584]
jtag1 = Atmel JTAG ICE (mkI) [/usr/local/etc/avrdude.conf:576]
jtagmkI = Atmel JTAG ICE (mkI) [/usr/local/etc/avrdude.conf:568]
butterfly_mk = Mikrokopter.de Butterfly [/usr/local/etc/avrdude.conf:562]
mkbutterfly = Mikrokopter.de Butterfly [/usr/local/etc/avrdude.conf:556]
avr911 = Atmel AppNote AVR911 AVROSP [/usr/local/etc/avrdude.conf:549]
avr109 = Atmel AppNote AVR109 Boot Loader [/usr/local/etc/avrdude.conf:543]
butterfly = Atmel Butterfly Development Board [/usr/local/etc/avrdude.conf:537]
usbtiny = USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/ [/usr/local/etc/avrdude.conf:531]
usbasp = USBasp, http://www.fischl.de/usbasp/ [/usr/local/etc/avrdude.conf:525]
avr910 = Atmel Low Cost Serial Programmer [/usr/local/etc/avrdude.conf:519]
stk600hvsp = Atmel STK600 in high-voltage serial programming mode [/usr/local/etc/avrdude.conf:513]
stk600pp = Atmel STK600 in parallel programming mode [/usr/local/etc/avrdude.conf:507]
stk600 = Atmel STK600 [/usr/local/etc/avrdude.conf:501]
stk500hvsp = Atmel STK500 V2 in high-voltage serial programming mode [/usr/local/etc/avrdude.conf:495]
stk500pp = Atmel STK500 V2 in parallel programming mode [/usr/local/etc/avrdude.conf:489]
stk500v2 = Atmel STK500 Version 2.x firmware [/usr/local/etc/avrdude.conf:483]
mib510 = Crossbow MIB510 programming board [/usr/local/etc/avrdude.conf:477]
stk500v1 = Atmel STK500 Version 1.x firmware [/usr/local/etc/avrdude.conf:471]
stk500 = Atmel STK500 [/usr/local/etc/avrdude.conf:465]
buspirate = The Bus Pirate [/usr/local/etc/avrdude.conf:455]
avrisp2 = Atmel AVR ISP mkII [/usr/local/etc/avrdude.conf:449]
avrispmkII = Atmel AVR ISP mkII [/usr/local/etc/avrdude.conf:443]
avrispv2 = Atmel AVR ISP V2 [/usr/local/etc/avrdude.conf:437]
avrisp = Atmel AVR ISP [/usr/local/etc/avrdude.conf:431]
jtagkey = Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2 [/usr/local/etc/avrdude.conf:408]
2232HIO = FT2232H based generic programmer [/usr/local/etc/avrdude.conf:382]
avrftdi = FT2232D based generic programmer [/usr/local/etc/avrdude.conf:355]
arduino = Arduino [/usr/local/etc/avrdude.conf:335]
wiring = Wiring [/usr/local/etc/avrdude.conf:329]

I tried all of the 'stk500' variants, but I still kept getting the timeout error. Eventually I just used Dan Novy's FabISP as the ISP for my ISP and it magically worked. I assume that the programmer I had was just broken in some way perhaps.

Also for a bit of fun, I tried to cut out a picture of Starry Night onto one of the copper plates. I downloaded the image, grayscaled it, thresholded it, and uploaded it to the modela. I kept most of the settings the same, but changed the "offsets" settings to 1 so that it could mill really fine detail. Didn't work too well though.