acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
RF69.cpp (31559B)
1 #include "RF69.h" 2 #if !defined(RADIOLIB_EXCLUDE_RF69) 3 4 RF69::RF69(Module* module) : PhysicalLayer(RADIOLIB_RF69_FREQUENCY_STEP_SIZE, RADIOLIB_RF69_MAX_PACKET_LENGTH) { 5 _mod = module; 6 } 7 8 Module* RF69::getMod() { 9 return(_mod); 10 } 11 12 int16_t RF69::begin(float freq, float br, float freqDev, float rxBw, int8_t power, uint8_t preambleLen) { 13 // set module properties 14 _mod->init(); 15 _mod->pinMode(_mod->getIrq(), INPUT); 16 17 // try to find the RF69 chip 18 uint8_t i = 0; 19 bool flagFound = false; 20 while((i < 10) && !flagFound) { 21 // reset the module 22 reset(); 23 24 // check version register 25 int16_t version = getChipVersion(); 26 if(version == RADIOLIB_RF69_CHIP_VERSION) { 27 flagFound = true; 28 } else { 29 #if defined(RADIOLIB_DEBUG) 30 RADIOLIB_DEBUG_PRINT(F("RF69 not found! (")); 31 RADIOLIB_DEBUG_PRINT(i + 1); 32 RADIOLIB_DEBUG_PRINT(F(" of 10 tries) RADIOLIB_RF69_REG_VERSION == ")); 33 34 char buffHex[7]; 35 sprintf(buffHex, "0x%04X", version); 36 RADIOLIB_DEBUG_PRINT(buffHex); 37 RADIOLIB_DEBUG_PRINT(F(", expected 0x0024")); 38 RADIOLIB_DEBUG_PRINTLN(); 39 #endif 40 _mod->delay(10); 41 i++; 42 } 43 } 44 45 if(!flagFound) { 46 RADIOLIB_DEBUG_PRINTLN(F("No RF69 found!")); 47 _mod->term(); 48 return(RADIOLIB_ERR_CHIP_NOT_FOUND); 49 } else { 50 RADIOLIB_DEBUG_PRINTLN(F("M\tRF69")); 51 } 52 53 // configure settings not accessible by API 54 int16_t state = config(); 55 RADIOLIB_ASSERT(state); 56 57 // configure publicly accessible settings 58 state = setFrequency(freq); 59 RADIOLIB_ASSERT(state); 60 61 // configure bitrate 62 _rxBw = 125.0; 63 state = setBitRate(br); 64 RADIOLIB_ASSERT(state); 65 66 // configure default RX bandwidth 67 state = setRxBandwidth(rxBw); 68 RADIOLIB_ASSERT(state); 69 70 // configure default frequency deviation 71 state = setFrequencyDeviation(freqDev); 72 RADIOLIB_ASSERT(state); 73 74 // configure default TX output power 75 state = setOutputPower(power); 76 RADIOLIB_ASSERT(state); 77 78 // configure default preamble length 79 state = setPreambleLength(preambleLen); 80 RADIOLIB_ASSERT(state); 81 82 // set default packet length mode 83 state = variablePacketLengthMode(); 84 RADIOLIB_ASSERT(state); 85 86 // set default sync word 87 uint8_t syncWord[] = {0x12, 0xAD}; 88 state = setSyncWord(syncWord, sizeof(syncWord)); 89 RADIOLIB_ASSERT(state); 90 91 // set default data shaping 92 state = setDataShaping(RADIOLIB_SHAPING_NONE); 93 RADIOLIB_ASSERT(state); 94 95 // set default encoding 96 state = setEncoding(RADIOLIB_ENCODING_NRZ); 97 RADIOLIB_ASSERT(state); 98 99 // set CRC on by default 100 state = setCrcFiltering(true); 101 RADIOLIB_ASSERT(state); 102 103 return(state); 104 } 105 106 void RF69::reset() { 107 _mod->pinMode(_mod->getRst(), OUTPUT); 108 _mod->digitalWrite(_mod->getRst(), HIGH); 109 _mod->delay(1); 110 _mod->digitalWrite(_mod->getRst(), LOW); 111 _mod->delay(10); 112 } 113 114 int16_t RF69::transmit(uint8_t* data, size_t len, uint8_t addr) { 115 // calculate timeout (5ms + 500 % of expected time-on-air) 116 uint32_t timeout = 5000000 + (uint32_t)((((float)(len * 8)) / (_br * 1000.0)) * 5000000.0); 117 118 // start transmission 119 int16_t state = startTransmit(data, len, addr); 120 RADIOLIB_ASSERT(state); 121 122 // wait for transmission end or timeout 123 uint32_t start = _mod->micros(); 124 while(!_mod->digitalRead(_mod->getIrq())) { 125 _mod->yield(); 126 127 if(_mod->micros() - start > timeout) { 128 standby(); 129 clearIRQFlags(); 130 return(RADIOLIB_ERR_TX_TIMEOUT); 131 } 132 } 133 134 // set mode to standby 135 standby(); 136 137 // clear interrupt flags 138 clearIRQFlags(); 139 140 return(RADIOLIB_ERR_NONE); 141 } 142 143 int16_t RF69::receive(uint8_t* data, size_t len) { 144 // calculate timeout (500 ms + 400 full 64-byte packets at current bit rate) 145 uint32_t timeout = 500000 + (1.0/(_br*1000.0))*(RADIOLIB_RF69_MAX_PACKET_LENGTH*400.0); 146 147 // start reception 148 int16_t state = startReceive(); 149 RADIOLIB_ASSERT(state); 150 151 // wait for packet reception or timeout 152 uint32_t start = _mod->micros(); 153 while(!_mod->digitalRead(_mod->getIrq())) { 154 _mod->yield(); 155 156 if(_mod->micros() - start > timeout) { 157 standby(); 158 clearIRQFlags(); 159 return(RADIOLIB_ERR_RX_TIMEOUT); 160 } 161 } 162 163 // read packet data 164 return(readData(data, len)); 165 } 166 167 int16_t RF69::sleep() { 168 // set RF switch (if present) 169 _mod->setRfSwitchState(LOW, LOW); 170 171 // set module to sleep 172 return(setMode(RADIOLIB_RF69_SLEEP)); 173 } 174 175 int16_t RF69::standby() { 176 // set RF switch (if present) 177 _mod->setRfSwitchState(LOW, LOW); 178 179 // set module to standby 180 return(setMode(RADIOLIB_RF69_STANDBY)); 181 } 182 183 int16_t RF69::transmitDirect(uint32_t frf) { 184 // set RF switch (if present) 185 _mod->setRfSwitchState(LOW, HIGH); 186 187 // user requested to start transmitting immediately (required for RTTY) 188 if(frf != 0) { 189 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FRF_MSB, (frf & 0xFF0000) >> 16); 190 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FRF_MID, (frf & 0x00FF00) >> 8); 191 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FRF_LSB, frf & 0x0000FF); 192 193 return(setMode(RADIOLIB_RF69_TX)); 194 } 195 196 // activate direct mode 197 int16_t state = directMode(); 198 RADIOLIB_ASSERT(state); 199 200 // start transmitting 201 return(setMode(RADIOLIB_RF69_TX)); 202 } 203 204 int16_t RF69::receiveDirect() { 205 // set RF switch (if present) 206 _mod->setRfSwitchState(HIGH, LOW); 207 208 // activate direct mode 209 int16_t state = directMode(); 210 RADIOLIB_ASSERT(state); 211 212 // start receiving 213 return(setMode(RADIOLIB_RF69_RX)); 214 } 215 216 int16_t RF69::directMode() { 217 // set mode to standby 218 int16_t state = setMode(RADIOLIB_RF69_STANDBY); 219 RADIOLIB_ASSERT(state); 220 221 // set DIO mapping 222 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, RADIOLIB_RF69_DIO1_CONT_DCLK | RADIOLIB_RF69_DIO2_CONT_DATA, 5, 2); 223 RADIOLIB_ASSERT(state); 224 225 // set continuous mode 226 if(_bitSync) { 227 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_CONTINUOUS_MODE_WITH_SYNC, 6, 5)); 228 } else { 229 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_CONTINUOUS_MODE, 6, 5)); 230 } 231 } 232 233 int16_t RF69::packetMode() { 234 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_PACKET_MODE, 6, 5)); 235 } 236 237 void RF69::setAESKey(uint8_t* key) { 238 _mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_AES_KEY_1, key, 16); 239 } 240 241 int16_t RF69::enableAES() { 242 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_2, RADIOLIB_RF69_AES_ON, 0, 0)); 243 } 244 245 int16_t RF69::disableAES() { 246 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_2, RADIOLIB_RF69_AES_OFF, 0, 0)); 247 } 248 249 int16_t RF69::startReceive() { 250 // set mode to standby 251 int16_t state = setMode(RADIOLIB_RF69_STANDBY); 252 RADIOLIB_ASSERT(state); 253 254 // set RX timeouts and DIO pin mapping 255 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, RADIOLIB_RF69_DIO0_PACK_PAYLOAD_READY, 7, 4); 256 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_RX_TIMEOUT_1, RADIOLIB_RF69_TIMEOUT_RX_START); 257 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_RX_TIMEOUT_2, RADIOLIB_RF69_TIMEOUT_RSSI_THRESH); 258 RADIOLIB_ASSERT(state); 259 260 // clear interrupt flags 261 clearIRQFlags(); 262 263 // set RF switch (if present) 264 _mod->setRfSwitchState(HIGH, LOW); 265 266 // set mode to receive 267 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_OCP, RADIOLIB_RF69_OCP_ON | RADIOLIB_RF69_OCP_TRIM); 268 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_TEST_PA1, RADIOLIB_RF69_PA1_NORMAL); 269 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_TEST_PA2, RADIOLIB_RF69_PA2_NORMAL); 270 RADIOLIB_ASSERT(state); 271 272 state = setMode(RADIOLIB_RF69_RX); 273 274 return(state); 275 } 276 277 void RF69::setDio0Action(void (*func)(void)) { 278 _mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getIrq()), func, RISING); 279 } 280 281 void RF69::clearDio0Action() { 282 _mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getIrq())); 283 } 284 285 void RF69::setDio1Action(void (*func)(void)) { 286 if(_mod->getGpio() == RADIOLIB_NC) { 287 return; 288 } 289 _mod->pinMode(_mod->getGpio(), INPUT); 290 _mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()), func, RISING); 291 } 292 293 void RF69::clearDio1Action() { 294 if(_mod->getGpio() == RADIOLIB_NC) { 295 return; 296 } 297 _mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio())); 298 } 299 300 void RF69::setFifoEmptyAction(void (*func)(void)) { 301 // set DIO1 to the FIFO empty event (the register setting is done in startTransmit) 302 if(_mod->getGpio() == RADIOLIB_NC) { 303 return; 304 } 305 _mod->pinMode(_mod->getGpio(), INPUT); 306 307 // we need to invert the logic here (as compared to setDio1Action), since we are using the "FIFO not empty interrupt" 308 _mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()), func, FALLING); 309 } 310 311 void RF69::clearFifoEmptyAction() { 312 clearDio1Action(); 313 } 314 315 void RF69::setFifoFullAction(void (*func)(void)) { 316 // set the interrupt 317 _mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_FIFO_THRESH, 6, 0); 318 _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, RADIOLIB_RF69_DIO1_PACK_FIFO_LEVEL, 5, 4); 319 320 // set DIO1 to the FIFO full event 321 setDio1Action(func); 322 } 323 324 void RF69::clearFifoFullAction() { 325 clearDio1Action(); 326 _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, 0x00, 5, 4); 327 } 328 329 bool RF69::fifoAdd(uint8_t* data, int totalLen, volatile int* remLen) { 330 // subtract first (this may be the first time we get to modify the remaining length) 331 *remLen -= RADIOLIB_RF69_FIFO_THRESH - 1; 332 333 // check if there is still something left to send 334 if(*remLen <= 0) { 335 // we're done 336 return(true); 337 } 338 339 // calculate the number of bytes we can copy 340 int len = *remLen; 341 if(len > RADIOLIB_RF69_FIFO_THRESH - 1) { 342 len = RADIOLIB_RF69_FIFO_THRESH - 1; 343 } 344 345 // clear interrupt flags 346 clearIRQFlags(); 347 348 // copy the bytes to the FIFO 349 _mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_FIFO, &data[totalLen - *remLen], len); 350 351 // this is a hack, but it seems Rx FIFO level is getting triggered 1 byte before it should 352 // we just add a padding byte that we can drop without consequence 353 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FIFO, '/'); 354 355 // we're not done yet 356 return(false); 357 } 358 359 bool RF69::fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen) { 360 // get pointer to the correct position in data buffer 361 uint8_t* dataPtr = (uint8_t*)&data[*rcvLen]; 362 363 // check how much data are we still expecting 364 uint8_t len = RADIOLIB_RF69_FIFO_THRESH - 1; 365 if(totalLen - *rcvLen < len) { 366 // we're nearly at the end 367 len = totalLen - *rcvLen; 368 } 369 370 // get the data 371 _mod->SPIreadRegisterBurst(RADIOLIB_RF69_REG_FIFO, len, dataPtr); 372 (*rcvLen) += (len); 373 374 // dump the padding byte 375 _mod->SPIreadRegister(RADIOLIB_RF69_REG_FIFO); 376 377 // clear flags 378 clearIRQFlags(); 379 380 // check if we're done 381 if(*rcvLen >= totalLen) { 382 return(true); 383 } 384 return(false); 385 } 386 387 int16_t RF69::startTransmit(uint8_t* data, size_t len, uint8_t addr) { 388 // set mode to standby 389 int16_t state = setMode(RADIOLIB_RF69_STANDBY); 390 RADIOLIB_ASSERT(state); 391 392 // clear interrupt flags 393 clearIRQFlags(); 394 395 // set DIO mapping 396 if(len > RADIOLIB_RF69_MAX_PACKET_LENGTH) { 397 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, RADIOLIB_RF69_DIO1_PACK_FIFO_NOT_EMPTY, 5, 4); 398 } else { 399 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, RADIOLIB_RF69_DIO0_PACK_PACKET_SENT, 7, 6); 400 } 401 RADIOLIB_ASSERT(state); 402 403 // optionally write packet length 404 if (_packetLengthConfig == RADIOLIB_RF69_PACKET_FORMAT_VARIABLE) { 405 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FIFO, len); 406 } 407 408 // check address filtering 409 uint8_t filter = _mod->SPIgetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, 2, 1); 410 if((filter == RADIOLIB_RF69_ADDRESS_FILTERING_NODE) || (filter == RADIOLIB_RF69_ADDRESS_FILTERING_NODE_BROADCAST)) { 411 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FIFO, addr); 412 } 413 414 // write packet to FIFO 415 size_t packetLen = len; 416 if(len > RADIOLIB_RF69_MAX_PACKET_LENGTH) { 417 packetLen = RADIOLIB_RF69_FIFO_THRESH - 1; 418 _mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_TX_START_CONDITION_FIFO_NOT_EMPTY, 7, 7); 419 } 420 _mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_FIFO, data, packetLen); 421 422 // this is a hack, but it seems than in Stream mode, Rx FIFO level is getting triggered 1 byte before it should 423 // just add a padding byte that can be dropped without consequence 424 if(len > RADIOLIB_RF69_MAX_PACKET_LENGTH) { 425 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FIFO, '/'); 426 } 427 428 // enable +20 dBm operation 429 if(_power > 17) { 430 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_OCP, RADIOLIB_RF69_OCP_OFF | 0x0F); 431 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_TEST_PA1, RADIOLIB_RF69_PA1_20_DBM); 432 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_TEST_PA2, RADIOLIB_RF69_PA2_20_DBM); 433 RADIOLIB_ASSERT(state); 434 } 435 436 // set RF switch (if present) 437 _mod->setRfSwitchState(LOW, HIGH); 438 439 // set mode to transmit 440 state = setMode(RADIOLIB_RF69_TX); 441 442 return(state); 443 } 444 445 int16_t RF69::readData(uint8_t* data, size_t len) { 446 // set mode to standby 447 int16_t state = standby(); 448 RADIOLIB_ASSERT(state); 449 450 // get packet length 451 size_t length = getPacketLength(); 452 size_t dumpLen = 0; 453 if((len != 0) && (len < length)) { 454 // user requested less data than we got, only return what was requested 455 dumpLen = length - len; 456 length = len; 457 } 458 459 // check address filtering 460 uint8_t filter = _mod->SPIgetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, 2, 1); 461 if((filter == RADIOLIB_RF69_ADDRESS_FILTERING_NODE) || (filter == RADIOLIB_RF69_ADDRESS_FILTERING_NODE_BROADCAST)) { 462 _mod->SPIreadRegister(RADIOLIB_RF69_REG_FIFO); 463 } 464 465 // read packet data 466 _mod->SPIreadRegisterBurst(RADIOLIB_RF69_REG_FIFO, length, data); 467 468 // dump the bytes that weren't requested 469 if(dumpLen != 0) { 470 clearFIFO(dumpLen); 471 } 472 473 // clear internal flag so getPacketLength can return the new packet length 474 _packetLengthQueried = false; 475 476 // clear interrupt flags 477 clearIRQFlags(); 478 479 return(RADIOLIB_ERR_NONE); 480 } 481 482 int16_t RF69::setOOK(bool enableOOK) { 483 // set OOK and if successful, save the new setting 484 int16_t state = RADIOLIB_ERR_NONE; 485 if(enableOOK) { 486 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_OOK, 4, 3, 5); 487 } else { 488 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_FSK, 4, 3, 5); 489 } 490 491 if(state == RADIOLIB_ERR_NONE) { 492 _ook = enableOOK; 493 } 494 495 // call setRxBandwidth again, since register values differ based on OOK mode being enabled 496 state |= setRxBandwidth(_rxBw); 497 498 return(state); 499 } 500 501 int16_t RF69::setOokThresholdType(uint8_t type) { 502 if((type != RADIOLIB_RF69_OOK_THRESH_FIXED) && (type != RADIOLIB_RF69_OOK_THRESH_PEAK) && (type != RADIOLIB_RF69_OOK_THRESH_AVERAGE)) { 503 return(RADIOLIB_ERR_INVALID_OOK_RSSI_PEAK_TYPE); 504 } 505 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_OOK_PEAK, type, 7, 3, 5)); 506 } 507 508 int16_t RF69::setOokFixedThreshold(uint8_t value) { 509 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_OOK_FIX, value, 7, 0, 5)); 510 } 511 512 int16_t RF69::setOokPeakThresholdDecrement(uint8_t value) { 513 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_OOK_PEAK, value, 2, 0, 5)); 514 } 515 516 int16_t RF69::setFrequency(float freq) { 517 // check allowed frequency range 518 if(!(((freq > 290.0) && (freq < 340.0)) || 519 ((freq > 431.0) && (freq < 510.0)) || 520 ((freq > 862.0) && (freq < 1020.0)))) { 521 return(RADIOLIB_ERR_INVALID_FREQUENCY); 522 } 523 524 // set mode to standby 525 setMode(RADIOLIB_RF69_STANDBY); 526 527 //set carrier frequency 528 uint32_t FRF = (freq * (uint32_t(1) << RADIOLIB_RF69_DIV_EXPONENT)) / RADIOLIB_RF69_CRYSTAL_FREQ; 529 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FRF_MSB, (FRF & 0xFF0000) >> 16); 530 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FRF_MID, (FRF & 0x00FF00) >> 8); 531 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_FRF_LSB, FRF & 0x0000FF); 532 533 _freq = freq; 534 535 return(RADIOLIB_ERR_NONE); 536 } 537 538 int16_t RF69::setBitRate(float br) { 539 RADIOLIB_CHECK_RANGE(br, 1.2, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE); 540 541 // check bitrate-bandwidth ratio 542 if(!(br < 2000 * _rxBw)) { 543 return(RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO); 544 } 545 546 // set mode to standby 547 setMode(RADIOLIB_RF69_STANDBY); 548 549 // set bit rate 550 uint16_t bitRate = 32000 / br; 551 int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0); 552 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0); 553 if(state == RADIOLIB_ERR_NONE) { 554 RF69::_br = br; 555 } 556 return(state); 557 } 558 559 int16_t RF69::setRxBandwidth(float rxBw) { 560 // check bitrate-bandwidth ratio 561 if(!(_br < 2000 * rxBw)) { 562 return(RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO); 563 } 564 565 // set mode to standby 566 int16_t state = setMode(RADIOLIB_RF69_STANDBY); 567 RADIOLIB_ASSERT(state); 568 569 // calculate exponent and mantissa values for receiver bandwidth 570 for(int8_t e = 7; e >= 0; e--) { 571 for(int8_t m = 2; m >= 0; m--) { 572 float point = (RADIOLIB_RF69_CRYSTAL_FREQ * 1000000.0)/(((4 * m) + 16) * ((uint32_t)1 << (e + (_ook ? 3 : 2)))); 573 if(fabs(rxBw - (point / 1000.0)) <= 0.1) { 574 // set Rx bandwidth 575 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_RX_BW, (m << 3) | e, 4, 0); 576 if(state == RADIOLIB_ERR_NONE) { 577 RF69::_rxBw = rxBw; 578 } 579 return(state); 580 } 581 } 582 } 583 584 return(RADIOLIB_ERR_INVALID_RX_BANDWIDTH); 585 } 586 587 int16_t RF69::setFrequencyDeviation(float freqDev) { 588 // set frequency deviation to lowest available setting (required for digimodes) 589 float newFreqDev = freqDev; 590 if(freqDev < 0.0) { 591 newFreqDev = 0.6; 592 } 593 594 // check frequency deviation range 595 if(!((newFreqDev + _br/2 <= 500))) { 596 return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION); 597 } 598 599 // set mode to standby 600 setMode(RADIOLIB_RF69_STANDBY); 601 602 // set frequency deviation from carrier frequency 603 uint32_t base = 1; 604 uint32_t fdev = (newFreqDev * (base << 19)) / 32000; 605 int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_FDEV_MSB, (fdev & 0xFF00) >> 8, 5, 0); 606 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_FDEV_LSB, fdev & 0x00FF, 7, 0); 607 608 return(state); 609 } 610 611 int16_t RF69::setOutputPower(int8_t power, bool highPower) { 612 if(highPower) { 613 RADIOLIB_CHECK_RANGE(power, -2, 20, RADIOLIB_ERR_INVALID_OUTPUT_POWER); 614 } else { 615 RADIOLIB_CHECK_RANGE(power, -18, 13, RADIOLIB_ERR_INVALID_OUTPUT_POWER); 616 } 617 618 // set mode to standby 619 setMode(RADIOLIB_RF69_STANDBY); 620 621 // set output power 622 int16_t state; 623 if(highPower) { 624 // check if both PA1 and PA2 are needed 625 if(power <= 10) { 626 // -2 to 13 dBm, PA1 is enough 627 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PA_LEVEL, RADIOLIB_RF69_PA0_OFF | RADIOLIB_RF69_PA1_ON | RADIOLIB_RF69_PA2_OFF | (power + 18), 7, 0); 628 } else if(power <= 17) { 629 // 13 to 17 dBm, both PAs required 630 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PA_LEVEL, RADIOLIB_RF69_PA0_OFF | RADIOLIB_RF69_PA1_ON | RADIOLIB_RF69_PA2_ON | (power + 14), 7, 0); 631 } else { 632 // 18 - 20 dBm, both PAs and hig power settings required 633 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PA_LEVEL, RADIOLIB_RF69_PA0_OFF | RADIOLIB_RF69_PA1_ON | RADIOLIB_RF69_PA2_ON | (power + 11), 7, 0); 634 } 635 636 } else { 637 // low power module, use only PA0 638 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PA_LEVEL, RADIOLIB_RF69_PA0_ON | RADIOLIB_RF69_PA1_OFF | RADIOLIB_RF69_PA2_OFF | (power + 18), 7, 0); 639 } 640 641 // cache the power value 642 if(state == RADIOLIB_ERR_NONE) { 643 _power = power; 644 } 645 646 return(state); 647 } 648 649 int16_t RF69::setSyncWord(uint8_t* syncWord, size_t len, uint8_t maxErrBits) { 650 // check constraints 651 if((maxErrBits > 7) || (len > 8)) { 652 return(RADIOLIB_ERR_INVALID_SYNC_WORD); 653 } 654 655 // sync word must not contain value 0x00 656 for(uint8_t i = 0; i < len; i++) { 657 if(syncWord[i] == 0x00) { 658 return(RADIOLIB_ERR_INVALID_SYNC_WORD); 659 } 660 } 661 662 _syncWordLength = len; 663 664 int16_t state = enableSyncWordFiltering(maxErrBits); 665 RADIOLIB_ASSERT(state); 666 667 // set sync word register 668 _mod->SPIwriteRegisterBurst(RADIOLIB_RF69_REG_SYNC_VALUE_1, syncWord, len); 669 return(RADIOLIB_ERR_NONE); 670 } 671 672 int16_t RF69::setPreambleLength(uint8_t preambleLen) { 673 // RF69 configures preamble length in bytes 674 if(preambleLen % 8 != 0) { 675 return(RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH); 676 } 677 678 uint8_t preLenBytes = preambleLen / 8; 679 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_PREAMBLE_MSB, 0x00); 680 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PREAMBLE_LSB, preLenBytes)); 681 } 682 683 int16_t RF69::setNodeAddress(uint8_t nodeAddr) { 684 // enable address filtering (node only) 685 int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, RADIOLIB_RF69_ADDRESS_FILTERING_NODE, 2, 1); 686 RADIOLIB_ASSERT(state); 687 688 // set node address 689 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_NODE_ADRS, nodeAddr)); 690 } 691 692 int16_t RF69::setBroadcastAddress(uint8_t broadAddr) { 693 // enable address filtering (node + broadcast) 694 int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, RADIOLIB_RF69_ADDRESS_FILTERING_NODE_BROADCAST, 2, 1); 695 RADIOLIB_ASSERT(state); 696 697 // set broadcast address 698 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_BROADCAST_ADRS, broadAddr)); 699 } 700 701 int16_t RF69::disableAddressFiltering() { 702 // disable address filtering 703 int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, RADIOLIB_RF69_ADDRESS_FILTERING_OFF, 2, 1); 704 RADIOLIB_ASSERT(state); 705 706 // set node address to default (0x00) 707 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_NODE_ADRS, 0x00); 708 RADIOLIB_ASSERT(state); 709 710 // set broadcast address to default (0x00) 711 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_BROADCAST_ADRS, 0x00)); 712 } 713 714 void RF69::setAmbientTemperature(int16_t tempAmbient) { 715 _tempOffset = getTemperature() - tempAmbient; 716 } 717 718 int16_t RF69::getTemperature() { 719 // set mode to STANDBY 720 setMode(RADIOLIB_RF69_STANDBY); 721 722 // start temperature measurement 723 _mod->SPIsetRegValue(RADIOLIB_RF69_REG_TEMP_1, RADIOLIB_RF69_TEMP_MEAS_START, 3, 3); 724 725 // wait until measurement is finished 726 while(_mod->SPIgetRegValue(RADIOLIB_RF69_REG_TEMP_1, 2, 2) == RADIOLIB_RF69_TEMP_MEAS_RUNNING) { 727 // check every 10 us 728 _mod->delay(10); 729 } 730 int8_t rawTemp = _mod->SPIgetRegValue(RADIOLIB_RF69_REG_TEMP_2); 731 732 return(0 - (rawTemp + _tempOffset)); 733 } 734 735 size_t RF69::getPacketLength(bool update) { 736 if(!_packetLengthQueried && update) { 737 if (_packetLengthConfig == RADIOLIB_RF69_PACKET_FORMAT_VARIABLE) { 738 _packetLength = _mod->SPIreadRegister(RADIOLIB_RF69_REG_FIFO); 739 } else { 740 _packetLength = _mod->SPIreadRegister(RADIOLIB_RF69_REG_PAYLOAD_LENGTH); 741 } 742 _packetLengthQueried = true; 743 } 744 745 return(_packetLength); 746 } 747 748 int16_t RF69::fixedPacketLengthMode(uint8_t len) { 749 return(setPacketMode(RADIOLIB_RF69_PACKET_FORMAT_FIXED, len)); 750 } 751 752 int16_t RF69::variablePacketLengthMode(uint8_t maxLen) { 753 return(setPacketMode(RADIOLIB_RF69_PACKET_FORMAT_VARIABLE, maxLen)); 754 } 755 756 int16_t RF69::enableSyncWordFiltering(uint8_t maxErrBits) { 757 // enable sync word recognition 758 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_SYNC_CONFIG, RADIOLIB_RF69_SYNC_ON | RADIOLIB_RF69_FIFO_FILL_CONDITION_SYNC | (_syncWordLength - 1) << 3 | maxErrBits, 7, 0)); 759 } 760 761 int16_t RF69::disableSyncWordFiltering() { 762 // disable preamble detection and generation 763 int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PREAMBLE_LSB, 0, 7, 0); 764 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PREAMBLE_MSB, 0, 7, 0); 765 RADIOLIB_ASSERT(state); 766 767 // disable sync word detection and generation 768 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_SYNC_CONFIG, RADIOLIB_RF69_SYNC_OFF | RADIOLIB_RF69_FIFO_FILL_CONDITION, 7, 6); 769 770 return(state); 771 } 772 773 int16_t RF69::enableContinuousModeBitSync() { 774 int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_CONTINUOUS_MODE_WITH_SYNC, 6, 5); 775 if(state == RADIOLIB_ERR_NONE) { 776 _bitSync = true; 777 } 778 779 return(state); 780 } 781 782 int16_t RF69::disableContinuousModeBitSync() { 783 int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_CONTINUOUS_MODE, 6, 5); 784 if(state == RADIOLIB_ERR_NONE) { 785 _bitSync = false; 786 } 787 788 return(state); 789 } 790 791 int16_t RF69::setCrcFiltering(bool crcOn) { 792 if (crcOn == true) { 793 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, RADIOLIB_RF69_CRC_ON, 4, 4)); 794 } else { 795 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, RADIOLIB_RF69_CRC_OFF, 4, 4)); 796 } 797 } 798 799 int16_t RF69::setPromiscuousMode(bool promiscuous) { 800 int16_t state = RADIOLIB_ERR_NONE; 801 802 if (_promiscuous == promiscuous) { 803 return(state); 804 } 805 806 if (promiscuous == true) { 807 // disable preamble and sync word filtering and insertion 808 state = disableSyncWordFiltering(); 809 RADIOLIB_ASSERT(state); 810 811 // disable CRC filtering 812 state = setCrcFiltering(false); 813 } else { 814 // enable preamble and sync word filtering and insertion 815 state = enableSyncWordFiltering(); 816 RADIOLIB_ASSERT(state); 817 818 // enable CRC filtering 819 state = setCrcFiltering(true); 820 } 821 822 return(state); 823 } 824 825 int16_t RF69::setDataShaping(uint8_t sh) { 826 // set mode to standby 827 int16_t state = standby(); 828 RADIOLIB_ASSERT(state); 829 830 // set data shaping 831 switch(sh) { 832 case RADIOLIB_SHAPING_NONE: 833 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_NO_SHAPING, 1, 0)); 834 case RADIOLIB_SHAPING_0_3: 835 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_FSK_GAUSSIAN_0_3, 1, 0)); 836 case RADIOLIB_SHAPING_0_5: 837 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_FSK_GAUSSIAN_0_5, 1, 0)); 838 case RADIOLIB_SHAPING_1_0: 839 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_FSK_GAUSSIAN_1_0, 1, 0)); 840 default: 841 return(RADIOLIB_ERR_INVALID_DATA_SHAPING); 842 } 843 } 844 845 int16_t RF69::setEncoding(uint8_t encoding) { 846 // set mode to standby 847 int16_t state = standby(); 848 RADIOLIB_ASSERT(state); 849 850 // set encoding 851 switch(encoding) { 852 case RADIOLIB_ENCODING_NRZ: 853 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, RADIOLIB_RF69_DC_FREE_NONE, 6, 5)); 854 case RADIOLIB_ENCODING_MANCHESTER: 855 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, RADIOLIB_RF69_DC_FREE_MANCHESTER, 6, 5)); 856 case RADIOLIB_ENCODING_WHITENING: 857 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, RADIOLIB_RF69_DC_FREE_WHITENING, 6, 5)); 858 default: 859 return(RADIOLIB_ERR_INVALID_ENCODING); 860 } 861 } 862 863 int16_t RF69::setLnaTestBoost(bool value) { 864 if(value) { 865 return (_mod->SPIsetRegValue(RADIOLIB_RF69_REG_TEST_LNA, RADIOLIB_RF69_TEST_LNA_BOOST_HIGH, 7, 0)); 866 } 867 868 return(_mod->SPIsetRegValue(RADIOLIB_RF69_TEST_LNA_BOOST_NORMAL, RADIOLIB_RF69_TEST_LNA_BOOST_HIGH, 7, 0)); 869 } 870 871 float RF69::getRSSI() { 872 return(-1.0 * (_mod->SPIgetRegValue(RADIOLIB_RF69_REG_RSSI_VALUE)/2.0)); 873 } 874 875 int16_t RF69::setRSSIThreshold(float dbm) { 876 RADIOLIB_CHECK_RANGE(dbm, -127.5, 0, RADIOLIB_ERR_INVALID_RSSI_THRESHOLD); 877 878 return _mod->SPIsetRegValue(RADIOLIB_RF69_REG_RSSI_THRESH, (uint8_t)(-2.0 * dbm), 7, 0); 879 } 880 881 void RF69::setRfSwitchPins(RADIOLIB_PIN_TYPE rxEn, RADIOLIB_PIN_TYPE txEn) { 882 _mod->setRfSwitchPins(rxEn, txEn); 883 } 884 885 uint8_t RF69::randomByte() { 886 // set mode to Rx 887 setMode(RADIOLIB_RF69_RX); 888 889 // wait a bit for the RSSI reading to stabilise 890 _mod->delay(10); 891 892 // read RSSI value 8 times, always keep just the least significant bit 893 uint8_t randByte = 0x00; 894 for(uint8_t i = 0; i < 8; i++) { 895 randByte |= ((_mod->SPIreadRegister(RADIOLIB_RF69_REG_RSSI_VALUE) & 0x01) << i); 896 } 897 898 // set mode to standby 899 setMode(RADIOLIB_RF69_STANDBY); 900 901 return(randByte); 902 } 903 904 #if !defined(RADIOLIB_EXCLUDE_DIRECT_RECEIVE) 905 void RF69::setDirectAction(void (*func)(void)) { 906 setDio1Action(func); 907 } 908 909 void RF69::readBit(RADIOLIB_PIN_TYPE pin) { 910 updateDirectBuffer((uint8_t)digitalRead(pin)); 911 } 912 #endif 913 914 int16_t RF69::setDIOMapping(RADIOLIB_PIN_TYPE pin, uint8_t value) { 915 if(pin > 5) { 916 return(RADIOLIB_ERR_INVALID_DIO_PIN); 917 } 918 919 if(pin < 4) { 920 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_1, value, 7 - 2 * pin, 6 - 2 * pin)); 921 } 922 923 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_2, value, 15 - 2 * pin, 14 - 2 * pin)); 924 } 925 926 int16_t RF69::getChipVersion() { 927 return(_mod->SPIgetRegValue(RADIOLIB_RF69_REG_VERSION)); 928 } 929 930 int16_t RF69::config() { 931 int16_t state = RADIOLIB_ERR_NONE; 932 933 // set mode to STANDBY 934 state = setMode(RADIOLIB_RF69_STANDBY); 935 RADIOLIB_ASSERT(state); 936 937 // set operation modes 938 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_OP_MODE, RADIOLIB_RF69_SEQUENCER_ON | RADIOLIB_RF69_LISTEN_OFF, 7, 6); 939 RADIOLIB_ASSERT(state); 940 941 // enable over-current protection 942 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_OCP, RADIOLIB_RF69_OCP_ON, 4, 4); 943 RADIOLIB_ASSERT(state); 944 945 // set data mode, modulation type and shaping 946 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_PACKET_MODE | RADIOLIB_RF69_FSK, 6, 3); 947 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DATA_MODUL, RADIOLIB_RF69_FSK_GAUSSIAN_0_3, 1, 0); 948 RADIOLIB_ASSERT(state); 949 950 // set RSSI threshold 951 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_RSSI_THRESH, RADIOLIB_RF69_RSSI_THRESHOLD, 7, 0); 952 RADIOLIB_ASSERT(state); 953 954 // reset FIFO flag 955 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_IRQ_FLAGS_2, RADIOLIB_RF69_IRQ_FIFO_OVERRUN); 956 957 // disable ClkOut on DIO5 958 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_DIO_MAPPING_2, RADIOLIB_RF69_CLK_OUT_OFF, 2, 0); 959 RADIOLIB_ASSERT(state); 960 961 // set packet configuration and disable encryption 962 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, RADIOLIB_RF69_PACKET_FORMAT_VARIABLE | RADIOLIB_RF69_DC_FREE_NONE | RADIOLIB_RF69_CRC_ON | RADIOLIB_RF69_CRC_AUTOCLEAR_ON | RADIOLIB_RF69_ADDRESS_FILTERING_OFF, 7, 1); 963 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_2, RADIOLIB_RF69_INTER_PACKET_RX_DELAY, 7, 4); 964 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_2, RADIOLIB_RF69_AUTO_RX_RESTART_ON | RADIOLIB_RF69_AES_OFF, 1, 0); 965 RADIOLIB_ASSERT(state); 966 967 // set payload length 968 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PAYLOAD_LENGTH, RADIOLIB_RF69_PAYLOAD_LENGTH, 7, 0); 969 RADIOLIB_ASSERT(state); 970 971 // set FIFO threshold 972 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_FIFO_THRESH, RADIOLIB_RF69_TX_START_CONDITION_FIFO_NOT_EMPTY | RADIOLIB_RF69_FIFO_THRESH, 7, 0); 973 RADIOLIB_ASSERT(state); 974 975 // set Rx timeouts 976 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_RX_TIMEOUT_1, RADIOLIB_RF69_TIMEOUT_RX_START, 7, 0); 977 state |= _mod->SPIsetRegValue(RADIOLIB_RF69_REG_RX_TIMEOUT_2, RADIOLIB_RF69_TIMEOUT_RSSI_THRESH, 7, 0); 978 RADIOLIB_ASSERT(state); 979 980 // enable improved fading margin 981 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_TEST_DAGC, RADIOLIB_RF69_CONTINUOUS_DAGC_LOW_BETA_OFF, 7, 0); 982 983 return(state); 984 } 985 986 int16_t RF69::setPacketMode(uint8_t mode, uint8_t len) { 987 // check length 988 if (len > RADIOLIB_RF69_MAX_PACKET_LENGTH) { 989 return(RADIOLIB_ERR_PACKET_TOO_LONG); 990 } 991 992 // set to fixed packet length 993 int16_t state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PACKET_CONFIG_1, mode, 7, 7); 994 RADIOLIB_ASSERT(state); 995 996 // set length to register 997 state = _mod->SPIsetRegValue(RADIOLIB_RF69_REG_PAYLOAD_LENGTH, len); 998 RADIOLIB_ASSERT(state); 999 1000 // update the cached value 1001 _packetLengthConfig = mode; 1002 return(state); 1003 } 1004 1005 int16_t RF69::setMode(uint8_t mode) { 1006 return(_mod->SPIsetRegValue(RADIOLIB_RF69_REG_OP_MODE, mode, 4, 2)); 1007 } 1008 1009 void RF69::clearIRQFlags() { 1010 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_IRQ_FLAGS_1, 0b11111111); 1011 _mod->SPIwriteRegister(RADIOLIB_RF69_REG_IRQ_FLAGS_2, 0b11111111); 1012 } 1013 1014 void RF69::clearFIFO(size_t count) { 1015 while(count) { 1016 _mod->SPIreadRegister(RADIOLIB_RF69_REG_FIFO); 1017 count--; 1018 } 1019 } 1020 1021 #endif