ATXmega64D4 support for Arduino

ATXmega64D4 ATMel Info Page
ATXMega64D4 on a TQFP44 breakout board from Adafruit

PROJECT STATUS (as of 10/27/2014)

General Project Features


Background

A customer of mine wanted to improve an existing ATmega device that ran on 3.3v (for various design reasons, such as hardware being controlled by an ATmega processor that only runs on 3.3v). That device used the Arduino development environment, as do several of my own projects. As Arduino lends itself to rapid prototyping, the next step is often to design a board of your own with an ATmega processor on it that duplicates what the Arduino board does, but is directly wired to your controlled hardware. In this case, that is exactly how it was set up.

Unfortunately, the existing customer device was too limited by the ATmega CPU. I suggested upgrading to an ATXmega device, based on information I received from an ATMel sales representative that I'd met some time ago at a San Diego Hardware Hackers user group meeting. The ATXmega devices are very much like the ATmega devices, except that they run on 3.3v and have internal clocks, additional capabilities, and completely different register mapping for I/O. So it wasn't a drop-in replacement, but the potential existed for 'dropping it in' so long as some additional software work was done.

Like with many small businesses that are developing 'electronic things' to sell, my customer had a limited budget. Unable to afford a pile of effort needed to support the desired processor, I volunteered to contribute to the open source community and do the work necessary to implement support for the ATXmega64D4 processor (a relatively simple modification, once I had a proper header file for that CPU) and the MORE DIFFICULT changes needed to support the CPU for Arduino, which included a bootloader that is capable of flashing firmware.

The ATXmega64D4 is probably the wisest choice of CPUs for this particular project. First, it has TWICE the code space of an ATmega328. Second, it's a TQFP44 footprint, only slightly larger than the ATmega328 (so it could still fit on the board, with a little effort). Third, it has the additional I/O pins that were required for the project, as well as 4 times the clock speed (the ATmega328 was restricted to 8Mhz due to the 3.3v supply). And as it all turned out, it worked VERY well, providing my customer with what he needed to present to the investors, and ultimately continue its development.


A Sample Project

