LCOV - code coverage report
Current view: top level - src/modules/SX126x - SX126x_config.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 43 471 9.1 %
Date: 2026-04-20 19:58:46 Functions: 11 45 24.4 %

          Line data    Source code
       1             : #include "SX126x.h"
       2             : 
       3             : #include <math.h>
       4             : #include <string.h>
       5             : 
       6             : // this file contains all configuration methods
       7             : // of the SX126x, which let user control the
       8             : // modulation properties, packet configuration etc.
       9             : 
      10             : #if !RADIOLIB_EXCLUDE_SX126X
      11             : 
      12           0 : void SX126x::setDio1Action(void (*func)(void)) {
      13           0 :   this->mod->hal->attachInterrupt(this->mod->hal->pinToInterrupt(this->mod->getIrq()), func, this->mod->hal->GpioInterruptRising);
      14           0 : }
      15             : 
      16           0 : void SX126x::clearDio1Action() {
      17           0 :   this->mod->hal->detachInterrupt(this->mod->hal->pinToInterrupt(this->mod->getIrq()));
      18           0 : }
      19             : 
      20           0 : void SX126x::setPacketReceivedAction(void (*func)(void)) {
      21           0 :   this->setDio1Action(func);
      22           0 : }
      23             : 
      24           0 : void SX126x::clearPacketReceivedAction() {
      25           0 :   this->clearDio1Action();
      26           0 : }
      27             : 
      28           0 : void SX126x::setPacketSentAction(void (*func)(void)) {
      29           0 :   this->setDio1Action(func);
      30           0 : }
      31             : 
      32           0 : void SX126x::clearPacketSentAction() {
      33           0 :   this->clearDio1Action();
      34           0 : }
      35             : 
      36           0 : void SX126x::setChannelScanAction(void (*func)(void)) {
      37           0 :   this->setDio1Action(func);
      38           0 : }
      39             : 
      40           0 : void SX126x::clearChannelScanAction() {
      41           0 :   this->clearDio1Action();
      42           0 : }
      43             : 
      44           0 : int16_t SX126x::setBandwidth(float bw) {
      45             :   // check active modem
      46           0 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
      47           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
      48             :   }
      49             : 
      50             :   // ensure byte conversion doesn't overflow
      51           0 :   RADIOLIB_CHECK_RANGE(bw, 0.0f, 510.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
      52             : 
      53             :   // check allowed bandwidth values
      54           0 :   uint8_t bw_div2 = bw / 2 + 0.01f;
      55           0 :   switch (bw_div2)  {
      56           0 :     case 3: // 7.8:
      57           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_7_8;
      58           0 :       break;
      59           0 :     case 5: // 10.4:
      60           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_10_4;
      61           0 :       break;
      62           0 :     case 7: // 15.6:
      63           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_15_6;
      64           0 :       break;
      65           0 :     case 10: // 20.8:
      66           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_20_8;
      67           0 :       break;
      68           0 :     case 15: // 31.25:
      69           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_31_25;
      70           0 :       break;
      71           0 :     case 20: // 41.7:
      72           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_41_7;
      73           0 :       break;
      74           0 :     case 31: // 62.5:
      75           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_62_5;
      76           0 :       break;
      77           0 :     case 62: // 125.0:
      78           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_125_0;
      79           0 :       break;
      80           0 :     case 125: // 250.0
      81           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_250_0;
      82           0 :       break;
      83           0 :     case 250: // 500.0
      84           0 :       this->bandwidth = RADIOLIB_SX126X_LORA_BW_500_0;
      85           0 :       break;
      86           0 :     default:
      87           0 :       return(RADIOLIB_ERR_INVALID_BANDWIDTH);
      88             :   }
      89             : 
      90             :   // update modulation parameters
      91           0 :   this->bandwidthKhz = bw;
      92           0 :   return(setModulationParams(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
      93             : }
      94             : 
      95           0 : int16_t SX126x::setSpreadingFactor(uint8_t sf) {
      96             :   // check active modem
      97           0 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
      98           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
      99             :   }
     100             : 
     101           0 :   RADIOLIB_CHECK_RANGE(sf, 5, 12, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
     102             : 
     103             :   // update modulation parameters
     104           0 :   this->spreadingFactor = sf;
     105           0 :   return(setModulationParams(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
     106             : }
     107             : 
     108           0 : int16_t SX126x::setCodingRate(uint8_t cr, bool longInterleave) {
     109             :   // check active modem
     110           0 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
     111           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     112             :   }
     113             : 
     114           0 :   RADIOLIB_CHECK_RANGE(cr, 4, 8, RADIOLIB_ERR_INVALID_CODING_RATE);
     115             : 
     116           0 :   if(longInterleave) {
     117           0 :     switch(cr) {
     118           0 :       case 4:
     119           0 :         this->codingRate = 0;
     120           0 :         break;
     121           0 :       case 5:
     122             :       case 6:
     123           0 :         this->codingRate = cr;
     124           0 :         break;
     125           0 :       case 8: 
     126           0 :         this->codingRate = cr - 1;
     127           0 :         break;
     128           0 :       default:
     129           0 :         return(RADIOLIB_ERR_INVALID_CODING_RATE);
     130             :     }
     131             :   } else {
     132           0 :     this->codingRate = cr - 4;
     133             :   }
     134             : 
     135             :   // update modulation parameters
     136           0 :   return(setModulationParams(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
     137             : }
     138             : 
     139           0 : int16_t SX126x::setSyncWord(uint8_t syncWord, uint8_t controlBits) {
     140             :   // check active modem
     141           0 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
     142           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     143             :   }
     144             : 
     145             :   // update register
     146           0 :   const uint8_t data[2] = {(uint8_t)((syncWord & 0xF0) | ((controlBits & 0xF0) >> 4)), (uint8_t)(((syncWord & 0x0F) << 4) | (controlBits & 0x0F))};
     147           0 :   return(writeRegister(RADIOLIB_SX126X_REG_LORA_SYNC_WORD_MSB, data, 2));
     148             : }
     149             : 
     150           0 : int16_t SX126x::setCurrentLimit(float currentLimit) {
     151             :   // check allowed range
     152           0 :   if(!((currentLimit >= 0) && (currentLimit <= 140))) {
     153           0 :     return(RADIOLIB_ERR_INVALID_CURRENT_LIMIT);
     154             :   }
     155             : 
     156             :   // calculate raw value
     157           0 :   uint8_t rawLimit = (uint8_t)(currentLimit / 2.5f);
     158             : 
     159             :   // update register
     160           0 :   return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &rawLimit, 1));
     161             : }
     162             : 
     163           0 : float SX126x::getCurrentLimit() {
     164             :   // get the raw value
     165           0 :   uint8_t ocp = 0;
     166           0 :   readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
     167             : 
     168             :   // return the actual value
     169           0 :   return((float)ocp * 2.5f);
     170             : }
     171             : 
     172           3 : int16_t SX126x::setPreambleLength(size_t preambleLength) {
     173           3 :   uint8_t modem = getPacketType();
     174           3 :   if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
     175           0 :     this->preambleLengthLoRa = preambleLength;
     176           0 :     return(setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, this->implicitLen, this->headerType, this->invertIQEnabled));
     177           3 :   } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
     178           0 :     this->preambleLengthFSK = preambleLength;
     179             :     // maximum preamble detector length is limited by sync word length
     180             :     // for details, see the note in SX1261 datasheet, Rev 2.1, section 6.2.2.1, page 45
     181           0 :     uint8_t maxDetLen = RADIOLIB_MIN(this->syncWordLength, this->preambleLengthFSK);
     182           0 :     this->preambleDetLength = maxDetLen >= 32 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_32 :
     183             :                               maxDetLen >= 24 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_24 :
     184             :                               maxDetLen >= 16 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_16 :
     185             :                               maxDetLen >   0 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_8 :
     186             :                               RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_OFF;
     187           0 :     return(setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening,
     188           0 :       this->packetType, (this->packetType == RADIOLIB_SX126X_GFSK_PACKET_FIXED) ? this->implicitLen : RADIOLIB_SX126X_MAX_PACKET_LENGTH));
     189             :   }
     190             : 
     191           3 :   return(RADIOLIB_ERR_UNKNOWN);
     192             : }
     193             : 
     194           3 : int16_t SX126x::setFrequencyDeviation(float freqDev) {
     195             :   // check active modem
     196           3 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
     197           3 :     return(RADIOLIB_ERR_WRONG_MODEM);
     198             :   }
     199             : 
     200             :   // set frequency deviation to lowest available setting (required for digimodes)
     201           0 :   float newFreqDev = freqDev;
     202           0 :   if(freqDev < 0.0f) {
     203           0 :     newFreqDev = 0.6f;
     204             :   }
     205             : 
     206           0 :   RADIOLIB_CHECK_RANGE(newFreqDev, 0.6f, 200.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
     207             : 
     208             :   // calculate raw frequency deviation value
     209           0 :   uint32_t freqDevRaw = (uint32_t)(((newFreqDev * 1000.0f) * (float)((uint32_t)(1) << 25)) / (RADIOLIB_SX126X_CRYSTAL_FREQ * 1000000.0f));
     210             : 
     211             :   // check modulation parameters
     212           0 :   this->frequencyDev = freqDevRaw;
     213             : 
     214             :   // update modulation parameters
     215           0 :   return(setModulationParamsFSK(this->bitRate, this->pulseShape, this->rxBandwidth, this->frequencyDev));
     216             : }
     217             : 
     218           3 : int16_t SX126x::setBitRate(float br) {
     219             :   // check active modem
     220           3 :   uint8_t modem = getPacketType();
     221           3 :   if((modem != RADIOLIB_SX126X_PACKET_TYPE_GFSK) &&
     222           3 :      (modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) &&
     223             :      (modem != RADIOLIB_SX126X_PACKET_TYPE_BPSK)) {
     224           3 :     return(RADIOLIB_ERR_WRONG_MODEM);
     225             :   }
     226             : 
     227           0 :   if(modem == RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
     228             :     // at the moment only the very specific 488.28125 bps rate is supported
     229           0 :     RADIOLIB_CHECK_RANGE(br, 0.488f, 0.489f, RADIOLIB_ERR_INVALID_BIT_RATE);
     230           0 :   } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_BPSK) {
     231             :     // this should be just either 100 or 600 bps, not the range
     232             :     // but the BPSK support is so experimental it probably does not matter
     233           0 :     RADIOLIB_CHECK_RANGE(br, 0.1f, 0.6f, RADIOLIB_ERR_INVALID_BIT_RATE);
     234             :   }
     235             : 
     236             :   // calculate raw bit rate value
     237           0 :   uint32_t brRaw = (uint32_t)((RADIOLIB_SX126X_CRYSTAL_FREQ * 1000000.0f * 32.0f) / (br * 1000.0f));
     238             : 
     239             :   // check modulation parameters
     240           0 :   this->bitRate = brRaw;
     241             : 
     242             :   // update modulation parameters
     243           0 :   int16_t state = RADIOLIB_ERR_UNKNOWN;
     244           0 :   if(modem == RADIOLIB_SX126X_PACKET_TYPE_BPSK) {
     245           0 :     state = setModulationParamsBPSK(this->bitRate);
     246             :   } else {
     247           0 :     state = setModulationParamsFSK(this->bitRate, this->pulseShape, this->rxBandwidth, this->frequencyDev);
     248             :   }
     249           0 :   RADIOLIB_ASSERT(state);
     250             : 
     251             :   // apply workaround or reset it, as needed
     252           0 :   return(fixGFSK());
     253             : }
     254             : 
     255           3 : int16_t SX126x::setDataRate(DataRate_t dr, ModemType_t modem) {
     256             :   // get the current modem
     257             :   ModemType_t currentModem;
     258           3 :   int16_t state = this->getModem(&currentModem);
     259           3 :   RADIOLIB_ASSERT(state);
     260             : 
     261             :   // switch over if the requested modem is different
     262           0 :   if(modem != RADIOLIB_MODEM_NONE && modem != currentModem) {
     263           0 :     state = this->standby();
     264           0 :     RADIOLIB_ASSERT(state);
     265           0 :     state = this->setModem(modem);
     266           0 :     RADIOLIB_ASSERT(state);
     267             :   }
     268             :   
     269           0 :   if(modem == RADIOLIB_MODEM_NONE) {
     270           0 :     modem = currentModem;
     271             :   }
     272             : 
     273             :   // select interpretation based on modem
     274           0 :   if(modem == RADIOLIB_MODEM_FSK) {
     275             :     // set the bit rate
     276           0 :     state = this->setBitRate(dr.fsk.bitRate);
     277           0 :     RADIOLIB_ASSERT(state);
     278             : 
     279             :     // set the frequency deviation
     280           0 :     state = this->setFrequencyDeviation(dr.fsk.freqDev);
     281             : 
     282           0 :   } else if(modem == RADIOLIB_MODEM_LORA) {
     283             :     // set the spreading factor
     284           0 :     state = this->setSpreadingFactor(dr.lora.spreadingFactor);
     285           0 :     RADIOLIB_ASSERT(state);
     286             : 
     287             :     // set the bandwidth
     288           0 :     state = this->setBandwidth(dr.lora.bandwidth);
     289           0 :     RADIOLIB_ASSERT(state);
     290             : 
     291             :     // set the coding rate
     292           0 :     state = this->setCodingRate(dr.lora.codingRate);
     293             :   
     294           0 :   } else if(modem == RADIOLIB_MODEM_LRFHSS) {
     295             :     // set the basic config
     296           0 :     state = this->setLrFhssConfig(dr.lrFhss.bw, dr.lrFhss.cr);
     297           0 :     RADIOLIB_ASSERT(state);
     298             : 
     299             :     // set hopping grid
     300           0 :     this->lrFhssGridNonFcc = dr.lrFhss.narrowGrid ? RADIOLIB_SX126X_LR_FHSS_GRID_STEP_NON_FCC : RADIOLIB_SX126X_LR_FHSS_GRID_STEP_FCC;
     301             : 
     302             :   }
     303             : 
     304           0 :   return(state);
     305             : }
     306             : 
     307             : 
     308           3 : int16_t SX126x::checkDataRate(DataRate_t dr, ModemType_t modem) {
     309           3 :   int16_t state = RADIOLIB_ERR_UNKNOWN;
     310             : 
     311             :   // retrieve modem if not supplied
     312           3 :   if(modem == RADIOLIB_MODEM_NONE) {
     313           3 :     state = this->getModem(&modem);
     314           3 :     RADIOLIB_ASSERT(state);
     315             :   }
     316             : 
     317             :   // select interpretation based on modem
     318           0 :   if(modem == RADIOLIB_MODEM_FSK) {
     319           0 :     RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 0.6f, 300.0f, RADIOLIB_ERR_INVALID_BIT_RATE);
     320           0 :     RADIOLIB_CHECK_RANGE(dr.fsk.freqDev, 0.6f, 200.0f, RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
     321           0 :     return(RADIOLIB_ERR_NONE);
     322             : 
     323           0 :   } else if(modem == RADIOLIB_MODEM_LORA) {
     324           0 :     RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 5, 12, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
     325           0 :     RADIOLIB_CHECK_RANGE(dr.lora.bandwidth, 0.0f, 510.0f, RADIOLIB_ERR_INVALID_BANDWIDTH);
     326           0 :     RADIOLIB_CHECK_RANGE(dr.lora.codingRate, 4, 8, RADIOLIB_ERR_INVALID_CODING_RATE);
     327           0 :     return(RADIOLIB_ERR_NONE);
     328             :   
     329             :   }
     330             : 
     331           0 :   return(state);
     332             : }
     333             : 
     334           0 : int16_t SX126x::setRxBandwidth(float rxBw) {
     335             :   // check active modem
     336           0 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
     337           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     338             :   }
     339             : 
     340             :   // check modulation parameters
     341             :   /*if(2 * this->frequencyDev + this->bitRate > rxBw * 1000.0) {
     342             :     return(RADIOLIB_ERR_INVALID_MODULATION_PARAMETERS);
     343             :   }*/
     344           0 :   this->rxBandwidthKhz = rxBw;
     345             : 
     346             :   // check allowed receiver bandwidth values
     347           0 :   if(fabsf(rxBw - 4.8f) <= 0.001f) {
     348           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_4_8;
     349           0 :   } else if(fabsf(rxBw - 5.8f) <= 0.001f) {
     350           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_5_8;
     351           0 :   } else if(fabsf(rxBw - 7.3f) <= 0.001f) {
     352           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_7_3;
     353           0 :   } else if(fabsf(rxBw - 9.7f) <= 0.001f) {
     354           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_9_7;
     355           0 :   } else if(fabsf(rxBw - 11.7f) <= 0.001f) {
     356           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_11_7;
     357           0 :   } else if(fabsf(rxBw - 14.6f) <= 0.001f) {
     358           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_14_6;
     359           0 :   } else if(fabsf(rxBw - 19.5f) <= 0.001f) {
     360           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_19_5;
     361           0 :   } else if(fabsf(rxBw - 23.4f) <= 0.001f) {
     362           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_23_4;
     363           0 :   } else if(fabsf(rxBw - 29.3f) <= 0.001f) {
     364           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_29_3;
     365           0 :   } else if(fabsf(rxBw - 39.0f) <= 0.001f) {
     366           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_39_0;
     367           0 :   } else if(fabsf(rxBw - 46.9f) <= 0.001f) {
     368           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_46_9;
     369           0 :   } else if(fabsf(rxBw - 58.6f) <= 0.001f) {
     370           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_58_6;
     371           0 :   } else if(fabsf(rxBw - 78.2f) <= 0.001f) {
     372           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_78_2;
     373           0 :   } else if(fabsf(rxBw - 93.8f) <= 0.001f) {
     374           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_93_8;
     375           0 :   } else if(fabsf(rxBw - 117.3f) <= 0.001f) {
     376           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_117_3;
     377           0 :   } else if(fabsf(rxBw - 156.2f) <= 0.001f) {
     378           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_156_2;
     379           0 :   } else if(fabsf(rxBw - 187.2f) <= 0.001f) {
     380           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_187_2;
     381           0 :   } else if(fabsf(rxBw - 234.3f) <= 0.001f) {
     382           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_234_3;
     383           0 :   } else if(fabsf(rxBw - 312.0f) <= 0.001f) {
     384           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_312_0;
     385           0 :   } else if(fabsf(rxBw - 373.6f) <= 0.001f) {
     386           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_373_6;
     387           0 :   } else if(fabsf(rxBw - 467.0f) <= 0.001f) {
     388           0 :     this->rxBandwidth = RADIOLIB_SX126X_GFSK_RX_BW_467_0;
     389             :   } else {
     390           0 :     return(RADIOLIB_ERR_INVALID_RX_BANDWIDTH);
     391             :   }
     392             : 
     393             :   // update modulation parameters
     394           0 :   return(setModulationParamsFSK(this->bitRate, this->pulseShape, this->rxBandwidth, this->frequencyDev));
     395             : }
     396             : 
     397           0 : int16_t SX126x::setRxBoostedGainMode(bool rxbgm, bool persist) {
     398           0 :   this->rxBoostedGainMode = rxbgm;
     399             : 
     400             :   // update RX gain setting register
     401           0 :   uint8_t rxGain = rxbgm ? RADIOLIB_SX126X_RX_GAIN_BOOSTED : RADIOLIB_SX126X_RX_GAIN_POWER_SAVING;
     402           0 :   int16_t state = writeRegister(RADIOLIB_SX126X_REG_RX_GAIN, &rxGain, 1);
     403           0 :   RADIOLIB_ASSERT(state);
     404             : 
     405             :   // add Rx Gain register to retention memory if requested
     406           0 :   if(persist) {
     407             :     // values and registers below are specified in SX126x datasheet v2.1 section 9.6, just below table 9-3
     408           0 :     const uint8_t data[] = { 0x01, (uint8_t)((RADIOLIB_SX126X_REG_RX_GAIN >> 8) & 0xFF), (uint8_t)(RADIOLIB_SX126X_REG_RX_GAIN & 0xFF) };
     409           0 :     state = writeRegister(RADIOLIB_SX126X_REG_RX_GAIN_RETENTION_0, data, 3);
     410             :   }
     411             : 
     412           0 :   return(state);
     413             : }
     414             : 
     415           3 : int16_t SX126x::setDataShaping(uint8_t sh) {
     416             :   // check active modem
     417           3 :   uint8_t modem = getPacketType();
     418           3 :   if((modem != RADIOLIB_SX126X_PACKET_TYPE_GFSK) && (modem != RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS)) {
     419           3 :     return(RADIOLIB_ERR_WRONG_MODEM);
     420             :   }
     421             : 
     422             :   // set data shaping
     423           0 :   switch(sh) {
     424           0 :     case RADIOLIB_SHAPING_NONE:
     425           0 :       this->pulseShape = RADIOLIB_SX126X_GFSK_FILTER_NONE;
     426           0 :       break;
     427           0 :     case RADIOLIB_SHAPING_0_3:
     428           0 :       this->pulseShape = RADIOLIB_SX126X_GFSK_FILTER_GAUSS_0_3;
     429           0 :       break;
     430           0 :     case RADIOLIB_SHAPING_0_5:
     431           0 :       this->pulseShape = RADIOLIB_SX126X_GFSK_FILTER_GAUSS_0_5;
     432           0 :       break;
     433           0 :     case RADIOLIB_SHAPING_0_7:
     434           0 :       this->pulseShape = RADIOLIB_SX126X_GFSK_FILTER_GAUSS_0_7;
     435           0 :       break;
     436           0 :     case RADIOLIB_SHAPING_1_0:
     437           0 :       this->pulseShape = RADIOLIB_SX126X_GFSK_FILTER_GAUSS_1;
     438           0 :       break;
     439           0 :     default:
     440           0 :       return(RADIOLIB_ERR_INVALID_DATA_SHAPING);
     441             :   }
     442             : 
     443             :   // update modulation parameters
     444           0 :   return(setModulationParamsFSK(this->bitRate, this->pulseShape, this->rxBandwidth, this->frequencyDev));
     445             : }
     446             : 
     447           3 : int16_t SX126x::setSyncWord(uint8_t* syncWord, size_t len) {
     448             :   // check active modem
     449           3 :   uint8_t modem = getPacketType();
     450           3 :   if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
     451             :     // check sync word Length
     452           0 :     if(len > 8) {
     453           0 :       return(RADIOLIB_ERR_INVALID_SYNC_WORD);
     454             :     }
     455             : 
     456             :     // write sync word
     457           0 :     int16_t state = writeRegister(RADIOLIB_SX126X_REG_SYNC_WORD_0, syncWord, len);
     458           0 :     RADIOLIB_ASSERT(state);
     459             : 
     460             :     // update packet parameters
     461           0 :     this->syncWordLength = len * 8;
     462             :     
     463             :     // maximum preamble detector length is limited by sync word length
     464             :     // for details, see the note in SX1261 datasheet, Rev 2.1, section 6.2.2.1, page 45
     465           0 :     uint8_t maxDetLen = RADIOLIB_MIN(this->syncWordLength, this->preambleLengthFSK);
     466           0 :     this->preambleDetLength = maxDetLen >= 32 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_32 :
     467             :                               maxDetLen >= 24 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_24 :
     468             :                               maxDetLen >= 16 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_16 :
     469             :                               maxDetLen >   0 ? RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_8 :
     470             :                               RADIOLIB_SX126X_GFSK_PREAMBLE_DETECT_OFF;
     471           0 :     state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening,
     472           0 :       this->packetType, (this->packetType == RADIOLIB_SX126X_GFSK_PACKET_FIXED) ? this->implicitLen : RADIOLIB_SX126X_MAX_PACKET_LENGTH);
     473           0 :     return(state);
     474             :   
     475           3 :   } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
     476             :     // with length set to 1 and LoRa modem active, assume it is the LoRa sync word
     477           0 :     if(len > 1) {
     478           0 :       return(RADIOLIB_ERR_INVALID_SYNC_WORD);
     479             :     }
     480           0 :     return(setSyncWord(syncWord[0]));
     481             : 
     482           3 :   } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_LR_FHSS) {
     483             :     // with length set to 4 and LR-FHSS modem active, assume it is the LR-FHSS sync word
     484           0 :     if(len != sizeof(uint32_t)) {
     485           0 :       return(RADIOLIB_ERR_INVALID_SYNC_WORD);
     486             :     }
     487           0 :     memcpy(this->lrFhssSyncWord, syncWord, sizeof(uint32_t));
     488             :   
     489             :   }
     490             : 
     491           3 :   return(RADIOLIB_ERR_WRONG_MODEM);
     492             : }
     493             : 
     494           0 : int16_t SX126x::setCRC(uint8_t len, uint16_t initial, uint16_t polynomial, bool inverted) {
     495             :   // check active modem
     496           0 :   uint8_t modem = getPacketType();
     497             : 
     498           0 :   if(modem == RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
     499             :     // update packet parameters
     500           0 :     switch(len) {
     501           0 :       case 0:
     502           0 :         this->crcTypeFSK = RADIOLIB_SX126X_GFSK_CRC_OFF;
     503           0 :         break;
     504           0 :       case 1:
     505           0 :         if(inverted) {
     506           0 :           this->crcTypeFSK = RADIOLIB_SX126X_GFSK_CRC_1_BYTE_INV;
     507             :         } else {
     508           0 :           this->crcTypeFSK = RADIOLIB_SX126X_GFSK_CRC_1_BYTE;
     509             :         }
     510           0 :         break;
     511           0 :       case 2:
     512           0 :         if(inverted) {
     513           0 :           this->crcTypeFSK = RADIOLIB_SX126X_GFSK_CRC_2_BYTE_INV;
     514             :         } else {
     515           0 :           this->crcTypeFSK = RADIOLIB_SX126X_GFSK_CRC_2_BYTE;
     516             :         }
     517           0 :         break;
     518           0 :       default:
     519           0 :         return(RADIOLIB_ERR_INVALID_CRC_CONFIGURATION);
     520             :     }
     521             : 
     522           0 :     int16_t state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening,
     523           0 :       this->packetType, (this->packetType == RADIOLIB_SX126X_GFSK_PACKET_FIXED) ? this->implicitLen : RADIOLIB_SX126X_MAX_PACKET_LENGTH);
     524           0 :     RADIOLIB_ASSERT(state);
     525             : 
     526             :     // write initial CRC value
     527           0 :     uint8_t data[2] = {(uint8_t)((initial >> 8) & 0xFF), (uint8_t)(initial & 0xFF)};
     528           0 :     state = writeRegister(RADIOLIB_SX126X_REG_CRC_INITIAL_MSB, data, 2);
     529           0 :     RADIOLIB_ASSERT(state);
     530             : 
     531             :     // write CRC polynomial value
     532           0 :     data[0] = (uint8_t)((polynomial >> 8) & 0xFF);
     533           0 :     data[1] = (uint8_t)(polynomial & 0xFF);
     534           0 :     state = writeRegister(RADIOLIB_SX126X_REG_CRC_POLYNOMIAL_MSB, data, 2);
     535             : 
     536           0 :     return(state);
     537             : 
     538           0 :   } else if(modem == RADIOLIB_SX126X_PACKET_TYPE_LORA) {
     539             :     // LoRa CRC doesn't allow to set CRC polynomial, initial value, or inversion
     540             : 
     541             :     // update packet parameters
     542           0 :     if(len) {
     543           0 :       this->crcTypeLoRa = RADIOLIB_SX126X_LORA_CRC_ON;
     544             :     } else {
     545           0 :       this->crcTypeLoRa = RADIOLIB_SX126X_LORA_CRC_OFF;
     546             :     }
     547             : 
     548           0 :     return(setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, this->implicitLen, this->headerType, this->invertIQEnabled));
     549             :   }
     550             : 
     551           0 :   return(RADIOLIB_ERR_UNKNOWN);
     552             : }
     553             : 
     554           3 : int16_t SX126x::setWhitening(bool enabled, uint16_t initial) {
     555             :   // check active modem
     556           3 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
     557           3 :     return(RADIOLIB_ERR_WRONG_MODEM);
     558             :   }
     559             : 
     560           0 :   int16_t state = RADIOLIB_ERR_NONE;
     561           0 :   if(!enabled) {
     562             :     // disable whitening
     563           0 :     this->whitening = RADIOLIB_SX126X_GFSK_WHITENING_OFF;
     564             : 
     565           0 :     state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening,
     566           0 :       this->packetType, (this->packetType == RADIOLIB_SX126X_GFSK_PACKET_FIXED) ? this->implicitLen : RADIOLIB_SX126X_MAX_PACKET_LENGTH);
     567           0 :     RADIOLIB_ASSERT(state);
     568             : 
     569             :   } else {
     570             :     // enable whitening
     571           0 :     this->whitening = RADIOLIB_SX126X_GFSK_WHITENING_ON;
     572             : 
     573             :     // write initial whitening value
     574             :     // as per note on pg. 65 of datasheet v1.2: "The user should not change the value of the 7 MSB's of this register"
     575             :     uint8_t data[2];
     576             :     // first read the actual value and mask 7 MSB which we can not change
     577             :     // if different value is written in 7 MSB, the Rx won't even work (tested on HW)
     578           0 :     state = readRegister(RADIOLIB_SX126X_REG_WHITENING_INITIAL_MSB, data, 1);
     579           0 :     RADIOLIB_ASSERT(state);
     580             : 
     581           0 :     data[0] = (data[0] & 0xFE) | (uint8_t)((initial >> 8) & 0x01);
     582           0 :     data[1] = (uint8_t)(initial & 0xFF);
     583           0 :     state = writeRegister(RADIOLIB_SX126X_REG_WHITENING_INITIAL_MSB, data, 2);
     584           0 :     RADIOLIB_ASSERT(state);
     585             : 
     586           0 :     state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening,
     587           0 :       this->packetType, (this->packetType == RADIOLIB_SX126X_GFSK_PACKET_FIXED) ? this->implicitLen : RADIOLIB_SX126X_MAX_PACKET_LENGTH);
     588           0 :     RADIOLIB_ASSERT(state);
     589             :   }
     590           0 :   return(state);
     591             : }
     592             : 
     593           0 : int16_t SX126x::fixedPacketLengthMode(uint8_t len) {
     594           0 :   return(setPacketMode(RADIOLIB_SX126X_GFSK_PACKET_FIXED, len));
     595             : }
     596             : 
     597           0 : int16_t SX126x::variablePacketLengthMode(uint8_t maxLen) {
     598           0 :   return(setPacketMode(RADIOLIB_SX126X_GFSK_PACKET_VARIABLE, maxLen));
     599             : }
     600           0 : int16_t SX126x::implicitHeader(size_t len) {
     601           0 :   return(setHeaderType(RADIOLIB_SX126X_LORA_HEADER_IMPLICIT, len));
     602             : }
     603             : 
     604           0 : int16_t SX126x::explicitHeader() {
     605           0 :   return(setHeaderType(RADIOLIB_SX126X_LORA_HEADER_EXPLICIT));
     606             : }
     607             : 
     608           0 : int16_t SX126x::setRegulatorLDO() {
     609           0 :   return(setRegulatorMode(RADIOLIB_SX126X_REGULATOR_LDO));
     610             : }
     611             : 
     612           0 : int16_t SX126x::setRegulatorDCDC() {
     613           0 :   return(setRegulatorMode(RADIOLIB_SX126X_REGULATOR_DC_DC));
     614             : }
     615             : 
     616           3 : int16_t SX126x::setEncoding(uint8_t encoding) {
     617           3 :   return(setWhitening(encoding));
     618             : }
     619             : 
     620           0 : void SX126x::setRfSwitchPins(uint32_t rxEn, uint32_t txEn) {
     621           0 :   this->mod->setRfSwitchPins(rxEn, txEn);
     622           0 : }
     623             : 
     624           0 : void SX126x::setRfSwitchTable(const uint32_t (&pins)[Module::RFSWITCH_MAX_PINS], const Module::RfSwitchMode_t table[]) {
     625           0 :   this->mod->setRfSwitchTable(pins, table);
     626           0 : }
     627             : 
     628           0 : int16_t SX126x::forceLDRO(bool enable) {
     629             :   // check active modem
     630           0 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
     631           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     632             :   }
     633             : 
     634             :   // update modulation parameters
     635           0 :   this->ldroAuto = false;
     636           0 :   this->ldrOptimize = (uint8_t)enable;
     637           0 :   return(setModulationParams(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
     638             : }
     639             : 
     640           0 : int16_t SX126x::autoLDRO() {
     641           0 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
     642           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     643             :   }
     644             : 
     645           0 :   this->ldroAuto = true;
     646           0 :   return(RADIOLIB_ERR_NONE);
     647             : }
     648             : 
     649           3 : int16_t SX126x::invertIQ(bool enable) {
     650           3 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
     651           3 :     return(RADIOLIB_ERR_WRONG_MODEM);
     652             :   }
     653             : 
     654           0 :   if(enable) {
     655           0 :     this->invertIQEnabled = RADIOLIB_SX126X_LORA_IQ_INVERTED;
     656             :   } else {
     657           0 :     this->invertIQEnabled = RADIOLIB_SX126X_LORA_IQ_STANDARD;
     658             :   }
     659             : 
     660           0 :   return(setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, this->implicitLen, this->headerType, this->invertIQEnabled));
     661             : }
     662             : 
     663           0 : int16_t SX126x::setTCXO(float voltage, uint32_t delay) {
     664             :   // check if TCXO is enabled at all
     665           0 :   if(this->XTAL) {
     666           0 :     return(RADIOLIB_ERR_INVALID_TCXO_VOLTAGE);
     667             :   }
     668             : 
     669             :   // set mode to standby
     670           0 :   standby();
     671             : 
     672             :   // check RADIOLIB_SX126X_XOSC_START_ERR flag and clear it
     673           0 :   if(getDeviceErrors() & RADIOLIB_SX126X_XOSC_START_ERR) {
     674           0 :     clearDeviceErrors();
     675             :   }
     676             : 
     677             :   // check 0 V disable
     678           0 :   if(fabsf(voltage - 0.0f) <= 0.001f) {
     679           0 :     return(reset(true));
     680             :   }
     681             : 
     682             :   // check alowed voltage values
     683             :   uint8_t data[4];
     684           0 :   if(fabsf(voltage - 1.6f) <= 0.001f) {
     685           0 :     data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_1_6;
     686           0 :   } else if(fabsf(voltage - 1.7f) <= 0.001f) {
     687           0 :     data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_1_7;
     688           0 :   } else if(fabsf(voltage - 1.8f) <= 0.001f) {
     689           0 :     data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_1_8;
     690           0 :   } else if(fabsf(voltage - 2.2f) <= 0.001f) {
     691           0 :     data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_2_2;
     692           0 :   } else if(fabsf(voltage - 2.4f) <= 0.001f) {
     693           0 :     data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_2_4;
     694           0 :   } else if(fabsf(voltage - 2.7f) <= 0.001f) {
     695           0 :     data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_2_7;
     696           0 :   } else if(fabsf(voltage - 3.0f) <= 0.001f) {
     697           0 :     data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_3_0;
     698           0 :   } else if(fabsf(voltage - 3.3f) <= 0.001f) {
     699           0 :     data[0] = RADIOLIB_SX126X_DIO3_OUTPUT_3_3;
     700             :   } else {
     701           0 :     return(RADIOLIB_ERR_INVALID_TCXO_VOLTAGE);
     702             :   }
     703             : 
     704             :   // calculate delay
     705           0 :   uint32_t delayValue = (float)delay / 15.625f;
     706           0 :   data[1] = (uint8_t)((delayValue >> 16) & 0xFF);
     707           0 :   data[2] = (uint8_t)((delayValue >> 8) & 0xFF);
     708           0 :   data[3] = (uint8_t)(delayValue & 0xFF);
     709             : 
     710           0 :   this->tcxoDelay = delay;
     711             : 
     712             :   // enable TCXO control on DIO3
     713           0 :   return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_DIO3_AS_TCXO_CTRL, data, 4));
     714             : }
     715             : 
     716           0 : int16_t SX126x::setDio2AsRfSwitch(bool enable) {
     717           0 :   this->dio2RfSwitch = enable;
     718           0 :   uint8_t data = enable ? RADIOLIB_SX126X_DIO2_AS_RF_SWITCH : RADIOLIB_SX126X_DIO2_AS_IRQ;
     719           0 :   return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_DIO2_AS_RF_SWITCH_CTRL, &data, 1));
     720             : }
     721             : 
     722           0 : int16_t SX126x::setPaRampTime(uint8_t rampTime) {
     723           0 :   return(this->setTxParams(this->pwr, rampTime));
     724             : }
     725             : 
     726           2 : int16_t SX126x::setOutputPower(int8_t power, uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel) {
     727             :   // get current OCP configuration
     728           2 :   uint8_t ocp = 0;
     729           2 :   int16_t state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1);
     730           2 :   RADIOLIB_ASSERT(state);
     731             : 
     732             :   // set PA config
     733           0 :   state = SX126x::setPaConfig(paDutyCycle, deviceSel, hpMax);
     734           0 :   RADIOLIB_ASSERT(state);
     735             : 
     736             :   // set output power with default 200us ramp
     737           0 :   state = SX126x::setTxParams(power, RADIOLIB_SX126X_PA_RAMP_200U);
     738           0 :   RADIOLIB_ASSERT(state);
     739             : 
     740             :   // restore OCP configuration
     741           0 :   return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1));
     742             : }
     743             : 
     744           0 : int16_t SX126x::setPacketMode(uint8_t mode, uint8_t len) {
     745             :   // check active modem
     746           0 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_GFSK) {
     747           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     748             :   }
     749             : 
     750             :   // set requested packet mode
     751           0 :   int16_t state = setPacketParamsFSK(this->preambleLengthFSK, this->preambleDetLength, this->crcTypeFSK, this->syncWordLength, RADIOLIB_SX126X_GFSK_ADDRESS_FILT_OFF, this->whitening, mode, len);
     752           0 :   RADIOLIB_ASSERT(state);
     753             : 
     754             :   // update cached value
     755           0 :   this->packetType = mode;
     756           0 :   this->implicitLen = len;
     757           0 :   return(state);
     758             : }
     759             : 
     760           0 : int16_t SX126x::setHeaderType(uint8_t hdrType, size_t len) {
     761             :   // check active modem
     762           0 :   if(getPacketType() != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
     763           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     764             :   }
     765             : 
     766             :   // set requested packet mode
     767           0 :   int16_t state = setPacketParams(this->preambleLengthLoRa, this->crcTypeLoRa, len, hdrType, this->invertIQEnabled);
     768           0 :   RADIOLIB_ASSERT(state);
     769             : 
     770             :   // update cached value
     771           0 :   this->headerType = hdrType;
     772           0 :   this->implicitLen = len;
     773             : 
     774           0 :   return(state);
     775             : }
     776             : 
     777           0 : int16_t SX126x::setFrequencyRaw(float freq) {
     778             :   // calculate raw value
     779           0 :   this->freqMHz = freq;
     780           0 :   uint32_t frf = (this->freqMHz * (uint32_t(1) << RADIOLIB_SX126X_DIV_EXPONENT)) / RADIOLIB_SX126X_CRYSTAL_FREQ;
     781           0 :   return(setRfFrequency(frf));
     782             : }
     783             : 
     784           0 : int16_t SX126x::config(uint8_t modem) {
     785             :   // reset buffer base address
     786           0 :   int16_t state = setBufferBaseAddress();
     787           0 :   RADIOLIB_ASSERT(state);
     788             : 
     789             :   // set modem
     790             :   uint8_t data[7];
     791           0 :   data[0] = modem;
     792           0 :   state = this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_PACKET_TYPE, data, 1);
     793           0 :   RADIOLIB_ASSERT(state);
     794             : 
     795             :   // set Rx/Tx fallback mode to STDBY_RC
     796           0 :   data[0] = this->standbyXOSC ? RADIOLIB_SX126X_RX_TX_FALLBACK_MODE_STDBY_XOSC : RADIOLIB_SX126X_RX_TX_FALLBACK_MODE_STDBY_RC;
     797           0 :   state = this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_RX_TX_FALLBACK_MODE, data, 1);
     798           0 :   RADIOLIB_ASSERT(state);
     799             : 
     800             :   // set some CAD parameters - will be overwritten when calling CAD anyway
     801           0 :   data[0] = RADIOLIB_SX126X_CAD_ON_8_SYMB;
     802           0 :   data[1] = this->spreadingFactor + 13;
     803           0 :   data[2] = RADIOLIB_SX126X_CAD_PARAM_DET_MIN;
     804           0 :   data[3] = RADIOLIB_SX126X_CAD_GOTO_STDBY;
     805           0 :   data[4] = 0x00;
     806           0 :   data[5] = 0x00;
     807           0 :   data[6] = 0x00;
     808           0 :   state = this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_CAD_PARAMS, data, 7);
     809           0 :   RADIOLIB_ASSERT(state);
     810             : 
     811             :   // clear IRQ
     812           0 :   state = clearIrqStatus();
     813           0 :   state |= setDioIrqParams(RADIOLIB_SX126X_IRQ_NONE, RADIOLIB_SX126X_IRQ_NONE);
     814           0 :   RADIOLIB_ASSERT(state);
     815             : 
     816             :   // calibrate all blocks
     817           0 :   data[0] = RADIOLIB_SX126X_CALIBRATE_ALL;
     818           0 :   state = this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_CALIBRATE, data, 1, true, false);
     819           0 :   RADIOLIB_ASSERT(state);
     820             : 
     821             :   // wait for calibration completion
     822           0 :   this->mod->hal->delay(5);
     823           0 :   while(this->mod->hal->digitalRead(this->mod->getGpio())) {
     824           0 :     this->mod->hal->yield();
     825             :   }
     826             : 
     827             :   // check calibration result
     828           0 :   return(this->mod->SPIcheckStream());
     829             : }
     830             : 
     831             : #endif

Generated by: LCOV version 1.14