Library to send and receive data using RF12B transceiver modules Big thanks to the tutorial at https://loee.jottit.com/rfm12b_and_avr_-_quick_start and madcowswe

Dependents:   Measure_system Quadcopter_copy

Committer:
harryeakins
Date:
Fri Mar 11 21:38:26 2011 +0000
Revision:
9:cd34784da6da
Parent:
8:6fc24b44e027
Fixed bug in initialization routine where the mode of the RF module was not set.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
harryeakins 3:e72ad65868ab 1 #include "RF12B.h"
harryeakins 3:e72ad65868ab 2
harryeakins 6:98da0571ec31 3 #include "RF_defs.h"
harryeakins 8:6fc24b44e027 4 #include <algorithm>
harryeakins 5:a92c3f6d1711 5
harryeakins 4:2a295db9ba1a 6 RF12B::RF12B(PinName _SDI,
harryeakins 4:2a295db9ba1a 7 PinName _SDO,
harryeakins 4:2a295db9ba1a 8 PinName _SCK,
harryeakins 4:2a295db9ba1a 9 PinName _NCS,
harryeakins 4:2a295db9ba1a 10 PinName _NIRQ):spi(_SDI, _SDO, _SCK),
harryeakins 5:a92c3f6d1711 11 NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ), rfled(LED3) {
harryeakins 3:e72ad65868ab 12
harryeakins 4:2a295db9ba1a 13 /* SPI frequency, word lenght, polarity and phase */
harryeakins 4:2a295db9ba1a 14 spi.format(16,0);
harryeakins 4:2a295db9ba1a 15 spi.frequency(2000000);
harryeakins 4:2a295db9ba1a 16
harryeakins 4:2a295db9ba1a 17 /* Set ~CS high */
harryeakins 4:2a295db9ba1a 18 NCS = 1;
harryeakins 3:e72ad65868ab 19
harryeakins 4:2a295db9ba1a 20 /* Initialise RF Module */
harryeakins 3:e72ad65868ab 21 init();
harryeakins 4:2a295db9ba1a 22
harryeakins 4:2a295db9ba1a 23 /* Setup interrupt to happen on falling edge of NIRQ */
harryeakins 4:2a295db9ba1a 24 NIRQ.fall(this, &RF12B::rxISR);
harryeakins 3:e72ad65868ab 25 }
harryeakins 3:e72ad65868ab 26
harryeakins 7:9f9e2a63a8a2 27 /* Returns the packet length if data is available in the receive buffer, 0 otherwise*/
harryeakins 7:9f9e2a63a8a2 28 unsigned int RF12B::available() {
harryeakins 7:9f9e2a63a8a2 29 return fifo.size();
harryeakins 7:9f9e2a63a8a2 30 }
harryeakins 7:9f9e2a63a8a2 31
harryeakins 7:9f9e2a63a8a2 32 /* Reads a packet of data, with length "size" Returns false if read failed. TODO: make a metafifo to isolate packets*/
harryeakins 7:9f9e2a63a8a2 33 bool RF12B::read(unsigned char* data, unsigned int size) {
harryeakins 7:9f9e2a63a8a2 34 if (fifo.size() == 0) {
harryeakins 7:9f9e2a63a8a2 35 return false;
harryeakins 7:9f9e2a63a8a2 36 } else {
harryeakins 7:9f9e2a63a8a2 37 unsigned int i = 0;
harryeakins 7:9f9e2a63a8a2 38 while (fifo.size() > 0 && i < size) {
harryeakins 7:9f9e2a63a8a2 39 data[i++] = fifo.front();
harryeakins 7:9f9e2a63a8a2 40 fifo.pop();
harryeakins 7:9f9e2a63a8a2 41 }
harryeakins 7:9f9e2a63a8a2 42 return true;
harryeakins 7:9f9e2a63a8a2 43 }
harryeakins 4:2a295db9ba1a 44 }
harryeakins 3:e72ad65868ab 45
harryeakins 4:2a295db9ba1a 46 /* Reads a byte of data from the receive buffer */
harryeakins 3:e72ad65868ab 47 unsigned char RF12B::read() {
harryeakins 4:2a295db9ba1a 48 if (available()) {
harryeakins 4:2a295db9ba1a 49 unsigned char data = fifo.front();
harryeakins 4:2a295db9ba1a 50 fifo.pop();
harryeakins 4:2a295db9ba1a 51 return data;
harryeakins 4:2a295db9ba1a 52 } else {
harryeakins 4:2a295db9ba1a 53 return 0xFF; // Error val although could also be data...
harryeakins 3:e72ad65868ab 54 }
harryeakins 3:e72ad65868ab 55 }
harryeakins 3:e72ad65868ab 56
harryeakins 7:9f9e2a63a8a2 57 /* Sends a packet of data to the RF module for transmission TODO: Make asych*/
harryeakins 4:2a295db9ba1a 58 void RF12B::write(unsigned char *data, unsigned char length) {
harryeakins 6:98da0571ec31 59 unsigned char crc = 0;
harryeakins 8:6fc24b44e027 60
harryeakins 4:2a295db9ba1a 61 /* Transmitter mode */
harryeakins 4:2a295db9ba1a 62 changeMode(TX);
harryeakins 4:2a295db9ba1a 63
harryeakins 3:e72ad65868ab 64 writeCmd(0x0000);
harryeakins 3:e72ad65868ab 65 send(0xAA); // PREAMBLE
harryeakins 3:e72ad65868ab 66 send(0xAA);
harryeakins 3:e72ad65868ab 67 send(0xAA);
harryeakins 3:e72ad65868ab 68 send(0x2D); // SYNC
harryeakins 3:e72ad65868ab 69 send(0xD4);
harryeakins 4:2a295db9ba1a 70 /* Packet Length */
harryeakins 4:2a295db9ba1a 71 send(length);
harryeakins 6:98da0571ec31 72 crc = crc8(crc, length);
harryeakins 7:9f9e2a63a8a2 73 send(crc);
harryeakins 7:9f9e2a63a8a2 74 crc = crc8(crc, crc);
harryeakins 4:2a295db9ba1a 75 /* Packet Data */
harryeakins 4:2a295db9ba1a 76 for (unsigned char i=0; i<length; i++) {
harryeakins 3:e72ad65868ab 77 send(data[i]);
harryeakins 6:98da0571ec31 78 crc = crc8(crc, data[i]);
harryeakins 3:e72ad65868ab 79 }
harryeakins 6:98da0571ec31 80 send(crc);
harryeakins 3:e72ad65868ab 81 send(0xAA); // DUMMY BYTES
harryeakins 3:e72ad65868ab 82 send(0xAA);
harryeakins 3:e72ad65868ab 83 send(0xAA);
harryeakins 3:e72ad65868ab 84
harryeakins 4:2a295db9ba1a 85 /* Back to receiver mode */
harryeakins 4:2a295db9ba1a 86 changeMode(RX);
harryeakins 5:a92c3f6d1711 87 status();
harryeakins 3:e72ad65868ab 88 }
harryeakins 3:e72ad65868ab 89
harryeakins 4:2a295db9ba1a 90 /* Transmit a 1-byte data packet */
harryeakins 4:2a295db9ba1a 91 void RF12B::write(unsigned char data) {
harryeakins 4:2a295db9ba1a 92 write(&data, 1);
harryeakins 3:e72ad65868ab 93 }
harryeakins 3:e72ad65868ab 94
harryeakins 8:6fc24b44e027 95 void RF12B::write(queue<char> &data, int length) {
harryeakins 8:6fc24b44e027 96 char crc = 0;
harryeakins 8:6fc24b44e027 97 char length_byte = 0;
harryeakins 8:6fc24b44e027 98
harryeakins 8:6fc24b44e027 99 /* -1 means try to transmit everything in the queue */
harryeakins 8:6fc24b44e027 100 if(length == -1) {
harryeakins 8:6fc24b44e027 101 length = data.size();
harryeakins 8:6fc24b44e027 102 }
harryeakins 8:6fc24b44e027 103
harryeakins 8:6fc24b44e027 104 /* max length of packet is 255 */
harryeakins 8:6fc24b44e027 105 length_byte = min(length, 255);
harryeakins 8:6fc24b44e027 106
harryeakins 8:6fc24b44e027 107 /* Transmitter mode */
harryeakins 8:6fc24b44e027 108 changeMode(TX);
harryeakins 8:6fc24b44e027 109
harryeakins 8:6fc24b44e027 110 writeCmd(0x0000);
harryeakins 8:6fc24b44e027 111 send(0xAA); // PREAMBLE
harryeakins 8:6fc24b44e027 112 send(0xAA);
harryeakins 8:6fc24b44e027 113 send(0xAA);
harryeakins 8:6fc24b44e027 114 send(0x2D); // SYNC
harryeakins 8:6fc24b44e027 115 send(0xD4);
harryeakins 8:6fc24b44e027 116 /* Packet Length */
harryeakins 8:6fc24b44e027 117 send(length_byte);
harryeakins 8:6fc24b44e027 118 crc = crc8(crc, length_byte);
harryeakins 8:6fc24b44e027 119 send(crc);
harryeakins 8:6fc24b44e027 120 crc = crc8(crc, crc);
harryeakins 8:6fc24b44e027 121 /* Packet Data */
harryeakins 8:6fc24b44e027 122 for (char i=0; i<length_byte; i++) {
harryeakins 8:6fc24b44e027 123 send(data.front());
harryeakins 8:6fc24b44e027 124 crc = crc8(crc, data.front());
harryeakins 8:6fc24b44e027 125 data.pop();
harryeakins 8:6fc24b44e027 126 }
harryeakins 8:6fc24b44e027 127 send(crc);
harryeakins 8:6fc24b44e027 128 send(0xAA); // DUMMY BYTES
harryeakins 8:6fc24b44e027 129 send(0xAA);
harryeakins 8:6fc24b44e027 130 send(0xAA);
harryeakins 8:6fc24b44e027 131
harryeakins 8:6fc24b44e027 132 /* Back to receiver mode */
harryeakins 8:6fc24b44e027 133 changeMode(RX);
harryeakins 8:6fc24b44e027 134 status();
harryeakins 8:6fc24b44e027 135 }
harryeakins 8:6fc24b44e027 136
harryeakins 4:2a295db9ba1a 137 /**********************************************************************
harryeakins 4:2a295db9ba1a 138 * PRIVATE FUNCTIONS
harryeakins 4:2a295db9ba1a 139 *********************************************************************/
harryeakins 3:e72ad65868ab 140
harryeakins 4:2a295db9ba1a 141 /* Initialises the RF12B module */
harryeakins 3:e72ad65868ab 142 void RF12B::init() {
harryeakins 6:98da0571ec31 143 /* writeCmd(0x80E7); //EL,EF,868band,12.0pF
harryeakins 6:98da0571ec31 144 changeMode(RX);
harryeakins 6:98da0571ec31 145 writeCmd(0xA640); //frequency select
harryeakins 6:98da0571ec31 146 writeCmd(0xC647); //4.8kbps
harryeakins 6:98da0571ec31 147 writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
harryeakins 6:98da0571ec31 148 writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
harryeakins 6:98da0571ec31 149 writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
harryeakins 6:98da0571ec31 150 writeCmd(0xCED4); //SYNC=2DD4
harryeakins 6:98da0571ec31 151 writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
harryeakins 6:98da0571ec31 152 writeCmd(0x9850); //!mp,90kHz,MAX OUT
harryeakins 7:9f9e2a63a8a2 153 writeCmd(0xCC17); //OB1, COB0, LPX, Iddy, CDDIT&#65533;CBW0
harryeakins 6:98da0571ec31 154 writeCmd(0xE000); //NOT USED
harryeakins 6:98da0571ec31 155 writeCmd(0xC800); //NOT USED
harryeakins 6:98da0571ec31 156 writeCmd(0xC040); //1.66MHz,2.2V */
harryeakins 6:98da0571ec31 157
harryeakins 6:98da0571ec31 158 writeCmd(
harryeakins 6:98da0571ec31 159 RFM_CONFIG_EL |
harryeakins 6:98da0571ec31 160 RFM_CONFIG_EF |
harryeakins 6:98da0571ec31 161 RFM_CONFIG_BAND_433 //|
harryeakins 6:98da0571ec31 162 //RFM_CONFIG_X_11_0pf // meh, using default
harryeakins 6:98da0571ec31 163 );
harryeakins 6:98da0571ec31 164
harryeakins 6:98da0571ec31 165 // 2. Power Management Command
harryeakins 6:98da0571ec31 166 // leave everything switched off for now
harryeakins 6:98da0571ec31 167 /*
harryeakins 6:98da0571ec31 168 writeCmd(
harryeakins 6:98da0571ec31 169 RFM_POWER_MANAGEMENT // switch all off
harryeakins 6:98da0571ec31 170 );
harryeakins 6:98da0571ec31 171 */
harryeakins 6:98da0571ec31 172
harryeakins 6:98da0571ec31 173 // 3. Frequency Setting Command
harryeakins 6:98da0571ec31 174 writeCmd(
harryeakins 6:98da0571ec31 175 RFM_FREQUENCY |
harryeakins 6:98da0571ec31 176 RFM_FREQ_433Band(435.7) //I totally made this value up... if someone knows where the sweetspots are in this band, tell me!
harryeakins 6:98da0571ec31 177 );
harryeakins 6:98da0571ec31 178
harryeakins 6:98da0571ec31 179
harryeakins 6:98da0571ec31 180 // 4. Data Rate Command
harryeakins 6:98da0571ec31 181 writeCmd(RFM_DATA_RATE_9600);
harryeakins 6:98da0571ec31 182
harryeakins 6:98da0571ec31 183
harryeakins 6:98da0571ec31 184 // 5. Receiver Control Command
harryeakins 6:98da0571ec31 185 writeCmd(
harryeakins 6:98da0571ec31 186 RFM_RX_CONTROL_P20_VDI |
harryeakins 6:98da0571ec31 187 RFM_RX_CONTROL_VDI_FAST |
harryeakins 6:98da0571ec31 188 //RFM_RX_CONTROL_BW(RFM_BAUD_RATE) |
harryeakins 6:98da0571ec31 189 RFM_RX_CONTROL_BW_134 | // CHANGE THIS TO 67 TO IMPROVE RANGE! (though the bitrate must then be below 8kbaud, and fsk modulation changed)
harryeakins 6:98da0571ec31 190 RFM_RX_CONTROL_GAIN_0 |
harryeakins 6:98da0571ec31 191 RFM_RX_CONTROL_RSSI_103 // Might need adjustment. Datasheet says around 10^-5 bit error rate at this level and baudrate.
harryeakins 6:98da0571ec31 192 );
harryeakins 6:98da0571ec31 193
harryeakins 6:98da0571ec31 194 // 6. Data Filter Command
harryeakins 6:98da0571ec31 195 writeCmd(
harryeakins 6:98da0571ec31 196 RFM_DATA_FILTER_AL |
harryeakins 6:98da0571ec31 197 RFM_DATA_FILTER_ML |
harryeakins 6:98da0571ec31 198 RFM_DATA_FILTER_DIG //|
harryeakins 6:98da0571ec31 199 //RFM_DATA_FILTER_DQD(4)
harryeakins 6:98da0571ec31 200 );
harryeakins 6:98da0571ec31 201
harryeakins 6:98da0571ec31 202 // 7. FIFO and Reset Mode Command
harryeakins 6:98da0571ec31 203 writeCmd(
harryeakins 6:98da0571ec31 204 RFM_FIFO_IT(8) |
harryeakins 6:98da0571ec31 205 RFM_FIFO_DR |
harryeakins 6:98da0571ec31 206 0x8 //turn on 16bit sync word
harryeakins 6:98da0571ec31 207 );
harryeakins 6:98da0571ec31 208
harryeakins 6:98da0571ec31 209 // 8. FIFO Syncword
harryeakins 6:98da0571ec31 210 // Leave as default: 0xD4
harryeakins 6:98da0571ec31 211
harryeakins 6:98da0571ec31 212 // 9. Receiver FIFO Read
harryeakins 6:98da0571ec31 213 // when the interupt goes high, (and if we can assume that it was a fifo fill interrupt) we can read a byte using:
harryeakins 6:98da0571ec31 214 // result = RFM_READ_FIFO();
harryeakins 6:98da0571ec31 215
harryeakins 6:98da0571ec31 216 // 10. AFC Command
harryeakins 6:98da0571ec31 217 writeCmd(
harryeakins 6:98da0571ec31 218 //RFM_AFC_AUTO_VDI | //Note this might be changed to improve range. Refer to datasheet.
harryeakins 6:98da0571ec31 219 RFM_AFC_AUTO_INDEPENDENT |
harryeakins 6:98da0571ec31 220 RFM_AFC_RANGE_LIMIT_7_8 |
harryeakins 6:98da0571ec31 221 RFM_AFC_EN |
harryeakins 6:98da0571ec31 222 RFM_AFC_OE |
harryeakins 6:98da0571ec31 223 RFM_AFC_FI
harryeakins 6:98da0571ec31 224 );
harryeakins 6:98da0571ec31 225
harryeakins 6:98da0571ec31 226 // 11. TX Configuration Control Command
harryeakins 6:98da0571ec31 227 writeCmd(
harryeakins 6:98da0571ec31 228 RFM_TX_CONTROL_MOD_60 |
harryeakins 6:98da0571ec31 229 RFM_TX_CONTROL_POW_0
harryeakins 6:98da0571ec31 230 );
harryeakins 6:98da0571ec31 231
harryeakins 6:98da0571ec31 232
harryeakins 6:98da0571ec31 233 // 12. PLL Setting Command
harryeakins 6:98da0571ec31 234 writeCmd(
harryeakins 6:98da0571ec31 235 0xCC77 & ~0x01 // Setting the PLL bandwith, less noise, but max bitrate capped at 86.2
harryeakins 7:9f9e2a63a8a2 236 // I think this will slow down the pll's reaction time. Not sure, check with someone!
harryeakins 6:98da0571ec31 237 );
harryeakins 5:a92c3f6d1711 238
harryeakins 9:cd34784da6da 239 changeMode(RX);
harryeakins 5:a92c3f6d1711 240 resetRX();
harryeakins 5:a92c3f6d1711 241 status();
harryeakins 4:2a295db9ba1a 242 }
harryeakins 3:e72ad65868ab 243
harryeakins 4:2a295db9ba1a 244 /* Write a command to the RF Module */
harryeakins 4:2a295db9ba1a 245 unsigned int RF12B::writeCmd(unsigned int cmd) {
harryeakins 4:2a295db9ba1a 246 NCS = 0;
harryeakins 4:2a295db9ba1a 247 unsigned int recv = spi.write(cmd);
harryeakins 4:2a295db9ba1a 248 NCS = 1;
harryeakins 4:2a295db9ba1a 249 return recv;
harryeakins 3:e72ad65868ab 250 }
harryeakins 3:e72ad65868ab 251
harryeakins 4:2a295db9ba1a 252 /* Sends a byte of data across RF */
harryeakins 4:2a295db9ba1a 253 void RF12B::send(unsigned char data) {
harryeakins 4:2a295db9ba1a 254 while (NIRQ);
harryeakins 4:2a295db9ba1a 255 writeCmd(0xB800 + data);
harryeakins 4:2a295db9ba1a 256 }
harryeakins 4:2a295db9ba1a 257
harryeakins 4:2a295db9ba1a 258 /* Change the mode of the RF module to Transmitting or Receiving */
harryeakins 8:6fc24b44e027 259 void RF12B::changeMode(rfmode_t _mode) {
harryeakins 8:6fc24b44e027 260 mode = _mode;
harryeakins 8:6fc24b44e027 261 if (_mode == TX) {
harryeakins 3:e72ad65868ab 262 writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
harryeakins 4:2a295db9ba1a 263 } else { /* mode == RX */
harryeakins 3:e72ad65868ab 264 writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC
harryeakins 3:e72ad65868ab 265 }
harryeakins 3:e72ad65868ab 266 }
harryeakins 3:e72ad65868ab 267
harryeakins 4:2a295db9ba1a 268 /* Interrupt routine for data reception */
harryeakins 4:2a295db9ba1a 269 void RF12B::rxISR() {
harryeakins 7:9f9e2a63a8a2 270 unsigned int data = 0;
harryeakins 7:9f9e2a63a8a2 271 static int i = -2;
harryeakins 7:9f9e2a63a8a2 272 static unsigned char packet_length = 0;
harryeakins 7:9f9e2a63a8a2 273 static unsigned char crc = 0;
harryeakins 7:9f9e2a63a8a2 274 static queue<unsigned char> temp;
harryeakins 7:9f9e2a63a8a2 275
harryeakins 7:9f9e2a63a8a2 276 //Loop while interrupt is asserted
harryeakins 8:6fc24b44e027 277 while (!NIRQ_in && mode == RX) {
harryeakins 7:9f9e2a63a8a2 278
harryeakins 7:9f9e2a63a8a2 279 /* Grab the packet's length byte */
harryeakins 7:9f9e2a63a8a2 280 if (i == -2) {
harryeakins 7:9f9e2a63a8a2 281 data = writeCmd(0x0000);
harryeakins 7:9f9e2a63a8a2 282 if ( (data&0x8000) ) {
harryeakins 7:9f9e2a63a8a2 283 data = writeCmd(0xB000);
harryeakins 7:9f9e2a63a8a2 284 packet_length = (data&0x00FF);
harryeakins 7:9f9e2a63a8a2 285 crc = crc8(crc, packet_length);
harryeakins 7:9f9e2a63a8a2 286 i++;
harryeakins 7:9f9e2a63a8a2 287 }
harryeakins 7:9f9e2a63a8a2 288 }
harryeakins 7:9f9e2a63a8a2 289
harryeakins 7:9f9e2a63a8a2 290 //If we exhaust the interrupt, exit
harryeakins 7:9f9e2a63a8a2 291 if (NIRQ_in)
harryeakins 7:9f9e2a63a8a2 292 break;
harryeakins 4:2a295db9ba1a 293
harryeakins 7:9f9e2a63a8a2 294 // Check that packet length was correct
harryeakins 7:9f9e2a63a8a2 295 if (i == -1) {
harryeakins 7:9f9e2a63a8a2 296 data = writeCmd(0x0000);
harryeakins 7:9f9e2a63a8a2 297 if ( (data&0x8000) ) {
harryeakins 7:9f9e2a63a8a2 298 data = writeCmd(0xB000);
harryeakins 7:9f9e2a63a8a2 299 unsigned char crcofsize = (data&0x00FF);
harryeakins 7:9f9e2a63a8a2 300 if (crcofsize != crc) {
harryeakins 7:9f9e2a63a8a2 301 //It was wrong, start over
harryeakins 7:9f9e2a63a8a2 302 i = -2;
harryeakins 7:9f9e2a63a8a2 303 packet_length = 0;
harryeakins 7:9f9e2a63a8a2 304 crc = 0;
harryeakins 7:9f9e2a63a8a2 305 temp = queue<unsigned char>();
harryeakins 7:9f9e2a63a8a2 306 resetRX();
harryeakins 7:9f9e2a63a8a2 307 } else {
harryeakins 7:9f9e2a63a8a2 308 crc = crc8(crc, crcofsize);
harryeakins 7:9f9e2a63a8a2 309 i++;
harryeakins 7:9f9e2a63a8a2 310 }
harryeakins 7:9f9e2a63a8a2 311 }
harryeakins 7:9f9e2a63a8a2 312 }
harryeakins 5:a92c3f6d1711 313
harryeakins 7:9f9e2a63a8a2 314 //If we exhaust the interrupt, exit
harryeakins 7:9f9e2a63a8a2 315 if (NIRQ_in)
harryeakins 7:9f9e2a63a8a2 316 break;
harryeakins 7:9f9e2a63a8a2 317
harryeakins 7:9f9e2a63a8a2 318 /* Grab the packet's data */
harryeakins 7:9f9e2a63a8a2 319 if (i >= 0 && i < packet_length) {
harryeakins 5:a92c3f6d1711 320 data = writeCmd(0x0000);
harryeakins 5:a92c3f6d1711 321 if ( (data&0x8000) ) {
harryeakins 5:a92c3f6d1711 322 data = writeCmd(0xB000);
harryeakins 6:98da0571ec31 323 temp.push(data&0x00FF);
harryeakins 6:98da0571ec31 324 crc = crc8(crc, (unsigned char)(data&0x00FF));
harryeakins 5:a92c3f6d1711 325 i++;
harryeakins 5:a92c3f6d1711 326 }
harryeakins 4:2a295db9ba1a 327 }
harryeakins 7:9f9e2a63a8a2 328
harryeakins 7:9f9e2a63a8a2 329 //If we exhaust the interrupt, exit
harryeakins 7:9f9e2a63a8a2 330 if (NIRQ_in)
harryeakins 7:9f9e2a63a8a2 331 break;
harryeakins 7:9f9e2a63a8a2 332
harryeakins 7:9f9e2a63a8a2 333 if (i >= packet_length) {
harryeakins 6:98da0571ec31 334 data = writeCmd(0x0000);
harryeakins 6:98da0571ec31 335 if ( (data&0x8000) ) {
harryeakins 6:98da0571ec31 336 data = writeCmd(0xB000);
harryeakins 6:98da0571ec31 337 if ((unsigned char)(data & 0x00FF) == crc) {
harryeakins 7:9f9e2a63a8a2 338 //If the checksum is correct, add our data to the end of the output buffer
harryeakins 6:98da0571ec31 339 while (!temp.empty()) {
harryeakins 6:98da0571ec31 340 fifo.push(temp.front());
harryeakins 6:98da0571ec31 341 temp.pop();
harryeakins 6:98da0571ec31 342 }
harryeakins 6:98da0571ec31 343 }
harryeakins 7:9f9e2a63a8a2 344
harryeakins 7:9f9e2a63a8a2 345 /* Tell RF Module we are finished, and clean up */
harryeakins 7:9f9e2a63a8a2 346 i = -2;
harryeakins 7:9f9e2a63a8a2 347 packet_length = 0;
harryeakins 7:9f9e2a63a8a2 348 crc = 0;
harryeakins 7:9f9e2a63a8a2 349 temp = queue<unsigned char>();
harryeakins 7:9f9e2a63a8a2 350 resetRX();
harryeakins 6:98da0571ec31 351 }
harryeakins 6:98da0571ec31 352 }
harryeakins 6:98da0571ec31 353 }
harryeakins 3:e72ad65868ab 354 }
harryeakins 4:2a295db9ba1a 355
harryeakins 5:a92c3f6d1711 356 unsigned int RF12B::status() {
harryeakins 5:a92c3f6d1711 357 return writeCmd(0x0000);
harryeakins 5:a92c3f6d1711 358 }
harryeakins 5:a92c3f6d1711 359
harryeakins 4:2a295db9ba1a 360 /* Tell the RF Module this packet is received and wait for the next */
harryeakins 4:2a295db9ba1a 361 void RF12B::resetRX() {
harryeakins 4:2a295db9ba1a 362 writeCmd(0xCA81);
harryeakins 4:2a295db9ba1a 363 writeCmd(0xCA83);
harryeakins 6:98da0571ec31 364 };
harryeakins 6:98da0571ec31 365
harryeakins 6:98da0571ec31 366 /* Calculate CRC8 */
harryeakins 6:98da0571ec31 367 unsigned char RF12B::crc8(unsigned char crc, unsigned char data) {
harryeakins 6:98da0571ec31 368 crc = crc ^ data;
harryeakins 6:98da0571ec31 369 for (int i = 0; i < 8; i++) {
harryeakins 6:98da0571ec31 370 if (crc & 0x01) {
harryeakins 6:98da0571ec31 371 crc = (crc >> 1) ^ 0x8C;
harryeakins 6:98da0571ec31 372 } else {
harryeakins 6:98da0571ec31 373 crc >>= 1;
harryeakins 6:98da0571ec31 374 }
harryeakins 6:98da0571ec31 375 }
harryeakins 6:98da0571ec31 376 return crc;
harryeakins 6:98da0571ec31 377 }