Cooper Liu
/
Eurobot2013_Co-Processor
working version with calibration done
Fork of Eurobot2013 by
Embed:
(wiki syntax)
Show/hide line numbers
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 writeCmd(RFM_DATA_RATE_57600); 00191 00192 00193 // 5. Receiver Control Command 00194 writeCmd( 00195 RFM_RX_CONTROL_P20_VDI | 00196 RFM_RX_CONTROL_VDI_FAST | 00197 //RFM_RX_CONTROL_BW(RFM_BAUD_RATE) | 00198 RFM_RX_CONTROL_BW_134 | // CHANGE THIS TO 67 TO IMPROVE RANGE! (though the bitrate must then be below 8kbaud, and fsk modulation changed) 00199 RFM_RX_CONTROL_GAIN_0 | 00200 RFM_RX_CONTROL_RSSI_103 // Might need adjustment. Datasheet says around 10^-5 bit error rate at this level and baudrate. 00201 ); 00202 00203 // 6. Data Filter Command 00204 writeCmd( 00205 RFM_DATA_FILTER_AL | 00206 RFM_DATA_FILTER_ML | 00207 RFM_DATA_FILTER_DIG //| 00208 //RFM_DATA_FILTER_DQD(4) 00209 ); 00210 00211 // 7. FIFO and Reset Mode Command 00212 writeCmd( 00213 RFM_FIFO_IT(8) | 00214 RFM_FIFO_DR | 00215 0x8 //turn on 16bit sync word 00216 ); 00217 00218 // 8. FIFO Syncword 00219 // Leave as default: 0xD4 00220 00221 // 9. Receiver FIFO Read 00222 // when the interupt goes high, (and if we can assume that it was a fifo fill interrupt) we can read a byte using: 00223 // result = RFM_READ_FIFO(); 00224 00225 // 10. AFC Command 00226 writeCmd( 00227 //RFM_AFC_AUTO_VDI | //Note this might be changed to improve range. Refer to datasheet. 00228 RFM_AFC_AUTO_INDEPENDENT | 00229 RFM_AFC_RANGE_LIMIT_7_8 | 00230 RFM_AFC_EN | 00231 RFM_AFC_OE | 00232 RFM_AFC_FI 00233 ); 00234 00235 // 11. TX Configuration Control Command 00236 writeCmd( 00237 RFM_TX_CONTROL_MOD_60 | 00238 RFM_TX_CONTROL_POW_0 00239 ); 00240 00241 00242 // 12. PLL Setting Command 00243 writeCmd( 00244 0xCC77 & ~0x01 // Setting the PLL bandwith, less noise, but max bitrate capped at 86.2 00245 // I think this will slow down the pll's reaction time. Not sure, check with someone! 00246 ); 00247 00248 changeMode(RX); 00249 resetRX(); 00250 status(); 00251 } 00252 00253 /* Write a command to the RF Module */ 00254 unsigned int RF12B::writeCmd(unsigned int cmd) { 00255 NCS = 0; 00256 unsigned int recv = spi.write(cmd); 00257 NCS = 1; 00258 return recv; 00259 } 00260 00261 /* Sends a byte of data across RF */ 00262 void RF12B::send(unsigned char data) { 00263 while (NIRQ); 00264 writeCmd(0xB800 + data); 00265 } 00266 00267 /* Change the mode of the RF module to Transmitting or Receiving */ 00268 void RF12B::changeMode(rfmode_t _mode) { 00269 mode = _mode; 00270 if (_mode == TX) { 00271 writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC 00272 } else { /* mode == RX */ 00273 writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC 00274 } 00275 } 00276 00277 // Interrupt routine for data reception */ 00278 void RF12B::rxISR() { 00279 00280 unsigned int data = 0; 00281 static int i = -2; 00282 static unsigned char packet_length = 0; 00283 static unsigned char crc = 0; 00284 // #ifdef ROBOT_SECONDARY 00285 static unsigned char temp; 00286 // #endif 00287 00288 //Loop while interrupt is asserted 00289 while (!NIRQ_in && mode == RX) { 00290 00291 // Grab the packet's length byte 00292 if (i == -2) { 00293 data = writeCmd(0x0000); 00294 if ( (data&0x8000) ) { 00295 data = writeCmd(0xB000); 00296 packet_length = (data&0x00FF); 00297 crc = crc8(crc, packet_length); 00298 i++; 00299 } 00300 } 00301 00302 //If we exhaust the interrupt, exit 00303 if (NIRQ_in) 00304 break; 00305 00306 // Check that packet length was correct 00307 if (i == -1) { 00308 data = writeCmd(0x0000); 00309 if ( (data&0x8000) ) { 00310 data = writeCmd(0xB000); 00311 unsigned char crcofsize = (data&0x00FF); 00312 if (crcofsize != crc) { 00313 //It was wrong, start over 00314 i = -2; 00315 packet_length = 0; 00316 crc = 0; 00317 //temp = queue<unsigned char>(); 00318 resetRX(); 00319 } else { 00320 crc = crc8(crc, crcofsize); 00321 i++; 00322 } 00323 } 00324 } 00325 00326 //If we exhaust the interrupt, exit 00327 if (NIRQ_in) 00328 break; 00329 00330 // Grab the packet's data 00331 if (i >= 0 && i < packet_length) { 00332 data = writeCmd(0x0000); 00333 if ( (data&0x8000) ) { 00334 data = writeCmd(0xB000); 00335 // #ifdef ROBOT_SECONDARY 00336 temp = data&0x00FF; 00337 // #endif 00338 //temp.push(data&0x00FF); 00339 crc = crc8(crc, (unsigned char)(data&0x00FF)); 00340 i++; 00341 } 00342 } 00343 00344 //If we exhaust the interrupt, exit 00345 if (NIRQ_in) 00346 break; 00347 00348 if (i >= packet_length) { 00349 data = writeCmd(0x0000); 00350 if ( (data&0x8000) ) { 00351 data = writeCmd(0xB000); 00352 if ((unsigned char)(data & 0x00FF) == crc) { 00353 //If the checksum is correct, add our data to the end of the output buffer 00354 //while (!temp.empty()) { 00355 //fifo.push(temp); 00356 // temp.pop(); 00357 //#ifdef ROBOT_SECONDARY 00358 if (callbackfunc) 00359 (*callbackfunc)(temp); 00360 00361 if (callbackobj && mcallbackfunc) 00362 (callbackobj->*mcallbackfunc)(temp); 00363 //#endif 00364 // } 00365 } 00366 00367 // Tell RF Module we are finished, and clean up 00368 i = -2; 00369 packet_length = 0; 00370 crc = 0; 00371 //temp = queue<unsigned char>(); 00372 resetRX(); 00373 } 00374 } 00375 } 00376 00377 } 00378 00379 unsigned int RF12B::status() { 00380 return writeCmd(0x0000); 00381 } 00382 00383 // Tell the RF Module this packet is received and wait for the next */ 00384 void RF12B::resetRX() { 00385 writeCmd(0xCA81); 00386 writeCmd(0xCA83); 00387 }; 00388 00389 // Calculate CRC8 */ 00390 unsigned char RF12B::crc8(unsigned char crc, unsigned char data) { 00391 crc = crc ^ data; 00392 for (int i = 0; i < 8; i++) { 00393 if (crc & 0x01) { 00394 crc = (crc >> 1) ^ 0x8C; 00395 } else { 00396 crc >>= 1; 00397 } 00398 } 00399 return crc; 00400 }
Generated on Tue Jul 12 2022 18:53:25 by 1.7.2