Running Paul Stoffregons's teensy_serial arduino core on DFU based chips.

das blinkin

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
...
Looking at pauls additions to the boards.txt I see that he is using the teensy_serial core that he has written to create a simple usb to serial interface and to map the usb avr pins and other peripherals to the arduino conventions. He is also adds an entry to the arduino uploader class which lets him use a wrapper for avrdude which lets him use his proprietary bootloader. This wrapper is installed by the Paul's installer and lives in the Arduino's bin directory. After looking to see if this wrapper was a script I replaced the entry in the boards.txt and put a script into the bin directory called "dfume", after seeing that my replacement wrapper worked I added two new entries for each class of avr that I wanted to use the atmega32u2 and the atmega32u4

#############################################################

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 erase\n";
system "$dfu $cpu erase";
print "$dfu $cpu flash $hexfile\n";
system"$dfu $cpu flash $hexfile";
print "$dfu $cpu start\n";
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.

Comments

Thanks

Thanks very much for the how-to to get the arduino to run with other chips! I plan on making a hackable project using an ATMEGA32U2 (has USB). Do you think the arduino would work with this? I reckon it would as i have found out (from your infromative page, above), you can use any programmer you like woo!

Cheers,

James


ongoing maintainence....

Hey Don, I think you're the first person to ever really dig into this particular portion of work I've done. Wasn't it nice of me to go to the extra trouble to make this configurable from boards.txt?

At the time, the Arduino Team had started talking about wanting to do more to support 3rd party boards (and they continue to say such), and at least one other person was making a lot of noise about wanting to interface a simulator to the Arduino IDE. I wrote it this way to contribute back to the project, and indeed I submitted it as a patch.

Since then, I've learned 2 fairly unpleasant things about working with non-Arduino hardware on Arduino:

1: they rarely accept outside contributions, even when there is a clear consensus to do so.

2: the platform is a moving target - the code changes pretty substantially every few months

Of course, my patch was rejected, as were a few others, even one I wrote because they specifically asked for it on the public developer mail list. Since then, six new versions of the code have been published, nearly all of them breaking every patch.

James, my main point is not to underestimate the ongoing maintenance required if you go down this path. Going off the '168 & '328 path is not easy, and once you've gotten it to work at all, you've only just begun the long-term work.

Even Arduino Mega users suffer STILL quite a bit of pain with ongoing compatibility issues (eg, Ethernet, Firmata, analogRead(8 to 15) in 0017, etc), now nearly a year after that board's release.

So far I've resisted doing what pretty much everyone else has done for significantly different hardware (illuminato, leaflabs maple, etc), which is completely forking the entire Arduino code base. But certainly that has been suggested to me, in fact very strongly and passionately by a particular person as I recall at some local Dorkbot meetups!

In hindsight, that would have been a lot easier. I still might get fed up and go that route.......


yeah. well..

Paul,

I think going back to barrigans code an really coming up with a library based system would serve us all well. I would even go so far as to suggest scrapping the .pde and exposing the .cpp files.

The baggage that the arduino team is packing around is pretty considerable and they don't seem to be learing anything (they start with an 80 platform they end with an 80 platform and they really dont add much value in the process).

I will certainly support and contribute to any effort to branch the wiring code into what the arduino should be.

James. the board on the left is an atmega32u2...


Short term and long term plans

In the short term, I'm focusing pretty heavily on developing new USB types and testing/porting libraries. I'm also going to pay some much-needed attention to stuff on my website that's been long neglected. It all eats up lots of time, as I'm sure you're well aware.

Long term, though, I would like to think about the IDE side. There are at least 2 pretty ambitious ideas I'd like to pursue that probably aren't feasible by patching. My patches have already grown from only a dozen changed lines to about 400 in development now, though some of that is fixing bugs in their code which have really started to annoy me. A good portion of the newest code is also taking some Teensy-specific liberties in the Tools menu. :-)

If there's time next Monday, or whenever, I would like to hear your thoughts on what Arduino should be. Last time we talked about this in person, months ago, the only clear picture I came away with was a euphemism about what to do to the Italians.

Just know that my top priorities right now are USB types, testing/porting libraries, and website improvements.


The core is in the Andies, F*** the Italians.

I notice that wiring supports multiple platforms, Its seems that it should be a no-brainer to get the teensy++ or the 2.0 both of which internally have much more in common with the mega128 than the mega8. Have you considered approaching the wiring team about rethinking the design.


ummm, not a no-brainer, not even close

Teensy is dramatically different than the mega128, mega8, '168, '328, '1280, etc, all of which interface via the FTDI chip. It's impossible to depend on rxtx and avrdude, as all other boards do. Java simply lacks the ability do to this stuff. The one Java library I found (admittedly about a year ago) only really worked on linux and sort-of worked on windows, and had zero support for macos. For a long time, this limited me to only the CDC serial option. Teensy is simply different, in that is often isn't serial at all, and that it effectively disconnects and re-enumerates.

I'd have to port all my Arduino hackery over to Wiring. So not fun. Have I ever mentioned how I really don't like working with Java? Then there's the matter of the Serial library in Wiring. I'd have to heavily patch that somehow, or work around with some funny compiler -I trickery, so my utterly different serial emulation code would be used even if a sketch contains #include <Serial.h>. Everything I'd done over in Arduino depends on that being part of the core (or "target" in Wiring speak). The difference between native Serial vs native USB is the huge problem. Neither Wiring nor Arduino offer a way to override libraries depending on the core/target (actually, the latest Arduino might... it's undocumented and I haven't dug through that java code to figure it out yet). A hardware specific library like that makes everything much harder, especially if it's Serial that would be used by all existing code. Very ugly tricks would likely be needed. Then it's a whole 'nother platform to test, time 3 operating systems. So not a no-brainer.

But after all that effort, what would the point be? Other than F***ing the Italians? Really, what does Wiring have that Arduino doesn't? Certainly it's not the user base, as nobody except you has ever asked me to port all this stuff to Wiring. And to be honest, if there aren't people actually using it, I probably won't keep up with maintaining it.

So the bottom line is, if I'm going to port to another platform, there better be both short-term and long-term benefit for real customers. So far, I can't see either in Wiring, since there seems to be virtually zero immediate demand for Teensy on Wiring, so I can't see any short-term benefit. Unless I've missed something wonderful about Wiring that doesn't existing in Arduino, especially if supporting Teensy on Wiring would be merely feature parity with Teensy on Arduino, then it's hard to see any long term benefit either.

Maybe I've simply missed something about Wiring? What does it have, other that not being a product of Italy, that makes it such a compelling platform to support?

If I were going to support a completely different platform, why not target something like code::blocks which is built around the scintilla editor?


Blah Blah

Branding. Blah Blah Status quo. Blah Blah. Lost in the unimportant details. Blah Blah. Product. Blah

The thing you missed is the stability of something that is what it is: The foundation and stability of every thing that is good about the ...duino.


I again apeal to your better senses.

Get rid of the IDE and focus on the targets/cores.

A teensy++ with a cdc bootloader should work with very little modification. I am not going to be at the next meeting but if you want to have a beer sometime we can discuss this.