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

Revision:
7:3cb67634fa4e
Parent:
6:3873db4a0164
Child:
8:fa84dacc45b9
--- a/xbee900hp.cpp	Thu Apr 30 17:01:46 2015 +0000
+++ b/xbee900hp.cpp	Thu Apr 07 18:09:59 2016 +0000
@@ -3,15 +3,20 @@
 /**
 * 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)
-{
+xbee900hp::xbee900hp(PinName pin_mosi,PinName pin_miso,PinName pin_sck,PinName pin_attn, PinName pin_rst, unsigned int freq)
+    : _pin_rst(pin_rst), _pin_attn(pin_attn), _xbeespi(pin_mosi,pin_miso,pin_sck) {
+    // Set proper spi transfer mode format.
     _xbeespi.format(8,0);
-    _xbeespi.frequency(1000000);
-    
+    // Set SPI frequency
+    _xbeespi.frequency(freq);
+
+    // Reset for good measure.
     reset();
+
+    // Xbee is up and running!
 }
 
+
 /**
 * Destructor
 */
@@ -24,33 +29,53 @@
 {
     _pin_rst = 0;
     // Minimum pulse is 1ms
-    wait_ms(1);
+    wait_ms(2);
     _pin_rst = 1;
-    // wait for module to come back online
-    wait_ms(500);
+    
+    // Wait for device to have time to start the reboot process.
+    wait_ms(80);
+
+    // Now wait for the startup message.
+    while (attn() == 1) {}
+
+    // This is the message the XBEE should send out on startup after a reset.
+    unsigned int modemMsg[6] = { 0x7E,0x00,0x02,0x8A,0x00,0x75 };
+    // Container for or new message.
+    unsigned int delim[6];
+
+    // Read in the new message from the xbee.
+    for (int i = 0; i < 6; i++) {
+        delim[i] = _xbeespi.write(0x00);
+    }
+
+    // Compare recieved msg with msg we want.
+    if (memcmp(delim, modemMsg, sizeof(modemMsg))) {
+        // If msg mismatch.
+        error("XBEE FAILURE");
+    }
 }
 
+
 /**
 * Send packet out on RF
 */
-void xbee900hp::sendPacket(char* data, unsigned int length)
-{
+int xbee900hp::sendPacket(char* data, unsigned int length, bool enMesh) {
     // 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
+    // id for later reference
     _xbeespi.write(0x00);
 
     // destination address
@@ -74,16 +99,30 @@
     //bcast radius
     _xbeespi.write(0x00);
 
-    //transmit options 0xC0 to enable digimesh
-    _xbeespi.write(0xC0);
-    checksumsub += 0xC0;
+    // This is a bitmasked field
+    // bit 0: Disable ACK
+    // bit 1: Disable Route Discovery
+    // bit 2: Enable Unicast NACK messages.
+    // bit 3: Enable Unicast Trace Route messages.
+    // bits 6,7: b’01 - Point-Multipoint
+    //          b’10 - Repeater mode (directed broadcast)
+    //          b’11 - DigiMesh
+    // All other bits must be set to 0.
+    if (enMesh == true) {
+        // Transmit using digimesh
+        _xbeespi.write(0xC0);
+        checksumsub += 0xC0;
+    } else {
+        // Transmit point to point (without ACK)
+        _xbeespi.write(0x41);
+        checksumsub += 0x41;
+    }
 
     // dat data
     for (int i = 0; i < (length - 1); i++) {
         _xbeespi.write(*data);
         checksumsub += (*(data++));
     }
-    
 
     // Calculate checksum
     checksumsub = checksumsub & 0xFF;
@@ -91,52 +130,74 @@
 
     // finally write checksum
     _xbeespi.write(checksum);
+
+    return 0;
 }
 
-int xbee900hp::readPacket(char* data) {
-    unsigned int temp1;
+
+/**
+* Wait for and read incoming data packet
+*/
+unsigned long long xbee900hp::readPacket(char* data) {
+    unsigned long long temp1;
     unsigned int temp2;
     
+    unsigned long long srcAddr = 0;
+
     unsigned int checksumsub = 0;
     unsigned int checksum;
-    
+
     // get first vars.
     temp1 = _xbeespi.write(0x00);
     if (temp1 != 0x7E) {
-        // drop packet
-        return 1;
+        return 0;
     }
     // 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;
+        return 0;       
     }
     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);
+    temp1 = _xbeespi.write(0x00);
+    srcAddr = (temp1 << 56);
+    checksumsub += temp1;
+    temp1 = _xbeespi.write(0x00);
+    srcAddr ^= (temp1 << 48);
+    checksumsub += temp1;
+    temp1 = _xbeespi.write(0x00);
+    srcAddr ^= (temp1 << 40);
+    checksumsub += temp1;
+    temp1 = _xbeespi.write(0x00);
+    srcAddr ^= (temp1 << 32);
+    checksumsub += temp1;
+    temp1 = _xbeespi.write(0x00);
+    srcAddr ^= (temp1 << 24);
+    checksumsub += temp1;
+    temp1 = _xbeespi.write(0x00);
+    srcAddr ^= (temp1 << 16);
+    checksumsub += temp1;
+    temp1 = _xbeespi.write(0x00);
+    srcAddr ^= (temp1 << 8);
+    checksumsub += temp1;
+    temp1 = _xbeespi.write(0x00);
+    srcAddr ^= (temp1);
+    checksumsub += temp1;
     // 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);
@@ -144,143 +205,228 @@
     }
     // 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;
     }
