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

SX127x.cpp (48170B)

      1 #include "SX127x.h"
      2 #if !defined(RADIOLIB_EXCLUDE_SX127X)
      3 
      4 SX127x::SX127x(Module* mod) : PhysicalLayer(RADIOLIB_SX127X_FREQUENCY_STEP_SIZE, RADIOLIB_SX127X_MAX_PACKET_LENGTH) {
      5   _mod = mod;
      6 }
      7 
      8 Module* SX127x::getMod() {
      9   return(_mod);
     10 }
     11 
     12 int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord, uint16_t preambleLength) {
     13   // set module properties
     14   _mod->init();
     15   _mod->pinMode(_mod->getIrq(), INPUT);
     16   _mod->pinMode(_mod->getGpio(), INPUT);
     17 
     18   // try to find the SX127x chip
     19   if(!SX127x::findChip(chipVersion)) {
     20     RADIOLIB_DEBUG_PRINTLN(F("No SX127x found!"));
     21     _mod->term();
     22     return(RADIOLIB_ERR_CHIP_NOT_FOUND);
     23   }
     24   RADIOLIB_DEBUG_PRINTLN(F("M\tSX127x"));
     25 
     26   // set mode to standby
     27   int16_t state = standby();
     28   RADIOLIB_ASSERT(state);
     29 
     30   // configure settings not accessible by API
     31   state = config();
     32   RADIOLIB_ASSERT(state);
     33 
     34   // check active modem
     35   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
     36     // set LoRa mode
     37     state = setActiveModem(RADIOLIB_SX127X_LORA);
     38     RADIOLIB_ASSERT(state);
     39   }
     40 
     41   // set LoRa sync word
     42   state = SX127x::setSyncWord(syncWord);
     43   RADIOLIB_ASSERT(state);
     44 
     45   // set over current protection
     46   state = SX127x::setCurrentLimit(60);
     47   RADIOLIB_ASSERT(state);
     48 
     49   // set preamble length
     50   state = SX127x::setPreambleLength(preambleLength);
     51   RADIOLIB_ASSERT(state);
     52 
     53   // initialize internal variables
     54   _dataRate = 0.0;
     55 
     56   return(state);
     57 }
     58 
     59 int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxBw, uint16_t preambleLength, bool enableOOK) {
     60   // set module properties
     61   _mod->init();
     62   _mod->pinMode(_mod->getIrq(), INPUT);
     63 
     64   // try to find the SX127x chip
     65   if(!SX127x::findChip(chipVersion)) {
     66     RADIOLIB_DEBUG_PRINTLN(F("No SX127x found!"));
     67     _mod->term();
     68     return(RADIOLIB_ERR_CHIP_NOT_FOUND);
     69   }
     70   RADIOLIB_DEBUG_PRINTLN(F("M\tSX127x"));
     71 
     72   // set mode to standby
     73   int16_t state = standby();
     74   RADIOLIB_ASSERT(state);
     75 
     76   // check currently active modem
     77   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
     78     // set FSK mode
     79     state = setActiveModem(RADIOLIB_SX127X_FSK_OOK);
     80     RADIOLIB_ASSERT(state);
     81   }
     82 
     83   // enable/disable OOK
     84   state = setOOK(enableOOK);
     85   RADIOLIB_ASSERT(state);
     86 
     87   // set bit rate
     88   state = SX127x::setBitRate(br);
     89   RADIOLIB_ASSERT(state);
     90 
     91   // set frequency deviation
     92   state = SX127x::setFrequencyDeviation(freqDev);
     93   RADIOLIB_ASSERT(state);
     94 
     95   // set AFC bandwidth
     96   state = SX127x::setAFCBandwidth(rxBw);
     97   RADIOLIB_ASSERT(state);
     98 
     99   // set AFC&AGC trigger to RSSI (both in OOK and FSK)
    100   state = SX127x::setAFCAGCTrigger(RADIOLIB_SX127X_RX_TRIGGER_RSSI_INTERRUPT);
    101   RADIOLIB_ASSERT(state);
    102 
    103   // enable AFC
    104   state = SX127x::setAFC(false);
    105   RADIOLIB_ASSERT(state);
    106 
    107   // set receiver bandwidth
    108   state = SX127x::setRxBandwidth(rxBw);
    109   RADIOLIB_ASSERT(state);
    110 
    111   // set over current protection
    112   state = SX127x::setCurrentLimit(60);
    113   RADIOLIB_ASSERT(state);
    114 
    115   // set preamble length
    116   state = SX127x::setPreambleLength(preambleLength);
    117   RADIOLIB_ASSERT(state);
    118 
    119   // set default sync word
    120   uint8_t syncWord[] = {0x12, 0xAD};
    121   state = setSyncWord(syncWord, 2);
    122   RADIOLIB_ASSERT(state);
    123 
    124   // disable address filtering
    125   state = disableAddressFiltering();
    126   RADIOLIB_ASSERT(state);
    127 
    128   // set default RSSI measurement config
    129   state = setRSSIConfig(2);
    130   RADIOLIB_ASSERT(state);
    131 
    132   // set default encoding
    133   state = setEncoding(RADIOLIB_ENCODING_NRZ);
    134   RADIOLIB_ASSERT(state);
    135 
    136   // set default packet length mode
    137   state = variablePacketLengthMode();
    138 
    139   return(state);
    140 }
    141 
    142 int16_t SX127x::transmit(uint8_t* data, size_t len, uint8_t addr) {
    143   // set mode to standby
    144   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    145   RADIOLIB_ASSERT(state);
    146 
    147   int16_t modem = getActiveModem();
    148   uint32_t start = 0;
    149   if(modem == RADIOLIB_SX127X_LORA) {
    150     // calculate timeout (150 % of expected time-on-air)
    151     uint32_t timeout = getTimeOnAir(len) * 1.5;
    152 
    153     // start transmission
    154     state = startTransmit(data, len, addr);
    155     RADIOLIB_ASSERT(state);
    156 
    157     // wait for packet transmission or timeout
    158     start = _mod->micros();
    159     while(!_mod->digitalRead(_mod->getIrq())) {
    160       _mod->yield();
    161       if(_mod->micros() - start > timeout) {
    162         clearIRQFlags();
    163         return(RADIOLIB_ERR_TX_TIMEOUT);
    164       }
    165     }
    166 
    167   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
    168     // calculate timeout (5ms + 500 % of expected time-on-air)
    169     uint32_t timeout = 5000 + getTimeOnAir(len) * 5;
    170 
    171     // start transmission
    172     state = startTransmit(data, len, addr);
    173     RADIOLIB_ASSERT(state);
    174 
    175     // wait for transmission end or timeout
    176     start = _mod->micros();
    177     while(!_mod->digitalRead(_mod->getIrq())) {
    178       _mod->yield();
    179       if(_mod->micros() - start > timeout) {
    180         clearIRQFlags();
    181         standby();
    182         return(RADIOLIB_ERR_TX_TIMEOUT);
    183       }
    184     }
    185   } else {
    186     return(RADIOLIB_ERR_UNKNOWN);
    187   }
    188 
    189   // update data rate
    190   uint32_t elapsed = _mod->micros() - start;
    191   _dataRate = (len*8.0)/((float)elapsed/1000000.0);
    192 
    193   // clear interrupt flags
    194   clearIRQFlags();
    195 
    196   // set mode to standby to disable transmitter
    197   return(standby());
    198 }
    199 
    200 int16_t SX127x::receive(uint8_t* data, size_t len) {
    201   // set mode to standby
    202   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    203   RADIOLIB_ASSERT(state);
    204 
    205   int16_t modem = getActiveModem();
    206   if(modem == RADIOLIB_SX127X_LORA) {
    207     // set mode to receive
    208     state = startReceive(len, RADIOLIB_SX127X_RXSINGLE);
    209     RADIOLIB_ASSERT(state);
    210 
    211     // wait for packet reception or timeout (100 LoRa symbols)
    212     while(!_mod->digitalRead(_mod->getIrq())) {
    213       _mod->yield();
    214       if(_mod->digitalRead(_mod->getGpio())) {
    215         clearIRQFlags();
    216         return(RADIOLIB_ERR_RX_TIMEOUT);
    217       }
    218     }
    219 
    220   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
    221     // calculate timeout (500 % of expected time-on-air)
    222     uint32_t timeout = getTimeOnAir(len) * 5;
    223 
    224     // set mode to receive
    225     state = startReceive(len, RADIOLIB_SX127X_RX);
    226     RADIOLIB_ASSERT(state);
    227 
    228     // wait for packet reception or timeout
    229     uint32_t start = _mod->micros();
    230     while(!_mod->digitalRead(_mod->getIrq())) {
    231       _mod->yield();
    232       if(_mod->micros() - start > timeout) {
    233         clearIRQFlags();
    234         return(RADIOLIB_ERR_RX_TIMEOUT);
    235       }
    236     }
    237   }
    238 
    239   // read the received data
    240   state = readData(data, len);
    241 
    242   return(state);
    243 }
    244 
    245 int16_t SX127x::scanChannel() {
    246   // start CAD
    247   int16_t state = startChannelScan();
    248   RADIOLIB_ASSERT(state);
    249 
    250   // wait for channel activity detected or timeout
    251   while(!_mod->digitalRead(_mod->getIrq())) {
    252     _mod->yield();
    253     if(_mod->digitalRead(_mod->getGpio())) {
    254       clearIRQFlags();
    255       return(RADIOLIB_PREAMBLE_DETECTED);
    256     }
    257   }
    258 
    259   // clear interrupt flags
    260   clearIRQFlags();
    261 
    262   return(RADIOLIB_CHANNEL_FREE);
    263 }
    264 
    265 int16_t SX127x::sleep() {
    266   // set RF switch (if present)
    267   _mod->setRfSwitchState(LOW, LOW);
    268 
    269   // set mode to sleep
    270   return(setMode(RADIOLIB_SX127X_SLEEP));
    271 }
    272 
    273 int16_t SX127x::standby() {
    274   // set RF switch (if present)
    275   _mod->setRfSwitchState(LOW, LOW);
    276 
    277   // set mode to standby
    278   return(setMode(RADIOLIB_SX127X_STANDBY));
    279 }
    280 
    281 int16_t SX127x::transmitDirect(uint32_t frf) {
    282   // check modem
    283   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    284     return(RADIOLIB_ERR_WRONG_MODEM);
    285   }
    286 
    287   // set RF switch (if present)
    288   _mod->setRfSwitchState(LOW, HIGH);
    289 
    290   // user requested to start transmitting immediately (required for RTTY)
    291   if(frf != 0) {
    292     _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FRF_MSB, (frf & 0xFF0000) >> 16);
    293     _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FRF_MID, (frf & 0x00FF00) >> 8);
    294     _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FRF_LSB, frf & 0x0000FF);
    295 
    296     return(setMode(RADIOLIB_SX127X_TX));
    297   }
    298 
    299   // activate direct mode
    300   int16_t state = directMode();
    301   RADIOLIB_ASSERT(state);
    302 
    303   // apply fixes to errata
    304   RADIOLIB_ERRATA_SX127X(false);
    305 
    306   // start transmitting
    307   return(setMode(RADIOLIB_SX127X_TX));
    308 }
    309 
    310 int16_t SX127x::receiveDirect() {
    311   // check modem
    312   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    313     return(RADIOLIB_ERR_WRONG_MODEM);
    314   }
    315 
    316   // set RF switch (if present)
    317   _mod->setRfSwitchState(HIGH, LOW);
    318 
    319   // activate direct mode
    320   int16_t state = directMode();
    321   RADIOLIB_ASSERT(state);
    322 
    323   // apply fixes to errata
    324   RADIOLIB_ERRATA_SX127X(true);
    325 
    326   // start receiving
    327   return(setMode(RADIOLIB_SX127X_RX));
    328 }
    329 
    330 int16_t SX127x::directMode() {
    331   // set mode to standby
    332   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    333   RADIOLIB_ASSERT(state);
    334 
    335   // set DIO mapping
    336   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_CONT_DCLK | RADIOLIB_SX127X_DIO2_CONT_DATA, 5, 2);
    337   RADIOLIB_ASSERT(state);
    338 
    339   // enable receiver startup without preamble or RSSI
    340   state = SX127x::setAFCAGCTrigger(RADIOLIB_SX127X_RX_TRIGGER_NONE);
    341   RADIOLIB_ASSERT(state);
    342 
    343   // set continuous mode
    344   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_2, RADIOLIB_SX127X_DATA_MODE_CONTINUOUS, 6, 6));
    345 }
    346 
    347 int16_t SX127x::packetMode() {
    348   // check modem
    349   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    350     return(RADIOLIB_ERR_WRONG_MODEM);
    351   }
    352 
    353   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_2, RADIOLIB_SX127X_DATA_MODE_PACKET, 6, 6));
    354 }
    355 
    356 int16_t SX127x::startReceive(uint8_t len, uint8_t mode) {
    357   // set mode to standby
    358   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    359   RADIOLIB_ASSERT(state);
    360 
    361   int16_t modem = getActiveModem();
    362   if(modem == RADIOLIB_SX127X_LORA) {
    363     // set DIO pin mapping
    364     if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) {
    365       state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_RX_DONE | RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 7, 4);
    366     }
    367     else {
    368       state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_RX_DONE | RADIOLIB_SX127X_DIO1_LORA_RX_TIMEOUT, 7, 4);
    369     }
    370 
    371     // set expected packet length for SF6
    372     if(_sf == 6) {
    373       state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len);
    374     }
    375 
    376     // apply fixes to errata
    377     RADIOLIB_ERRATA_SX127X(true);
    378 
    379     // clear interrupt flags
    380     clearIRQFlags();
    381 
    382     // set FIFO pointers
    383     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_RX_BASE_ADDR, RADIOLIB_SX127X_FIFO_RX_BASE_ADDR_MAX);
    384     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_ADDR_PTR, RADIOLIB_SX127X_FIFO_RX_BASE_ADDR_MAX);
    385     RADIOLIB_ASSERT(state);
    386 
    387   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
    388     // set DIO pin mapping
    389     state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PAYLOAD_READY, 7, 6);
    390     RADIOLIB_ASSERT(state);
    391 
    392     // clear interrupt flags
    393     clearIRQFlags();
    394 
    395     // FSK modem does not distinguish between Rx single and continuous
    396     if(mode == RADIOLIB_SX127X_RXCONTINUOUS) {
    397       // set RF switch (if present)
    398       _mod->setRfSwitchState(HIGH, LOW);
    399       return(setMode(RADIOLIB_SX127X_RX));
    400     }
    401   }
    402 
    403   // set RF switch (if present)
    404   _mod->setRfSwitchState(HIGH, LOW);
    405 
    406   // set mode to receive
    407   return(setMode(mode));
    408 }
    409 
    410 void SX127x::setDio0Action(void (*func)(void)) {
    411   _mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getIrq()), func, RISING);
    412 }
    413 
    414 void SX127x::clearDio0Action() {
    415   _mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getIrq()));
    416 }
    417 
    418 void SX127x::setDio1Action(void (*func)(void)) {
    419   if(_mod->getGpio() == RADIOLIB_NC) {
    420     return;
    421   }
    422   _mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()), func, RISING);
    423 }
    424 
    425 void SX127x::clearDio1Action() {
    426   if(_mod->getGpio() == RADIOLIB_NC) {
    427     return;
    428   }
    429   _mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()));
    430 }
    431 
    432 void SX127x::setFifoEmptyAction(void (*func)(void)) {
    433   // set DIO1 to the FIFO empty event (the register setting is done in startTransmit)
    434   setDio1Action(func);
    435 }
    436 
    437 void SX127x::clearFifoEmptyAction() {
    438   clearDio1Action();
    439 }
    440 
    441 void SX127x::setFifoFullAction(void (*func)(void)) {
    442   // set the interrupt
    443   _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_FIFO_THRESH, 5, 0);
    444   _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_PACK_FIFO_LEVEL, 5, 4);
    445 
    446   // set DIO1 to the FIFO full event
    447   setDio1Action(func);
    448 }
    449 
    450 void SX127x::clearFifoFullAction() {
    451   clearDio1Action();
    452   _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, 0x00, 5, 4);
    453 }
    454 
    455 bool SX127x::fifoAdd(uint8_t* data, int totalLen, volatile int* remLen) {
    456   // subtract first (this may be the first time we get to modify the remaining length)
    457   *remLen -= RADIOLIB_SX127X_FIFO_THRESH - 1;
    458 
    459   // check if there is still something left to send
    460   if(*remLen <= 0) {
    461     // we're done
    462     return(true);
    463   }
    464 
    465   // calculate the number of bytes we can copy
    466   int len = *remLen;
    467   if(len > RADIOLIB_SX127X_FIFO_THRESH - 1) {
    468     len = RADIOLIB_SX127X_FIFO_THRESH - 1;
    469   }
    470 
    471   // clear interrupt flags
    472   clearIRQFlags();
    473 
    474   // copy the bytes to the FIFO
    475   _mod->SPIwriteRegisterBurst(RADIOLIB_SX127X_REG_FIFO, &data[totalLen - *remLen], len);
    476 
    477   // this is a hack, but it seems Rx FIFO level is getting triggered 1 byte before it should
    478   // we just add a padding byte that we can drop without consequence
    479   _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, '/');
    480 
    481   // we're not done yet
    482   return(false);
    483 }
    484 
    485 bool SX127x::fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen) {
    486   // get pointer to the correct position in data buffer
    487   uint8_t* dataPtr = (uint8_t*)&data[*rcvLen];
    488 
    489   // check how much data are we still expecting
    490   uint8_t len = RADIOLIB_SX127X_FIFO_THRESH - 1;
    491   if(totalLen - *rcvLen < len) {
    492     // we're nearly at the end
    493     len = totalLen - *rcvLen;
    494   }
    495 
    496   // get the data
    497   _mod->SPIreadRegisterBurst(RADIOLIB_SX127X_REG_FIFO, len, dataPtr);
    498   (*rcvLen) += (len);
    499 
    500   // dump the padding byte
    501   _mod->SPIreadRegister(RADIOLIB_SX127X_REG_FIFO);
    502 
    503   // clear flags
    504   clearIRQFlags();
    505 
    506   // check if we're done
    507   if(*rcvLen >= totalLen) {
    508     return(true);
    509   }
    510   return(false);
    511 }
    512 
    513 int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
    514   // set mode to standby
    515   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    516 
    517   int16_t modem = getActiveModem();
    518   if(modem == RADIOLIB_SX127X_LORA) {
    519     // check packet length
    520     if(len > RADIOLIB_SX127X_MAX_PACKET_LENGTH) {
    521       return(RADIOLIB_ERR_PACKET_TOO_LONG);
    522     }
    523 
    524     // set DIO mapping
    525     if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) {
    526       _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_TX_DONE | RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 7, 4);
    527     } else {
    528       _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_TX_DONE, 7, 6);
    529     }
    530 
    531     // apply fixes to errata
    532     RADIOLIB_ERRATA_SX127X(false);
    533 
    534     // clear interrupt flags
    535     clearIRQFlags();
    536 
    537     // set packet length
    538     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len);
    539 
    540     // set FIFO pointers
    541     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_TX_BASE_ADDR, RADIOLIB_SX127X_FIFO_TX_BASE_ADDR_MAX);
    542     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_ADDR_PTR, RADIOLIB_SX127X_FIFO_TX_BASE_ADDR_MAX);
    543 
    544   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
    545     // clear interrupt flags
    546     clearIRQFlags();
    547 
    548     // set DIO mapping
    549     if(len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK) {
    550       _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_PACK_FIFO_EMPTY, 5, 4);
    551     } else {
    552       _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PACKET_SENT, 7, 6);
    553     }
    554 
    555     // set packet length
    556     if (_packetLengthConfig == RADIOLIB_SX127X_PACKET_VARIABLE) {
    557       _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, len);
    558     }
    559 
    560     // check address filtering
    561     uint8_t filter = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, 2, 1);
    562     if((filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE) || (filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE_BROADCAST)) {
    563       _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, addr);
    564     }
    565   }
    566 
    567   // write packet to FIFO
    568   size_t packetLen = len;
    569   if((modem == RADIOLIB_SX127X_FSK_OOK) && (len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK)) {
    570     packetLen = RADIOLIB_SX127X_FIFO_THRESH - 1;
    571     _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_TX_START_FIFO_NOT_EMPTY, 7, 7);
    572   }
    573   _mod->SPIwriteRegisterBurst(RADIOLIB_SX127X_REG_FIFO, data, packetLen);
    574 
    575   // this is a hack, but it seems than in Stream mode, Rx FIFO level is getting triggered 1 byte before it should
    576   // just add a padding byte that can be dropped without consequence
    577   if((modem == RADIOLIB_SX127X_FSK_OOK) && (len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK)) {
    578     _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, '/');
    579   }
    580 
    581   // set RF switch (if present)
    582   _mod->setRfSwitchState(LOW, HIGH);
    583 
    584   // start transmission
    585   state |= setMode(RADIOLIB_SX127X_TX);
    586   RADIOLIB_ASSERT(state);
    587 
    588   return(RADIOLIB_ERR_NONE);
    589 }
    590 
    591 int16_t SX127x::readData(uint8_t* data, size_t len) {
    592   int16_t modem = getActiveModem();
    593 
    594   // put module to standby
    595   standby();
    596 
    597   // get packet length
    598   size_t length = getPacketLength();
    599   size_t dumpLen = 0;
    600   if((len != 0) && (len < length)) {
    601     // user requested less data than we got, only return what was requested
    602     dumpLen = length - len;
    603     length = len;
    604   }
    605 
    606   if(modem == RADIOLIB_SX127X_LORA) {
    607     // check packet header integrity
    608     if(_crcEnabled && (_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 6, 6)) == 0) {
    609       // CRC is disabled according to packet header and enabled according to user
    610       // most likely damaged packet header
    611       clearIRQFlags();
    612       return(RADIOLIB_ERR_LORA_HEADER_DAMAGED);
    613     }
    614 
    615     // check payload CRC
    616     if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_IRQ_FLAGS, 5, 5) == RADIOLIB_SX127X_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR) {
    617       // clear interrupt flags
    618       clearIRQFlags();
    619       return(RADIOLIB_ERR_CRC_MISMATCH);
    620     }
    621 
    622   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
    623     // check address filtering
    624     uint8_t filter = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, 2, 1);
    625     if((filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE) || (filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE_BROADCAST)) {
    626       _mod->SPIreadRegister(RADIOLIB_SX127X_REG_FIFO);
    627     }
    628   }
    629 
    630   // read packet data
    631   _mod->SPIreadRegisterBurst(RADIOLIB_SX127X_REG_FIFO, length, data);
    632 
    633   // dump the bytes that weren't requested
    634   if(dumpLen != 0) {
    635     clearFIFO(dumpLen);
    636   }
    637 
    638   // clear internal flag so getPacketLength can return the new packet length
    639   _packetLengthQueried = false;
    640 
    641   // clear interrupt flags
    642   clearIRQFlags();
    643 
    644   return(RADIOLIB_ERR_NONE);
    645 }
    646 
    647 int16_t SX127x::startChannelScan() {
    648   // check active modem
    649   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
    650     return(RADIOLIB_ERR_WRONG_MODEM);
    651   }
    652 
    653   // set mode to standby
    654   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    655   RADIOLIB_ASSERT(state);
    656 
    657   // set DIO pin mapping
    658   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_CAD_DONE | RADIOLIB_SX127X_DIO1_LORA_CAD_DETECTED, 7, 4);
    659   RADIOLIB_ASSERT(state);
    660 
    661   // clear interrupt flags
    662   clearIRQFlags();
    663 
    664   // set RF switch (if present)
    665   _mod->setRfSwitchState(HIGH, LOW);
    666 
    667   // set mode to CAD
    668   state = setMode(RADIOLIB_SX127X_CAD);
    669   return(state);
    670 }
    671 
    672 int16_t SX127x::setSyncWord(uint8_t syncWord) {
    673   // check active modem
    674   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
    675     return(RADIOLIB_ERR_WRONG_MODEM);
    676   }
    677 
    678   // set mode to standby
    679   setMode(RADIOLIB_SX127X_STANDBY);
    680 
    681   // write register
    682   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYNC_WORD, syncWord));
    683 }
    684 
    685 int16_t SX127x::setCurrentLimit(uint8_t currentLimit) {
    686   // check allowed range
    687   if(!(((currentLimit >= 45) && (currentLimit <= 240)) || (currentLimit == 0))) {
    688     return(RADIOLIB_ERR_INVALID_CURRENT_LIMIT);
    689   }
    690 
    691   // set mode to standby
    692   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    693 
    694   // set OCP limit
    695   uint8_t raw;
    696   if(currentLimit == 0) {
    697     // limit set to 0, disable OCP
    698     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OCP, RADIOLIB_SX127X_OCP_OFF, 5, 5);
    699   } else if(currentLimit <= 120) {
    700     raw = (currentLimit - 45) / 5;
    701     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OCP, RADIOLIB_SX127X_OCP_ON | raw, 5, 0);
    702   } else if(currentLimit <= 240) {
    703     raw = (currentLimit + 30) / 10;
    704     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OCP, RADIOLIB_SX127X_OCP_ON | raw, 5, 0);
    705   }
    706   return(state);
    707 }
    708 
    709 int16_t SX127x::setPreambleLength(uint16_t preambleLength) {
    710   // set mode to standby
    711   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    712   RADIOLIB_ASSERT(state);
    713 
    714   // check active modem
    715   uint8_t modem = getActiveModem();
    716   if(modem == RADIOLIB_SX127X_LORA) {
    717     // check allowed range
    718     if(preambleLength < 6) {
    719       return(RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH);
    720     }
    721 
    722     // set preamble length
    723     state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB, (uint8_t)((preambleLength >> 8) & 0xFF));
    724     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB, (uint8_t)(preambleLength & 0xFF));
    725     return(state);
    726 
    727   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
    728     // set preamble length (in bytes)
    729     uint16_t numBytes = preambleLength / 8;
    730     state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB_FSK, (uint8_t)((numBytes >> 8) & 0xFF));
    731     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB_FSK, (uint8_t)(numBytes & 0xFF));
    732     return(state);
    733   }
    734 
    735   return(RADIOLIB_ERR_UNKNOWN);
    736 }
    737 
    738 float SX127x::getFrequencyError(bool autoCorrect) {
    739   int16_t modem = getActiveModem();
    740   if(modem == RADIOLIB_SX127X_LORA) {
    741     // get raw frequency error
    742     uint32_t raw = (uint32_t)_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_MSB, 3, 0) << 16;
    743     raw |= (uint16_t)_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_MID) << 8;
    744     raw |= _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_LSB);
    745 
    746     uint32_t base = (uint32_t)2 << 23;
    747     float error;
    748 
    749     // check the first bit
    750     if(raw & 0x80000) {
    751       // frequency error is negative
    752       raw |= (uint32_t)0xFFF00000;
    753       raw = ~raw + 1;
    754       error = (((float)raw * (float)base)/32000000.0) * (_bw/500.0) * -1.0;
    755     } else {
    756       error = (((float)raw * (float)base)/32000000.0) * (_bw/500.0);
    757     }
    758 
    759     if(autoCorrect) {
    760       // adjust LoRa modem data rate
    761       float ppmOffset = 0.95 * (error/32.0);
    762       _mod->SPIwriteRegister(0x27, (uint8_t)ppmOffset);
    763     }
    764 
    765     return(error);
    766 
    767   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
    768     // get raw frequency error
    769     uint16_t raw = (uint16_t)_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_MSB_FSK) << 8;
    770     raw |= _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_LSB_FSK);
    771 
    772     uint32_t base = 1;
    773     float error;
    774 
    775     // check the first bit
    776     if(raw & 0x8000) {
    777       // frequency error is negative
    778       raw |= (uint32_t)0xFFF00000;
    779       raw = ~raw + 1;
    780       error = (float)raw * (32000000.0 / (float)(base << 19)) * -1.0;
    781     } else {
    782       error = (float)raw * (32000000.0 / (float)(base << 19));
    783     }
    784 
    785     return(error);
    786   }
    787 
    788   return(RADIOLIB_ERR_UNKNOWN);
    789 }
    790 
    791 float SX127x::getAFCError()
    792 {
    793   // check active modem
    794   int16_t modem = getActiveModem();
    795   if(modem != RADIOLIB_SX127X_FSK_OOK) {
    796     return 0;
    797   }
    798 
    799   // get raw frequency error
    800   int16_t raw = (uint16_t)_mod->SPIreadRegister(RADIOLIB_SX127X_REG_AFC_MSB) << 8;
    801   raw |= _mod->SPIreadRegister(RADIOLIB_SX127X_REG_AFC_LSB);
    802 
    803   uint32_t base = 1;
    804   return raw * (32000000.0 / (float)(base << 19));
    805 }
    806 
    807 float SX127x::getSNR() {
    808   // check active modem
    809   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
    810     return(0);
    811   }
    812 
    813   // get SNR value
    814   int8_t rawSNR = (int8_t)_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PKT_SNR_VALUE);
    815   return(rawSNR / 4.0);
    816 }
    817 
    818 float SX127x::getDataRate() const {
    819   return(_dataRate);
    820 }
    821 
    822 int16_t SX127x::setBitRate(float br) {
    823   // check active modem
    824   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    825     return(RADIOLIB_ERR_WRONG_MODEM);
    826   }
    827 
    828   // check allowed bit rate
    829   if(_ook) {
    830     RADIOLIB_CHECK_RANGE(br, 1.2, 32.768002, RADIOLIB_ERR_INVALID_BIT_RATE);      // Found that 32.768 is 32.768002
    831   } else {
    832     RADIOLIB_CHECK_RANGE(br, 1.2, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE);
    833   }
    834 
    835   // set mode to STANDBY
    836   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    837   RADIOLIB_ASSERT(state);
    838 
    839   // set bit rate
    840   uint16_t bitRate = (RADIOLIB_SX127X_CRYSTAL_FREQ * 1000.0) / br;
    841   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0);
    842   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0);
    843 
    844   /// \todo fractional part of bit rate setting (not in OOK)
    845   if(state == RADIOLIB_ERR_NONE) {
    846     SX127x::_br = br;
    847   }
    848   return(state);
    849 }
    850 
    851 int16_t SX127x::setFrequencyDeviation(float freqDev) {
    852   // check active modem
    853   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    854     return(RADIOLIB_ERR_WRONG_MODEM);
    855   }
    856 
    857   // set frequency deviation to lowest available setting (required for digimodes)
    858   float newFreqDev = freqDev;
    859   if(freqDev < 0.0) {
    860     newFreqDev = 0.6;
    861   }
    862 
    863   // check frequency deviation range
    864   if(!((newFreqDev + _br/2.0 <= 250.0) && (freqDev <= 200.0))) {
    865     return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
    866   }
    867 
    868   // set mode to STANDBY
    869   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    870   RADIOLIB_ASSERT(state);
    871 
    872   // set allowed frequency deviation
    873   uint32_t base = 1;
    874   uint32_t FDEV = (newFreqDev * (base << 19)) / 32000;
    875   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FDEV_MSB, (FDEV & 0xFF00) >> 8, 5, 0);
    876   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FDEV_LSB, FDEV & 0x00FF, 7, 0);
    877   return(state);
    878 }
    879 
    880 uint8_t SX127x::calculateBWManExp(float bandwidth)
    881 {
    882   for(uint8_t e = 7; e >= 1; e--) {
    883     for(int8_t m = 2; m >= 0; m--) {
    884       float point = (RADIOLIB_SX127X_CRYSTAL_FREQ * 1000000.0)/(((4 * m) + 16) * ((uint32_t)1 << (e + 2)));
    885       if(fabs(bandwidth - ((point / 1000.0) + 0.05)) <= 0.5) {
    886         return((m << 3) | e);
    887       }
    888     }
    889   }
    890   return 0;
    891 }
    892 
    893 int16_t SX127x::setRxBandwidth(float rxBw) {
    894   // check active modem
    895   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    896     return(RADIOLIB_ERR_WRONG_MODEM);
    897   }
    898 
    899   RADIOLIB_CHECK_RANGE(rxBw, 2.6, 250.0, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
    900 
    901   // set mode to STANDBY
    902   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    903   RADIOLIB_ASSERT(state);
    904 
    905   // set Rx bandwidth
    906   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_BW, calculateBWManExp(rxBw), 4, 0));
    907 }
    908 
    909 int16_t SX127x::setAFCBandwidth(float rxBw) {
    910   // check active modem
    911   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK){
    912       return(RADIOLIB_ERR_WRONG_MODEM);
    913   }
    914 
    915   RADIOLIB_CHECK_RANGE(rxBw, 2.6, 250.0, RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
    916 
    917   // set mode to STANDBY
    918   int16_t state = setMode(RADIOLIB_SX127X_STANDBY);
    919   RADIOLIB_ASSERT(state);
    920 
    921   // set AFC bandwidth
    922   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_AFC_BW, calculateBWManExp(rxBw), 4, 0));
    923 }
    924 
    925 int16_t SX127x::setAFC(bool isEnabled) {
    926   // check active modem
    927   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    928     return(RADIOLIB_ERR_WRONG_MODEM);
    929   }
    930 
    931   //set AFC auto on/off
    932   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_CONFIG, isEnabled ? RADIOLIB_SX127X_AFC_AUTO_ON : RADIOLIB_SX127X_AFC_AUTO_OFF, 4, 4));
    933 }
    934 
    935 int16_t SX127x::setAFCAGCTrigger(uint8_t trigger) {
    936   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    937     return(RADIOLIB_ERR_WRONG_MODEM);
    938   }
    939 
    940   //set AFC&AGC trigger
    941   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_CONFIG, trigger, 2, 0));
    942 }
    943 
    944 int16_t SX127x::setSyncWord(uint8_t* syncWord, size_t len) {
    945   // check active modem
    946   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    947     return(RADIOLIB_ERR_WRONG_MODEM);
    948   }
    949 
    950   RADIOLIB_CHECK_RANGE(len, 1, 8, RADIOLIB_ERR_INVALID_SYNC_WORD);
    951 
    952   // sync word must not contain value 0x00
    953   for(size_t i = 0; i < len; i++) {
    954     if(syncWord[i] == 0x00) {
    955       return(RADIOLIB_ERR_INVALID_SYNC_WORD);
    956     }
    957   }
    958 
    959   // enable sync word recognition
    960   int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYNC_CONFIG, RADIOLIB_SX127X_SYNC_ON, 4, 4);
    961   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYNC_CONFIG, len - 1, 2, 0);
    962   RADIOLIB_ASSERT(state);
    963 
    964   // set sync word
    965   _mod->SPIwriteRegisterBurst(RADIOLIB_SX127X_REG_SYNC_VALUE_1, syncWord, len);
    966   return(RADIOLIB_ERR_NONE);
    967 }
    968 
    969 int16_t SX127x::setNodeAddress(uint8_t nodeAddr) {
    970   // check active modem
    971   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    972     return(RADIOLIB_ERR_WRONG_MODEM);
    973   }
    974 
    975   // enable address filtering (node only)
    976   int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_ADDRESS_FILTERING_NODE, 2, 1);
    977   RADIOLIB_ASSERT(state);
    978 
    979   // set node address
    980   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_NODE_ADRS, nodeAddr));
    981 }
    982 
    983 int16_t SX127x::setBroadcastAddress(uint8_t broadAddr) {
    984   // check active modem
    985   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
    986     return(RADIOLIB_ERR_WRONG_MODEM);
    987   }
    988 
    989   // enable address filtering (node + broadcast)
    990   int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_ADDRESS_FILTERING_NODE_BROADCAST, 2, 1);
    991   RADIOLIB_ASSERT(state);
    992 
    993   // set broadcast address
    994   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BROADCAST_ADRS, broadAddr));
    995 }
    996 
    997 int16_t SX127x::disableAddressFiltering() {
    998   // check active modem
    999   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
   1000     return(RADIOLIB_ERR_WRONG_MODEM);
   1001   }
   1002 
   1003   // disable address filtering
   1004   int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_ADDRESS_FILTERING_OFF, 2, 1);
   1005   RADIOLIB_ASSERT(state);
   1006 
   1007   // set node address to default (0x00)
   1008   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_NODE_ADRS, 0x00);
   1009   RADIOLIB_ASSERT(state);
   1010 
   1011   // set broadcast address to default (0x00)
   1012   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BROADCAST_ADRS, 0x00));
   1013 }
   1014 
   1015 int16_t SX127x::setOokThresholdType(uint8_t type) {
   1016   // check active modem
   1017   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
   1018     return(RADIOLIB_ERR_WRONG_MODEM);
   1019   }
   1020   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_PEAK, type, 4, 3, 5));
   1021 }
   1022 
   1023 int16_t SX127x::setOokFixedOrFloorThreshold(uint8_t value) {
   1024   // check active modem
   1025   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
   1026     return(RADIOLIB_ERR_WRONG_MODEM);
   1027   }
   1028   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_FIX, value, 7, 0, 5));
   1029 }
   1030 
   1031 int16_t SX127x::setOokPeakThresholdDecrement(uint8_t value) {
   1032   // check active modem
   1033   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
   1034     return(RADIOLIB_ERR_WRONG_MODEM);
   1035   }
   1036   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_AVG, value, 7, 5, 5));
   1037 }
   1038 
   1039 int16_t SX127x::setOokPeakThresholdStep(uint8_t value) {
   1040   // check active modem
   1041   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
   1042     return(RADIOLIB_ERR_WRONG_MODEM);
   1043   }
   1044   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_PEAK, value, 2, 0, 5));
   1045 }
   1046 
   1047 int16_t SX127x::enableBitSync() {
   1048   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_PEAK, RADIOLIB_SX127X_BIT_SYNC_ON, 5, 5, 5));
   1049 }
   1050 
   1051 int16_t SX127x::disableBitSync() {
   1052   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_PEAK, RADIOLIB_SX127X_BIT_SYNC_OFF, 5, 5, 5));
   1053 }
   1054 
   1055 int16_t SX127x::setOOK(bool enableOOK) {
   1056   // check active modem
   1057   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
   1058     return(RADIOLIB_ERR_WRONG_MODEM);
   1059   }
   1060 
   1061   // set OOK and if successful, save the new setting
   1062   int16_t state = RADIOLIB_ERR_NONE;
   1063   if(enableOOK) {
   1064     state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX127X_MODULATION_OOK, 6, 5, 5);
   1065     state |= SX127x::setAFCAGCTrigger(RADIOLIB_SX127X_RX_TRIGGER_RSSI_INTERRUPT);
   1066   } else {
   1067     state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX127X_MODULATION_FSK, 6, 5, 5);
   1068     state |= SX127x::setAFCAGCTrigger(RADIOLIB_SX127X_RX_TRIGGER_BOTH);
   1069   }
   1070   if(state == RADIOLIB_ERR_NONE) {
   1071     _ook = enableOOK;
   1072   }
   1073 
   1074   return(state);
   1075 }
   1076 
   1077 int16_t SX127x::setFrequencyRaw(float newFreq) {
   1078   int16_t state = RADIOLIB_ERR_NONE;
   1079 
   1080   // set mode to standby if not FHSS
   1081   if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) == RADIOLIB_SX127X_HOP_PERIOD_OFF) {
   1082     state = setMode(RADIOLIB_SX127X_STANDBY);
   1083   }
   1084 
   1085   // calculate register values
   1086   uint32_t FRF = (newFreq * (uint32_t(1) << RADIOLIB_SX127X_DIV_EXPONENT)) / RADIOLIB_SX127X_CRYSTAL_FREQ;
   1087 
   1088   // write registers
   1089   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_MSB, (FRF & 0xFF0000) >> 16);
   1090   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_MID, (FRF & 0x00FF00) >> 8);
   1091   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_LSB, FRF & 0x0000FF);
   1092   return(state);
   1093 }
   1094 
   1095 size_t SX127x::getPacketLength(bool update) {
   1096   int16_t modem = getActiveModem();
   1097 
   1098   if(modem == RADIOLIB_SX127X_LORA) {
   1099     if(_sf != 6) {
   1100       // get packet length for SF7 - SF12
   1101       return(_mod->SPIreadRegister(RADIOLIB_SX127X_REG_RX_NB_BYTES));
   1102 
   1103     } else {
   1104       // return the cached value for SF6
   1105       return(_packetLength);
   1106     }
   1107 
   1108   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
   1109     // get packet length
   1110     if(!_packetLengthQueried && update) {
   1111       if (_packetLengthConfig == RADIOLIB_SX127X_PACKET_VARIABLE) {
   1112         _packetLength = _mod->SPIreadRegister(RADIOLIB_SX127X_REG_FIFO);
   1113       } else {
   1114         _packetLength = _mod->SPIreadRegister(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH_FSK);
   1115       }
   1116       _packetLengthQueried = true;
   1117     }
   1118   }
   1119 
   1120   return(_packetLength);
   1121 }
   1122 
   1123 int16_t SX127x::fixedPacketLengthMode(uint8_t len) {
   1124   return(SX127x::setPacketMode(RADIOLIB_SX127X_PACKET_FIXED, len));
   1125 }
   1126 
   1127 int16_t SX127x::variablePacketLengthMode(uint8_t maxLen) {
   1128   return(SX127x::setPacketMode(RADIOLIB_SX127X_PACKET_VARIABLE, maxLen));
   1129 }
   1130 
   1131 uint32_t SX127x::getTimeOnAir(size_t len) {
   1132   // check active modem
   1133   uint8_t modem = getActiveModem();
   1134   if (modem == RADIOLIB_SX127X_LORA) {
   1135     // Get symbol length in us
   1136     float symbolLength = (float) (uint32_t(1) << _sf) / (float) _bw;
   1137     // Get Low Data Rate optimization flag
   1138     float de = 0;
   1139     if (symbolLength >= 16.0) {
   1140       de = 1;
   1141     }
   1142     // Get explicit/implicit header enabled flag
   1143     float ih = (float) _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, 0, 0);
   1144     // Get CRC enabled flag
   1145     float crc = (float) (_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, 2, 2) >> 2);
   1146     // Get number of bits preamble
   1147     float n_pre = (float) ((_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB) << 8) | _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB));
   1148     // Get number of bits payload
   1149     float n_pay = 8.0 + max(ceil((8.0 * (float) len - 4.0 * (float) _sf + 28.0 + 16.0 * crc - 20.0 * ih) / (4.0 * (float) _sf - 8.0 * de)) * (float) _cr, 0.0);
   1150 
   1151     // Get time-on-air in us
   1152     return ceil(symbolLength * (n_pre + n_pay + 4.25)) * 1000;
   1153   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
   1154     // Get number of bits preamble
   1155     float n_pre = (float) ((_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB_FSK) << 8) | _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB_FSK)) * 8;
   1156     //Get the number of bits of the sync word
   1157     float n_syncWord = (float) (_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_SYNC_CONFIG, 2, 0) + 1) * 8;
   1158     //Get CRC bits
   1159     float crc = (_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, 4, 4) == RADIOLIB_SX127X_CRC_ON) * 16;
   1160 
   1161     if (_packetLengthConfig == RADIOLIB_SX127X_PACKET_FIXED) {
   1162       //If Packet size fixed -> len = fixed packet length
   1163       len = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH_FSK);
   1164     } else {
   1165       //if packet variable -> Add 1 extra byte for payload length
   1166       len += 1;
   1167     }
   1168 
   1169     // Calculate time-on-air in us {[(length in bytes) * (8 bits / 1 byte)] / [(Bit Rate in kbps) * (1000 bps / 1 kbps)]} * (1000000 us in 1 sec)
   1170     return (uint32_t) (((crc + n_syncWord + n_pre + (float) (len * 8)) / (_br * 1000.0)) * 1000000.0);
   1171   } else {
   1172     return(RADIOLIB_ERR_UNKNOWN);
   1173   }
   1174 
   1175 }
   1176 
   1177 int16_t SX127x::setCrcFiltering(bool crcOn) {
   1178   _crcOn = crcOn;
   1179 
   1180   if (crcOn == true) {
   1181     return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_CRC_ON, 4, 4));
   1182   } else {
   1183     return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_CRC_OFF, 4, 4));
   1184   }
   1185 }
   1186 
   1187 int16_t SX127x::setRSSIThreshold(float dbm) {
   1188   RADIOLIB_CHECK_RANGE(dbm, -127.5, 0, RADIOLIB_ERR_INVALID_RSSI_THRESHOLD);
   1189 
   1190   return _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_THRESH, (uint8_t)(-2.0 * dbm), 7, 0);
   1191 }
   1192 
   1193 int16_t SX127x::setRSSIConfig(uint8_t smoothingSamples, int8_t offset) {
   1194   // check active modem
   1195   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
   1196     return(RADIOLIB_ERR_WRONG_MODEM);
   1197   }
   1198 
   1199   // set mode to standby
   1200   int16_t state = standby();
   1201   RADIOLIB_ASSERT(state);
   1202 
   1203   // check provided values
   1204   if(!(smoothingSamples <= 7)) {
   1205     return(RADIOLIB_ERR_INVALID_NUM_SAMPLES);
   1206   }
   1207 
   1208   RADIOLIB_CHECK_RANGE(offset, -16, 15, RADIOLIB_ERR_INVALID_RSSI_OFFSET);
   1209 
   1210   // set new register values
   1211   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_CONFIG, offset << 3, 7, 3);
   1212   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_CONFIG, smoothingSamples, 2, 0);
   1213   return(state);
   1214 }
   1215 
   1216 int16_t SX127x::setEncoding(uint8_t encoding) {
   1217   // check active modem
   1218   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
   1219     return(RADIOLIB_ERR_WRONG_MODEM);
   1220   }
   1221 
   1222   // set encoding
   1223   switch(encoding) {
   1224     case RADIOLIB_ENCODING_NRZ:
   1225       return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_DC_FREE_NONE, 6, 5));
   1226     case RADIOLIB_ENCODING_MANCHESTER:
   1227       return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_DC_FREE_MANCHESTER, 6, 5));
   1228     case RADIOLIB_ENCODING_WHITENING:
   1229       return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_DC_FREE_WHITENING, 6, 5));
   1230     default:
   1231       return(RADIOLIB_ERR_INVALID_ENCODING);
   1232   }
   1233 }
   1234 
   1235 uint16_t SX127x::getIRQFlags() {
   1236   // check active modem
   1237   if(getActiveModem() == RADIOLIB_SX127X_LORA) {
   1238     // LoRa, just 8-bit value
   1239     return((uint16_t)_mod->SPIreadRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS));
   1240 
   1241   } else {
   1242     // FSK, the IRQ flags are 16 bits in total
   1243     uint16_t flags = ((uint16_t)_mod->SPIreadRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2)) << 8;
   1244     flags |= (uint16_t)_mod->SPIreadRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_1);
   1245     return(flags);
   1246   }
   1247 
   1248 }
   1249 
   1250 uint8_t SX127x::getModemStatus() {
   1251   // check active modem
   1252   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
   1253     return(0x00);
   1254   }
   1255 
   1256   // read the register
   1257   return(_mod->SPIreadRegister(RADIOLIB_SX127X_REG_MODEM_STAT));
   1258 }
   1259 
   1260 void SX127x::setRfSwitchPins(RADIOLIB_PIN_TYPE rxEn, RADIOLIB_PIN_TYPE txEn) {
   1261   _mod->setRfSwitchPins(rxEn, txEn);
   1262 }
   1263 
   1264 uint8_t SX127x::randomByte() {
   1265   // check active modem
   1266   uint8_t rssiValueReg = RADIOLIB_SX127X_REG_RSSI_WIDEBAND;
   1267   if(getActiveModem() == RADIOLIB_SX127X_FSK_OOK) {
   1268     rssiValueReg = RADIOLIB_SX127X_REG_RSSI_VALUE_FSK;
   1269   }
   1270 
   1271   // set mode to Rx
   1272   setMode(RADIOLIB_SX127X_RX);
   1273 
   1274   // wait a bit for the RSSI reading to stabilise
   1275   _mod->delay(10);
   1276 
   1277   // read RSSI value 8 times, always keep just the least significant bit
   1278   uint8_t randByte = 0x00;
   1279   for(uint8_t i = 0; i < 8; i++) {
   1280     randByte |= ((_mod->SPIreadRegister(rssiValueReg) & 0x01) << i);
   1281   }
   1282 
   1283   // set mode to standby
   1284   setMode(RADIOLIB_SX127X_STANDBY);
   1285 
   1286   return(randByte);
   1287 }
   1288 
   1289 int16_t SX127x::getChipVersion() {
   1290   return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_VERSION));
   1291 }
   1292 
   1293 int8_t SX127x::getTempRaw() {
   1294   int8_t temp = 0;
   1295   uint8_t previousOpMode;
   1296   uint8_t ival;
   1297 
   1298   // save current Op Mode
   1299   previousOpMode = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_OP_MODE);
   1300 
   1301   // check if we need to step out of LoRa mode first
   1302   if ((previousOpMode & RADIOLIB_SX127X_LORA) == RADIOLIB_SX127X_LORA) {
   1303     _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_LORA | RADIOLIB_SX127X_SLEEP));
   1304   }
   1305 
   1306   // put device in FSK sleep
   1307   _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_FSK_OOK | RADIOLIB_SX127X_SLEEP));
   1308 
   1309   // put device in FSK RxSynth
   1310   _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_FSK_OOK | RADIOLIB_SX127X_FSRX));
   1311 
   1312   // enable temperature reading
   1313   _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_IMAGE_CAL, RADIOLIB_SX127X_TEMP_MONITOR_ON, 0, 0);
   1314 
   1315   // wait
   1316   _mod->delayMicroseconds(200);
   1317 
   1318   // disable temperature reading
   1319   _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_IMAGE_CAL, RADIOLIB_SX127X_TEMP_MONITOR_OFF, 0, 0);
   1320 
   1321   // put device in FSK sleep
   1322   _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_FSK_OOK | RADIOLIB_SX127X_SLEEP));
   1323 
   1324   // read temperature
   1325   ival = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_TEMP);
   1326 
   1327   // convert very raw value
   1328   if ((ival & 0x80) == 0x80) {
   1329     temp = 255 - ival;
   1330   } else {
   1331     temp = -1 * ival;
   1332   }
   1333 
   1334   // check if we need to step back into LoRa mode
   1335   if ((previousOpMode & RADIOLIB_SX127X_LORA) == RADIOLIB_SX127X_LORA) {
   1336     _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_LORA | RADIOLIB_SX127X_SLEEP));
   1337   }
   1338 
   1339   // reload previous Op Mode
   1340   _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, previousOpMode);
   1341 
   1342   return(temp);
   1343 }
   1344 
   1345 int16_t SX127x::config() {
   1346   // turn off frequency hopping
   1347   int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, RADIOLIB_SX127X_HOP_PERIOD_OFF);
   1348   return(state);
   1349 }
   1350 
   1351 int16_t SX127x::configFSK() {
   1352   // set RSSI threshold
   1353   int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_THRESH, RADIOLIB_SX127X_RSSI_THRESHOLD);
   1354   RADIOLIB_ASSERT(state);
   1355 
   1356   // reset FIFO flag
   1357   _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2, RADIOLIB_SX127X_FLAG_FIFO_OVERRUN);
   1358 
   1359   // set packet configuration
   1360   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_PACKET_VARIABLE | RADIOLIB_SX127X_DC_FREE_NONE | RADIOLIB_SX127X_CRC_ON | RADIOLIB_SX127X_CRC_AUTOCLEAR_ON | RADIOLIB_SX127X_ADDRESS_FILTERING_OFF | RADIOLIB_SX127X_CRC_WHITENING_TYPE_CCITT, 7, 0);
   1361   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_2, RADIOLIB_SX127X_DATA_MODE_PACKET | RADIOLIB_SX127X_IO_HOME_OFF, 6, 5);
   1362   RADIOLIB_ASSERT(state);
   1363 
   1364   // set preamble polarity
   1365   state =_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYNC_CONFIG, RADIOLIB_SX127X_PREAMBLE_POLARITY_55, 5, 5);
   1366   RADIOLIB_ASSERT(state);
   1367 
   1368   // set FIFO threshold
   1369   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_TX_START_FIFO_NOT_EMPTY, 7, 7);
   1370   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_FIFO_THRESH, 5, 0);
   1371   RADIOLIB_ASSERT(state);
   1372 
   1373   // disable Rx timeouts
   1374   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_TIMEOUT_1, RADIOLIB_SX127X_TIMEOUT_RX_RSSI_OFF);
   1375   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_TIMEOUT_2, RADIOLIB_SX127X_TIMEOUT_RX_PREAMBLE_OFF);
   1376   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_TIMEOUT_3, RADIOLIB_SX127X_TIMEOUT_SIGNAL_SYNC_OFF);
   1377   RADIOLIB_ASSERT(state);
   1378 
   1379   // enable preamble detector
   1380   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_DETECT, RADIOLIB_SX127X_PREAMBLE_DETECTOR_ON | RADIOLIB_SX127X_PREAMBLE_DETECTOR_2_BYTE | RADIOLIB_SX127X_PREAMBLE_DETECTOR_TOL);
   1381 
   1382   return(state);
   1383 }
   1384 
   1385 int16_t SX127x::setPacketMode(uint8_t mode, uint8_t len) {
   1386   // check packet length
   1387   if (len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK) {
   1388     return(RADIOLIB_ERR_PACKET_TOO_LONG);
   1389   }
   1390 
   1391   // check active modem
   1392   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
   1393     return(RADIOLIB_ERR_WRONG_MODEM);
   1394   }
   1395 
   1396   // set to fixed packet length
   1397   int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, mode, 7, 7);
   1398   RADIOLIB_ASSERT(state);
   1399 
   1400   // set length to register
   1401   state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH_FSK, len);
   1402   RADIOLIB_ASSERT(state);
   1403 
   1404   // update cached value
   1405   _packetLengthConfig = mode;
   1406   return(state);
   1407 }
   1408 
   1409 bool SX127x::findChip(uint8_t ver) {
   1410   uint8_t i = 0;
   1411   bool flagFound = false;
   1412   while((i < 10) && !flagFound) {
   1413     // reset the module
   1414     reset();
   1415 
   1416     // check version register
   1417     int16_t version = getChipVersion();
   1418     if(version == ver) {
   1419       flagFound = true;
   1420     } else {
   1421       #if defined(RADIOLIB_DEBUG)
   1422         RADIOLIB_DEBUG_PRINT(F("SX127x not found! ("));
   1423         RADIOLIB_DEBUG_PRINT(i + 1);
   1424         RADIOLIB_DEBUG_PRINT(F(" of 10 tries) RADIOLIB_SX127X_REG_VERSION == "));
   1425 
   1426         char buffHex[12];
   1427         sprintf(buffHex, "0x%04X", version);
   1428         RADIOLIB_DEBUG_PRINT(buffHex);
   1429         RADIOLIB_DEBUG_PRINT(F(", expected 0x00"));
   1430         RADIOLIB_DEBUG_PRINTLN(ver, HEX);
   1431       #endif
   1432       _mod->delay(10);
   1433       i++;
   1434     }
   1435   }
   1436 
   1437   return(flagFound);
   1438 }
   1439 
   1440 int16_t SX127x::setMode(uint8_t mode) {
   1441   uint8_t checkMask = 0xFF;
   1442   if((getActiveModem() == RADIOLIB_SX127X_FSK_OOK) && (mode == RADIOLIB_SX127X_RX)) {
   1443     // disable checking of RX bit in FSK RX mode, as it sometimes seem to fail (#276)
   1444     checkMask = 0xFE;
   1445   }
   1446   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, mode, 2, 0, 5, checkMask));
   1447 }
   1448 
   1449 int16_t SX127x::getActiveModem() {
   1450   return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_OP_MODE, 7, 7));
   1451 }
   1452 
   1453 int16_t SX127x::setActiveModem(uint8_t modem) {
   1454   // set mode to SLEEP
   1455   int16_t state = setMode(RADIOLIB_SX127X_SLEEP);
   1456 
   1457   // set modem
   1458   state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, modem, 7, 7, 5);
   1459 
   1460   // set mode to STANDBY
   1461   state |= setMode(RADIOLIB_SX127X_STANDBY);
   1462   return(state);
   1463 }
   1464 
   1465 void SX127x::clearIRQFlags() {
   1466   int16_t modem = getActiveModem();
   1467   if(modem == RADIOLIB_SX127X_LORA) {
   1468     _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, 0b11111111);
   1469   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
   1470     _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_1, 0b11111111);
   1471     _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2, 0b11111111);
   1472   }
   1473 }
   1474 
   1475 void SX127x::clearFIFO(size_t count) {
   1476   while(count) {
   1477     _mod->SPIreadRegister(RADIOLIB_SX127X_REG_FIFO);
   1478     count--;
   1479   }
   1480 }
   1481 
   1482 int16_t SX127x::invertIQ(bool invertIQ) {
   1483   // check active modem
   1484   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
   1485     return(RADIOLIB_ERR_WRONG_MODEM);
   1486   }
   1487 
   1488   int16_t state;
   1489   if(invertIQ) {
   1490     state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ, RADIOLIB_SX127X_INVERT_IQ_RXPATH_ON, 6, 6);
   1491     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ, RADIOLIB_SX127X_INVERT_IQ_TXPATH_ON, 0, 0);
   1492     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ2, RADIOLIB_SX127X_IQ2_ENABLE);
   1493   } else {
   1494     state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ, RADIOLIB_SX127X_INVERT_IQ_RXPATH_OFF, 6, 6);
   1495     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ, RADIOLIB_SX127X_INVERT_IQ_TXPATH_OFF, 0, 0);
   1496     state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ2, RADIOLIB_SX127X_IQ2_DISABLE);
   1497   }
   1498 
   1499   return(state);
   1500 }
   1501 
   1502 #if !defined(RADIOLIB_EXCLUDE_DIRECT_RECEIVE)
   1503 void SX127x::setDirectAction(void (*func)(void)) {
   1504   setDio1Action(func);
   1505 }
   1506 
   1507 void SX127x::readBit(RADIOLIB_PIN_TYPE pin) {
   1508   updateDirectBuffer((uint8_t)digitalRead(pin));
   1509 }
   1510 #endif
   1511 
   1512 int16_t SX127x::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) {
   1513   return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod));
   1514 }
   1515 
   1516 uint8_t SX127x::getFHSSHoppingPeriod(void) {
   1517   return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD));
   1518 }
   1519 
   1520 uint8_t SX127x::getFHSSChannel(void) {
   1521   return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0));
   1522 }
   1523 
   1524 void SX127x::clearFHSSInt(void) {
   1525   int16_t modem = getActiveModem();
   1526   if(modem == RADIOLIB_SX127X_LORA) {
   1527     _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL);
   1528   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
   1529     return; //These are not the interrupts you are looking for
   1530   }
   1531 }
   1532 
   1533 int16_t SX127x::setDIOMapping(RADIOLIB_PIN_TYPE pin, uint8_t value) {
   1534   if (pin > 5)
   1535     return RADIOLIB_ERR_INVALID_DIO_PIN;
   1536 
   1537   if (pin < 4)
   1538     return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, value, 7 - 2 * pin, 6 - 2 * pin));
   1539   else
   1540     return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_2, value, 15 - 2 * pin, 14 - 2 * pin));
   1541 }
   1542 
   1543 int16_t SX127x::setDIOPreambleDetect(bool usePreambleDetect) {
   1544   return _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_2, (usePreambleDetect) ? RADIOLIB_SX127X_DIO_MAP_PREAMBLE_DETECT : RADIOLIB_SX127X_DIO_MAP_RSSI, 0, 0);
   1545 }
   1546 
   1547 #endif