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