Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed FATFileSystem
Fork of KL46Z-USBHostMSD_HelloWorld by
RF22.cpp
00001 // RF22.cpp 00002 00003 #include "mbed.h" 00004 #include "RF22.h" 00005 00006 Serial pc1(USBTX, USBRX); 00007 00008 // These are indexed by the values of ModemConfigChoic 00009 // Stored in flash (program) memory to save SRAM 00010 /*PROGMEM */ static const RF22::ModemConfig MODEM_CONFIG_TABLE[] = { 00011 { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x00, 0x08 }, // Unmodulated carrier 00012 { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x33, 0x08 }, // FSK, PN9 random modulation, 2, 5 00013 00014 // All the following enable FIFO with reg 71 00015 // 1c, 1f, 20, 21, 22, 23, 24, 25, 2c, 2d, 2e, 58, 69, 6e, 6f, 70, 71, 72 00016 // FSK, No Manchester, Max Rb err <1%, Xtal Tol 20ppm 00017 { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x22, 0x08 }, // 2, 5 00018 { 0x1b, 0x03, 0x41, 0x60, 0x27, 0x52, 0x00, 0x07, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x13, 0xa9, 0x2c, 0x22, 0x3a }, // 2.4, 36 00019 { 0x1d, 0x03, 0xa1, 0x20, 0x4e, 0xa5, 0x00, 0x13, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x27, 0x52, 0x2c, 0x22, 0x48 }, // 4.8, 45 00020 { 0x1e, 0x03, 0xd0, 0x00, 0x9d, 0x49, 0x00, 0x45, 0x40, 0x0a, 0x20, 0x80, 0x60, 0x4e, 0xa5, 0x2c, 0x22, 0x48 }, // 9.6, 45 00021 { 0x2b, 0x03, 0x34, 0x02, 0x75, 0x25, 0x07, 0xff, 0x40, 0x0a, 0x1b, 0x80, 0x60, 0x9d, 0x49, 0x2c, 0x22, 0x0f }, // 19.2, 9.6 00022 { 0x02, 0x03, 0x68, 0x01, 0x3a, 0x93, 0x04, 0xd5, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x09, 0xd5, 0x0c, 0x22, 0x1f }, // 38.4, 19.6 00023 { 0x06, 0x03, 0x45, 0x01, 0xd7, 0xdc, 0x07, 0x6e, 0x40, 0x0a, 0x2d, 0x80, 0x60, 0x0e, 0xbf, 0x0c, 0x22, 0x2e }, // 57.6. 28.8 00024 { 0x8a, 0x03, 0x60, 0x01, 0x55, 0x55, 0x02, 0xad, 0x40, 0x0a, 0x50, 0x80, 0x60, 0x20, 0x00, 0x0c, 0x22, 0xc8 }, // 125, 125 00025 00026 // GFSK, No Manchester, Max Rb err <1%, Xtal Tol 20ppm 00027 // These differ from FSK only in register 71, for the modulation type 00028 { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x23, 0x08 }, // 2, 5 00029 { 0x1b, 0x03, 0x41, 0x60, 0x27, 0x52, 0x00, 0x07, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x13, 0xa9, 0x2c, 0x23, 0x3a }, // 2.4, 36 00030 { 0x1d, 0x03, 0xa1, 0x20, 0x4e, 0xa5, 0x00, 0x13, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x27, 0x52, 0x2c, 0x23, 0x48 }, // 4.8, 45 00031 { 0x1e, 0x03, 0xd0, 0x00, 0x9d, 0x49, 0x00, 0x45, 0x40, 0x0a, 0x20, 0x80, 0x60, 0x4e, 0xa5, 0x2c, 0x23, 0x48 }, // 9.6, 45 00032 { 0x2b, 0x03, 0x34, 0x02, 0x75, 0x25, 0x07, 0xff, 0x40, 0x0a, 0x1b, 0x80, 0x60, 0x9d, 0x49, 0x2c, 0x23, 0x0f }, // 19.2, 9.6 00033 { 0x02, 0x03, 0x68, 0x01, 0x3a, 0x93, 0x04, 0xd5, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x09, 0xd5, 0x0c, 0x23, 0x1f }, // 38.4, 19.6 00034 { 0x06, 0x03, 0x45, 0x01, 0xd7, 0xdc, 0x07, 0x6e, 0x40, 0x0a, 0x2d, 0x80, 0x60, 0x0e, 0xbf, 0x0c, 0x23, 0x2e }, // 57.6. 28.8 00035 { 0x8a, 0x03, 0x60, 0x01, 0x55, 0x55, 0x02, 0xad, 0x40, 0x0a, 0x50, 0x80, 0x60, 0x20, 0x00, 0x0c, 0x23, 0xc8 }, // 125, 125 00036 00037 // OOK, No Manchester, Max Rb err <1%, Xtal Tol 20ppm 00038 { 0x51, 0x03, 0x68, 0x00, 0x3a, 0x93, 0x01, 0x3d, 0x2c, 0x11, 0x28, 0x80, 0x60, 0x09, 0xd5, 0x2c, 0x21, 0x08 }, // 1.2, 75 00039 { 0xc8, 0x03, 0x39, 0x20, 0x68, 0xdc, 0x00, 0x6b, 0x2a, 0x08, 0x2a, 0x80, 0x60, 0x13, 0xa9, 0x2c, 0x21, 0x08 }, // 2.4, 335 00040 { 0xc8, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x29, 0x04, 0x29, 0x80, 0x60, 0x27, 0x52, 0x2c, 0x21, 0x08 }, // 4.8, 335 00041 { 0xb8, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x28, 0x82, 0x29, 0x80, 0x60, 0x4e, 0xa5, 0x2c, 0x21, 0x08 }, // 9.6, 335 00042 { 0xa8, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x28, 0x41, 0x29, 0x80, 0x60, 0x9d, 0x49, 0x2c, 0x21, 0x08 }, // 19.2, 335 00043 { 0x98, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x28, 0x20, 0x29, 0x80, 0x60, 0x09, 0xd5, 0x0c, 0x21, 0x08 }, // 38.4, 335 00044 { 0x98, 0x03, 0x96, 0x00, 0xda, 0x74, 0x00, 0xdc, 0x28, 0x1f, 0x29, 0x80, 0x60, 0x0a, 0x3d, 0x0c, 0x21, 0x08 }, // 40, 335 00045 00046 }; 00047 00048 RF22::RF22(PinName slaveSelectPin, PinName mosi, PinName miso, PinName sclk, PinName interrupt) 00049 : _slaveSelectPin(slaveSelectPin), _spi(mosi, miso, sclk), _interrupt(interrupt) /*, led1(LED1), led2(LED2), led3(LED3), led4(LED4) */ 00050 { 00051 00052 00053 _idleMode = RF22_XTON; // Default idle state is READY mode 00054 _mode = RF22_MODE_IDLE; // We start up in idle mode 00055 _rxGood = 0; 00056 _rxBad = 0; 00057 _txGood = 0; 00058 00059 00060 } 00061 00062 //moje dopsane metody 00063 00064 void RF22::obsluhapreruseni() 00065 { 00066 handleInterrupt(); 00067 } 00068 00069 /* void RF22::vypisfifo() 00070 { 00071 _slaveSelectPin = 0; 00072 _spi.write(RF22_REG_7F_FIFO_ACCESS); 00073 pc1.printf("\n\r Obsah FIFA je:"); 00074 for(int a = 0; a<10; a++) 00075 { 00076 uint8_t x = _spi.write(RF22_REG_7F_FIFO_ACCESS); 00077 pc1.printf("\t %i", x); 00078 } 00079 _slaveSelectPin = 1; 00080 }*/ 00081 00082 boolean RF22::init() 00083 { 00084 wait_ms(16); 00085 00086 _slaveSelectPin = 1; // cip select 00087 00088 wait_ms(100); 00089 00090 _spi.format(8,0); //konfigurace SPI 00091 _spi.frequency(10000000); 00092 00093 // Software reset the device 00094 reset(); 00095 00096 // Get the device type and check it 00097 // This also tests whether we are really connected to a device 00098 _deviceType = spiRead(RF22_REG_00_DEVICE_TYPE); 00099 00100 if ( _deviceType != RF22_DEVICE_TYPE_RX_TRX 00101 && _deviceType != RF22_DEVICE_TYPE_TX) 00102 return false; 00103 00104 _interrupt.fall(this, &RF22::isr0); 00105 00106 clearTxBuf(); 00107 clearRxBuf(); 00108 00109 // Most of these are the POR default 00110 spiWrite(RF22_REG_7D_TX_FIFO_CONTROL2, RF22_TXFFAEM_THRESHOLD); 00111 spiWrite(RF22_REG_7E_RX_FIFO_CONTROL, RF22_RXFFAFULL_THRESHOLD); 00112 spiWrite(RF22_REG_30_DATA_ACCESS_CONTROL, RF22_ENPACRX | RF22_ENPACTX | RF22_ENCRC | RF22_CRC_CRC_16_IBM); 00113 // Configure the message headers 00114 // Here we set up the standard packet format for use by the RF22 library 00115 // 8 nibbles preamble 00116 // 2 SYNC words 2d, d4 00117 // Header length 4 (to, from, id, flags) 00118 // 1 octet of data length (0 to 255) 00119 // 0 to 255 octets data 00120 // 2 CRC octets as CRC16(IBM), computed on the header, length and data 00121 // On reception the to address is check for validity against RF22_REG_3F_CHECK_HEADER3 00122 // or the broadcast address of 0xff 00123 // If no changes are made after this, the transmitted 00124 // to address will be 0xff, the from address will be 0xff 00125 // and all such messages will be accepted. This permits the out-of the box 00126 // RF22 config to act as an unaddresed, unreliable datagram service 00127 spiWrite(RF22_REG_32_HEADER_CONTROL1, RF22_BCEN_HEADER3 | RF22_HDCH_HEADER3); 00128 spiWrite(RF22_REG_33_HEADER_CONTROL2, RF22_HDLEN_4 | RF22_SYNCLEN_2); 00129 setPreambleLength(8); //delka preambule 00130 uint8_t syncwords[] = { 0x2d, 0xd4 }; 00131 setSyncWords(syncwords, sizeof(syncwords)); 00132 setPromiscuous(false); 00133 // Check the TO header against RF22_DEFAULT_NODE_ADDRESS 00134 spiWrite(RF22_REG_3F_CHECK_HEADER3, RF22_DEFAULT_NODE_ADDRESS); 00135 // Set the default transmit header values 00136 setHeaderTo(RF22_DEFAULT_NODE_ADDRESS); 00137 setHeaderFrom(RF22_DEFAULT_NODE_ADDRESS); 00138 setHeaderId(0); 00139 setHeaderFlags(0); 00140 00141 // Ensure the antenna can be switched automatically according to transmit and receive 00142 // This assumes GPIO0(out) is connected to TX_ANT(in) to enable tx antenna during transmit 00143 // This assumes GPIO1(out) is connected to RX_ANT(in) to enable rx antenna during receive 00144 spiWrite (RF22_REG_0B_GPIO_CONFIGURATION0, 0x12) ; // TX state 00145 spiWrite (RF22_REG_0C_GPIO_CONFIGURATION1, 0x15) ; // RX state 00146 00147 // Enable interrupts 00148 00149 spiWrite(RF22_REG_05_INTERRUPT_ENABLE1, RF22_ENTXFFAEM |RF22_ENRXFFAFULL | RF22_ENPKSENT |RF22_ENPKVALID| RF22_ENCRCERROR); 00150 spiWrite(RF22_REG_06_INTERRUPT_ENABLE2, RF22_ENPREAVAL); 00151 00152 // Set some defaults. An innocuous ISM frequency, and reasonable pull-in 00153 setFrequency(434.0, 0.05); 00154 // setFrequency(900.0); 00155 // Some slow, reliable default speed and modulation 00156 setModemConfig(FSK_Rb2_4Fd36); 00157 // setModemConfig(FSK_Rb125Fd125); 00158 // Minimum power 00159 setTxPower(RF22_TXPOW_8DBM); 00160 // setTxPower(RF22_TXPOW_17DBM); 00161 00162 00163 00164 return true; 00165 } 00166 00167 // C++ level interrupt handler for this instance 00168 void RF22::handleInterrupt() 00169 { 00170 uint8_t _lastInterruptFlags[2]; 00171 00172 //led1 = 1; 00173 00174 // Read the interrupt flags which clears the interrupt 00175 spiBurstRead(RF22_REG_03_INTERRUPT_STATUS1, _lastInterruptFlags, 2); 00176 00177 #if 0 00178 // Caution: Serial printing in this interrupt routine can cause mysterious crashes 00179 Serial.print("interrupt "); 00180 Serial.print(_lastInterruptFlags[0], HEX); 00181 Serial.print(" "); 00182 Serial.println(_lastInterruptFlags[1], HEX); 00183 if (_lastInterruptFlags[0] == 0 && _lastInterruptFlags[1] == 0) 00184 Serial.println("FUNNY: no interrupt!"); 00185 #endif 00186 00187 #if 0 00188 // TESTING: fake an RF22_IFFERROR 00189 static int counter = 0; 00190 if (_lastInterruptFlags[0] & RF22_IPKSENT && counter++ == 10) { 00191 _lastInterruptFlags[0] = RF22_IFFERROR; 00192 counter = 0; 00193 } 00194 #endif 00195 00196 00197 if (_lastInterruptFlags[0] & RF22_IFFERROR) { 00198 // Serial.println("IFFERROR"); 00199 //led4 = !led4; 00200 resetFifos(); // Clears the interrupt 00201 if (_mode == RF22_MODE_TX) 00202 restartTransmit(); 00203 else if (_mode == RF22_MODE_RX){ 00204 clearRxBuf(); 00205 //stop and start Rx 00206 setModeIdle(); 00207 setModeRx(); 00208 } 00209 // stop handling the remaining interruppts as something went wrong here 00210 return; 00211 } 00212 00213 // Caution, any delay here may cause a FF underflow or overflow 00214 if (_lastInterruptFlags[0] & RF22_ITXFFAEM) { 00215 // See if more data has to be loaded into the Tx FIFO 00216 //led2 = !led2; 00217 sendNextFragment(); 00218 // Serial.println("ITXFFAEM"); 00219 } 00220 00221 if (_lastInterruptFlags[0] & RF22_IRXFFAFULL) { 00222 // Caution, any delay here may cause a FF overflow 00223 // Read some data from the Rx FIFO 00224 //led4 = !led4; 00225 readNextFragment(); 00226 // Serial.println("IRXFFAFULL"); 00227 } 00228 if (_lastInterruptFlags[0] & RF22_IEXT) { 00229 // This is not enabled by the base code, but users may want to enable it 00230 //led2 = !led2; 00231 handleExternalInterrupt(); 00232 // Serial.println("IEXT"); 00233 } 00234 if (_lastInterruptFlags[1] & RF22_IWUT) { 00235 // This is not enabled by the base code, but users may want to enable it 00236 //led2 = !led2; 00237 handleWakeupTimerInterrupt(); 00238 // Serial.println("IWUT"); 00239 } 00240 if (_lastInterruptFlags[0] & RF22_IPKSENT) { 00241 // Serial.println("IPKSENT"); 00242 _txGood++; 00243 //led4 = !led4; 00244 // Transmission does not automatically clear the tx buffer. 00245 // Could retransmit if we wanted 00246 // RF22 transitions automatically to Idle 00247 _mode = RF22_MODE_IDLE; 00248 } 00249 00250 if (_lastInterruptFlags[0] & RF22_IPKVALID) { 00251 uint8_t len = spiRead(RF22_REG_4B_RECEIVED_PACKET_LENGTH); 00252 // Serial.println("IPKVALID"); 00253 // Serial.println(len); 00254 // Serial.println(_bufLen); 00255 00256 // May have already read one or more fragments 00257 // Get any remaining unread octets, based on the expected length 00258 // First make sure we dont overflow the buffer in the case of a stupid length 00259 // or partial bad receives 00260 00261 if ( len > RF22_MAX_MESSAGE_LEN || len < _bufLen) //pokud je delka zpravy delsi nez FIFO 00262 { 00263 _rxBad++; 00264 _mode = RF22_MODE_IDLE; 00265 clearRxBuf(); 00266 return; // Hmmm receiver buffer overflow. 00267 } 00268 00269 spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, len - _bufLen); 00270 __disable_irq(); // Disable Interrupts 00271 _rxGood++; 00272 _bufLen = len; 00273 _mode = RF22_MODE_IDLE; 00274 _rxBufValid = true; 00275 // reset the fifo for next packet?? 00276 //resetRxFifo(); 00277 __enable_irq(); // Enable Interrupts 00278 00279 //led3 = !led3; 00280 00281 } 00282 00283 if (_lastInterruptFlags[0] & RF22_ICRCERROR) { 00284 // Serial.println("ICRCERR"); 00285 _rxBad++; 00286 //led2 = !led2; 00287 clearRxBuf(); 00288 resetRxFifo(); 00289 _mode = RF22_MODE_IDLE; 00290 setModeRx(); // Keep trying 00291 } 00292 00293 if (_lastInterruptFlags[1] & RF22_IPREAVAL) { 00294 // Serial.println("IPREAVAL"); 00295 00296 _lastRssi = spiRead(RF22_REG_26_RSSI); 00297 00298 00299 // why clear the rx-buf here? charly 00300 clearRxBuf(); 00301 00302 00303 } 00304 //led1 = 0; 00305 } 00306 00307 // These are low level functions that call the interrupt handler for the correct 00308 // instance of RF22. 00309 // 2 interrupts allows us to have 2 different devices 00310 00311 void RF22::isr0() 00312 { 00313 //handleInterrupt(); 00314 obsluhapreruseni(); 00315 00316 } 00317 00318 00319 void RF22::reset() 00320 { 00321 spiWrite(RF22_REG_07_OPERATING_MODE1, RF22_SWRES); //soft reset 00322 wait_ms(1); 00323 } 00324 00325 uint8_t RF22::spiRead(uint8_t reg) 00326 { 00327 __disable_irq(); // Disable Interrupts 00328 00329 _slaveSelectPin=0; 00330 00331 _spi.write(reg & ~RF22_SPI_WRITE_MASK); // Send the address with the write mask off 00332 uint8_t val = _spi.write(0); // The written value is ignored, reg value is read ?????? 00333 00334 _slaveSelectPin = 1; 00335 __enable_irq(); // Enable Interrupts 00336 return val; 00337 } 00338 00339 void RF22::spiWrite(uint8_t reg, uint8_t val) //zapis hodnot z define 00340 { 00341 __disable_irq(); // Disable Interrupts 00342 00343 _slaveSelectPin = 0; 00344 _spi.write(reg | RF22_SPI_WRITE_MASK); // Send the address with the write mask on 00345 _spi.write(val); // New value follows 00346 00347 _slaveSelectPin = 1; 00348 __enable_irq(); // Enable Interrupts 00349 } 00350 00351 void RF22::spiBurstRead(uint8_t reg, uint8_t* dest, uint8_t len) //tady se vycitaji data 00352 { 00353 _slaveSelectPin = 0; 00354 _spi.write(reg & ~RF22_SPI_WRITE_MASK); // Send the start address with the write mask off 00355 if(reg == RF22_REG_7F_FIFO_ACCESS) pc1.printf("\n\r Data primo z bufferu:"); 00356 while (len--) 00357 { 00358 *dest++ = _spi.write(0); 00359 if(reg == RF22_REG_7F_FIFO_ACCESS) pc1.printf(" %i", *dest); 00360 } 00361 _slaveSelectPin = 1; 00362 } 00363 00364 void RF22::spiBurstWrite(uint8_t reg, const uint8_t* src, uint8_t len) 00365 { 00366 _slaveSelectPin = 0; 00367 _spi.write(reg | RF22_SPI_WRITE_MASK); // Send the start address with the write mask on 00368 while (len--) 00369 _spi.write(*src++); 00370 _slaveSelectPin = 1; 00371 } 00372 00373 uint8_t RF22::statusRead() 00374 { 00375 return spiRead(RF22_REG_02_DEVICE_STATUS); 00376 } 00377 00378 uint8_t RF22::adcRead(uint8_t adcsel, 00379 uint8_t adcref , 00380 uint8_t adcgain, 00381 uint8_t adcoffs) 00382 { 00383 uint8_t configuration = adcsel | adcref | (adcgain & RF22_ADCGAIN); 00384 spiWrite(RF22_REG_0F_ADC_CONFIGURATION, configuration | RF22_ADCSTART); 00385 spiWrite(RF22_REG_10_ADC_SENSOR_AMP_OFFSET, adcoffs); 00386 00387 // Conversion time is nominally 305usec 00388 // Wait for the DONE bit 00389 while (!(spiRead(RF22_REG_0F_ADC_CONFIGURATION) & RF22_ADCDONE)) 00390 ; 00391 // Return the value 00392 return spiRead(RF22_REG_11_ADC_VALUE); 00393 } 00394 00395 00396 uint16_t RF22::wutRead() 00397 { 00398 uint8_t buf[2]; 00399 spiBurstRead(RF22_REG_17_WAKEUP_TIMER_VALUE1, buf, 2); 00400 return ((uint16_t)buf[0] << 8) | buf[1]; // Dont rely on byte order 00401 } 00402 00403 // RFM-22 doc appears to be wrong: WUT for wtm = 10000, r, = 0, d = 0 is about 1 sec 00404 void RF22::setWutPeriod(uint16_t wtm, uint8_t wtr, uint8_t wtd) 00405 { 00406 uint8_t period[3]; 00407 00408 period[0] = ((wtr & 0xf) << 2) | (wtd & 0x3); 00409 period[1] = wtm >> 8; 00410 period[2] = wtm & 0xff; 00411 spiBurstWrite(RF22_REG_14_WAKEUP_TIMER_PERIOD1, period, sizeof(period)); 00412 } 00413 00414 // Returns true if centre + (fhch * fhs) is within limits 00415 // Caution, different versions of the RF22 support different max freq 00416 // so YMMV 00417 boolean RF22::setFrequency(float centre, float afcPullInRange) 00418 { 00419 uint8_t fbsel = RF22_SBSEL; 00420 uint8_t afclimiter; 00421 if (centre < 240.0 || centre > 960.0) // 930.0 for early silicon 00422 return false; 00423 if (centre >= 480.0) { 00424 if (afcPullInRange < 0.0 || afcPullInRange > 0.318750) 00425 return false; 00426 centre /= 2; 00427 fbsel |= RF22_HBSEL; 00428 afclimiter = afcPullInRange * 1000000.0 / 1250.0; 00429 } else { 00430 if (afcPullInRange < 0.0 || afcPullInRange > 0.159375) 00431 return false; 00432 afclimiter = afcPullInRange * 1000000.0 / 625.0; 00433 } 00434 centre /= 10.0; 00435 float integerPart = floor(centre); 00436 float fractionalPart = centre - integerPart; 00437 00438 uint8_t fb = (uint8_t)integerPart - 24; // Range 0 to 23 00439 fbsel |= fb; 00440 uint16_t fc = fractionalPart * 64000; 00441 spiWrite(RF22_REG_73_FREQUENCY_OFFSET1, 0); // REVISIT 00442 spiWrite(RF22_REG_74_FREQUENCY_OFFSET2, 0); 00443 spiWrite(RF22_REG_75_FREQUENCY_BAND_SELECT, fbsel); 00444 spiWrite(RF22_REG_76_NOMINAL_CARRIER_FREQUENCY1, fc >> 8); 00445 spiWrite(RF22_REG_77_NOMINAL_CARRIER_FREQUENCY0, fc & 0xff); 00446 spiWrite(RF22_REG_2A_AFC_LIMITER, afclimiter); 00447 return !(statusRead() & RF22_FREQERR); 00448 } 00449 00450 // Step size in 10kHz increments 00451 // Returns true if centre + (fhch * fhs) is within limits 00452 boolean RF22::setFHStepSize(uint8_t fhs) 00453 { 00454 spiWrite(RF22_REG_7A_FREQUENCY_HOPPING_STEP_SIZE, fhs); 00455 return !(statusRead() & RF22_FREQERR); 00456 } 00457 00458 // Adds fhch * fhs to centre frequency 00459 // Returns true if centre + (fhch * fhs) is within limits 00460 boolean RF22::setFHChannel(uint8_t fhch) 00461 { 00462 spiWrite(RF22_REG_79_FREQUENCY_HOPPING_CHANNEL_SELECT, fhch); 00463 return !(statusRead() & RF22_FREQERR); 00464 } 00465 00466 uint8_t RF22::rssiRead() 00467 { 00468 return spiRead(RF22_REG_26_RSSI); 00469 } 00470 00471 uint8_t RF22::ezmacStatusRead() 00472 { 00473 return spiRead(RF22_REG_31_EZMAC_STATUS); 00474 } 00475 00476 void RF22::setMode(uint8_t mode) 00477 { 00478 spiWrite(RF22_REG_07_OPERATING_MODE1, mode); 00479 } 00480 00481 void RF22::setModeIdle() 00482 { 00483 if (_mode != RF22_MODE_IDLE) { 00484 setMode(_idleMode); 00485 _mode = RF22_MODE_IDLE; 00486 00487 } 00488 } 00489 00490 void RF22::setModeRx() 00491 { 00492 if (_mode != RF22_MODE_RX) { 00493 setMode(_idleMode | RF22_RXON); 00494 _mode = RF22_MODE_RX; 00495 } 00496 } 00497 00498 void RF22::setModeTx() 00499 { 00500 if (_mode != RF22_MODE_TX) { 00501 setMode(_idleMode | RF22_TXON); 00502 _mode = RF22_MODE_TX; 00503 // Hmmm, if you dont clear the RX FIFO here, then it appears that going 00504 // to transmit mode in the middle of a receive can corrupt the 00505 // RX FIFO 00506 resetRxFifo(); 00507 00508 } 00509 } 00510 00511 uint8_t RF22::mode() 00512 { 00513 return _mode; 00514 } 00515 00516 void RF22::setTxPower(uint8_t power) 00517 { 00518 spiWrite(RF22_REG_6D_TX_POWER, power); 00519 } 00520 00521 // Sets registers from a canned modem configuration structure 00522 void RF22::setModemRegisters(const ModemConfig* config) 00523 { 00524 spiWrite(RF22_REG_1C_IF_FILTER_BANDWIDTH, config->reg_1c); 00525 spiWrite(RF22_REG_1F_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE, config->reg_1f); 00526 spiBurstWrite(RF22_REG_20_CLOCK_RECOVERY_OVERSAMPLING_RATE, &config->reg_20, 6); 00527 spiBurstWrite(RF22_REG_2C_OOK_COUNTER_VALUE_1, &config->reg_2c, 3); 00528 spiWrite(RF22_REG_58_CHARGE_PUMP_CURRENT_TRIMMING, config->reg_58); 00529 spiWrite(RF22_REG_69_AGC_OVERRIDE1, config->reg_69); 00530 spiBurstWrite(RF22_REG_6E_TX_DATA_RATE1, &config->reg_6e, 5); 00531 } 00532 00533 // Set one of the canned FSK Modem configs 00534 // Returns true if its a valid choice 00535 boolean RF22::setModemConfig(ModemConfigChoice index) 00536 { 00537 if (index > (sizeof(MODEM_CONFIG_TABLE) / sizeof(ModemConfig))) 00538 return false; 00539 00540 RF22::ModemConfig cfg; 00541 memcpy(&cfg, &MODEM_CONFIG_TABLE[index], sizeof(RF22::ModemConfig)); 00542 setModemRegisters(&cfg); 00543 00544 return true; 00545 } 00546 00547 // REVISIT: top bit is in Header Control 2 0x33 00548 void RF22::setPreambleLength(uint8_t nibbles) 00549 { 00550 spiWrite(RF22_REG_34_PREAMBLE_LENGTH, nibbles); 00551 } 00552 00553 // Caution doesnt set sync word len in Header Control 2 0x33 00554 void RF22::setSyncWords(const uint8_t* syncWords, uint8_t len) 00555 { 00556 spiBurstWrite(RF22_REG_36_SYNC_WORD3, syncWords, len); 00557 } 00558 00559 void RF22::clearRxBuf() 00560 { 00561 __disable_irq(); // Disable Interrupts 00562 _bufLen = 0; 00563 _rxBufValid = false; 00564 __enable_irq(); // Enable Interrupts 00565 } 00566 00567 boolean RF22::available() 00568 { 00569 if (!_rxBufValid) 00570 setModeRx(); // Make sure we are receiving 00571 return _rxBufValid; 00572 } 00573 00574 // Blocks until a valid message is received 00575 void RF22::waitAvailable() 00576 { 00577 while (!available()) 00578 ; 00579 } 00580 00581 // Blocks until a valid message is received or timeout expires 00582 // Return true if there is a message available 00583 bool RF22::waitAvailableTimeout(uint16_t timeout) 00584 { 00585 Timer t; 00586 t.start(); 00587 unsigned long endtime = t.read_ms() + timeout; 00588 while (t.read_ms() < endtime) 00589 if (available()) 00590 return true; 00591 return false; 00592 } 00593 00594 void RF22::waitPacketSent() 00595 { 00596 while (_mode == RF22_MODE_TX) 00597 ; // Wait for any previous transmit to finish 00598 } 00599 00600 // Diagnostic help 00601 void RF22::printBuffer(const uint8_t *buf, uint8_t len) 00602 { 00603 00604 uint8_t i; 00605 00606 pc1.printf("\n\rObsah Bufferu "); 00607 for (i = 0; i < len; i++) { 00608 if (i % 16 == 15) 00609 pc1.printf("%d", buf[i]); 00610 else { 00611 pc1.printf("%d", buf[i]); 00612 pc1.printf(" "); 00613 } 00614 } 00615 pc1.printf(" "); 00616 00617 } 00618 00619 boolean RF22::recv(uint8_t* buf, uint8_t* len) 00620 { 00621 if (!available()) 00622 return false; 00623 __disable_irq(); // Disable Interrupts 00624 if (*len > _bufLen) 00625 *len = _bufLen; 00626 memcpy(buf, _buf, *len); 00627 printBuffer(_buf, *len); 00628 clearRxBuf(); 00629 __enable_irq(); // Enable Interrupts 00630 printBuffer( buf, *len); 00631 00632 return true; 00633 } 00634 00635 void RF22::clearTxBuf() 00636 { 00637 __disable_irq(); // Disable Interrupts 00638 _bufLen = 0; 00639 _txBufSentIndex = 0; 00640 _txPacketSent = false; 00641 __enable_irq(); // Enable Interrupts 00642 } 00643 00644 void RF22::startTransmit() 00645 { 00646 sendNextFragment(); // Actually the first fragment 00647 spiWrite(RF22_REG_3E_PACKET_LENGTH, _bufLen); // Total length that will be sent 00648 setModeTx(); // Start the transmitter, turns off the receiver 00649 } 00650 00651 // Restart the transmission of a packet that had a problem 00652 void RF22::restartTransmit() 00653 { 00654 _mode = RF22_MODE_IDLE; 00655 _txBufSentIndex = 0; 00656 // Serial.println("Restart"); 00657 startTransmit(); 00658 } 00659 00660 boolean RF22::send(const uint8_t* data, uint8_t len) //pocka, nez se odesle paket a potom odesle data 00661 { 00662 waitPacketSent(); 00663 { 00664 if (!fillTxBuf(data, len)) 00665 return false; 00666 startTransmit(); 00667 } 00668 // printBuffer("send:", data, len); 00669 return true; 00670 } 00671 00672 boolean RF22::fillTxBuf(const uint8_t* data, uint8_t len) 00673 { 00674 clearTxBuf(); 00675 if (!len) 00676 return false; 00677 return appendTxBuf(data, len); 00678 } 00679 00680 boolean RF22::appendTxBuf(const uint8_t* data, uint8_t len) 00681 { 00682 if (((uint16_t)_bufLen + len) > RF22_MAX_MESSAGE_LEN) 00683 return false; 00684 __disable_irq(); // Disable Interrupts 00685 memcpy(_buf + _bufLen, data, len); 00686 _bufLen += len; 00687 __enable_irq(); // Enable Interrupts 00688 00689 // printBuffer("txbuf:", _buf, _bufLen); 00690 return true; 00691 } 00692 00693 // Assumption: there is currently <= RF22_TXFFAEM_THRESHOLD bytes in the Tx FIFO 00694 void RF22::sendNextFragment() 00695 { 00696 if (_txBufSentIndex < _bufLen) { 00697 // Some left to send? 00698 uint8_t len = _bufLen - _txBufSentIndex; 00699 // But dont send too much 00700 if (len > (RF22_FIFO_SIZE - RF22_TXFFAEM_THRESHOLD - 1)) 00701 len = (RF22_FIFO_SIZE - RF22_TXFFAEM_THRESHOLD - 1); 00702 spiBurstWrite(RF22_REG_7F_FIFO_ACCESS, _buf + _txBufSentIndex, len); 00703 _txBufSentIndex += len; 00704 } 00705 } 00706 00707 // Assumption: there are at least RF22_RXFFAFULL_THRESHOLD in the RX FIFO 00708 // That means it should only be called after a RXFFAFULL interrupt 00709 void RF22::readNextFragment() 00710 { 00711 if (((uint16_t)_bufLen + RF22_RXFFAFULL_THRESHOLD) > RF22_MAX_MESSAGE_LEN) 00712 return; // Hmmm receiver overflow. Should never occur 00713 00714 // Read the RF22_RXFFAFULL_THRESHOLD octets that should be there 00715 spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, RF22_RXFFAFULL_THRESHOLD); 00716 _bufLen += RF22_RXFFAFULL_THRESHOLD; 00717 } 00718 00719 // Clear the FIFOs 00720 void RF22::resetFifos() 00721 { 00722 spiWrite(RF22_REG_08_OPERATING_MODE2, RF22_FFCLRRX | RF22_FFCLRTX); 00723 spiWrite(RF22_REG_08_OPERATING_MODE2, 0); 00724 } 00725 00726 // Clear the Rx FIFO 00727 void RF22::resetRxFifo() 00728 { 00729 spiWrite(RF22_REG_08_OPERATING_MODE2, RF22_FFCLRRX); 00730 spiWrite(RF22_REG_08_OPERATING_MODE2, 0); 00731 } 00732 00733 // CLear the TX FIFO 00734 void RF22::resetTxFifo() 00735 { 00736 spiWrite(RF22_REG_08_OPERATING_MODE2, RF22_FFCLRTX); 00737 spiWrite(RF22_REG_08_OPERATING_MODE2, 0); 00738 } 00739 00740 // Default implmentation does nothing. Override if you wish 00741 void RF22::handleExternalInterrupt() 00742 { 00743 } 00744 00745 // Default implmentation does nothing. Override if you wish 00746 void RF22::handleWakeupTimerInterrupt() 00747 { 00748 } 00749 00750 void RF22::setHeaderTo(uint8_t to) 00751 { 00752 spiWrite(RF22_REG_3A_TRANSMIT_HEADER3, to); 00753 } 00754 00755 void RF22::setHeaderFrom(uint8_t from) 00756 { 00757 spiWrite(RF22_REG_3B_TRANSMIT_HEADER2, from); 00758 } 00759 00760 void RF22::setHeaderId(uint8_t id) 00761 { 00762 spiWrite(RF22_REG_3C_TRANSMIT_HEADER1, id); 00763 } 00764 00765 void RF22::setHeaderFlags(uint8_t flags) 00766 { 00767 spiWrite(RF22_REG_3D_TRANSMIT_HEADER0, flags); 00768 } 00769 00770 uint8_t RF22::headerTo() 00771 { 00772 return spiRead(RF22_REG_47_RECEIVED_HEADER3); 00773 } 00774 00775 uint8_t RF22::headerFrom() 00776 { 00777 return spiRead(RF22_REG_48_RECEIVED_HEADER2); 00778 } 00779 00780 uint8_t RF22::headerId() 00781 { 00782 return spiRead(RF22_REG_49_RECEIVED_HEADER1); 00783 } 00784 00785 uint8_t RF22::headerFlags() 00786 { 00787 return spiRead(RF22_REG_4A_RECEIVED_HEADER0); 00788 } 00789 00790 uint8_t RF22::lastRssi() 00791 { 00792 return _lastRssi; 00793 } 00794 00795 void RF22::setPromiscuous(boolean promiscuous) 00796 { 00797 spiWrite(RF22_REG_43_HEADER_ENABLE3, promiscuous ? 0x00 : 0xff); 00798 }
Generated on Thu Jul 14 2022 18:53:30 by
1.7.2
