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