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-30
Revision:
6:3873db4a0164
Parent:
5:c8bb6b5d7fa0
Child:
7:3cb67634fa4e

File content as of revision 6:3873db4a0164:

#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 0xC0 to enable digimesh
    _xbeespi.write(0xC0);
    checksumsub += 0xC0;

    // 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 = '\0';
    
    // 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);
}

int xbee900hp::getSerial(char* serialnumber) {
    ///////////////////////////////////////////////////Send portion
    // checksum Variables
    unsigned int checksum = 0;
    unsigned int checksumsub = 0;
    
    // Write frame to return serial high and low.s
    
    // Start config, send frames for SPI pins enable
    _xbeespi.write(0x7E);
    _xbeespi.write(0x00);
    _xbeespi.write(0x04);
    
    // Frame type (config)
    _xbeespi.write(0x08);
    checksumsub += 0x08;
    _xbeespi.write(0x52);
    checksumsub += 0x52;
    
    // Setting wanted
    _xbeespi.write('S');
    checksumsub += 'S';
    _xbeespi.write('H');
    checksumsub += 'H';
    
    // Calculate checksum
    checksumsub = checksumsub & 0xFF;
    checksum = 0xFF - checksumsub;
    // finally write checksum
    _xbeespi.write(checksum);
    
    //////////////////////////////////////RECIEVE PORTION
    // Block until xbee replys
    while (_pin_attn != 0) {}
    
    // Containers for read values
    char temp1 = 0;
    char temp2 = 0;
    
    // reset checksum to zero.
    checksum = 0;
    checksumsub = 0;
    
    // get start byte
    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 response packet.
    temp1 = _xbeespi.write(0x00);
    if (temp1 != 0x88) {
        // drop packet
        return 1;
    }
    checksumsub += temp1;
    
    // get response frame id
    temp1 = _xbeespi.write(0x00);
    if (temp1 != 0x52) {
        // drop packet
        return 1;
    }
    checksumsub += temp1;
    
    // get at response parameter
    temp1 = _xbeespi.write(0x00);
    checksumsub += temp1;
    temp2 = _xbeespi.write(0x00);
    checksumsub += temp2;
    
    if ((temp1 != 'S') || (temp2 != 'H')) {
        return 1;
        // drop
    }
    
    // Check OK flag
    temp1 = _xbeespi.write(0x00);
    if (temp1 != 0x00) {
        return 1;
        // drop
    }
    checksumsub += temp1;
    
    // Now for the sweet sweet data.
    for (int i = 0; i<(length-5); i++) {
        *serialnumber = _xbeespi.write(0x00);
        checksumsub += *(serialnumber++);
    }
    
    // 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;
    }
    
////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////Send portion
    // checksum Variables
    checksum = 0;
    checksumsub = 0;
    
    // Write frame to return serial high and low.s
    
    // Start config, send frames for SPI pins enable
    _xbeespi.write(0x7E);
    _xbeespi.write(0x00);
    _xbeespi.write(0x04);
    
    // Frame type (config)
    _xbeespi.write(0x08);
    checksumsub += 0x08;
    _xbeespi.write(0x52);
    checksumsub += 0x52;
    
    // Setting wanted
    _xbeespi.write('S');
    checksumsub += 'S';
    _xbeespi.write('L');
    checksumsub += 'L';
    
    // Calculate checksum
    checksumsub = checksumsub & 0xFF;
    checksum = 0xFF - checksumsub;
    // finally write checksum
    _xbeespi.write(checksum);
    
    //////////////////////////////////////RECIEVE PORTION
    // Block until xbee replys
    while (_pin_attn != 0) {}
    
    // Containers for read values
    temp1 = 0;
    temp2 = 0;
    
    // reset checksum to zero.
    checksum = 0;
    checksumsub = 0;
    
    // get start byte
    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
    length = (temp1<<8) | temp2;
    
    // Next read frame type to ensure it is an response packet.
    temp1 = _xbeespi.write(0x00);
    if (temp1 != 0x88) {
        // drop packet
        return 1;
    }
    checksumsub += temp1;
    
    // get response frame id
    temp1 = _xbeespi.write(0x00);
    if (temp1 != 0x52) {
        // drop packet
        return 1;
    }
    checksumsub += temp1;
    
    // get at response parameter
    temp1 = _xbeespi.write(0x00);
    checksumsub += temp1;
    temp2 = _xbeespi.write(0x00);
    checksumsub += temp2;
    
    if ((temp1 != 'S') || (temp2 != 'L')) {
        return 1;
        // drop
    }
    
    // Check OK flag
    temp1 = _xbeespi.write(0x00);
    if (temp1 != 0x00) {
        return 1;
        // drop
    }
    checksumsub += temp1;
    
    // Now for the sweet sweet data.
    for (int i = 0; i<(length-5); i++) {
        *serialnumber = _xbeespi.write(0x00);
        checksumsub += *(serialnumber++);
    }
    // Null terminate char array.
    *serialnumber = '\0';
    
    // 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;

}

void xbee900hp::clearBuff()
{
    while(_pin_attn == 0) {
        _xbeespi.write(0x00);
    }
}