![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Eurobot_2012_Secondary
Embed:
(wiki syntax)
Show/hide line numbers
RF12B.cpp
00001 #include "RF12B.h" 00002 00003 #include "RF_defs.h" 00004 #include <algorithm> 00005 00006 //#include "globals.h" 00007 00008 //DigitalOut DBG2(LED2); 00009 //DigitalOut DBG3(LED3); 00010 //DigitalOut DBG4(LED4); 00011 00012 RF12B::RF12B(PinName _SDI, 00013 PinName _SDO, 00014 PinName _SCK, 00015 PinName _NCS, 00016 PinName _NIRQ):spi(_SDI, _SDO, _SCK), 00017 NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ){// rfled(LED3) { 00018 00019 /* SPI frequency, word lenght, polarity and phase */ 00020 spi.format(16,0); 00021 spi.frequency(2000000); 00022 00023 /* Set ~CS high */ 00024 NCS = 1; 00025 00026 /* Initialise RF Module */ 00027 init(); 00028 00029 /* Setup interrupt to happen on falling edge of NIRQ */ 00030 NIRQ.fall(this, &RF12B::rxISR); 00031 } 00032 00033 /* Returns the packet length if data is available in the receive buffer, 0 otherwise*/ 00034 unsigned int RF12B::available() { 00035 return fifo.size(); 00036 } 00037 00038 /* Reads a packet of data, with length "size" Returns false if read failed. TODO: make a metafifo to isolate packets*/ 00039 bool RF12B::read(unsigned char* data, unsigned int size) { 00040 if (fifo.size() == 0) { 00041 return false; 00042 } else { 00043 unsigned int i = 0; 00044 while (fifo.size() > 0 && i < size) { 00045 data[i++] = fifo.front(); 00046 fifo.pop(); 00047 } 00048 return true; 00049 } 00050 } 00051 00052 /* Reads a byte of data from the receive buffer */ 00053 unsigned char RF12B::read() { 00054 if (available()) { 00055 unsigned char data = fifo.front(); 00056 fifo.pop(); 00057 return data; 00058 } else { 00059 return 0xFF; // Error val although could also be data... 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 //static int cnt = 0; 00280 //printf("%d hits\r\n", cnt); 00281 //cnt++; 00282 00283 //DBG2 = !(cnt%3); 00284 //DBG3 = !((cnt+1)%3); 00285 //DBG4 = !((cnt+2)%3); 00286 00287 unsigned int data = 0; 00288 static int i = -2; 00289 static unsigned char packet_length = 0; 00290 static unsigned char crc = 0; 00291 00292 //Loop while interrupt is asserted 00293 while (!NIRQ_in && mode == RX) { 00294 00295 // Grab the packet's length byte 00296 if (i == -2) { 00297 data = writeCmd(0x0000); 00298 if ( (data&0x8000) ) { 00299 data = writeCmd(0xB000); 00300 packet_length = (data&0x00FF); 00301 crc = crc8(crc, packet_length); 00302 i++; 00303 } 00304 } 00305 00306 //If we exhaust the interrupt, exit 00307 if (NIRQ_in) 00308 break; 00309 00310 // Check that packet length was correct 00311 if (i == -1) { 00312 data = writeCmd(0x0000); 00313 if ( (data&0x8000) ) { 00314 data = writeCmd(0xB000); 00315 unsigned char crcofsize = (data&0x00FF); 00316 if (crcofsize != crc) { 00317 //It was wrong, start over 00318 i = -2; 00319 packet_length = 0; 00320 crc = 0; 00321 //temp = queue<unsigned char>(); 00322 resetRX(); 00323 } else { 00324 crc = crc8(crc, crcofsize); 00325 i++; 00326 } 00327 } 00328 } 00329 00330 //If we exhaust the interrupt, exit 00331 if (NIRQ_in) 00332 break; 00333 00334 // Grab the packet's data 00335 if (i >= 0 && i < packet_length) { 00336 data = writeCmd(0x0000); 00337 if ( (data&0x8000) ) { 00338 data = writeCmd(0xB000); 00339 //temp.push(data&0x00FF); 00340 crc = crc8(crc, (unsigned char)(data&0x00FF)); 00341 i++; 00342 } 00343 } 00344 00345 //If we exhaust the interrupt, exit 00346 if (NIRQ_in) 00347 break; 00348 00349 if (i >= packet_length) { 00350 data = writeCmd(0x0000); 00351 if ( (data&0x8000) ) { 00352 data = writeCmd(0xB000); 00353 if ((unsigned char)(data & 0x00FF) == crc) { 00354 //If the checksum is correct, add our data to the end of the output buffer 00355 //while (!temp.empty()) { 00356 // fifo.push(temp.front()); 00357 // temp.pop(); 00358 //} 00359 } 00360 00361 // Tell RF Module we are finished, and clean up 00362 i = -2; 00363 packet_length = 0; 00364 crc = 0; 00365 //temp = queue<unsigned char>(); 00366 resetRX(); 00367 } 00368 } 00369 } 00370 } 00371 00372 unsigned int RF12B::status() { 00373 return writeCmd(0x0000); 00374 } 00375 00376 /* Tell the RF Module this packet is received and wait for the next */ 00377 void RF12B::resetRX() { 00378 writeCmd(0xCA81); 00379 writeCmd(0xCA83); 00380 }; 00381 00382 /* Calculate CRC8 */ 00383 unsigned char RF12B::crc8(unsigned char crc, unsigned char data) { 00384 crc = crc ^ data; 00385 for (int i = 0; i < 8; i++) { 00386 if (crc & 0x01) { 00387 crc = (crc >> 1) ^ 0x8C; 00388 } else { 00389 crc >>= 1; 00390 } 00391 } 00392 return crc; 00393 }
Generated on Sat Jul 16 2022 01:26:17 by
![doxygen](doxygen.png)