This is an experimental driver for the XBee 900 HP pro module's SPI connection. This driver is unfinished and stability is not guaranteed. Use with caution.

Dependents:   Sentinel_BASE Sentinel_NODE

xbee900hp.cpp

Committer:
ottaviano3
Date:
2015-04-23
Revision:
2:7f4ddf710a44
Parent:
1:b97d46c5d7ce
Child:
3:3c3707b0f5cd

File content as of revision 2:7f4ddf710a44:

#include "xbee900hp.h"

/**
* Initialize the xBee Module
*/
xbee900hp::xbee900hp(PinName pin_mosi,PinName pin_miso,PinName pin_sck,PinName pin_attn, PinName pin_rst)
    : _pin_rst(pin_rst), _pin_attn(pin_attn), _xbeespi(pin_mosi,pin_miso,pin_sck)
{
    _xbeespi.format(8,0);
    _xbeespi.frequency(1000000);
    
    reset();
}

/**
* Destructor
*/
xbee900hp::~xbee900hp() {}

/**
* Reset xBee to SPI mode
*/
void xbee900hp::reset()
{
    _pin_rst = 0;
    // Minimum pulse is 1ms
    wait_ms(1);
    _pin_rst = 1;
    // wait for module to come back online
    wait_ms(500);
}

/**
* Send packet out on RF
*/
void xbee900hp::sendPacket(char* data, unsigned int length)
{
    // checksum
    unsigned int checksum;
    unsigned int checksumsub = 0;
    
    // start char
    _xbeespi.write(0x7E);
    // lenght
    _xbeespi.write(0x00);
    
    unsigned int totallength = 14 + length - 1;
    _xbeespi.write(totallength);

    // frame delimter
    _xbeespi.write(0x10);
    checksumsub += 0x10;
    // id for later reference 0 = no id
    _xbeespi.write(0x00);

    // destination address
    _xbeespi.write(0x00);
    _xbeespi.write(0x00);
    _xbeespi.write(0x00);
    _xbeespi.write(0x00);
    _xbeespi.write(0x00);
    _xbeespi.write(0x00);
    _xbeespi.write(0xFF);
    checksumsub += 0xFF;
    _xbeespi.write(0xFF);
    checksumsub += 0xFF;

    // reserved field, dont change
    _xbeespi.write(0xFF);
    checksumsub += 0xFF;
    _xbeespi.write(0xFE);
    checksumsub += 0xFE;

    //bcast radius
    _xbeespi.write(0x00);

    //transmit options 0x00 to disable ACK
    _xbeespi.write(0x00);

    // dat data
    for (int i = 0; i < (length - 1); i++) {
        _xbeespi.write(*data);
        checksumsub += (*(data++));
    }
    

    // Calculate checksum
    checksumsub = checksumsub & 0xFF;
    checksum = 0xFF - checksumsub;

    // finally write checksum
    _xbeespi.write(checksum);
}

int xbee900hp::readPacket(char* data) {
    unsigned int temp1;
    unsigned int temp2;
    
    unsigned int checksumsub = 0;
    unsigned int checksum;
    
    // get first vars.
    temp1 = _xbeespi.write(0x00);
    if (temp1 != 0x7E) {
        // drop packet
        return 1;
    }
    // Get length of message
    temp1 = _xbeespi.write(0x00);
    temp2 = _xbeespi.write(0x00);
    
    // Get total length
    unsigned int length = (temp1<<8) | temp2;
    
    // Next read frame type to ensure it is an RX packet.
    temp1 = _xbeespi.write(0x00);
    if (temp1 != 0x90) {
        // drop packet
        return 1;
    }
    checksumsub += temp1;
    
    // in our case we dont care about source address this should be modified to extract source address if needed.
    checksumsub += _xbeespi.write(0x00);
    checksumsub += _xbeespi.write(0x00);
    checksumsub += _xbeespi.write(0x00);
    checksumsub += _xbeespi.write(0x00);
    checksumsub += _xbeespi.write(0x00);
    checksumsub += _xbeespi.write(0x00);
    checksumsub += _xbeespi.write(0x00);
    checksumsub += _xbeespi.write(0x00);
    // reserved field, we dont care about except for checksum
    checksumsub += _xbeespi.write(0x00);
    checksumsub += _xbeespi.write(0x00);
    
    // recive options we also dont care though
    checksumsub += _xbeespi.write(0x00);
    
    // Now for the sweet sweet data.
    for (int i = 0; i<(length-12); i++) {
        *data = _xbeespi.write(0x00);
        checksumsub += *(data++);
    }
    // Null terminate char array.
    *data = NULL;
    
    // Get that salty checksum
    temp1 = _xbeespi.write(0x00);
    
    checksumsub = checksumsub & 0xFF;
    checksum = 0xFF - checksumsub;
    
    // Check the checksum
    if (temp1 != checksum) {
        // Checksum failure, flag to discard packet
        return 1;
    }
    
    return 0;
}

int xbee900hp::attn() {
    return _pin_attn;
}

void xbee900hp::writeSetting(char command[2], unsigned int value) {
    // checksum Variables
    unsigned int checksum = 0;
    unsigned int checksumsub = 0;
    
    // Start config, send frames for SPI pins enable
    _xbeespi.write(0x7E);
    _xbeespi.write(0x00);
    _xbeespi.write(0x05);
    
    // Frame type (config)
    _xbeespi.write(0x08);
    checksumsub += 0x08;
    _xbeespi.write(0x00);
    
    
    // AT Command
    for (int i = 0; i < 2; i++) {
        _xbeespi.write(*command);
        checksumsub += (*(command++));
    }
    
    // Value to set
    _xbeespi.write(value);
    checksumsub += value;
    
    // Calculate checksum
    checksumsub = checksumsub & 0xFF;
    checksum = 0xFF - checksumsub;

    // finally write checksum
    _xbeespi.write(checksum);
}