Line data Source code
1 : #include "LR1120.h" 2 : #include <math.h> 3 : 4 : #if !RADIOLIB_EXCLUDE_LR11X0 5 : 6 2 : LR1120::LR1120(Module* mod) : LR11x0(mod) { 7 2 : chipType = RADIOLIB_LR11X0_DEVICE_LR1120; 8 2 : this->updatePowerLimits(false); 9 2 : } 10 : 11 0 : int16_t LR1120::begin(const ConfigLoRa_t& cfg) { 12 : // execute common part 13 0 : int16_t state = LR11x0::begin(cfg.bandwidth, cfg.spreadingFactor, cfg.codingRate, cfg.syncWord, cfg.preambleLength, (cfg.frequency > RADIOLIB_LR11X0_LF_CUTOFF_FREQ)); 14 0 : RADIOLIB_ASSERT(state); 15 : 16 : // configure publicly accessible settings 17 0 : state = setFrequency(cfg.frequency); 18 0 : RADIOLIB_ASSERT(state); 19 : 20 0 : state = setOutputPower(cfg.power); 21 0 : return(state); 22 : } 23 : 24 0 : int16_t LR1120::beginGFSK(const ConfigFSK_t& cfg) { 25 : // execute common part 26 0 : int16_t state = LR11x0::beginGFSK(cfg.bitRate, cfg.frequencyDeviation, cfg.receiverBandwidth, cfg.preambleLength); 27 0 : RADIOLIB_ASSERT(state); 28 : 29 : // configure publicly accessible settings 30 0 : state = setFrequency(cfg.frequency); 31 0 : RADIOLIB_ASSERT(state); 32 : 33 0 : state = setOutputPower(cfg.power); 34 0 : return(state); 35 : } 36 : 37 0 : int16_t LR1120::beginLRFHSS(const ConfigLRFHSS_t& cfg) { 38 : // execute common part 39 0 : int16_t state = LR11x0::beginLRFHSS(cfg.bandwidth, cfg.bandwidth, cfg.narrowGrid); 40 0 : RADIOLIB_ASSERT(state); 41 : 42 : // configure publicly accessible settings 43 0 : state = setFrequency(cfg.frequency); 44 0 : RADIOLIB_ASSERT(state); 45 : 46 0 : state = setOutputPower(cfg.power); 47 0 : return(state); 48 : } 49 : 50 2 : int16_t LR1120::setFrequency(uint32_t freq) { 51 2 : return(this->setFrequency(freq, false)); 52 : } 53 : 54 2 : int16_t LR1120::setFrequency(uint32_t freq, bool skipCalibration, uint32_t band) { 55 : #if RADIOLIB_CHECK_PARAMS 56 2 : if(!(((freq >= RADIOLIB_UNIT_MEGA(150)) && (freq <= RADIOLIB_UNIT_MEGA(960))) || 57 0 : ((freq >= RADIOLIB_UNIT_MEGA(1900)) && (freq <= RADIOLIB_UNIT_MEGA(2200))) || 58 0 : ((freq >= RADIOLIB_UNIT_MEGA(2400)) && (freq <= RADIOLIB_UNIT_MEGA(2500))))) { 59 2 : return(RADIOLIB_ERR_INVALID_FREQUENCY); 60 : } 61 : #endif 62 : 63 : // check if we need to recalibrate image 64 : int16_t state; 65 0 : if(!skipCalibration && (RADIOLIB_ABS_UNSIGNED(freq, this->freqHz) >= RADIOLIB_UNIT_MEGA(RADIOLIB_LR11X0_CAL_IMG_FREQ_TRIG_MHZ))) { 66 0 : state = LR11x0::calibrateImageRejection(freq - band, freq + band); 67 0 : RADIOLIB_ASSERT(state); 68 : } 69 : 70 : // set frequency 71 0 : state = LR11x0::setRfFrequency(freq); 72 0 : RADIOLIB_ASSERT(state); 73 : 74 0 : this->freqHz = freq; 75 0 : this->highFreq = (freq > RADIOLIB_LR11X0_LF_CUTOFF_FREQ); 76 : 77 : // power limits depend on the frequency band 78 0 : this->updatePowerLimits(this->highFreq); 79 : 80 : // apply workaround for GFSK 81 0 : return(workaroundGFSK()); 82 : } 83 : 84 2 : int16_t LR1120::setOutputPower(int8_t power) { 85 2 : return(this->setOutputPower(power, false)); 86 : } 87 : 88 2 : int16_t LR1120::setOutputPower(int8_t power, bool forceHighPower, uint32_t rampTimeUs) { 89 : // apply offset for external PA 90 2 : int8_t pwr = power; 91 2 : int16_t state = this->applyOutputPowerOffset(this->highFreq ? RADIOLIB_LR112X_HF_POUT_MIN : RADIOLIB_LR112X_LP_POUT_MIN, &power, &pwr); 92 2 : RADIOLIB_ASSERT(state); 93 : 94 : // determine whether to use HP or LP PA 95 2 : bool useHp = forceHighPower || (pwr > RADIOLIB_LR112X_LP_POUT_MAX); 96 2 : uint8_t paSel = 0; 97 2 : uint8_t paSupply = 0; 98 2 : this->txMode = LR11x0::MODE_TX; 99 2 : if(this->highFreq) { 100 0 : paSel = 2; 101 0 : this->txMode = LR11x0::MODE_TX_HF; 102 2 : } else if(useHp) { 103 0 : paSel = 1; 104 0 : paSupply = 1; 105 0 : this->txMode = LR11x0::MODE_TX_HP; 106 : } 107 : 108 : //! \TODO: [LR1120] how and when to configure OCP? 109 : 110 : // update PA config and set output power - always use VBAT for high-power PA 111 : // the value returned by LRxxxx class is offset by 3 for LR11x0 112 2 : state = LR11x0::setOutputPower(pwr, paSel, paSupply, 0x04, 0x07, roundRampTime(rampTimeUs) - 0x03); 113 2 : return(state); 114 : } 115 : 116 2 : int16_t LR1120::setModem(ModemType_t modem) { 117 2 : switch(modem) { 118 0 : case(ModemType_t::RADIOLIB_MODEM_LORA): { 119 0 : ConfigLoRa_t cfg; 120 0 : return(this->begin(cfg)); 121 : } break; 122 0 : case(ModemType_t::RADIOLIB_MODEM_FSK): { 123 0 : ConfigFSK_t cfg; 124 0 : return(this->beginGFSK(cfg)); 125 : } break; 126 0 : case(ModemType_t::RADIOLIB_MODEM_LRFHSS): { 127 0 : ConfigLRFHSS_t cfg; 128 0 : return(this->beginLRFHSS(cfg)); 129 : } break; 130 2 : default: 131 2 : return(RADIOLIB_ERR_WRONG_MODEM); 132 : } 133 : return(RADIOLIB_ERR_WRONG_MODEM); 134 : } 135 : 136 2 : void LR1120::updatePowerLimits(bool highFreq) { 137 2 : if(highFreq) { 138 0 : this->powerMin = RADIOLIB_LR112X_HF_POUT_MIN; 139 0 : this->powerMax = RADIOLIB_LR112X_HF_POUT_MAX; 140 : } else { 141 2 : this->powerMin = RADIOLIB_LR112X_LP_POUT_MIN; 142 2 : this->powerMax = RADIOLIB_LR112X_HP_POUT_MAX; 143 : } 144 2 : this->paSteps = this->powerMax - this->powerMin + 1; 145 2 : } 146 : 147 : #endif