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:
- 2016-04-27
- Revision:
- 8:fa84dacc45b9
- Parent:
- 7:3cb67634fa4e
- Child:
- 9:d4542525b218
File content as of revision 8:fa84dacc45b9:
#include "xbee900hp.h" 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); // Set SPI frequency _xbeespi.frequency(freq); // Reset for good measure. reset(); // Xbee is up and running! } /** * Destructor */ xbee900hp::~xbee900hp() {} /** * Reset xBee to SPI mode */ void xbee900hp::reset() { _pin_rst = 0; // Minimum pulse is 1ms wait_ms(2); _pin_rst = 1; // 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 */ 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 _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); // 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; checksum = 0xFF - checksumsub; // finally write checksum _xbeespi.write(checksum); return 0; } /** * 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) { 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) { return 0; } checksumsub += temp1; // in our case we dont care about source address this should be modified to extract source address if needed. 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); 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 0; } return srcAddr; } /** * Check ATTN signal */ int xbee900hp::attn() { return _pin_attn; } /** * Get signal strength of last recieved packet */ unsigned int xbee900hp::getRSSI() { // checksum Variables unsigned int checksum = 0; unsigned int checksumsub = 0; // RSSI storage container unsigned int rssi; // Frame initiator _xbeespi.write(0x7E); // Length _xbeespi.write(0x00); _xbeespi.write(0x04); // Frame type (config) _xbeespi.write(0x08); checksumsub += 0x08; // Response frame ID _xbeespi.write(0x44); checksumsub += 0x44; // AT Command _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); // 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; // get response frame id 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 != 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) { return 1; // drop } checksumsub += temp1; // 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; } /** * Get serial number of xbee module */ unsigned long long xbee900hp::getSerial() { // checksum Variables 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 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 // 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; } // 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 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 != 0x48)) { 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; // 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 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; } // 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; } /** * Clear output buffer */ void xbee900hp::clearBuff() { while(_pin_attn == 0) { _xbeespi.write(0x00); } } /** * Read raw data in from module */ char xbee900hp::debug() { return _xbeespi.write(0x00); }