|Getting Started With The ATXMega - The ATXMega Test Library||| Print ||
|Written by Akiba|
|Tuesday, 06 July 2010|
The ATXMega is an upgraded version of the popular AVR microcontroller from Atmel. It still contains the basic AVR core but has a huge amount of enhancements to both the core and the peripherals. Basically, you can think of it like an AVR on steroids…a whole lot of steroids. Switching from the ATMega to the ATXMega series is a bit overwhelming because there are so many new features and improvements. Consequently, there is also a lot of new documentation which shows how to use the new features and the old ones. Because of the potential register shock to people that try out the ATXMega, I decided to put together a library of the Atmel drivers and some example functions. And of course, all the functions are ported and tested. Some of the examples may seem trivial, but they’re not designed for evaluation purposes. Their real purpose is to serve as a reference on how to access and use the peripherals, now that the register set is different.
One of the first things I always do with a new microcontroller board is load a bootloader on it. I prefer developing with bootloaders whenever possible because its much easier than pulling out the JTAG debugger. It’s also handy for on-location development where all you need is a USB cable.
Bootloader Source Code Link
Next is to connect the USB to the target board and turn the board on. You'll need to figure out which COM port the board is on. The boards use an FTDI USB to serial converter which is very standard and supported on Windows, Linux, and Mac platforms. If you have any problems with the driver, you can find your platform here and download the driver . Once you figure out the COM port, you’ll need to go into the makefile and configure AVRDUDE with that COM port.
AVRDUDE_PORT = com2 # programmer connected to serial device
and change it to whichever COM port the board is on.
Once that’s done, you follow the same sequence as with the other FreakLabs MCU boards, where you push and hold down the BOOT button while pressing and releasing the RESET button. If this sequence seems bizarre to you, check out my bootloader tutorial. The board should now be in bootloader mode and ready to accept new code.
The AVRDude program is used to program the boards. AVRDude is an open source firmware downloader for AVRs and is included in WinAVR for Windows and CrossPack for Mac. For Linux, you can either download the program directly here , or use a package manager and download it using the name "avrdude". Support for downloading via AVRDude is already integrated into the makefile.
After the correct COM port is set in the makefile and the board is connected and in bootloader mode, you can simply download by typing
You should see something like this:
And finally, you can then get a command prompt when you open up your terminal program that looks like this:
You can ignore the "Command not recognized" message at the top. You need to press Enter to trigger the command shell to re-print the prompt when you first connect via terminal.
ATXMega Test Library
Now it's time to get into the nitty-gritty. I've put together example functions and integrated them into a command line shell. The test code is not really comprehensive, since the ATXMega feature set is too huge. However it should be enough to get people started working with the ATXMega and get a feel for how to migrate from an ATMega to the ATXMega. The test code currently consists of example functions that use the following:
External Memory Bus
Ex: “rd 3” will read address 3 of the external RAM. The address is a hex value and address 0 is the bottom of external memory. When you call this function, it’ll print out the value at the specified address on the command line.
wr <addr> <data>
Ex: wr 3 ff
One last thing I did for the external memory bus was to create a large 32 kB array and locate it in external RAM:
// create large array and locate it in external SRAM.
This was done as a demonstration of how to locate structures and arrays in external memory. I’ll probably do a post later on about other ways to use external RAM, but this is a pretty efficient way to do things for protocol stacks. The reason is because in protocol stacks, you usually have some type of managed memory which consists of a single large array that serves as a memory pool. This memory pool is used for dynamic allocation of memory for things like routing table entries and usually has some type of logic to prevent memory fragmentation which plagues communication stacks. Anyhoo, I made this example to show how a large managed memory pool can be created in external RAM. I also wrote a function similar to the memory test, but instead does a memtest on the array rather than the individual memory addresses. To call the function, type:
One of the nice things about the ATXMega is that it has 4 independent SPI ports. The FreakLabs board uses two independent SPI ports on each of the peripheral connectors. This is nice because you don’t have to worry about switching between different SPI modes if you have SPI peripherals hanging off each of the connectors. This is actually fairly common issue if you’re using a wireless radio and an SPI-based peripheral since both use SPI and may require different SPI modes.
Where the address is in hex. It will print out the value at that address to the command line.
To perform an SPI write, type:
sw <addr> <data>
Where both the address and data are in hex.
The ATXMega also generously provides four separate I2C buses which makes it possible to have separate I2C buses for each peripheral port on the board. This isn’t really necessary since I2C is an addressable bus, but it does make things nicer. Plus, if any device is overly chatty, you won’t have to worry about it hogging the I2C bus completely.
Because of this, I put together a couple of reference functions to demonstrate how the library is used. There are actually four functions altogether: an 8-bit I2C read, 16-bit I2C read, 8-bit I2C write, and 16-bit I2C write. They are accessible from the command line so if you plug in an I2C device, you’ll be able to access it immediately without having to write any code. Well, actually you’ll first need to set the device address in the main() file. Just look for this and change it to whatever address is being used by the device you’re hooking onto the connector:
#define I2C_DEV_ADDR 0x18
As for the actual command line functions, they’re:
The address and values are always in hex format and an “ir” command signifies an I2C read while an “iw” command signifies an I2C write.
One of the more interesting new features about the ATXMega is that they’ve integrated a configurable PLL to generate the clock frequency and even integrated the clock source. There’s now a 2 MHz internal clock source that you can configure to feed the PLL. From there, you can multiply the clock up to 32 MHz. The implications are quite interesting from a wireless point of view because we’re always worrying about the power consumption of the chips we’re using. The power consumption is also proportional to the clock frequency. Hence it’s now possible to change the clock frequency higher when a lot of computing needs to be done (like sensor data processing), and then go back to a low frequency for normal tasks. It’s also possible to configure the chip to run off its internal 32 kHz oscillator for extremely low power operations without putting the chip to sleep.
There are no arguments and it will print out a message at the command line saying what the current clock frequency is.
Here's a quick video on doing a memory test at two different clock speeds. You can see that the speed difference between the test at 2 MHz and 32 MHz is quite significant:
I put together two functions on reading and writing to the internal EEPROM of the chip. The EEPROM is very useful for storing things like node addresses, configuration information, and funny messages. The latter is the most interesting so in my command line EEPROM write function, you can actually write a text message and store it in the EEPROM. It doesn’t serve a very useful purpose but it does give an example of how to read and write to the EEPROM since you can’t use the standard eeprom functions in avrlibc.
eew <eeprom start address> <text string>
Ex: eew 0 I really need to get out more or at least exercise
eer <eeprom start address>
The read function will automatically know how long the text string is because of the string terminator (‘/0’) I tack on to the end of the text message when you write to the memory.
One of the big issues when you have sensor arrays is synchronizing the data samples. Say you have 50 samples from 3 different nodes. You won’t really know if those data samples are aligned unless they’re timestamped and the clocks are synchronized. That’s when the real time clock (RTC) starts becoming important. A real time clock is very useful in a sensor network for timestamping purposes so that when you read out the sensor data from different nodes, you’ll know how the samples line up for processing or visualization.
That's it for the test code at this moment. I'm hoping to add other functions later on as I test out some of the new features on the ATXMega. So far, the platform looks very promising for wireless sensor networks and seems to be an excellent choice for a WSN node on an 8-bit platform.
cheap coach bags, Lowly rated comment [Show]
|< Prev||Next >|