To prototype the device, I searched for useful boards, and NONE were using this particular CPU. However, at the time there was an inexpensive generic TQFP44 breakout board (OK it used to be available from Sparkfun, see left, but isn't any more) that worked PERFECTLY for building a simple prototype. All I had to do was wire up the ISP header and a power supply, and provide some female headers for plugging wires into. I built two different versions of these, and 'upgraded' the one you see here to include extra LEDs and an 'FTDI Friend' compatible pinout. In any case, the end result of the original 2 prototypes was something that was a _little_ difficult to work with, but very effective for prototyping the customer's hardware being driven by an ATXmega64D4 processor, and to allow a 3rd party to write custom software to do firmware upgrades and data transfer, 2 months before the actual (assembled) boards arrived.

In the photo to the left, you can see one of the Sparkfun breakout boards with an ATXmega64D4 soldered on. There is also an ISP header (bottom, left), and a set of female headers exposing ALL of the device's pins. The 4 Vcc and 4 ground pins are soldered together under the board, and there are some 0.47µF filter capacitors across the power pins. Vcc is applied where the power LED is (at the right side) and must be 3.3V regulated. The breadboard at the top has a 3.3v regulator (left), some LEDs, and an 'FTDI Friend' (available from Adafruit) connected by jumper wires to one of the serial ports on the xmega. The default LED output is connected to an LED and resistor (to ground) on the breadboard. Some additional components are also on the breadboard, which had been used for testing, and aren't currently connected. The disconnected black wire (lower left) is connected to the reset pin on the xmega.

With a lack of TQFP-44 breakouts from Sparkfun, I checked elsewhere for something equivalent. I found something BETTER. Adafruit now has a breakout board that works VERY well. In fact, they have a LOT of breakout boards now (but unfortunately, no TQFP-100's). There is a photograph of a working prototype with an ATXMega64D4 on an Adafruit breakout board at the top of this page. To the right of the device is a small LED + ISP/PDI header and the power supply cable for 3.3VDC, taped on with white electrical tape. There are a handful of 'blue wires of salvation' on the board, basically wiring up the power and a couple of bypass capacitors, plus wires to the LED+ISP/PDI board at the right. And what you get is something that's mostly wired up for power and ISP programming that can be PLUGGED IN TO A BREADBOARD. In many ways it's like some of the breadboard-capable Arduino clones out there [and they are VERY handy for testing things]. But you can somewhat easily make your own ATXMega64d4 version, at a reasonably low cost, and that's the point.

Because the ATXmega series have a BUILT-IN 32Mhz clock (no external resonator or crystal required) there is no external oscillator nor resonant circuits needed. This makes it VERY simple to create a near-Arduino-compatible device using a simple breakout board and some extra wiring underneath the board to wire up the essential things (power, ground, filter caps, ISP header).

One important detail about the xmega series is that the old way of flashing a bootloader wasn't going to work. I was able to obtain an AVRISP Mk II from a well-known electronics distributor, however, and this device works for both the ATMega and ATXmega devices. Further, I am still able to use 'avrdude' (the open source AVR flash program, that Arduino also uses) to flash using the AVRISP Mk II, under FreeBSD even. So no problems at all getting the hardware to accept an image, once I had updated the AVRISP Mk II firmware to the latest version.

With that out of the way, it was just a matter of wiring up an ISP header (only 4 lines are used for the xmega, vs 6 for the ATMega devices, so the 'middle 2' pins are unconnected) and programming the device.

One caveat remained: The boot section requires a special programming method. In short, you can't use the normal address offset for the code section, since it will not write the boot section from there. Instead, you must specify the boot section. Even though the bootloader was correctly assigned a start address of 10000H, the boot section's offset starts at 0000H, so you must program the first byte of the image at 0000:0000H. To solve this problem, I did a simple text edit of the original 'hex' file, and created a modified 'hex' file in which the initial address offset of 10000H is "left out", thus (effectively) specifying 0000:0000H. The bootloader flashed perfectly.

Initially I flashed code images using the AVRISP Mk II, until I was able to get serial programming working with the bootloader. Following that, I was able to program applications using the Arduino environment itself, as if it were an Uno or other Arduino/compatible device. Therefore, the net result of my efforts was to be able to write an Arduino script and program it onto an xmega-based device using the Arduino IDE, just as I would any other Arduino/compatible device.


Building an actual Arduino Compatible Device

a hacked-up prototype of an arduino using an xmega64d4

As an experiment, I actually built an Arduino-compatible device using the ATXMega64D4 processor. As you can see at the right of the page, there's a board with Arduino-style pins and a 44-pin breakout board wired up to it, with an ATXMega64d4 on the breakout board. The red board underneath is a blank shield board from Sparkfun. Since I had no intent to actually use it as a 'shield' I just got the blank board, which is SO handy! The serial port pins on the side were for Sparkfun's bluetooth serial adaptor. But I need to use it for the Adafruit FTDI cable (same pinout as FTDI Friend) and so I had to 'hack' it a bit to make it work. So cut the power and ground pins, connect ground to one side, and hook a capacitor and resistor for the reset line, and VOILA! Now, the serial flash process works PERFECTLY! And I also have the ISP header already on the shield board on top of THAT. You couldn't ask for a better 'starting point' for setting up an Arduino clone board, except maybe an actual Arduino board (minus the CPU connections).

Of course, this is a 3.3v board. The ATXMega64D4 doesn't work at 5V. But for compatibility with my OWN shields, I wired the 5V and 3.3V pins together. 5V was already wired up to the appropriate Arduino pin and broken out as a bus, and also on ISP and a couple of other places. So wiring them together was the simplest way of making sure I power up with 3.3V, but have 3.3v available for shields on the 3.3v line. Ok so it's not 100% compatible, but there you go. It demonstrates the concept and works with my TFT shield. That and I didn't want to cut any traces. But it _IS_ something to be aware of if you make your OWN 'Arduino Compatible' with the Sparkfun shield board.

So with a bit of patience on the blue wires to each of the appropriate pins, I wired up the ATXMega64D4 processor to match the definition in the 'pins_arduino.h' header file for the 'xmega64d4' variant. There's an ASCII art diagram for it. Wiring up wasn't too hard, actually, and only took the better part of an afternoon to do it (with occasional profanity, of course, as I can't seem to solder anything tedious without it).

another view of a hacked-up prototype of an arduino using an xmega64d4

I tested this configuration with the ultimate test: a TFT 'shield' I created for an Arduino Uno. It has a color TFT device (that I got from Adafruit, probably 2 years ago) that also has an SD card slot on it. I've tested with this firmware before, and so it was just a matter of doing a build for the 'atxmega64d4' variant and VOILA! It works! Screen updates are twice as fast as the Arduino Uno because the clock is at 32Mhz, and that affects SPI speed and the time it takes to refresh the TFT and read files from the SD card. So in short EVERYTHING is twice as fast, and the SD card and TFT can both handle the higher clock speed.

FYI - the cable at the left is an Arduino-style power connector, and the cable at the right (with the 2 pins) is for the TWI pins. Arduino Uno Rev 3 and mega2560 Rev 3 both break out separate TWI connections that aren't in the pinout for the earlier devices. In this case I mapped the TWIC pins from PORTC, pins 0 and 1, to be unique TWI outputs on these 2 pins. Unfortunately the shield board didn't have pins for these (it uses the old layout). So I broke them out on a separate connector so that it wouldn't interfere with shields being plugged in, but I could still access them to experiment with TWI (I still need to work on it).


On a related note, the picture at the right is of an ATXMega128A1U ('u' being for USB support) on an inexpensive 100 pin QFP breakout board, which is then 'stilt mounted' onto a Radio Shack proto board that supplies power and has plugs for the serial port and ISP header. Solid copper wires plug into the appropriate holes on the board. I'll need to add some ground and power busses (and a USB connector for testing the USB capabilities of the ATXMega128A1U) but for NOW this tests that particular CPU pretty well. And yeah, it's got 100 pins. The cpu really is a bit of a 'monster', with THAT many I/O pins, *AND* external RAM support, Yeah. Soldering the chip onto the breakout board was tricky. I messed one of them up, had it rotated 90 degrees 'cause there are THREE marks, not just one, and you can't see them all properly unless you shine the light on it 'just right', but if you get the text oriented right side up, the pin one mark is in the upper left corner. The chips are kinda pricey, too, so you want to know what you're doing. But it IS possible with a standard soldering iron, as long as you don't put too much solder onto the pads. Use a LOT of flux, a TEENY amount of solder 'on the iron', slide it back and forth until all of the pins look good under a loupe. YES, under a loupe. Normal eyes can't see these things without magnification.

If done carefully, you can use good quality solder wick to remove excess solder that is causing pin-to-pin shorts, if you can't merely 'slide it away' using a soldering iron. And a flux pen is mandatory for successfully soldering those 'too small to see properly' pins. Fortunately, flux pens are cheap, and so are loupes [digikey stocks plastic ones, I have 2 on hand], and if you work with modern electronics, you really SHOULD own a loupe and a good lighted magnifier.

All of the power pins on the CPU are connected to 0.1" male breakout pins, that plug into corresponding female pins underneath. The female breakout pins were individually cut and soldered onto the board. OK it was difficult doing it this way, but it make the board pluggable in case I need to switch it out or fix something, and also exposes EVERY! SINGLE! NON! POWER! PIN! on the ATXMega128A1U. [so I'll need power busses on the power supply 'support' board underneath, at some point].

I built this because I am currently adding support for additional ATMel 'xmega' CPUs, not just the ATXMega64D4, to the XMegaForArduino project. The ATXMega128A1U is one of those.



Customizing the Arduino Environment for YOUR Hardware

Some time ago I submitted a short article to the Arduino Playground wiki site regarding customization of the Arduino IDE for different kinds of hardware. In short, I described what I had done so far with respect to the ATXmega64D4 processor and the customer's device. There are several specific modifications that need to be made, all of which are necessary to make the Arduino IDE work with a new type of processor.

Although there is already a GitHub project for an 'xmega' version of the Arduino IDE, I did not see the need to modify the entire thing just to handle a new CPU. In fact, it seems so easy to modify the existing Arduino IDE with a simple patch, that the need for modifying the entire environment was just too impractical. It also makes it VERY easy to update to a new version of the IDE. I based my modifications on Arduino 1.05 since that's what I had installed under FreeBSD.

The sub-directories I list here exist within the Arduino IDE directory tree. Typically this will be /usr/local/arduino (as on FreeBSD), or /usr/share/arduino (as on Ubuntu 12.04). On windows or OSX, your mileage may vary.


The 'boards.txt' file

The 'boards.txt' file resides in the Arduino IDE's 'hardware/arduino' sub-directory, and contains entries that describe the various board types, and the correct sub-directories and compiler CPU settings to use when compiling for that particular board. Using the supplied patch file (or manually editing boards.txt) allows you to specify a new board type for an ATXmega64D4 device. An appropriate entry would describe the 'cores' and 'variants' sub-directory as well as the flash method and CPU for your particular hardware. If you examine the 'boards.txt' file, you will find a number of different Arduino and compatible devices listed. When you look in the appropriate 'cores' or 'variants' sub-directory, you'll see CPU-specific and board-specific implementations of the Arduino API functions and definition files. Setting these correctly in 'boards.txt' allows you to customize the Arduino IDE to work with whatever board configuration you might have, so long as it is possible to map everything properly.


The 'cores' sub-directory

Within the 'cores' sub-directory are a number of CPU-specific sub-directories, each named according to the type of device. The main directory is 'arduino', and corresponds to the ATmega328p (and related) CPUs for Arduino and compatibles. The corresponding entry in the 'boards.txt' file will be 'xxx.build.core', where 'xxx' is the name for your boards.txt entries, and the entry value will be the sub-directory name (such as 'arduino'). The source and header files within this sub-directory implement the startup code (device initialization), the timer functions, the serial port, and both the analog and digital I/O, as well as a few other features (like the 'Tone' library). In short, it's a hardware abstraction for the type of CPU you are using, but is generally NOT board-specific.
On non-windows systems, it is possible to use a symbolic link to point to a directory containing your own implementation. This is recommended for OSX, Linux and BSD installations, so that you do not have to modify the actual Arduino directory structure.


The 'variants' sub-directory

Within the 'variants' sub-directory are a number of board-specific directories, each definining the pin-to-pin mapping for the various analog and digital I/O pins. In short, it implements the board-specific 'abstraction' header file 'pins_arduino.h'. For the 'xmega' implementation, D2 is mapped to digital pin 0, D3 to pin 1, and so forth, so that the serial port on port D will map to the same pins as the serial port on an ATmega328p.
On non-windows systems, it is possible to use a symbolic link to point to a directory containing your own implementation. This is recommended for OSX, Linux and BSD installations, so that you do not have to modify the actual Arduino directory structure.


The 'avrdude.conf' file

An additional file, one that is used by 'avrdude', is the 'avrdude.conf' file. It contains information that avrdude needs in order to flash a device. You can modify this file using the supplied patch file in the Arduino IDE patch tarball for the ATXmega64D4. Other ATXmega series processors should already implemented, though. It seems that only the D4 was missing, but as it is not supported by the existing avr compilers (without the patches I made), it is understandable.
The 'avrdude.conf' file is located in various places, depending upon your implementation. On FreeBSD, it is in /usr/local/etc/avrdude.conf . On Ubuntu 12.04, it is /etc/avrdude.conf . A symbolic link to this file is typically in the hardware/tools directory within the Arduino environment.


The 'sketchbook' sub-directory (in the user's 'Home' directory)

When you set up the Arduino IDE, you can specify a default sub-directory for your sketches. Typically this will be the 'sketchbook' directory within the user's Home directory. If you create a sub-directory 'libraries' within this sketchbook directory, and populate it with library sub-directories, the Arduino environment will search for libraries HERE, in addition to the default libraries in the Arduino IDE's directory tree. As such, if you need to customize a library (let's say the SD card library) to work with the xmega, you would need to make a copy of it into your own library tree, and modify the code accordingly. This also makes it possible to have customized library versions of just about any Arduino library, ones that contain fixes or implement specific functions that YOUR projects need. So if you do not want to modify the existing Arduino libraries to work with the xmega


My 'xmega' Implementation

Prior to a recent gcc version (4.8.3), there was no support for the atxmega64d4 for 'avr-gcc' (and related tools). As a result, I produced my own modifications for the compiler suite (which I then submitted to appropriate places).

Since it's entirely GPL code, I have made my modifications for the ATXmega64D4 publically available, as well as modifications to the build environment for FreeBSD, Debian 'Wheezy', and Ubuntu 12.04 . These modifications are to the source files themselves. Additionally there are binary packages available for Debian 'Wheezy' (i386) and Ubuntu 12.04 (amd64). Since the source packages for Debian and Ubuntu are also available in the appropriate tarball, you can extract them via 'dpkg-deb -x' (man dpkg-deb for more info) and build each of them using 'debian/rules binary' (see appropriate debian package manuals for more info on that). You would then individually install the binary packages (after each build) using 'dpkg -i', since you need binutils-avr to build gcc-avr, and you need gcc-avr to build avr-libc. And now you know what order to build/install them in. A full discussion of the building of these packages from source is beyond the scope of this particular web page, but may be added at a later time.

If you were to install the (older)'arduino.xmega.20140308.tgz' patches onto your computer, you would get an implementation in which the 'xmega' core type and 'xmega' variant type were both implemented. The 'boards.txt' patch file would create a new board type 'ATXmega64D4' that would allow you to program a device similar to the one in the photograph above. The system clock would behave as you expect (for micros() and millis() and related functions), as would the serial port, for standard baud rates (see code). Both analogRead() and analogWrite() would function, as would digitalRead() and digitalWrite(). However, being in 'beta' state, a few functions are still missing, such as the Tone library as well as additional library support for the standard Arduin libraries (such as SD card).
Current plans are to supply some (additional) modified libraries based on Arduino 1.06. Since these are all open source, modified versions can be made available for download here on the XMegaForArduino github site.
NOTE: You should download the zip file for the 'arduino' and 'libraries' repositories from the github site, or use 'git clone' to obtain your OWN copies. Then, copy/symlink the latest stuff into your Arduino environment. You can also get the 'patches' repository to apply patches to compilers and tools, as needed (they are source patches, for specific releases, so you would have to be able to re-build the correct releases from source).

Here is a short list of features:

Here is a short list of items to be completed:



Related ATXmega Projects and Breakout Boards



Notes on Debian and Ubuntu 'source' packages

In the 'Source Download' section, below, there are packages for Ubuntu 12.04 and Debian 'Wheezy' that were pre-built for specific architectures. If your architecture is different, you can build from source using a procedure similar to the following:

  1. Download the appropriate package tarball and extract the tarball contents into an appropriate directory
  2. For each of the 3 packages, do '[sudo] apt-get build-dep {packagename}' where 'packagename' is 'avr-libc', 'binutils-avr', and 'gcc-avr'
  3. Use 'dpkg-source' to extract the '.dsc' similar to the following:
      dpkg-source -x avr-libc_1.8.0-2.1.dsc
  4. change directory to the package source directory (in this case avr-libc_1.8.0-2.1) and do the following:
      fakeroot debian/rules binary
    This will build the package as a '.deb' in the same directory you extracted the tarball into.
  5. once the packages are built, you can install the package as follows:
      [sudo] dpkg -i avr-libc_1.8.0-2.1_[your architecture].deb
    The build+install order is avr-libc, binutils-avr, and then gcc-avr.
    NOTE: since avr-libc is an 'all' package, you probably won't need to build this one, and can install the 'all' version as-is. But if you want to re-build it anyway, you still can.




Official site for the Arduino Uno
'Playground' wiki site for Arduino on Freebsd

(Original) Source Download (as-is, GPL, no warranty)

These patches and source files implement the necessary support for the ATXmega64D4 processor.
NOTE: for newer files and 'other CPU' support, see the github site.
Back to S.F.T. Inc. home page

FreeBSD® is a registered trademark of the FreeBSD Foundation.
Debian is a registered trademark of Software in the Public Interest, Inc.
Ubuntu and Canonical are registered trademarks of Canonical Ltd.
Arduino brand is copyright of Arduino SA
AVR®, XMEGA®, and Atmel® are registered trademarks of Atmel Corporation

©2014 by Bob Frazier and Stewart~Frazier Tools, Inc. - all rights reserved
last updated: 10/27/2014

Community projects are generally good, but socialism, in all of its forms, is always evil.