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