Xbee MAC Interface SAM4S

Posted By on Jun 30, 2015

(Update on June 2017)

This is the second version of a MAC Interface (based on Xbee S1 Radios) for the SAM4S Xplained Pro. More than Xbee drivers, or an Xbee library, it is an actual IEEE 802.15.4 MAC interface. I call it interface, because the entire MAC functionality is handled in hardware from within the Xbee. I simply wrote drivers for the Xbee, and added a MAC and message abstractions.



Xbee Mac Interface architecture


Setting up the radio

Using the XCTU utility make the following changes to the Xbee S1 radio:

  1. Reset to factory settings (to avoid any parameter being set to a value that might prevent communication),
  2. Set the baud rate to match RADIO_SPEED_RATE in mac_config.h
  3. Change to API mode
  4. Write changes and verify.

Then plug the radio’s Rx, Tx, Vcc and Gnd pins to the SAM4S Xpro board. Because the software uses USART1 you will need to use Rx (Pin 13), Tx (Pin 14), Gnd (Pin 19), and Vcc (Pin 20) in either EXT1 or EXT2. Alternatively, if you have an IO1 XPlained Pro, you could use the pins labeled Rx, Tx, Gnd, and VTG in the IO1 board. (Not sure why these pins? See here or check the SAM4s Xpro User Guide.)




There are three demos. One  demonstrating unicast messages, and one demonstrating the use of RSSI. The unicasting demo consists of two nodes. Both send a 1-byte asynchronous message to each other approximately every half a second. Whenever a message is received, they toggle their respective LEDs. Likewise, the RSSI demo consists of two nodes. They both blink their LEDs depending on the RSSI of the last message received.




This is a bare-metal implementation, so do not access the radio concurrently! Meaning, do not access the radio from interrupt handlers (that includes msg_received and ack_received). This is because the radio is a shared resource. Some radio functions (e.g. radio_read_address) span two operations: asking something to the radio, and then receiving a response. You don’t want to use the radio in between. Or say execution is in msg_received, which is executed from the USART1 interrupt handler. Then you ask for radio_read_address which will send data to the radio and then busy-wait until it receives a response. Because execution is already in the USART1 Handler it’ll deadlock. In other words, odd things may occur. So don’t!



To port to a different platform rewriting of xbee_cpu and xbee_uart modules should suffice. All data types used are stdint. h types (e.g. uint8_t).

Source code’s license is GPL (see source code).



In this second version some functionality is NOT IMPLEMENTED. Namely,

  • Networking-, security- and sleeping-related radio functions (e.g. node discover, sleep mode) .
  • 64-bit MAC address support
  • Verification of checksum when receiving API frames, as well as doing something when the checksum is wrong.
  • Verification of status (OK Status) in received responses to Xbee commands
  • Support for duplicate frames (maybe). The IEEE 802.15.4 standards defines a sequence number as part of the MAC header, to filter duplicate frames. This suggests this is all handled internally by the Xbee. Yet the Xbee has a MAC mode available to eliminate duplicate frames, hence suggesting otherwise.
  • Processing of Modem Status frames. Though, with the current functionality, modem status frames are never sent by the Xbee (see data_received_callback in xbee.c).



Tested with ASF v3.34.1 (it should compile for newer versions of the ASF with none or minimal changes).

Source code alone and as an Atmel Studio solution.



Unicast Demo




Download Read More

(Updated Nov 15, 2014).

The idea is simple. Xbee 802.15.4 radios cannot communicate off-the-shelf with TinyOS-based moted. They are supposed to, but they do not.  Sometimes communication is not possible because of parameter mismatch. In particular, a) TinyOS is set in low power listening mode (not supported in Xbees); or b) Xbees are set up to use the MAXTREAM MAC (not supported by TinyOS); or c) Xbees are set to use 64-bit source addressing (not supported by TinyOS).

Provided all that is avoided, there are still a few things that will prevent communication: the TinyOS Am Type field, and Some Xbee extra bytes. A TinyOS-specific extra field (one byte) in the headers called Am Type allows TinyOS to multiplex the use of the radio among different services executing within the same mote. Because it is not part of the IEEE 802.15.4 standard, Xbees have no support for it. As for the extra bytes, Xbee modules add two extra bytes to the payload in every packet regardless of the payload size. I’m not completely sure of what they are ( I should probably read the Xbee Data sheet again). In either case, the solution is to simply remove the Am Type field and those extra Xbee bytes.

To remove the Am Type field I modified the file CC2420ActiveMessageP.nc, which is in charge of multiplexing messages depending on their AM Type, and then modified CC2420.h where the radio message format is defined. Then removed the two extra bytes from every incoming Xbee packet.

With the new changes, definition of the pre-processor variable XBEE_MODE_ENABLED is required. When XBEE_MODE_ENABLED  is defined, it prevents the user (shows compile errors) from using Low Power Listening. It also disables automatically TinyOS Network Layer. So the only thing left for the user to do is: a) Set the Xbee to 16-bit addresing mode, and b) select the 802.15.4 MAC without MAXSTREAM headers.


Example of use

Tested for tmote and TinyOS 2.x (as installed in  UbunTOS)

The original files CC2420ActiveMessageP.nc and CC2420.h must be replaced with those provided at the bottom of the page. Both are located in: opt/tinyos-2.x/tos/chips/cc2420/

After replacing the original files, you must define the pre-processor variables XBEE_MODE_ENABLED in your application’s Makefile:


Then, as usual:

$ make platform install


If for some reason you try to enable low power listening you will get the following message:




The Xbee Module in the following tests is set to 802.15.4 MAC with ACK’s, 16-bit Addressing Mode, and Encryptation Disabled. Setting Hardware Acknowledgements for TinyOS or enabling TinyOS Packet Link Layer makes no difference.

The Demo App  (also included in the downloads) echoes back anything that is received from the Xbee, as shown:

xbee tinyos test_








Over the years, this “compatible” TinyOS has come in handy, as I’ve used it for a few projects—here they are.





Tested with UbunTOS (follow the link to download).



Read More


In Serial.h serial packets datatype is defined as:

typedef nx_struct serial_packet {
     serial_header_t header; //Headers!
     nx_uint8_t data[];
} serial_packet_t;

but, what if we don’t want to send any headers, i.e. raw data ???



A TinyOS interface that allows an application to tell the Serial Dispatcher, which is in charge of packet formatting, whether to use headers or not in the serial packets.

interface SerialConfigure {
  command void useHeaders( bool use_headers );


This is where the Serial Dispatcher is in TinyOS’s serial stack:



TinyOS Serial stack. Taken from TinyOS Documentation

The actual implementation is in SerialDispatcherP.nc, thus the original file must be replaced with the one provided at the bottom of this page. Then apps only need to implement the SerialConfigure interface.




Example of Use
( Not relevant code is omitted. See complete code on download area )

configuration TestAppC{
    components TestC as App;
    App.UartConfigure -> SerialDispatcherC.SerialConfigure; //we must wire it to the Serial Dispatcher,

module TestC{
    uses interface SerialConfigure as UartConfigure; 
    event void Boot.booted(){
        call UartConfigure.useHeaders(FALSE); //Then we set to false or true 



When calling UartConfigure.useHeaders( TRUE )

When calling UARTConfigure.useHeaders( FALSE )




Download Read More