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