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