Shuto Naruse
/
Eurobot2012_Beacons
Eurobot2012_Beacons
Embed:
(wiki syntax)
Show/hide line numbers
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