-    
-    return 0;
+
+    return srcAddr;
 }
 
+
+/**
+* Check ATTN signal
+*/
 int xbee900hp::attn() {
     return _pin_attn;
 }
 
-void xbee900hp::writeSetting(char command[2], unsigned int value) {
+/**
+* Get signal strength of last recieved packet
+*/
+unsigned int xbee900hp::getRSSI() {
     // checksum Variables
     unsigned int checksum = 0;
     unsigned int checksumsub = 0;
-    
-    // Start config, send frames for SPI pins enable
+
+    // RSSI storage container
+    unsigned int rssi;
+
+    // Frame initiator
     _xbeespi.write(0x7E);
+    // Length
     _xbeespi.write(0x00);
-    _xbeespi.write(0x05);
-    
+    _xbeespi.write(0x04);
+
     // Frame type (config)
     _xbeespi.write(0x08);
     checksumsub += 0x08;
-    _xbeespi.write(0x00);
-    
-    
+    // Response frame ID
+    _xbeespi.write(0x44);
+    checksumsub += 0x44;
+
     // AT Command
-    for (int i = 0; i < 2; i++) {
-        _xbeespi.write(*command);
-        checksumsub += (*(command++));
-    }
-    
-    // Value to set
-    _xbeespi.write(value);
-    checksumsub += value;
-    
+    _xbeespi.write(0x44); // Hex for ASCII D
+    checksumsub += 0x44;
+    _xbeespi.write(0x42); // Hex for ASCII B
+    checksumsub += 0x42;
+
     // 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;
-    
+    while (_pin_attn != 0) { }
+
     // reset checksum to zero.
     checksum = 0;
     checksumsub = 0;
-    
+
+    unsigned int temp1;
+    unsigned int temp2;
+
     // 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;
-    
+    // Get length of message (we dont care, we know what it is)
+    _xbeespi.write(0x00);
+    _xbeespi.write(0x00);
+
     // Next read frame type to ensure it is an response packet.
     temp1 = _xbeespi.write(0x00);
     if (temp1 != 0x88) {
         // drop packet
-        return 1;
+        return 0;
     }
     checksumsub += temp1;
-    
+
     // get response frame id
-    temp1 = _xbeespi.write(0x00);
-    if (temp1 != 0x52) {
-        // drop packet
-        return 1;
+
+    while (temp1 != 0x44) {
+        // Dredge through data until the response frame we want arrives.
+        temp1 = _xbeespi.write(0x00);
     }
     checksumsub += temp1;
-    
+
     // get at response parameter
     temp1 = _xbeespi.write(0x00);
     checksumsub += temp1;
     temp2 = _xbeespi.write(0x00);
     checksumsub += temp2;
-    
-    if ((temp1 != 'S') || (temp2 != 'H')) {
+
+    if ((temp1 != 0x44) || (temp2 != 0x42)) {
+        return 1;
+        // drop
+    }
+
+    // Check OK flag
+    temp1 = _xbeespi.write(0x00);
+    if (temp1 != 0x00) {
         return 1;
         // drop
     }
-    
+    checksumsub += temp1;
+
+    // Get RSSI Data
+    rssi = _xbeespi.write(0x00);
+    checksumsub += rssi;
+
+    // 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 rssi;
+}
+
+/**
+* Set the transmission power level.
+*/
+int xbee900hp::setPower(int value) {
+    if ((value > 4) || (value < 0)) {
+        return 1;
+    }
+
+    // checksum Variables
+    unsigned int checksum = 0;
+    unsigned int checksumsub = 0;
+
+    // Frame initiator
+    _xbeespi.write(0x7E);
+    // Length
+    _xbeespi.write(0x00);
+    _xbeespi.write(0x05);
+
+    // Frame type (config)
+    _xbeespi.write(0x08);
+    checksumsub += 0x08;
+    // Response frame ID
+    _xbeespi.write(0x50);
+    checksumsub += 0x50;
+
+    // AT Command
+    _xbeespi.write(0x50); // Hex for ASCII P
+    checksumsub += 0x50;
+    _xbeespi.write(0x4C); // Hex for ASCII L
+    checksumsub += 0x4C;
+
+    // Value to set
+    _xbeespi.write(value);
+    checksumsub += value;
+
+    // Calculate checksum
+    checksumsub = checksumsub & 0xFF;
+    checksum = 0xFF - checksumsub;
+
+    // finally write checksum
+    _xbeespi.write(checksum);
+
+    // Block until xbee replys
+    while (_pin_attn != 0) { }
+
+    // reset checksum to zero.
+    checksum = 0;
+    checksumsub = 0;
+
+    unsigned int temp1;
+    unsigned int temp2;
+
+    // get start byte
+    temp1 = _xbeespi.write(0x00);
+    if (temp1 != 0x7E) {
+        // drop packet
+        return 1;
+    }
+    // Get length of message (we dont care, we know what it is)
+    _xbeespi.write(0x00);
+    _xbeespi.write(0x00);
+
+    // Next read frame type to ensure it is an response packet.
+    temp1 = _xbeespi.write(0x00);
+    if (temp1 != 0x88) {
+        // drop packet
+        return 0;
+    }
+    checksumsub += temp1;
+
+    while (temp1 != 0x50) {
+        // Keep going through data until response frame is found.
+        temp1 = _xbeespi.write(0x00);
+    }
+    checksumsub += temp1;
+
+    // get at response parameter
+    temp1 = _xbeespi.write(0x00);
+    checksumsub += temp1;
+    temp2 = _xbeespi.write(0x00);
+    checksumsub += temp2;
+
+    if ((temp1 != 0x50) || (temp2 != 0x4C)) {
+        return 1;
+        // drop
+    }
+
     // Check OK flag
     temp1 = _xbeespi.write(0x00);
     if (temp1 != 0x00) {
@@ -288,143 +434,282 @@
         // 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
+
+    return 0;
+}
+
+/**
+* Get serial number of xbee module
+*/
+unsigned long long xbee900hp::getSerial() {
     // checksum Variables
-    checksum = 0;
-    checksumsub = 0;
-    
-    // Write frame to return serial high and low.s
-    
-    // Start config, send frames for SPI pins enable
+    unsigned int checksum = 0;
+    unsigned int checksumsub = 0;
+
+    // Container for serial as we calculate it.
+    unsigned long long serialNumber = 0;
+
+    // Containers for read values
+    unsigned long long temp1 = 0;
+    unsigned long long temp2 = 0;
+    unsigned long long temp3 = 0;
+    unsigned long long temp4 = 0;
+
+    // Write frame to return serial high.
+    // Total frame looks like this:
+    // 7E 00 04 08 52 53(S) 48(H) CHECKSUM
+    // Wait for response to get high part of serial
+    // Profit????
+
+    // Frame Header
     _xbeespi.write(0x7E);
+    // Frame Length
     _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';
-    
+
+    // Setting wanted SerialHigh
+    _xbeespi.write(0x53);
+    checksumsub += 0x53;
+    _xbeespi.write(0x48);
+    checksumsub += 0x48;
+
     // Calculate checksum
     checksumsub = checksumsub & 0xFF;
     checksum = 0xFF - checksumsub;
     // finally write checksum
     _xbeespi.write(checksum);
-    
-    //////////////////////////////////////RECIEVE PORTION
+
+    // RECIEVE PORTION
     // Block until xbee replys
-    while (_pin_attn != 0) {}
-    
-    // Containers for read values
-    temp1 = 0;
-    temp2 = 0;
-    
+    while (_pin_attn != 0) { }
+
     // reset checksum to zero.
     checksum = 0;
     checksumsub = 0;
-    
+
     // get start byte
     temp1 = _xbeespi.write(0x00);
     if (temp1 != 0x7E) {
         // drop packet
-        return 1;
+        return 0;
     }
-    // Get length of message
-    temp1 = _xbeespi.write(0x00);
-    temp2 = _xbeespi.write(0x00);
-    
-    // Get total length
-    length = (temp1<<8) | temp2;
-    
+    // Get length of message (we don't care we know how long)
+    _xbeespi.write(0x00);
+    _xbeespi.write(0x00);
+
     // Next read frame type to ensure it is an response packet.
     temp1 = _xbeespi.write(0x00);
     if (temp1 != 0x88) {
         // drop packet
-        return 1;
+        return 0;
     }
     checksumsub += temp1;
-    
+
     // get response frame id
     temp1 = _xbeespi.write(0x00);
     if (temp1 != 0x52) {
         // drop packet
-        return 1;
+        return 0;
     }
     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;
+
+    if ((temp1 != 0x53) || (temp2 != 0x48)) {
+        return 0;
         // drop
     }
-    
+
     // Check OK flag
     temp1 = _xbeespi.write(0x00);
     if (temp1 != 0x00) {
-        return 1;
+        return 0;
         // 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';
-    
+
+    // Now for the high portion of the serial
+    temp1 = _xbeespi.write(0x00);
+    checksumsub += temp1;
+    temp2 = _xbeespi.write(0x00);
+    checksumsub += temp2;
+    temp3 = _xbeespi.write(0x00);
+    checksumsub += temp3;
+    temp4 = _xbeespi.write(0x00);
+    checksumsub += temp4;
+
+    // Store new items in serial number
+    serialNumber += (temp1 << 56) ^ (temp2 << 48) ^ (temp3 << 40) ^ (temp4 << 32);
+
     // 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;
+    }
+
+    ///////////////////////////////////////////////////Send portion
+    // checksum Variables
+    checksum = 0;
+    checksumsub = 0;
+
+    // Containers for read values
+    temp1 = 0;
+    temp2 = 0;
+    temp3 = 0;
+    temp4 = 0;
+
+    // Write frame to return serial low.
+    // Total frame looks like this:
+    // 7E 00 04 08 52 53(S) 4C(L) CHECKSUM
+    // Wait for response to get lower part of serial
+    // Profit????
+
+    // Frame Header
+    _xbeespi.write(0x7E);
+    // Frame Length
+    _xbeespi.write(0x00);
+    _xbeespi.write(0x04);
+
+    // Frame type (config)
+    _xbeespi.write(0x08);
+    checksumsub += 0x08;
+    _xbeespi.write(0x52);
+    checksumsub += 0x52;
+
+    // Setting wanted SerialLow
+    _xbeespi.write(0x53);
+    checksumsub += 0x53;
+    _xbeespi.write(0x4C);
+    checksumsub += 0x4C;
+
+    // Calculate checksum
+    checksumsub = checksumsub & 0xFF;
+    checksum = 0xFF - checksumsub;
+    // finally write checksum
+    _xbeespi.write(checksum);
+
+    // RECIEVE PORTION
+    // Block until xbee replys
+    while (_pin_attn != 0) { }
+
+    // reset checksum to zero.
+    checksum = 0;
+    checksumsub = 0;
+
+    // get start byte
+    temp1 = _xbeespi.write(0x00);
+    if (temp1 != 0x7E) {
+        // drop packet
+        return 0;
     }
-    
-    return 0;
+    // Get length of message (dont care again)
+    _xbeespi.write(0x00);
+    _xbeespi.write(0x00);
+
+    // Next read frame type to ensure it is an response packet.
+    temp1 = _xbeespi.write(0x00);
+    if (temp1 != 0x88) {
+        // drop packet
+        return 0;
+    }
+    checksumsub += temp1;
+
+    // get response frame id
+    temp1 = _xbeespi.write(0x00);
+    if (temp1 != 0x52) {
+        // drop packet
+        return 0;
+    }
+    checksumsub += temp1;
+
+    // get at response parameter
+    temp1 = _xbeespi.write(0x00);
+    checksumsub += temp1;
+    temp2 = _xbeespi.write(0x00);
+    checksumsub += temp2;
+
+    if ((temp1 != 0x53) || (temp2 != 0x4C)) {
+        return 0;
+        // drop
+    }
 
+    // Check OK flag
+    temp1 = _xbeespi.write(0x00);
+    if (temp1 != 0x00) {
+        return 0;
+        // drop
+    }
+    checksumsub += temp1;
+
+    // Now for the high portion of the serial
+    temp1 = _xbeespi.write(0x00);
+    checksumsub += temp1;
+    temp2 = _xbeespi.write(0x00);
+    checksumsub += temp2;
+    temp3 = _xbeespi.write(0x00);
+    checksumsub += temp3;
+    temp4 = _xbeespi.write(0x00);
+    checksumsub += temp4;
+
+    serialNumber += (temp1 << 24) ^ (temp2 << 16) ^ (temp3 << 8) ^ (temp4);
+
+    // 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 0;
+    }
+
+    return serialNumber;
 }
 
-void xbee900hp::clearBuff()
-{
+
+/**
+* Clear output buffer
+*/
+void xbee900hp::clearBuff() {
     while(_pin_attn == 0) {
         _xbeespi.write(0x00);
     }
-}
\ No newline at end of file
+}
+
+
+/**
+* Read raw data in from module
+*/
+char xbee900hp::debug() {
+    return _xbeespi.write(0x00);
+}