Arduino Due

Arduino Due mBed Support

This page is documentation of my efforts to add mBed support for the Arduino Due board, which is based on the Atmel SAM3X8E chip. That chip is a Cortex M3 which runs at 84 MHz with 512 kB of flash and 100 kB of SRAM.

You might ask why I would want to do this, given the huge range of cheaper mBed platforms that already exist. The main reason is that the SAM3X8E is one of the very few (perhaps only?) chips that supports USB High Speed (480 MHz). As far as I can tell all existing mBed platforms only support USB Full Speed (12 MHz).

How the SAM3X8E is programmed

Traditional mBed boards feature an "interface chip" which provides the USB Mass Storage interface to the computer to receive your program binary, and then programs the target chip (e.g. LPC11U24) via SWD. The Arduino Due does have an interface chip that is used for programming, but it is not loaded with the mBed interface firmware so it must be programmed in a different way.

The Arduino Due actually has two methods for programming the chip. There are details about them here.

The SAM3X8E comes with a factory-programmed ROM containing a bootloader called SAM-BA which is run when the ERASE pin is asserted during a reset. This can be done by pressing the erase button on the Due, or via software (described later). Once the SAM-BA bootloader is running it starts a USB CDC (USB serial) device up on the serial port (the "native USB" port on the Due), and also monitors its UART pins for connections. Either of those can be used to program the chip. The UART is connected to an interface chip on the Due - an ATMEGA16U2, which provides the "programming" port on the Due. The SAM3X8E can be programmed via either communication channel.

To reset the chip without having to press the button, there are two software methods. The first is to use the programming port - when the ATMEGA16U2's USB serial port is opened and closed at 1200 baud it asserts the ERASE pin. The second is using the native port - when you compile an Arduino program it links in extra code which monitors for a 1200 baud rate on the native port's USB serial port and reboots into the SAM-BA bootloader so it acts identically to the programming port. Since we will not be using Arduino's code, this method will not work with mBed (without extra effort at least). But little is lost so it doesn't really matter.

Of course, in addition to these methods, you can use JTAG or SWD to program the chip directly, but this requires a JTAG or SWD programmer and extra connections which is more of a pain. It does allow debugging though.

Software to program the chip

Once you have the SAM-BA bootloader started, and can talk to it either through the native USB port directly to the SAM3X8E, or via the programming port with the ATMEGA16U2 acting as a USB-to-serial adapter, you need some software that sends your binary to the chip in an appropriate format.

The "official" software is also called SAM-BA, and is a large complicated TCL/TK application. Fortunately some clever people have written a simpler open source alternative called BOSSA (yeay contrived acronyms!). This is the program used by the Arduino "IDE" behind the scenes. It serves the same purpose as avrdude.

However, note that the original BOSSA code has not been updated for a while and does not support the SAM3X8E. Instead we must use one of the updated forks from github. The latest one as far as I can tell is 8devices' which has the version number 1.5-arduino, though I have just noticed commits in the original (shumatech) github adding support for Arduino things, so maybe that works too now. The latest "official" release - 1.2 - definitely does not work.

ASF vs Arduino

There are two possible places we could get source code to port to mBed: the official Atmel Software Foundation libraries, or the Arduino source code. After trying both, it turns out the ASF is much easier - all the code is there (Arduino removed a lot of drivers for example), and they even include board definitions and makefiles for code that works on the Arduino Due!

mBed porting requirements

This handbook page gives some helpful details on how to port another board to mBed. Basically the things we must do are:

1. Reorganise the ASF code into the mBed file tree structure. 2. Get the CMSIS code working, which is the basic code which lets us write an empty program and upload it to the board. 3. Implement the HAL code for timers and GPIO.

Code organisation

I wasn't too sure about this, but I have rearranged most of the ASF code into an mBed file structure. I mostly copied other targets, but some do it differently to others so I'm not 100% sure about the layout. Also I'm not using the "official" offline mBed build system (because QBS is awesome), so maybe it is a bit wrong.

I saved a *lot* of space by deleting all the documentation and example folders, but it is still quite a lot of code (22 MB). Most of that is unused drive code.


The main thing is that you don't need the syscalls.c file from ASF since those are handled by retarget.cpp.

HAL: Timers

For this I used the "tc" (Timer/Counter) driver code. The SAM3 chips come with timer modules that each have three channels. To get a 1us tick you need to use the first channel as a 1/84 prescalar (the chip runs at 84 MHz) and then get that channel to feed into the other one. It's not a lot of code.


There are actually two drivers in the ASF for GPIO - one is called GPIO, but Atmel have deprecated that and recomment its replacement "portio". Again this is not much code, though I'm not sure I really understood the set_pin_function() function. It works anyway.


TODO: This is a WIP - instructions and code coming soon.