Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
RF12B.cpp
00001 #include "RF12B.h" 00002 00003 #include "RF_defs.h" 00004 #include "defines.h" 00005 #include <algorithm> 00006 00007 RF12B::RF12B(PinName _SDI, 00008 PinName _SDO, 00009 PinName _SCK, 00010 PinName _NCS, 00011 PinName _NIRQ, 00012 PinName _TRIG):spi(_SDI, _SDO, _SCK), 00013 NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ), rfled(LED3),trigLED(LED1),TRIG(_TRIG) { 00014 00015 /* SPI frequency, word lenght, polarity and phase */ 00016 spi.format(16,0); 00017 spi.frequency(2000000); 00018 00019 /* Set ~CS high */ 00020 NCS = 1; 00021 00022 /* Initialise RF Module */ 00023 init(); 00024 00025 /* Setup interrupt to happen on falling edge of NIRQ */ 00026 NIRQ.fall(this, &RF12B::rxISR); 00027 00028 /* Dummy code init */ 00029 rfCode = 0x00; 00030 } 00031 00032 /* Returns the packet length if data is available in the receive buffer, 0 otherwise*/ 00033 unsigned int RF12B::available() { 00034 return fifo.size(); 00035 } 00036 00037 /* Reads a packet of data, with length "size" Returns false if read failed. TODO: make a metafifo to isolate packets*/ 00038 bool RF12B::read(unsigned char* data, unsigned int size) { 00039 if (fifo.size() == 0) { 00040 return false; 00041 } else { 00042 unsigned int i = 0; 00043 while (fifo.size() > 0 && i < size) { 00044 data[i++] = fifo.front(); 00045 fifo.pop(); 00046 } 00047 return true; 00048 } 00049 } 00050 00051 /* Reads a byte of data from the receive buffer */ 00052 unsigned char RF12B::read() { 00053 if (available()) { 00054 unsigned char data = fifo.front(); 00055 fifo.pop(); 00056 return data; 00057 } else { 00058 return 0xFF; // Error val although could also be data... 00059 } 00060 } 00061 00062 /* Sends a packet of data to the RF module for transmission TODO: Make asych*/ 00063 void RF12B::write(unsigned char *data, unsigned char length) { 00064 unsigned char crc = 0; 00065 00066 /* Transmitter mode */ 00067 changeMode(TX); 00068 00069 writeCmd(0x0000); 00070 send(0xAA); // PREAMBLE 00071 send(0xAA); 00072 send(0xAA); 00073 send(0x2D); // SYNC 00074 send(0xD4); 00075 /* Packet Length */ 00076 send(length); 00077 crc = crc8(crc, length); 00078 send(crc); 00079 crc = crc8(crc, crc); 00080 /* Packet Data */ 00081 for (unsigned char i=0; i<length; i++) { 00082 send(data[i]); 00083 crc = crc8(crc, data[i]); 00084 } 00085 send(crc); 00086 send(0xAA); // DUMMY BYTES 00087 send(0xAA); 00088 send(0xAA); 00089 00090 /* Back to receiver mode */ 00091 changeMode(RX); 00092 status(); 00093 } 00094 00095 /* Transmit a 1-byte data packet */ 00096 void RF12B::write(unsigned char data) { 00097 write(&data, 1); 00098 } 00099 00100 void RF12B::write(queue<char> &data, int length) { 00101 char crc = 0; 00102 char length_byte = 0; 00103 00104 /* -1 means try to transmit everything in the queue */ 00105 if (length == -1) { 00106 length = data.size(); 00107 } 00108 00109 /* max length of packet is 255 */ 00110 length_byte = min(length, 255); 00111 00112 /* Transmitter mode */ 00113 changeMode(TX); 00114 00115 writeCmd(0x0000); 00116 send(0xAA); // PREAMBLE 00117 send(0xAA); 00118 send(0xAA); 00119 send(0x2D); // SYNC 00120 send(0xD4); 00121 /* Packet Length */ 00122 send(length_byte); 00123 crc = crc8(crc, length_byte); 00124 send(crc); 00125 crc = crc8(crc, crc); 00126 /* Packet Data */ 00127 for (char i=0; i<length_byte; i++) { 00128 send(data.front()); 00129 crc = crc8(crc, data.front()); 00130 data.pop(); 00131 } 00132 send(crc); 00133 send(0xAA); // DUMMY BYTES 00134 send(0xAA); 00135 send(0xAA); 00136 00137 /* Back to receiver mode */ 00138 changeMode(RX); 00139 status(); 00140 } 00141 00142 /********************************************************************** 00143 * PRIVATE FUNCTIONS 00144 *********************************************************************/ 00145 00146 /* Initialises the RF12B module */ 00147 void RF12B::init() { 00148 /* writeCmd(0x80E7); //EL,EF,868band,12.0pF 00149 changeMode(RX); 00150 writeCmd(0xA640); //frequency select 00151 writeCmd(0xC647); //4.8kbps 00152 writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm 00153 writeCmd(0xC2AC); //AL,!ml,DIG,DQD4 00154 writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR 00155 writeCmd(0xCED4); //SYNC=2DD4 00156 writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN 00157 writeCmd(0x9850); //!mp,90kHz,MAX OUT 00158 writeCmd(0xCC17); //OB1, COB0, LPX, Iddy, CDDIT�CBW0 00159 writeCmd(0xE000); //NOT USED 00160 writeCmd(0xC800); //NOT USED 00161 writeCmd(0xC040); //1.66MHz,2.2V */ 00162 00163 writeCmd( 00164 RFM_CONFIG_EL | 00165 RFM_CONFIG_EF | 00166 RFM_CONFIG_BAND_433 //| 00167 //RFM_CONFIG_X_11_0pf // meh, using default 00168 ); 00169 00170 // 2. Power Management Command 00171 // leave everything switched off for now 00172 /* 00173 writeCmd( 00174 RFM_POWER_MANAGEMENT // switch all off 00175 ); 00176 */ 00177 00178 // 3. Frequency Setting Command 00179 writeCmd( 00180 RFM_FREQUENCY | 00181 RFM_FREQ_433Band(435.7) //I totally made this value up... if someone knows where the sweetspots are in this band, tell me! 00182 ); 00183 00184 00185 // 4. Data Rate Command 00186 //writeCmd(RFM_DATA_RATE_9600); 00187 writeCmd(RFM_DATA_RATE_57600); 00188 00189 // 5. Receiver Control Command 00190 writeCmd( 00191 RFM_RX_CONTROL_P20_VDI | 00192 RFM_RX_CONTROL_VDI_FAST | 00193 //RFM_RX_CONTROL_BW(RFM_BAUD_RATE) | 00194 RFM_RX_CONTROL_BW_134 | // CHANGE THIS TO 67 TO IMPROVE RANGE! (though the bitrate must then be below 8kbaud, and fsk modulation changed) 00195 RFM_RX_CONTROL_GAIN_0 | 00196 RFM_RX_CONTROL_RSSI_103 // Might need adjustment. Datasheet says around 10^-5 bit error rate at this level and baudrate. 00197 ); 00198 00199 // 6. Data Filter Command 00200 writeCmd( 00201 RFM_DATA_FILTER_AL | 00202 RFM_DATA_FILTER_ML | 00203 RFM_DATA_FILTER_DIG //| 00204 //RFM_DATA_FILTER_DQD(4) 00205 ); 00206 00207 // 7. FIFO and Reset Mode Command 00208 writeCmd( 00209 RFM_FIFO_IT(8) | 00210 RFM_FIFO_DR | 00211 0x8 //turn on 16bit sync word 00212 ); 00213 00214 // 8. FIFO Syncword 00215 // Leave as default: 0xD4 00216 00217 // 9. Receiver FIFO Read 00218 // when the interupt goes high, (and if we can assume that it was a fifo fill interrupt) we can read a byte using: 00219 // result = RFM_READ_FIFO(); 00220 00221 // 10. AFC Command 00222 writeCmd( 00223 //RFM_AFC_AUTO_VDI | //Note this might be changed to improve range. Refer to datasheet. 00224 RFM_AFC_AUTO_INDEPENDENT | 00225 RFM_AFC_RANGE_LIMIT_7_8 | 00226 RFM_AFC_EN | 00227 RFM_AFC_OE | 00228 RFM_AFC_FI 00229 ); 00230 00231 // 11. TX Configuration Control Command 00232 writeCmd( 00233 RFM_TX_CONTROL_MOD_60 | 00234 RFM_TX_CONTROL_POW_0 00235 ); 00236 00237 00238 // 12. PLL Setting Command 00239 writeCmd( 00240 0xCC77 & ~0x01 // Setting the PLL bandwith, less noise, but max bitrate capped at 86.2 00241 // I think this will slow down the pll's reaction time. Not sure, check with someone! 00242 ); 00243 00244 changeMode(RX); 00245 resetRX(); 00246 status(); 00247 } 00248 00249 /* Write a command to the RF Module */ 00250 unsigned int RF12B::writeCmd(unsigned int cmd) { 00251 NCS = 0; 00252 unsigned int recv = spi.write(cmd); 00253 NCS = 1; 00254 return recv; 00255 } 00256 00257 /* Sends a byte of data across RF */ 00258 void RF12B::send(unsigned char data) { 00259 while (NIRQ); 00260 writeCmd(0xB800 + data); 00261 } 00262 00263 /* Change the mode of the RF module to Transmitting or Receiving */ 00264 void RF12B::changeMode(rfmode_t _mode) { 00265 mode = _mode; 00266 if (_mode == TX) { 00267 writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC 00268 } else { /* mode == RX */ 00269 writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC 00270 } 00271 } 00272 00273 /* Interrupt routine for data reception */ 00274 void RF12B::rxISR() { 00275 unsigned int data = 0; 00276 static int i = -2; 00277 static unsigned char packet_length = 0; 00278 static unsigned char crc = 0; 00279 static queue<unsigned char> temp; 00280 00281 //Loop while interrupt is asserted 00282 while (!NIRQ_in && mode == RX) { 00283 00284 /* Grab the packet's length byte */ 00285 if (i == -2) { 00286 data = writeCmd(0x0000); 00287 if ( (data&0x8000) ) { 00288 data = writeCmd(0xB000); 00289 packet_length = (data&0x00FF); 00290 crc = crc8(crc, packet_length); 00291 i++; 00292 } 00293 } 00294 00295 //If we exhaust the interrupt, exit 00296 if (NIRQ_in) 00297 break; 00298 00299 // Check that packet length was correct 00300 if (i == -1) { 00301 data = writeCmd(0x0000); 00302 if ( (data&0x8000) ) { 00303 data = writeCmd(0xB000); 00304 unsigned char crcofsize = (data&0x00FF); 00305 if (crcofsize != crc) { 00306 //It was wrong, start over 00307 i = -2; 00308 packet_length = 0; 00309 crc = 0; 00310 temp = queue<unsigned char>(); 00311 resetRX(); 00312 } else { 00313 crc = crc8(crc, crcofsize); 00314 i++; 00315 } 00316 } 00317 } 00318 00319 //If we exhaust the interrupt, exit 00320 if (NIRQ_in) 00321 break; 00322 00323 /* Grab the packet's data */ 00324 if (i >= 0 && i < packet_length) { 00325 data = writeCmd(0x0000); 00326 if ( (data&0x8000) ) { 00327 data = writeCmd(0xB000); 00328 temp.push(data&0x00FF); 00329 crc = crc8(crc, (unsigned char)(data&0x00FF)); 00330 i++; 00331 } 00332 } 00333 00334 //If we exhaust the interrupt, exit 00335 if (NIRQ_in) 00336 break; 00337 00338 if (i >= packet_length) { 00339 data = writeCmd(0x0000); 00340 if ( (data&0x8000) ) { 00341 data = writeCmd(0xB000); 00342 if ((unsigned char)(data & 0x00FF) == crc) { 00343 //If the checksum is correct, add our data to the end of the output buffer 00344 while (!temp.empty()) { 00345 fifo.push(temp.front()); 00346 temp.pop(); 00347 00348 if (read() == rfCode) { 00349 TRIG = 1; 00350 wait_us(10); 00351 TRIG = 0; 00352 trigLED = !trigLED; 00353 } 00354 } 00355 } 00356 00357 /* Tell RF Module we are finished, and clean up */ 00358 i = -2; 00359 packet_length = 0; 00360 crc = 0; 00361 temp = queue<unsigned char>(); 00362 resetRX(); 00363 } 00364 } 00365 } 00366 } 00367 00368 unsigned int RF12B::status() { 00369 return writeCmd(0x0000); 00370 } 00371 00372 /* Tell the RF Module this packet is received and wait for the next */ 00373 void RF12B::resetRX() { 00374 writeCmd(0xCA81); 00375 writeCmd(0xCA83); 00376 }; 00377 00378 /* Calculate CRC8 */ 00379 unsigned char RF12B::crc8(unsigned char crc, unsigned char data) { 00380 crc = crc ^ data; 00381 for (int i = 0; i < 8; i++) { 00382 if (crc & 0x01) { 00383 crc = (crc >> 1) ^ 0x8C; 00384 } else { 00385 crc >>= 1; 00386 } 00387 } 00388 return crc; 00389 } 00390 00391 /* RF code set */ 00392 void RF12B::setCode(unsigned char code) { 00393 rfCode = code; 00394 }
Generated on Thu Jul 14 2022 07:33:28 by
1.7.2