We’ve been big fans of AVR microcontrollers for a few years now. If you look around our site a bit, you might find quite a few AVR projects. And our little friends the ATtiny2313 and the ATmega328P have become our go-to chips for many different purposes.
And, while none of that is changing, something that just seems better has come along. Or rather, a better AVR has come along.
The new chips are the “XMega” family of AVR microcontrollers. They are, simply and fundamentally, feature-loaded, hot-rodded, more professionally-oriented AVR microcontrollers with a number of common traits. But there are some important differences between these and the older “tinyAVR” and “megaAVR” chips that are worth pointing out, and that we’ll get to.
Admittedly, to call these things “new” is a brush with exaggeration in the age of the internet. The Xmega family was announced more than two years ago, in the spring of 2008. Let’s say that up to now, they’ve been a little too new. A lot of things have come together recently that conspire to make it a ripe season for xmega experimentation:
- First, they exist. Like totally and for real. You can get your hands on them– No mere promises of samples, there’s actually distributor inventory.
- There are choices. While only two devices (the ATxmega128A1 and ATxmega64A1) were announced at first, there are now more than twenty different Xmega devices available. Atmel has had some time to flesh out the line, and they’ve made good use of it.
- The open-source tools are catching up. The xmegas are now supported by popular distributions of avr-gcc and avrdude, including those found included with CrossPack and WinAVR for Mac and Windows.
- Programming options are opening up. Atmel’s AVRISP MkII programmer (about 30 dollars) has recently been updated to support the xmega’s PDI programming mode, making an inexpensive option to get started with. Open source hardware programmers for xmega are just around the corner, too.
- And finally, breakout and development boards– including Atmel’s Xplain and the ones pictured above from Boston Android –are now available. The whole ecosystem is starting to look pretty friendly.
Okay, so what’s so great about these things?
There really are a lot of improvements in the xmega family as compared to megaAVR; it’s hard to know where to begin.
If you’re comfortable reading data sheets and have used other AVR microcontrollers, I’d encourage you to just dive in and flip through one of the datasheets to get a feel for it– maybe that for the ATxmega256A3, for example. The datasheet is actually shorter than those for megaAVR parts, because much of the register-level detail has been moved to a central “Xmega A Manual” that is common to all of the ATxmega___ A _ devices.
That actually brings us to the first big change about these chips. The xmega devices have a consistent naming and design convention. Each chip has a name like ATxmega_nnn_ F _m_, where the nnn is the flash size in kB (say, 64 or 256), the F is a letter designating the “xmega family” and the m is a suffix that refers to a package size and pinout. Every device in the ‘A’ family is described in that “Xmega A Manual,” and has consistent naming of peripherals and their registers. That means immediately that code written for any xmega ‘A’ device can run on any other ‘A’ device. (Devices in different size packages may not have all of the possible features of an ‘A’ device, but the code will still run.) This makes it straightforward not just to change between devices of different memory size, but also between devices with different numbers of pins and types of available peripherals.
It also appears– although I don’t have positive confirmation on this –that the package sizes and pinouts are consistent for devices with the same trailing number (m, above), meaning that the ATxmega16A4 and ATxmega128D4 are pin-compatible 44-pin devices, with the same power and ground locations, as well as the same named GPIO pin locations. (Obviously the secondary function per pin may not be the same between ‘A’ and ‘D’ devices.)
While this sort of labeling change seems like it may be minor, it will have a huge effect in practice, because porting code between different AVR devices thus far has been a fairly painful process– if you’ve used more than a couple of devices, you’ve probably had to figure out which timer control register bits on different chips do what.
Some other neat things in the xmegas:
- Can now run up to 32 MHz, directly from the internal oscillator. Since most instructions are still single-cycle, that means up to 32 MIPS.
- Clock type and speed– and several other configuration options that used to be inaccessible at runtime –are now software controlled. This means that you can boot up on the internal oscillator and transfer to an external crystal if it’s present.
- Essentially every peripheral (timers, ADC, GPIO, serial ports, etc) has been improved greatly, and the number of available peripherals has been greatly increased.
- (For example) All timers are now full 16 bit. Also, each timer is either 2-channel or 4-channel. Timers an be cascaded for true 32-bit operation. And there are new high-resolution waveform generation modes.
- ADC (analog to digital conversion): Up to 14 channels, and up to 2 MS/s sample rate. (Not bad!)
- DAC (digital to analog converters) available on some devices
- On-boad crypto engines, real-time clocks, and IR Communication Modules
- Battery backup system
- DMA transfer system
- Multi-level interrupt system
- There’s a very impressive new “event system” that allows an increased number of peripherals to communicate directly with each other, without taking up CPU cycles to do so.
- Many more available UARTs (serial ports) on some chips– up to 8.
There’s really a lot more that could be said about the improvements to the peripherals. One thing that really caught my eye was the amount of care put into improving the humble GPIO (general-purpose input/output) functionality.
On an ATmega device, setting a pin B3 for output, taking it high and toggling it might look like this:
DDRB = DDRB & 8; // Data direction register B, set bit in the 8’s place
PORTB = PORTB | 8; // Set bit in the 8’s place, taking that output high
PORTB = PORTB & 247; // Clear bit in the 8’s place, taking that output low
(There are certain common functionally equivalent shorthands that I haven’t used here. The first line above might be more commonly written as DDRB &= _BV(3); for example. But it compiles to mean the same thing as I’ve written above.)
The xmega has a somewhat different structure for addressing its peripherals– derived from its design for portability. The direct equivalent on an xmega device would be:
PORTB.DIR = PORTB.DIR & 8;
PORTB.OUT = PORTB.OUT | 8;
PORTB.OUT = PORTB.OUT & 247;
But it’s actually much better than that, because the xmega has four each hardware registers defined for data direction and data output: For each, you can enter the full register directly, or you can set individual bits, or clear individual bits, or toggle individual bits. These are hardware registers, so there’s no time lost doing arithmetic. It works like so:
PORTB.DIRSET = 8;
PORTB.OUTSET = 8;
PORTB.OUTTGL = 8;
And that is a lot faster.
There are also advanced configurations for pull-ups, pull-downs, interrupts, triggers, level detection, and so on, but that’s what the datasheets are for.
One last word, if nothing else has caught your attention yet: The prices on xmega devices are worth noticing. Just as a quick example, A 100-pin ATmega1280, with 128 k of flash currently costs more than 1.5 times as much as a ATxmega128A1, also with 128 k of flash in a 100-pin package, in single-unit quantity.
So what sucks about these things?
It can’t be all roses, and it isn’t. There are definite drawbacks that you need be be aware of before you move ahead.
First, there’s the obvious backwards compatibility. None of the xmegas are pin compatible or code compatible with older devices. If you normally rely on other people’s code examples, right down to configuring timers and serial ports, you may want to wait for more widespread adoption so that there are more code examples out there to follow.
Next, these are definitely more “professionally oriented” chips. That’s clear from a number of features, particularly that the design lends itself to easily resizing up or down once the code is written. “Professionally oriented” has a couple other very real consequences. These chips are nowhere near as hobbyist friendly as the megaAVR chips, most of which are available in DIP packages– the xmega chips are available strictly in fairly-large pin count surface-mount packages. Along with this, the chips also run strictly at 1.6-3.6 V– they cannot be operated at 5 V like megaAVR. Both of these are a clear signal that xmega is for new designs, and isn’t intended for use with legacy hardware.
Finally, there’s the matter of programming interface. Xmega chips are not compatible with the ISP programming mode supported by most tinyAVR and megaAVR chips. Instead, the xmega chips support (1) JTAG and (2) a newer interface called PDI. If you have an older AVRisp MkII programmer, it can have its firmware upgraded so that it can speak PDI. So far as I know, the USBtinyISP isn’t (yet) able to speak PDI.
Yep, it’s pretty neat, all right. It’s nice to see AVR growing up a bit, to compete with all the low-end 32-bit chips, and still making things much easier for us simple folk that just want to use some nice chips.