With a lot of my projects I have done my prototyping with Paul Stoffregon’s Teensy series of boards before moving them onto their own codebases. On those occasions where the “prototype was all I needed” I would compile the code using the teensyduino and then manually load the .hex file onto the target. As I am looking at using the arduino for more projects I decided to take a look at how paul interacts with the Arduino IDE and see if I could load code directly onto my chips.
boards.txt
The arduino allows for different chips and configurations through the boards.txt and the programmers.txt files. Each configuration usually will also have a “core” which maps the pins and handles the particulars of that chip. When you run paul’s teensyduino installer it adds several entrys to the boards.txt file including the entry below.
teensy_ser.name=Teensy 1.0 (USB Serial) teensy_ser.upload.protocol=halfkay teensy_ser.upload.maximum_size=15872 teensy_ser.upload.speed=38400 teensy_ser.upload.disable_flushing=true teensy_ser.upload.avrdude_wrapper=teensy_reboot teensy_ser.build.mcu=at90usb162 teensy_ser.build.f_cpu=16000000L teensy_ser.build.core=teensy_serial teensy_ser.build.post_compile_script=teensy_post_compile teensy_ser.name=Teensy 1.0 (USB Serial) teensy_ser.upload.protocol=halfkay teensy_ser.upload.maximum_size=15872 teensy_ser.upload.speed=38400 teensy_ser.upload.disable_flushing=true teensy_ser.upload.avrdude_wrapper=teensy_reboot teensy_ser.build.mcu=at90usb162 teensy_ser.build.f_cpu=16000000L teensy_ser.build.core=teensy_serial ...
############################################################# fouryou.name = atMega32U4 fouryou.upload.protocol=atmega32u4< fouryou.upload.maximum_size=32256 fouryou.upload.speed=38400 fouryou.upload.disable_flushing=true fouryou.upload.avrdude_wrapper=dfume fouryou.build.mcu=atmega32u4 fouryou.build.f_cpu=16000000L fouryou.build.core=teensy_serial ############################################################# tooyou.name = atMega32u2 tooyou.upload.protocol=atmega32u2 tooyou.upload.maximum_size=32256 tooyou.upload.speed=38400 tooyou.upload.disable_flushing=true tooyou.upload.avrdude_wrapper=dfume tooyou.build.mcu=at90usb162 tooyou.build.f_cpu=16000000L tooyou.build.core=teensy_serial ############################################################# fouryou.name = atMega32U4 fouryou.upload.protocol=atmega32u4 fouryou.upload.maximum_size=32256 fouryou.upload.speed=38400 fouryou.upload.disable_flushing=true fouryou.upload.avrdude_wrapper=dfume fouryou.build.mcu=atmega32u4 fouryou.build.f_cpu=16000000L fouryou.build.core=teensy_serial ############################################################# tooyou.name = atMega32u2 tooyou.upload.protocol=atmega32u2 tooyou.upload.maximum_size=32256 tooyou.upload.speed=38400 tooyou.upload.disable_flushing=true tooyou.upload.avrdude_wrapper=dfume tooyou.build.mcu=at90usb162 tooyou.build.f_cpu=16000000L tooyou.build.core=teensy_serial
I started with a blank script that just printed the arguments passed to the wrapper and then called it by restarting my Arduino (to reload the boards.txt) And then selecting one of the new boards and “Uploading” my code. This gave me a window to interactively work through my script. Since the avrdude_wrapper code just pretends to be an avrdude most of the script is munging the arguments passed to avrdude to get the commands to pass to dfu-programmer.
#!/usr/bin/perl use Getopt::Std; print @ARGV; my %args; my $hexfile; my $dfu = "/usr/local/bin/dfu-programmer"; my $cpu; my $hexfile; getopt('pUc',%args); $hexfile=$args{U}; $hexfile =~ s/flash:w://; $hexfile =~ s/:i//; $cpu=$args{c}; print "n[" . $hexfile . "]"; print "n[" . $cpu . "]n"; print "$dfu $cpu erasen"; system "$dfu $cpu erase"; print "$dfu $cpu flash $hexfilen"; system"$dfu $cpu flash $hexfile"; print "$dfu $cpu startn"; system "$dfu $cpu start 1>&2"; print "n";
There is one tricky bit. The current avr-gcc doesnt support the atmega32u2 correctly but the code for the at90usb162 is binary compatible so the build.mcu is set to the at90usb162. But then dfu-programmer supports the correct chip and wont find the device so we use the fact that the upload.protocol argument is passed directlyalong using the -c argument and everything works fine.
So now we just use the hwb and reset buttons to get the system into dfu mode and upload our code directly from the arduino. Its not as slick as the teensy in “auto” mode but it works.