This document provides some basic hints and examples on how to getting started with the Xmega256a3
MCU that is embedded into the Embit EMB-ZRF212 EVB.
The target of the examples is the low level interfacing with the MCU sub-systems, not the ZigBee stack nor the radio communication interface.
Either if you are just interested in the development of higher level ZigBee compliant applications, sooner or later
you'll have to read/write an IO port, handle some sort of communications or interface with external sensors.
Those operations are the target of this documents and associated software.
This documents provides an introduction to the available documentation about the Xmega256a3 MCU
(micro-controller unit) and the custom EMB-ZRF212 EVB (Evaluation Board) available in Wireless System Lab @CS unibo.
It also provides some useful pointers (links, tips and so on) for developers that are completely new to firmware development or are used to older ATMEL devices, or other manufacturer's devices.
The default way to specify actions and commands in the document is supposed to be a default terminal emulator
running in a Linux (or similar *NIX) development box.
If you want to use some integrated development environment (IDE), such as the official ATMEL AVR Studio IDE, you have to switch to a Windows box, and consult the official ATMEL documentation freely available on-line.
Also, if you are just interested working with the ATMEL BitCloud ZigBee stack this documents will not help you
in any way.
Refer instead to the documentation provided in the CD-ROMs and on-line by both ATMEL and EMBIT.
The software is provided 'as it is' since it does nothing particularly useful. No license of any-kind is applied, so do what you want with it.
The provided (very simple) examples introduce some 'hands-on' techniques for manipulating
low level functions such as USART and ADC.
Makefile also provide an introduction on how software for AVR ATMEL gets
build and uploaded to the board.
To fully understand how this software works, gets build and uploaded, some preliminary
readings are quite mandatory.
Here you'll find many tutorials, about basic and more advanced
topics and typical MCU operations.
A good understanding of basic I/O (both digital and analog), serial communication protocols (USART, SPI, I2C), Analog to Digital Converters (ADC), is the bare minimum to start with a more advanced processor like Xmega256a3 is.
WARNING: ignore the code examples in the arduino wiki. You will have nothing like Arduino libraries or Arduino IDE for this platforms, just ANSI C and a bunch of registers.
ATMEL also provides an impressive collection of on-line documentation, with software examples
and documents specific to single processor's subsystems (such as "Getting started with ATXMega ADC" and so on).
Those documents are used to guide the developers in the transition from the ATMega series to the new XMega one.
You can find everything here:
This documentation is not all mandatory, but some readings are anyway recommended.
"Atmel AVR1927: XMEGA-A1 Xplained Getting Started Guide"Some articles also describes some (very) advanced features such as DMA, Event System, Clock Subsystem, DAC, that are not mandatory but could be useful to improve your firmware development skills.
"AVR1000: Getting Started Writing C-code for XMEGA"
"AVR1005: Getting started with XMEGA"
Tips (and tricks)
$ avr-gcc --target-help
Carefully read the instructions and proceed compiling, then verify that the chosen install directory is included in your
default system path. After compiling the tool-chain, remove the default avr-gcc package and try
$ which avr-gcc.
If nothing it's found, then add the install path (default one is /usr/local/avr/) to your .bashrc or .zshrc...
The header files (specifically the
'iox256a3.h') introduce a new name convention for bit-fields groups and masks.
Two different macros are now associated to each bit in a register , one that specify the position (BITNAME_bp) and one that specify the bit-shifting operation used to handle the bit (BITNAME_bm). The same happens for bit-groups, but corresponding macros end with the _gm and _gp suffixes.
In the simplest provided example (
src/blink.c) you'll find some example macros
following this new coding style.
This enables the developers to speed up the bit groups selection and bit setting or clearing.
It is suggested to open and consult the IO header file (
'iox256a3.h') while writing code,
to fully exploits the new _bm, _bp, _gm, _gp macros.
Also the I/O ports handling model has changed, since now every ports has many registers that could be used to manipulate a single pin operations.
/*=== from blink.c ===*/ #define LED1_bm (1<<0) #define LED2_bm (1<<1) #define LED3_bm (1<<2) #define LED1_bp 0 #define LED2_bp 1 #define LED3_bp 2 /*=== from iox256a3.h ===*/ /* ADC_CH.MUXCTRL bit masks and bit positions */ #define ADC_CH_MUXPOS_gm 0x78 /* Positive Input Select group mask. */ #define ADC_CH_MUXPOS_gp 3 /* Positive Input Select group position. */ #define ADC_CH_MUXPOS0_bm (1<<3) /* Positive Input Select bit 0 mask. */ #define ADC_CH_MUXPOS0_bp 3 /* Positive Input Select bit 0 position. */ #define ADC_CH_MUXPOS1_bm (1<<4) /* Positive Input Select bit 1 mask. */ #define ADC_CH_MUXPOS1_bp 4 /* Positive Input Select bit 1 position. */ #define ADC_CH_MUXPOS2_bm (1<<5) /* Positive Input Select bit 2 mask. */ #define ADC_CH_MUXPOS2_bp 5 /* Positive Input Select bit 2 position. */ #define ADC_CH_MUXPOS3_bm (1<<6) /* Positive Input Select bit 3 mask. */ #define ADC_CH_MUXPOS3_bp 6 /* Positive Input Select bit 3 position. */
The newly introduced modular device design (check on-line ATMEL documentation to know further about)
enables the developers to map the processor's registers used for configuring peripherals and input/output ports
into plain C structures, and access sub-register and bit fields in an "object oriented" coding style.
This features dramatically speeds up development process, since all the registers related to a specific subsystem are tightly coupled into a single data structure.
This structure could be directly manipulated or reassigned if another instance of the same subsystem has to be used (now you can switch from one USART interface to another simply changing a pointer value).
To understand how this feature can be exploited two different examples are provided.
usart.c handles the USARTD0 interface in the 'old fashioned' way, while
uses the new memory mapping functionality.
To understand why the new coding style is much more flexible, try to switch from using USARTD0 (the rs232 port on EMB-ZRF212) to USARTD1 (the USB one on EMB-ZRF212) in the previously mentioned files.
Many operations could be speed up with a minimal knowledge of AVR assembly.
This enables the developers to exploit new AVR assembly features, such as the indirect access with post/pre decrement, or efficient memory mapped I/O.
To reduce the produced code size could also be useful to learn how efficiently use variables data type, and how their
definition and use produce different assembly code.
The following loops, functionally equivalent, produce code of different size (assembly code is specified after each C instruction).
All that features are fully described in the "AVR035: Efficient C Coding for 8-bit AVR microcontrollers" document provided by ATMEL on-line reference.
src/directory and type
$ make upload
To change the example file you are building, edit the
src/Makefile SOURCE variable.
You will find binaries into the
Remember to clean up with
$ make clean
when you are done.
Before uploading the built file to the board verify that the selected port in the
src/Makefile PORT variable matches the port the board is attached to.
You can find it out connecting the USB cable (both ends) and powering the board up.
$ dmesg |grep tty
and check the last entry mentioning the FTDI keyword. Edit the
blink 2 led. Learn the new _bm and _bp macro style, and the new OUTSET OUTCLR registry.
setup a serial communication the "old fashioned" way, manipulating the single registers.
setup a serial communication the new way, using the flexible memory mapped IO model.
setup ADCA and read from channel 4 (connected to a trimmer on EMB-ZRF212 board). The resulting value is then sent out on the USARTD0 channel.
With the firmware examples, a simple test program it's also provided (
This application shows how to open and setup a serial communication with the board.
This example is tested with the adc.c firmware and displays messages incoming from the MCU (the voltage generate by the on-board variable resistor).
If you want to contribute to this page, with corrections, new code examples etc, please let me know!