LCOV - code coverage report
Current view: top level - src/modules/SX127x - SX1272.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 59 332 17.8 %
Date: 2026-11-08 19:43:08 Functions: 13 28 46.4 %

          Line data    Source code
       1             : #include "SX1272.h"
       2             : #include <math.h>
       3             : #if !RADIOLIB_EXCLUDE_SX127X
       4             : 
       5           3 : SX1272::SX1272(Module* mod) : SX127x(mod) {
       6           3 :   this->powerMin = RADIOLIB_SX1272_RFO_POUT_MIN;
       7           3 :   this->powerMax = RADIOLIB_SX1272_PA_BOOST_POUT_MAX;
       8           3 :   this->paSteps = this->powerMax - this->powerMin + 1;
       9           3 : }
      10             : 
      11           0 : int16_t SX1272::begin(const ConfigLoRa_t& cfg) {
      12             :   // execute common part
      13           0 :   uint8_t version = RADIOLIB_SX1272_CHIP_VERSION;
      14           0 :   int16_t state = SX127x::begin(&version, 1, cfg.syncWord, cfg.preambleLength);
      15           0 :   RADIOLIB_ASSERT(state);
      16             : 
      17             :   // configure publicly accessible settings
      18           0 :   state = setBandwidth(cfg.bandwidth);
      19           0 :   RADIOLIB_ASSERT(state);
      20             : 
      21           0 :   state = setFrequency(cfg.frequency);
      22           0 :   RADIOLIB_ASSERT(state);
      23             : 
      24           0 :   state = setSpreadingFactor(cfg.spreadingFactor);
      25           0 :   RADIOLIB_ASSERT(state);
      26             : 
      27           0 :   state = setCodingRate(cfg.codingRate);
      28           0 :   RADIOLIB_ASSERT(state);
      29             : 
      30           0 :   state = setOutputPower(cfg.power);
      31           0 :   RADIOLIB_ASSERT(state);
      32             : 
      33           0 :   state = setGain(this->gain);
      34           0 :   RADIOLIB_ASSERT(state);
      35             : 
      36             :   // set publicly accessible settings that are not a part of begin method
      37           0 :   state = setCRC(true);
      38           0 :   return(state);
      39             : }
      40             : 
      41           0 : int16_t SX1272::beginFSK(const ConfigFSK_t& cfg) {
      42             :   // execute common part
      43           0 :   uint8_t version = RADIOLIB_SX1272_CHIP_VERSION;
      44           0 :   int16_t state = SX127x::beginFSK(&version, 1, cfg.frequencyDeviation, cfg.receiverBandwidth, cfg.preambleLength);
      45           0 :   RADIOLIB_ASSERT(state);
      46             : 
      47             :   // configure settings not accessible by API
      48           0 :   state = configFSK();
      49           0 :   RADIOLIB_ASSERT(state);
      50             : 
      51             :   // configure publicly accessible settings
      52           0 :   state = setFrequency(cfg.frequency);
      53           0 :   RADIOLIB_ASSERT(state);
      54             : 
      55           0 :   state = setBitRate(cfg.bitRate);
      56           0 :   RADIOLIB_ASSERT(state);
      57             : 
      58           0 :   state = setOutputPower(cfg.power);
      59           0 :   RADIOLIB_ASSERT(state);
      60             : 
      61           0 :   if(this->enableOOK) {
      62           0 :     state = setDataShapingOOK(RADIOLIB_SHAPING_NONE);
      63           0 :     RADIOLIB_ASSERT(state);
      64             :   } else {
      65           0 :     state = setDataShaping(RADIOLIB_SHAPING_NONE);
      66           0 :     RADIOLIB_ASSERT(state);
      67             :   }
      68             : 
      69             :   // set publicly accessible settings that are not a part of begin method
      70           0 :   state = setCRC(true);
      71           0 :   return(state);
      72             : }
      73             : 
      74           0 : void SX1272::reset() {
      75           0 :   Module* mod = this->getMod();
      76           0 :   mod->hal->pinMode(mod->getRst(), mod->hal->GpioModeOutput);
      77           0 :   mod->hal->digitalWrite(mod->getRst(), mod->hal->GpioLevelHigh);
      78           0 :   mod->hal->delay(1);
      79           0 :   mod->hal->digitalWrite(mod->getRst(), mod->hal->GpioLevelLow);
      80           0 :   mod->hal->delay(5);
      81           0 : }
      82             : 
      83           3 : int16_t SX1272::setFrequency(uint32_t freq) {
      84           3 :   RADIOLIB_CHECK_RANGE(freq, RADIOLIB_UNIT_MEGA(860), RADIOLIB_UNIT_MEGA(1020), RADIOLIB_ERR_INVALID_FREQUENCY);
      85             : 
      86             :   // set frequency and if successful, save the new setting
      87           0 :   int16_t state = SX127x::setFrequencyRaw(freq);
      88           0 :   if(state == RADIOLIB_ERR_NONE) {
      89           0 :     SX127x::frequency = freq;
      90             :   }
      91           0 :   return(state);
      92             : }
      93             : 
      94           3 : int16_t SX1272::setBandwidth(uint32_t bw) {
      95             :   // check active modem
      96           3 :   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
      97           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
      98             :   }
      99             : 
     100             :   uint8_t newBandwidth;
     101             : 
     102             :   // check allowed bandwidth values
     103           3 :   switch(bw) {
     104           0 :     case(125000):
     105           0 :       newBandwidth = RADIOLIB_SX1272_BW_125_00_KHZ;
     106           0 :       break;
     107           0 :     case(250000):
     108           0 :       newBandwidth = RADIOLIB_SX1272_BW_250_00_KHZ;
     109           0 :       break;
     110           0 :     case(500000):
     111           0 :       newBandwidth = RADIOLIB_SX1272_BW_500_00_KHZ;
     112           0 :       break;
     113           3 :     default:
     114           3 :       return(RADIOLIB_ERR_INVALID_BANDWIDTH);
     115             :   }
     116             : 
     117             :   // set bandwidth and if successful, save the new setting
     118           0 :   int16_t state = SX1272::setBandwidthRaw(newBandwidth);
     119           0 :   if(state == RADIOLIB_ERR_NONE) {
     120           0 :     SX127x::bandwidth = bw;
     121             : 
     122             :     // calculate symbol length and set low data rate optimization, if auto-configuration is enabled
     123           0 :     if(this->ldroAuto) {
     124           0 :       uint32_t symbolLength_us = (RADIOLIB_UNIT_MEGA(1) << this->spreadingFactor) / this->bandwidth;
     125           0 :       Module* mod = this->getMod();
     126           0 :       if(symbolLength_us >= 16000) {
     127           0 :         this->ldroEnabled = true;
     128           0 :         state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_ON, 0, 0);
     129             :       } else {
     130           0 :         this->ldroEnabled = false;
     131           0 :         state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0);
     132             :       }
     133             :     }
     134             :   }
     135           0 :   return(state);
     136             : }
     137             : 
     138           4 : int16_t SX1272::setSpreadingFactor(uint8_t sf) {
     139             :   // check active modem
     140           4 :   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
     141           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     142             :   }
     143             : 
     144             :   uint8_t newSpreadingFactor;
     145             : 
     146             :   // check allowed spreading factor values
     147           4 :   switch(sf) {
     148           0 :     case 6:
     149           0 :       newSpreadingFactor = RADIOLIB_SX127X_SF_6;
     150           0 :       break;
     151           0 :     case 7:
     152           0 :       newSpreadingFactor = RADIOLIB_SX127X_SF_7;
     153           0 :       break;
     154           0 :     case 8:
     155           0 :       newSpreadingFactor = RADIOLIB_SX127X_SF_8;
     156           0 :       break;
     157           0 :     case 9:
     158           0 :       newSpreadingFactor = RADIOLIB_SX127X_SF_9;
     159           0 :       break;
     160           0 :     case 10:
     161           0 :       newSpreadingFactor = RADIOLIB_SX127X_SF_10;
     162           0 :       break;
     163           0 :     case 11:
     164           0 :       newSpreadingFactor = RADIOLIB_SX127X_SF_11;
     165           0 :       break;
     166           0 :     case 12:
     167           0 :       newSpreadingFactor = RADIOLIB_SX127X_SF_12;
     168           0 :       break;
     169           4 :     default:
     170           4 :       return(RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
     171             :   }
     172             : 
     173             :   // set spreading factor and if successful, save the new setting
     174           0 :   int16_t state = SX1272::setSpreadingFactorRaw(newSpreadingFactor);
     175           0 :   if(state == RADIOLIB_ERR_NONE) {
     176           0 :     SX127x::spreadingFactor = sf;
     177             : 
     178             :     // calculate symbol length and set low data rate optimization, if auto-configuration is enabled
     179           0 :     if(this->ldroAuto) {
     180           0 :       uint32_t symbolLength_us = (RADIOLIB_UNIT_MEGA(1) << this->spreadingFactor) / this->bandwidth;
     181           0 :       Module* mod = this->getMod();
     182           0 :       if(symbolLength_us >= 16000) {
     183           0 :         this->ldroEnabled = true;
     184           0 :         state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_ON, 0, 0);
     185             :       } else {
     186           0 :         this->ldroEnabled = false;
     187           0 :         state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0);
     188             :       }
     189             :     }
     190             :   }
     191           0 :   return(state);
     192             : }
     193             : 
     194           3 : int16_t SX1272::setCodingRate(uint8_t cr, bool longInterleave) {
     195             :   (void)longInterleave;
     196             :   // check active modem
     197           3 :   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
     198           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     199             :   }
     200             : 
     201             :   uint8_t newCodingRate;
     202             : 
     203             :   // check allowed coding rate values
     204           3 :   switch(cr) {
     205           0 :     case 4:
     206           0 :       newCodingRate = RADIOLIB_SX1272_CR_4_4;
     207           0 :       break;
     208           0 :     case 5:
     209           0 :       newCodingRate = RADIOLIB_SX1272_CR_4_5;
     210           0 :       break;
     211           0 :     case 6:
     212           0 :       newCodingRate = RADIOLIB_SX1272_CR_4_6;
     213           0 :       break;
     214           0 :     case 7:
     215           0 :       newCodingRate = RADIOLIB_SX1272_CR_4_7;
     216           0 :       break;
     217           0 :     case 8:
     218           0 :       newCodingRate = RADIOLIB_SX1272_CR_4_8;
     219           0 :       break;
     220           3 :     default:
     221           3 :       return(RADIOLIB_ERR_INVALID_CODING_RATE);
     222             :   }
     223             : 
     224             :   // set coding rate and if successful, save the new setting
     225           0 :   int16_t state = SX1272::setCodingRateRaw(newCodingRate);
     226           0 :   if(state == RADIOLIB_ERR_NONE) {
     227           0 :     SX127x::codingRate = cr;
     228             :   }
     229           0 :   return(state);
     230             : }
     231             : 
     232           3 : int16_t SX1272::setBitRate(uint32_t br) {
     233           3 :   return(SX127x::setBitRateCommon(br, RADIOLIB_SX1272_REG_BIT_RATE_FRAC));
     234             : }
     235             : 
     236           2 : int16_t SX1272::checkDataRate(DataRate_t dr, ModemType_t modem) {
     237           2 :   int16_t state = RADIOLIB_ERR_UNKNOWN;
     238             : 
     239             :   // retrieve modem if not supplied
     240           2 :   if(modem == RADIOLIB_MODEM_NONE) {
     241           2 :     state = this->getModem(&modem);
     242           2 :     RADIOLIB_ASSERT(state);
     243             :   }
     244             : 
     245             :   // select interpretation based on modem
     246           2 :   if(modem == RADIOLIB_MODEM_FSK) {
     247           0 :     RADIOLIB_CHECK_RANGE(dr.fsk.bitRate, 500, RADIOLIB_UNIT_KILO(300), RADIOLIB_ERR_INVALID_BIT_RATE);
     248           0 :     if(!((dr.fsk.freqDev + dr.fsk.bitRate/2 <= RADIOLIB_UNIT_KILO(250)) && (dr.fsk.freqDev <= RADIOLIB_UNIT_KILO(200)))) {
     249           0 :       return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION);
     250             :     }
     251           0 :     return(RADIOLIB_ERR_NONE);
     252             : 
     253           2 :   } else if(modem == RADIOLIB_MODEM_LORA) {
     254           2 :     RADIOLIB_CHECK_RANGE(dr.lora.spreadingFactor, 6, 12, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
     255           0 :     RADIOLIB_CHECK_RANGE(dr.lora.bandwidth, RADIOLIB_UNIT_KILO(125), RADIOLIB_UNIT_KILO(500), RADIOLIB_ERR_INVALID_BANDWIDTH);
     256           0 :     RADIOLIB_CHECK_RANGE(dr.lora.codingRate, 4, 8, RADIOLIB_ERR_INVALID_CODING_RATE);
     257           0 :     return(RADIOLIB_ERR_NONE);
     258             :   
     259             :   }
     260             : 
     261           0 :   return(state);
     262             : }
     263             : 
     264           3 : int16_t SX1272::setOutputPower(int8_t power) {
     265           3 :   return(this->setOutputPower(power, false));
     266             : }
     267             : 
     268           3 : int16_t SX1272::setOutputPower(int8_t power, bool forceRfo) {
     269             :   // apply offset for external PA
     270             :   // use the minimum possible output as LUT base
     271           3 :   int8_t pwr = power;
     272           3 :   int16_t state = this->applyOutputPowerOffset(RADIOLIB_SX1272_RFO_POUT_MIN, &power, &pwr);
     273           3 :   RADIOLIB_ASSERT(state);
     274             : 
     275             :   // check if power value is configurable
     276             :   // this check is not redundant with the one in applyOutputPowerOffset, because only now we know which Tx path to take
     277           3 :   bool useRfo = (pwr < RADIOLIB_SX1272_PA_BOOST_POUT_MIN) || forceRfo;
     278           3 :   if(useRfo) {
     279           3 :     RADIOLIB_CHECK_RANGE(pwr, RADIOLIB_SX1272_RFO_POUT_MIN, RADIOLIB_SX1272_RFO_POUT_MAX, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
     280             :   } else {
     281           0 :     RADIOLIB_CHECK_RANGE(pwr, RADIOLIB_SX1272_PA_BOOST_POUT_MIN, RADIOLIB_SX1272_PA_BOOST_POUT_MAX, RADIOLIB_ERR_INVALID_OUTPUT_POWER);
     282             :   }
     283             : 
     284             :   // set mode to standby
     285           3 :   state = SX127x::standby();
     286           3 :   Module* mod = this->getMod();
     287             : 
     288             :   // the output path depends on the commanded value
     289           3 :   if(useRfo) {
     290             :     // RFO output
     291           3 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PA_CONFIG, RADIOLIB_SX127X_PA_SELECT_RFO, 7, 7);
     292           3 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PA_CONFIG, (pwr + 1), 3, 0);
     293           3 :     state |= mod->SPIsetRegValue(RADIOLIB_SX1272_REG_PA_DAC, RADIOLIB_SX127X_PA_BOOST_OFF, 2, 0);
     294             : 
     295             :   } else {
     296           0 :     if(pwr <= 17) {
     297             :       // power is 2 - 17 dBm, enable PA1 + PA2 on PA_BOOST
     298           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PA_CONFIG, RADIOLIB_SX127X_PA_SELECT_BOOST, 7, 7);
     299           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PA_CONFIG, (pwr - 2), 3, 0);
     300           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX1272_REG_PA_DAC, RADIOLIB_SX127X_PA_BOOST_OFF, 2, 0);
     301             : 
     302             :     } else {
     303             :       // power is 18 - 20 dBm, enable PA1 + PA2 on PA_BOOST and enable high power control
     304           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PA_CONFIG, RADIOLIB_SX127X_PA_SELECT_BOOST, 7, 7);
     305           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PA_CONFIG, (pwr - 5), 3, 0);
     306           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX1272_REG_PA_DAC, RADIOLIB_SX127X_PA_BOOST_ON, 2, 0);
     307             : 
     308             :     }
     309             : 
     310             :   }
     311             : 
     312           3 :   return(state);
     313             : }
     314             : 
     315           0 : int16_t SX1272::setGain(uint8_t gain) {
     316             :   // check allowed range
     317           0 :   if(gain > 6) {
     318           0 :     return(RADIOLIB_ERR_INVALID_GAIN);
     319             :   }
     320             : 
     321             :   // set mode to standby
     322           0 :   int16_t state = SX127x::standby();
     323           0 :   Module* mod = this->getMod();
     324             : 
     325             :   // get modem
     326           0 :   int16_t modem = getActiveModem();
     327           0 :   if(modem == RADIOLIB_SX127X_LORA) {
     328             :     // set gain
     329           0 :     if(gain == 0) {
     330             :       // gain set to 0, enable AGC loop
     331           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, RADIOLIB_SX1272_AGC_AUTO_ON, 2, 2);
     332             :     } else {
     333           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, RADIOLIB_SX1272_AGC_AUTO_OFF, 2, 2);
     334           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_LNA, (gain << 5) | RADIOLIB_SX127X_LNA_BOOST_ON);
     335             :     }
     336             : 
     337           0 :   } else if(modem == RADIOLIB_SX127X_FSK_OOK) {
     338             :     // set gain
     339           0 :     if(gain == 0) {
     340             :       // gain set to 0, enable AGC loop
     341           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_CONFIG, RADIOLIB_SX127X_AGC_AUTO_ON, 3, 3);
     342             :     } else {
     343           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_CONFIG, RADIOLIB_SX127X_AGC_AUTO_ON, 3, 3);
     344           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_LNA, (gain << 5) | RADIOLIB_SX127X_LNA_BOOST_ON);
     345             :     }
     346             : 
     347             :   }
     348             : 
     349           0 :   return(state);
     350             : }
     351             : 
     352           3 : int16_t SX1272::setDataShaping(uint8_t sh) {
     353             :   // check active modem
     354           3 :   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
     355           3 :     return(RADIOLIB_ERR_WRONG_MODEM);
     356             :   }
     357             : 
     358             :   // check modulation
     359           0 :   if(SX127x::ookEnabled) {
     360           0 :     return(RADIOLIB_ERR_INVALID_MODULATION);
     361             :   }
     362             : 
     363             :   // set mode to standby
     364           0 :   int16_t state = SX127x::standby();
     365           0 :   RADIOLIB_ASSERT(state);
     366             : 
     367             :   // set data shaping
     368           0 :   Module* mod = this->getMod();
     369           0 :   switch(sh) {
     370           0 :     case RADIOLIB_SHAPING_NONE:
     371           0 :       return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX1272_NO_SHAPING, 4, 3));
     372           0 :     case RADIOLIB_SHAPING_0_3:
     373           0 :       return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX1272_FSK_GAUSSIAN_0_3, 4, 3));
     374           0 :     case RADIOLIB_SHAPING_0_5:
     375           0 :       return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX1272_FSK_GAUSSIAN_0_5, 4, 3));
     376           0 :     case RADIOLIB_SHAPING_1_0:
     377           0 :       return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX1272_FSK_GAUSSIAN_1_0, 4, 3));
     378           0 :     default:
     379           0 :       return(RADIOLIB_ERR_INVALID_DATA_SHAPING);
     380             :   }
     381             : }
     382             : 
     383           0 : int16_t SX1272::setDataShapingOOK(uint8_t sh) {
     384             :   // check active modem
     385           0 :   if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) {
     386           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     387             :   }
     388             : 
     389             :   // check modulation
     390           0 :   if(!SX127x::ookEnabled) {
     391           0 :     return(RADIOLIB_ERR_INVALID_MODULATION);
     392             :   }
     393             : 
     394             :   // set mode to standby
     395           0 :   int16_t state = SX127x::standby();
     396             : 
     397             :   // set data shaping
     398           0 :   Module* mod = this->getMod();
     399           0 :   switch(sh) {
     400           0 :     case 0:
     401           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX1272_NO_SHAPING, 4, 3);
     402           0 :       break;
     403           0 :     case 1:
     404           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX1272_OOK_FILTER_BR, 4, 3);
     405           0 :       break;
     406           0 :     case 2:
     407           0 :       state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX1272_OOK_FILTER_2BR, 4, 3);
     408           0 :       break;
     409           0 :     default:
     410           0 :       state = RADIOLIB_ERR_INVALID_DATA_SHAPING;
     411           0 :       break;
     412             :   }
     413             : 
     414           0 :   return(state);
     415             : }
     416             : 
     417           3 : float SX1272::getRSSI() {
     418           3 :   return(SX1272::getRSSI(true, false));
     419             : }
     420             : 
     421           3 : float SX1272::getRSSI(bool packet, bool skipReceive) {
     422           3 :   return(SX127x::getRSSICommon(packet, skipReceive, -139));
     423             : }
     424             : 
     425           0 : int16_t SX1272::setCRC(bool enable, bool mode) {
     426           0 :   SX127x::crcEnabled = enable;
     427           0 :   Module* mod = this->getMod();
     428           0 :   if(getActiveModem() == RADIOLIB_SX127X_LORA) {
     429           0 :     if(enable) {
     430           0 :       return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_RX_CRC_MODE_ON, 1, 1));
     431             :     } else {
     432           0 :       return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_RX_CRC_MODE_OFF, 1, 1));
     433             :     }
     434             :   } else {
     435             :     // set FSK CRC
     436           0 :     int16_t state = RADIOLIB_ERR_NONE;
     437           0 :     if(enable) {
     438           0 :       state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_CRC_ON, 4, 4);
     439             :     } else {
     440           0 :       state = mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_CRC_OFF, 4, 4);
     441             :     }
     442           0 :     RADIOLIB_ASSERT(state);
     443             : 
     444             :     // set FSK CRC mode
     445           0 :     if(mode) {
     446           0 :       return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_CRC_WHITENING_TYPE_IBM, 0, 0));
     447             :     } else {
     448           0 :       return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_CRC_WHITENING_TYPE_CCITT, 0, 0));
     449             :     }
     450             :   }
     451             : }
     452             : 
     453           0 : int16_t SX1272::forceLDRO(bool enable) {
     454           0 :   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
     455           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     456             :   }
     457             : 
     458           0 :   this->ldroAuto = false;
     459           0 :   this->ldroEnabled = enable;
     460           0 :   Module* mod = this->getMod();
     461           0 :   if(enable) {
     462           0 :     return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_ON, 0, 0));
     463             :   } else {
     464           0 :     return(mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0));
     465             :   }
     466             : }
     467             : 
     468           0 : int16_t SX1272::autoLDRO() {
     469           0 :   if(getActiveModem() != RADIOLIB_SX127X_LORA) {
     470           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     471             :   }
     472             : 
     473           0 :   this->ldroAuto = true;
     474           0 :   return(RADIOLIB_ERR_NONE);
     475             : }
     476             : 
     477           0 : int16_t SX1272::implicitHeader(size_t len) {
     478           0 :   this->implicitHdr = true;
     479           0 :   return(setHeaderType(RADIOLIB_SX1272_HEADER_IMPL_MODE, 2, len));
     480             : }
     481             : 
     482           0 : int16_t SX1272::explicitHeader() {
     483           0 :   this->implicitHdr = false;
     484           0 :   return(setHeaderType(RADIOLIB_SX1272_HEADER_EXPL_MODE, 2));
     485             : }
     486             : 
     487           0 : int16_t SX1272::setBandwidthRaw(uint8_t newBandwidth) {
     488             :   // set mode to standby
     489           0 :   int16_t state = SX127x::standby();
     490             : 
     491             :   // write register
     492           0 :   Module* mod = this->getMod();
     493           0 :   state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, newBandwidth, 7, 6);
     494           0 :   return(state);
     495             : }
     496             : 
     497           0 : int16_t SX1272::setSpreadingFactorRaw(uint8_t newSpreadingFactor) {
     498             :   // set mode to standby
     499           0 :   int16_t state = SX127x::standby();
     500             : 
     501             :   // write registers
     502           0 :   Module* mod = this->getMod();
     503           0 :   if(newSpreadingFactor == RADIOLIB_SX127X_SF_6) {
     504           0 :     this->implicitHdr = true;
     505           0 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_HEADER_IMPL_MODE | (SX127x::crcEnabled ? RADIOLIB_SX1272_RX_CRC_MODE_ON : RADIOLIB_SX1272_RX_CRC_MODE_OFF), 2, 1);
     506           0 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, RADIOLIB_SX127X_SF_6 | RADIOLIB_SX127X_TX_MODE_SINGLE, 7, 3);
     507           0 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECT_OPTIMIZE, RADIOLIB_SX127X_DETECT_OPTIMIZE_SF_6, 2, 0);
     508           0 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECTION_THRESHOLD, RADIOLIB_SX127X_DETECTION_THRESHOLD_SF_6);
     509             :   } else {
     510           0 :     this->implicitHdr = false;
     511           0 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, RADIOLIB_SX1272_HEADER_EXPL_MODE | (SX127x::crcEnabled ? RADIOLIB_SX1272_RX_CRC_MODE_ON : RADIOLIB_SX1272_RX_CRC_MODE_OFF),  2, 1);
     512           0 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, newSpreadingFactor | RADIOLIB_SX127X_TX_MODE_SINGLE, 7, 3);
     513           0 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECT_OPTIMIZE, RADIOLIB_SX127X_DETECT_OPTIMIZE_SF_7_12, 2, 0);
     514           0 :     state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DETECTION_THRESHOLD, RADIOLIB_SX127X_DETECTION_THRESHOLD_SF_7_12);
     515             :   }
     516           0 :   return(state);
     517             : }
     518             : 
     519           0 : int16_t SX1272::setCodingRateRaw(uint8_t newCodingRate) {
     520             :   // set mode to standby
     521           0 :   int16_t state = SX127x::standby();
     522             : 
     523             :   // write register
     524           0 :   Module* mod = this->getMod();
     525           0 :   state |= mod->SPIsetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, newCodingRate, 5, 3);
     526           0 :   return(state);
     527             : }
     528             : 
     529           0 : int16_t SX1272::configFSK() {
     530             :   // configure common registers
     531           0 :   int16_t state = SX127x::configFSK();
     532           0 :   RADIOLIB_ASSERT(state);
     533             : 
     534             :   // set fast PLL hop
     535           0 :   Module* mod = this->getMod();
     536           0 :   state = mod->SPIsetRegValue(RADIOLIB_SX1272_REG_PLL_HOP, RADIOLIB_SX127X_FAST_HOP_ON, 7, 7);
     537           0 :   return(state);
     538             : }
     539             : 
     540           0 : void SX1272::errataFix(bool rx) {
     541             :   (void)rx;
     542             : 
     543             :   // mitigation of receiver spurious response
     544             :   // see SX1272/73 Errata, section 2.2 for details
     545           0 :   Module* mod = this->getMod();
     546           0 :   mod->SPIsetRegValue(0x31, 0b10000000, 7, 7);
     547           0 : }
     548             : 
     549           2 : int16_t SX1272::setModem(ModemType_t modem) {
     550           2 :   switch(modem) {
     551             :     // the default 434 MHz is out of range for SX1272, so keep the current frequency
     552           0 :     case(ModemType_t::RADIOLIB_MODEM_LORA): {
     553           0 :       ConfigLoRa_t cfg;
     554           0 :       cfg.frequency = this->frequency;
     555           0 :       return(this->begin(cfg));
     556             :     } break;
     557           0 :     case(ModemType_t::RADIOLIB_MODEM_FSK): {
     558           0 :       ConfigFSK_t cfg;
     559           0 :       cfg.frequency = this->frequency;
     560           0 :       return(this->beginFSK(cfg));
     561             :     } break;
     562           2 :     default:
     563           2 :       return(RADIOLIB_ERR_WRONG_MODEM);
     564             :   }
     565             : }
     566             : 
     567             : #endif

Generated by: LCOV version 1.14