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
|