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