SingingCat 0
application
sx126x.c
Go to the documentation of this file.
1
32/*
33 * -----------------------------------------------------------------------------
34 * --- DEPENDENCIES ------------------------------------------------------------
35 */
36
37//#include <string.h> // memcpy
38#include "sx1262/sx126x.h"
39#include "sx1262/sx126x_hal.h"
40#include "sx1262/sx126x_regs.h"
41
42/*
43 * -----------------------------------------------------------------------------
44 * --- PRIVATE MACROS-----------------------------------------------------------
45 */
46
47/*
48 * -----------------------------------------------------------------------------
49 * --- PRIVATE CONSTANTS -------------------------------------------------------
50 */
51
55#define SX126X_XTAL_FREQ 32000000UL
56
60#define SX126X_RTC_FREQ_IN_HZ 64000UL
61
65#define SX126X_PLL_STEP_SHIFT_AMOUNT (14)
66
70#define SX126X_PLL_STEP_SCALED (SX126X_XTAL_FREQ >> (25 - SX126X_PLL_STEP_SHIFT_AMOUNT))
71
72/*
73 * -----------------------------------------------------------------------------
74 * --- PRIVATE TYPES -----------------------------------------------------------
75 */
76
80typedef enum sx126x_commands_e {
81 // Operational Modes Functions
82 SX126X_SET_SLEEP = 0x84,
83 SX126X_SET_STANDBY = 0x80,
84 SX126X_SET_FS = 0xC1,
85 SX126X_SET_TX = 0x83,
86 SX126X_SET_RX = 0x82,
87 SX126X_SET_STOP_TIMER_ON_PREAMBLE = 0x9F,
88 SX126X_SET_RX_DUTY_CYCLE = 0x94,
89 SX126X_SET_CAD = 0xC5,
90 SX126X_SET_TX_CONTINUOUS_WAVE = 0xD1,
91 SX126X_SET_TX_INFINITE_PREAMBLE = 0xD2,
92 SX126X_SET_REGULATOR_MODE = 0x96,
93 SX126X_CALIBRATE = 0x89,
94 SX126X_CALIBRATE_IMAGE = 0x98,
95 SX126X_SET_PA_CFG = 0x95,
96 SX126X_SET_RX_TX_FALLBACK_MODE = 0x93,
97 // Registers and buffer Access
98 SX126X_WRITE_REGISTER = 0x0D,
99 SX126X_READ_REGISTER = 0x1D,
100 SX126X_WRITE_BUFFER = 0x0E,
101 SX126X_READ_BUFFER = 0x1E,
102 // DIO and IRQ Control Functions
103 SX126X_SET_DIO_IRQ_PARAMS = 0x08,
104 SX126X_GET_IRQ_STATUS = 0x12,
105 SX126X_CLR_IRQ_STATUS = 0x02,
106 SX126X_SET_DIO2_AS_RF_SWITCH_CTRL = 0x9D,
107 SX126X_SET_DIO3_AS_TCXO_CTRL = 0x97,
108 // RF Modulation and Packet-Related Functions
109 SX126X_SET_RF_FREQUENCY = 0x86,
110 SX126X_SET_PKT_TYPE = 0x8A,
111 SX126X_GET_PKT_TYPE = 0x11,
112 SX126X_SET_TX_PARAMS = 0x8E,
113 SX126X_SET_MODULATION_PARAMS = 0x8B,
114 SX126X_SET_PKT_PARAMS = 0x8C,
115 SX126X_SET_CAD_PARAMS = 0x88,
116 SX126X_SET_BUFFER_BASE_ADDRESS = 0x8F,
117 SX126X_SET_LORA_SYMB_NUM_TIMEOUT = 0xA0,
118 // Communication Status Information
119 SX126X_GET_STATUS = 0xC0,
120 SX126X_GET_RX_BUFFER_STATUS = 0x13,
121 SX126X_GET_PKT_STATUS = 0x14,
122 SX126X_GET_RSSI_INST = 0x15,
123 SX126X_GET_STATS = 0x10,
124 SX126X_RESET_STATS = 0x00,
125 // Miscellaneous
126 SX126X_GET_DEVICE_ERRORS = 0x17,
127 SX126X_CLR_DEVICE_ERRORS = 0x07,
129
134 // Operational Modes Functions
135 SX126X_SIZE_SET_SLEEP = 2,
136 SX126X_SIZE_SET_STANDBY = 2,
137 SX126X_SIZE_SET_FS = 1,
138 SX126X_SIZE_SET_TX = 4,
139 SX126X_SIZE_SET_RX = 4,
140 SX126X_SIZE_SET_STOP_TIMER_ON_PREAMBLE = 2,
141 SX126X_SIZE_SET_RX_DUTY_CYCLE = 7,
142 SX126X_SIZE_SET_CAD = 1,
143 SX126X_SIZE_SET_TX_CONTINUOUS_WAVE = 1,
144 SX126X_SIZE_SET_TX_INFINITE_PREAMBLE = 1,
145 SX126X_SIZE_SET_REGULATOR_MODE = 2,
146 SX126X_SIZE_CALIBRATE = 2,
147 SX126X_SIZE_CALIBRATE_IMAGE = 3,
148 SX126X_SIZE_SET_PA_CFG = 5,
149 SX126X_SIZE_SET_RX_TX_FALLBACK_MODE = 2,
150 // Registers and buffer Access
151 // Full size: this value plus buffer size
152 SX126X_SIZE_WRITE_REGISTER = 3,
153 // Full size: this value plus buffer size
154 SX126X_SIZE_READ_REGISTER = 4,
155 // Full size: this value plus buffer size
156 SX126X_SIZE_WRITE_BUFFER = 2,
157 // Full size: this value plus buffer size
158 SX126X_SIZE_READ_BUFFER = 3,
159 // DIO and IRQ Control Functions
160 SX126X_SIZE_SET_DIO_IRQ_PARAMS = 9,
161 SX126X_SIZE_GET_IRQ_STATUS = 2,
162 SX126X_SIZE_CLR_IRQ_STATUS = 3,
163 SX126X_SIZE_SET_DIO2_AS_RF_SWITCH_CTRL = 2,
164 SX126X_SIZE_SET_DIO3_AS_TCXO_CTRL = 5,
165 // RF Modulation and Packet-Related Functions
166 SX126X_SIZE_SET_RF_FREQUENCY = 5,
167 SX126X_SIZE_SET_PKT_TYPE = 2,
168 SX126X_SIZE_GET_PKT_TYPE = 3,
169 SX126X_SIZE_SET_TX_PARAMS = 3,
170 SX126X_SIZE_SET_MODULATION_PARAMS_GFSK = 9,
171 SX126X_SIZE_SET_MODULATION_PARAMS_LORA = 5,
172 SX126X_SIZE_SET_PKT_PARAMS_GFSK = 10,
173 SX126X_SIZE_SET_PKT_PARAMS_LORA = 7,
174 SX126X_SIZE_SET_CAD_PARAMS = 8,
175 SX126X_SIZE_SET_BUFFER_BASE_ADDRESS = 3,
176 SX126X_SIZE_SET_LORA_SYMB_NUM_TIMEOUT = 2,
177 // Communication Status Information
178 SX126X_SIZE_GET_STATUS = 1,
179 SX126X_SIZE_GET_RX_BUFFER_STATUS = 2,
180 SX126X_SIZE_GET_PKT_STATUS = 2,
181 SX126X_SIZE_GET_RSSI_INST = 2,
182 SX126X_SIZE_GET_STATS = 2,
183 SX126X_SIZE_RESET_STATS = 7,
184 // Miscellaneous
185 SX126X_SIZE_GET_DEVICE_ERRORS = 2,
186 SX126X_SIZE_CLR_DEVICE_ERRORS = 3,
187 SX126X_SIZE_MAX_BUFFER = 255,
188 SX126X_SIZE_DUMMY_BYTE = 1,
190
191typedef struct {
192 uint32_t bw;
193 uint8_t param;
194} gfsk_bw_t;
195/*
196 * gfsk_bw_t gfsk_bw[] = {
197 * { 4800, SX126X_GFSK_BW_4800 }, { 5800, SX126X_GFSK_BW_5800 }, { 7300, SX126X_GFSK_BW_7300 },
198 * { 9700, SX126X_GFSK_BW_9700 }, { 11700, SX126X_GFSK_BW_11700 }, { 14600, SX126X_GFSK_BW_14600 },
199 * { 19500, SX126X_GFSK_BW_19500 }, { 23400, SX126X_GFSK_BW_23400 }, { 29300, SX126X_GFSK_BW_29300 },
200 * { 39000, SX126X_GFSK_BW_39000 }, { 46900, SX126X_GFSK_BW_46900 }, { 58600, SX126X_GFSK_BW_58600 },
201 * { 78200, SX126X_GFSK_BW_78200 }, { 93800, SX126X_GFSK_BW_93800 }, { 117300, SX126X_GFSK_BW_117300 },
202 * { 156200, SX126X_GFSK_BW_156200 }, { 187200, SX126X_GFSK_BW_187200 }, { 234300, SX126X_GFSK_BW_234300 },
203 * { 312000, SX126X_GFSK_BW_312000 }, { 373600, SX126X_GFSK_BW_373600 }, { 467000, SX126X_GFSK_BW_467000 },
204 * };
205 */
206/*
207 * -----------------------------------------------------------------------------
208 * --- PRIVATE VARIABLES -------------------------------------------------------
209 */
210
211/*
212 * -----------------------------------------------------------------------------
213 * --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
214 */
215
230static sx126x_status_t sx126x_tx_modulation_workaround(struct network_context *nctx, sx126x_pkt_type_t pkt_type, sx126x_lora_bw_t bw);
231
232
233/*
234 * -----------------------------------------------------------------------------
235 * --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
236 */
237/*
238 * sx126x_status_t sx126x_set_sleep(struct network_context *nctx, const sx126x_sleep_cfgs_t cfg) {
239 * uint8_t buf[SX126X_SIZE_SET_SLEEP] = { 0 };
240 *
241 * buf[0] = SX126X_SET_SLEEP;
242 *
243 * buf[1] = (uint8_t)cfg;
244 *
245 * return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_SLEEP, 0, 0);
246 * }
247 */
248sx126x_status_t sx126x_set_standby(struct network_context *nctx, const sx126x_standby_cfg_t cfg) {
249 uint8_t buf[SX126X_SIZE_SET_STANDBY] = { 0 };
250
251 buf[0] = SX126X_SET_STANDBY;
252
253 buf[1] = (uint8_t)cfg;
254
255 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_STANDBY, 0, 0);
256}
257
258sx126x_status_t sx126x_set_tx(struct network_context *nctx, const uint32_t timeout_in_ms) {
259 if (timeout_in_ms > SX126X_MAX_TIMEOUT_IN_MS) {
260 return SX126X_STATUS_UNKNOWN_VALUE;
261 }
262
263 const uint32_t timeout_in_rtc_step = sx126x_convert_timeout_in_ms_to_rtc_step(timeout_in_ms);
264
265 return sx126x_set_tx_with_timeout_in_rtc_step(nctx, timeout_in_rtc_step);
266}
267
268sx126x_status_t sx126x_set_tx_with_timeout_in_rtc_step(struct network_context *nctx, const uint32_t timeout_in_rtc_step) {
269 uint8_t buf[SX126X_SIZE_SET_TX] = { 0 };
270
271 buf[0] = SX126X_SET_TX;
272
273 buf[1] = (uint8_t)(timeout_in_rtc_step >> 16);
274 buf[2] = (uint8_t)(timeout_in_rtc_step >> 8);
275 buf[3] = (uint8_t)(timeout_in_rtc_step >> 0);
276
277 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_TX, 0, 0);
278}
279
280sx126x_status_t sx126x_set_rx(struct network_context *nctx, const uint32_t timeout_in_ms) {
281 if (timeout_in_ms > SX126X_MAX_TIMEOUT_IN_MS) {
282 return SX126X_STATUS_UNKNOWN_VALUE;
283 }
284
285 const uint32_t timeout_in_rtc_step = sx126x_convert_timeout_in_ms_to_rtc_step(timeout_in_ms);
286
287 return sx126x_set_rx_with_timeout_in_rtc_step(nctx, timeout_in_rtc_step);
288}
289
290sx126x_status_t sx126x_set_rx_with_timeout_in_rtc_step(struct network_context *nctx, const uint32_t timeout_in_rtc_step) {
291 uint8_t buf[SX126X_SIZE_SET_RX] = { 0 };
292
293 buf[0] = SX126X_SET_RX;
294
295 buf[1] = (uint8_t)(timeout_in_rtc_step >> 16);
296 buf[2] = (uint8_t)(timeout_in_rtc_step >> 8);
297 buf[3] = (uint8_t)(timeout_in_rtc_step >> 0);
298
299 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_RX, 0, 0);
300}
301
303 const uint32_t rx_time_in_rtc_step,
304 const uint32_t sleep_time_in_rtc_step) {
305 uint8_t buf[SX126X_SIZE_SET_RX_DUTY_CYCLE] = { 0 };
306
307 buf[0] = SX126X_SET_RX_DUTY_CYCLE;
308
309 buf[1] = (uint8_t)(rx_time_in_rtc_step >> 16);
310 buf[2] = (uint8_t)(rx_time_in_rtc_step >> 8);
311 buf[3] = (uint8_t)(rx_time_in_rtc_step >> 0);
312
313 buf[4] = (uint8_t)(sleep_time_in_rtc_step >> 16);
314 buf[5] = (uint8_t)(sleep_time_in_rtc_step >> 8);
315 buf[6] = (uint8_t)(sleep_time_in_rtc_step >> 0);
316
317 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_RX_DUTY_CYCLE, 0, 0);
318}
319
321 uint8_t buf[SX126X_SIZE_SET_CAD] = { 0 };
322
323 buf[0] = SX126X_SET_CAD;
324
325 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_CAD, 0, 0);
326}
327
329 uint8_t buf[SX126X_SIZE_SET_REGULATOR_MODE] = { 0 };
330
331 buf[0] = SX126X_SET_REGULATOR_MODE;
332
333 buf[1] = (uint8_t)mode;
334
335 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_REGULATOR_MODE, 0, 0);
336}
337
338sx126x_status_t sx126x_cal(struct network_context *nctx, const sx126x_cal_mask_t param) {
339 uint8_t buf[SX126X_SIZE_CALIBRATE] = { 0 };
340
341 buf[0] = SX126X_CALIBRATE;
342
343 buf[1] = param;
344
345 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_CALIBRATE, 0, 0);
346}
347
348sx126x_status_t sx126x_cal_img(struct network_context *nctx, const uint32_t freq_in_hz) {
349 uint8_t buf[SX126X_SIZE_CALIBRATE_IMAGE] = { 0 };
350
351 buf[0] = SX126X_CALIBRATE_IMAGE;
352
353 if (freq_in_hz > 900000000) {
354 buf[1] = 0xE1;
355 buf[2] = 0xE9;
356 } else if (freq_in_hz > 850000000) {
357 buf[1] = 0xD7;
358 buf[2] = 0xDB;
359 } else if (freq_in_hz > 770000000) {
360 buf[1] = 0xC1;
361 buf[2] = 0xC5;
362 } else if (freq_in_hz > 460000000) {
363 buf[1] = 0x75;
364 buf[2] = 0x81;
365 } else {
366 buf[1] = 0x6B;
367 buf[2] = 0x6F;
368 }
369
370 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_CALIBRATE_IMAGE, 0, 0);
371}
372
374 uint8_t buf[SX126X_SIZE_SET_PA_CFG] = { 0 };
375
376 buf[0] = SX126X_SET_PA_CFG;
377
378 buf[1] = params->pa_duty_cycle;
379 buf[2] = params->hp_max;
380 buf[3] = params->device_sel;
381 buf[4] = params->pa_lut;
382
383 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_PA_CFG, 0, 0);
384}
385
387 uint8_t buf[SX126X_SIZE_SET_RX_TX_FALLBACK_MODE] = { 0 };
388
389 buf[0] = SX126X_SET_RX_TX_FALLBACK_MODE;
390
391 buf[1] = (uint8_t)fallback_mode;
392
393 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_RX_TX_FALLBACK_MODE, 0, 0);
394}
395
396//
397// Registers and buffer Access
398//
399
400sx126x_status_t sx126x_write_register(struct network_context *nctx, const uint16_t address, const uint8_t *buffer,
401 const uint8_t size) {
402 uint8_t buf[SX126X_SIZE_WRITE_REGISTER] = { 0 };
403
404 buf[0] = SX126X_WRITE_REGISTER;
405
406 buf[1] = (uint8_t)(address >> 8);
407 buf[2] = (uint8_t)(address >> 0);
408
409 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_WRITE_REGISTER, buffer, size);
410}
411
412sx126x_status_t sx126x_read_register(struct network_context *nctx, const uint16_t address, uint8_t *buffer, const uint8_t size) {
413 uint8_t buf[SX126X_SIZE_READ_REGISTER] = { 0 };
414 sx126x_status_t status = SX126X_STATUS_ERROR;
415
416 buf[0] = SX126X_READ_REGISTER;
417
418 buf[1] = (uint8_t)(address >> 8);
419 buf[2] = (uint8_t)(address >> 0);
420
421 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_READ_REGISTER, buffer, size);
422
423 return status;
424}
425
426sx126x_status_t sx126x_write_buffer(struct network_context *nctx, const uint8_t offset, const uint8_t *buffer,
427 const uint8_t size) {
428 uint8_t buf[SX126X_SIZE_WRITE_BUFFER] = { 0 };
429
430 buf[0] = SX126X_WRITE_BUFFER;
431
432 buf[1] = offset;
433
434 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_WRITE_BUFFER, buffer, size);
435}
436
437sx126x_status_t sx126x_read_buffer(struct network_context *nctx, const uint8_t offset, uint8_t *buffer, const uint8_t size) {
438 uint8_t buf[SX126X_SIZE_READ_BUFFER] = { 0 };
439 sx126x_status_t status = SX126X_STATUS_ERROR;
440
441 buf[0] = SX126X_READ_BUFFER;
442
443 buf[1] = offset;
444
445 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_READ_BUFFER, buffer, size);
446
447 return status;
448}
449
450//
451// DIO and IRQ Control Functions
452//
453sx126x_status_t sx126x_set_dio_irq_params(struct network_context *nctx, const uint16_t irq_mask, const uint16_t dio1_mask,
454 const uint16_t dio2_mask, const uint16_t dio3_mask) {
455 uint8_t buf[SX126X_SIZE_SET_DIO_IRQ_PARAMS] = { 0 };
456
457 buf[0] = SX126X_SET_DIO_IRQ_PARAMS;
458
459 buf[1] = (uint8_t)(irq_mask >> 8);
460 buf[2] = (uint8_t)(irq_mask >> 0);
461
462 buf[3] = (uint8_t)(dio1_mask >> 8);
463 buf[4] = (uint8_t)(dio1_mask >> 0);
464
465 buf[5] = (uint8_t)(dio2_mask >> 8);
466 buf[6] = (uint8_t)(dio2_mask >> 0);
467
468 buf[7] = (uint8_t)(dio3_mask >> 8);
469 buf[8] = (uint8_t)(dio3_mask >> 0);
470
471 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_DIO_IRQ_PARAMS, 0, 0);
472}
473
474sx126x_status_t sx126x_get_irq_status(struct network_context *nctx, sx126x_irq_mask_t *irq) {
475 uint8_t buf[SX126X_SIZE_GET_IRQ_STATUS] = { 0 };
476 uint8_t irq_local[sizeof(sx126x_irq_mask_t)] = { 0x00 };
477 sx126x_status_t status = SX126X_STATUS_ERROR;
478
479 buf[0] = SX126X_GET_IRQ_STATUS;
480
481 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_GET_IRQ_STATUS, irq_local,
482 sizeof(sx126x_irq_mask_t));
483
484 if (status == SX126X_STATUS_OK) {
485 *irq = ((sx126x_irq_mask_t)irq_local[0] << 8) + ((sx126x_irq_mask_t)irq_local[1] << 0);
486 }
487
488 return status;
489}
490
491sx126x_status_t sx126x_clear_irq_status(struct network_context *nctx, const sx126x_irq_mask_t irq_mask) {
492 uint8_t buf[SX126X_SIZE_CLR_IRQ_STATUS] = { 0 };
493
494 buf[0] = SX126X_CLR_IRQ_STATUS;
495
496 buf[1] = (uint8_t)(irq_mask >> 8);
497 buf[2] = (uint8_t)(irq_mask >> 0);
498
499 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_CLR_IRQ_STATUS, 0, 0);
500}
501
503 sx126x_irq_mask_t sx126x_irq_mask = SX126X_IRQ_NONE;
504
505 sx126x_status_t status = sx126x_get_irq_status(nctx, &sx126x_irq_mask);
506
507 if ((status == SX126X_STATUS_OK) && (sx126x_irq_mask != 0)) {
508 status = sx126x_clear_irq_status(nctx, sx126x_irq_mask);
509 }
510 if ((status == SX126X_STATUS_OK) && (irq != NULL)) {
511 *irq = sx126x_irq_mask;
512 }
513 return status;
514}
515
517 uint8_t buf[SX126X_SIZE_SET_DIO2_AS_RF_SWITCH_CTRL] = { 0 };
518
519 buf[0] = SX126X_SET_DIO2_AS_RF_SWITCH_CTRL;
520
521 buf[1] = (enable == true) ? 1 : 0;
522
523 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_DIO2_AS_RF_SWITCH_CTRL, 0, 0);
524}
525
527 const uint32_t timeout) {
528 uint8_t buf[SX126X_SIZE_SET_DIO3_AS_TCXO_CTRL] = { 0 };
529
530 buf[0] = SX126X_SET_DIO3_AS_TCXO_CTRL;
531
532 buf[1] = (uint8_t)tcxo_voltage;
533
534 buf[2] = (uint8_t)(timeout >> 16);
535 buf[3] = (uint8_t)(timeout >> 8);
536 buf[4] = (uint8_t)(timeout >> 0);
537
538 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_DIO3_AS_TCXO_CTRL, 0, 0);
539}
540
541//
542// RF Modulation and Packet-Related Functions
543//
544
545sx126x_status_t sx126x_set_rf_freq(struct network_context *nctx, const uint32_t freq_in_hz) {
546 const uint32_t freq = sx126x_convert_freq_in_hz_to_pll_step(freq_in_hz);
547
548 return sx126x_set_rf_freq_in_pll_steps(nctx, freq);
549}
550
552 uint8_t buf[SX126X_SIZE_SET_RF_FREQUENCY] = { 0 };
553
554 buf[0] = SX126X_SET_RF_FREQUENCY;
555
556 buf[1] = (uint8_t)(freq >> 24);
557 buf[2] = (uint8_t)(freq >> 16);
558 buf[3] = (uint8_t)(freq >> 8);
559 buf[4] = (uint8_t)(freq >> 0);
560
561 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_RF_FREQUENCY, 0, 0);
562}
563
565 uint8_t buf[SX126X_SIZE_SET_PKT_TYPE] = { 0 };
566
567 buf[0] = SX126X_SET_PKT_TYPE;
568
569 buf[1] = (uint8_t)pkt_type;
570
571 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_PKT_TYPE, 0, 0);
572}
573
575 uint8_t buf[SX126X_SIZE_GET_PKT_TYPE] = { 0 };
576 sx126x_status_t status = SX126X_STATUS_ERROR;
577 uint8_t pkt_type_raw;
578
579 buf[0] = SX126X_GET_PKT_TYPE;
580
581 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_GET_PKT_TYPE, &pkt_type_raw, 1);
582 *pkt_type = (sx126x_pkt_type_t)pkt_type_raw;
583
584 return status;
585}
586
587sx126x_status_t sx126x_set_tx_params(struct network_context *nctx, const int8_t pwr_in_dbm, const sx126x_ramp_time_t ramp_time) {
588 uint8_t buf[SX126X_SIZE_SET_TX_PARAMS] = { 0 };
589
590 buf[0] = SX126X_SET_TX_PARAMS;
591
592 buf[1] = (uint8_t)pwr_in_dbm;
593 buf[2] = (uint8_t)ramp_time;
594
595 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_TX_PARAMS, 0, 0);
596}
597
598
599
601 sx126x_status_t status = SX126X_STATUS_ERROR;
602
603 uint8_t buf[SX126X_SIZE_SET_MODULATION_PARAMS_LORA] = { 0 };
604
605 buf[0] = SX126X_SET_MODULATION_PARAMS;
606
607 buf[1] = (uint8_t)(params->sf);
608 buf[2] = (uint8_t)(params->bw);
609 buf[3] = (uint8_t)(params->cr);
610 buf[4] = params->ldro & 0x01;
611
612 status = (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_MODULATION_PARAMS_LORA, 0, 0);
613
614 if (status == SX126X_STATUS_OK) {
615 // WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see datasheet DS_SX1261-2_V1.2 §15.1
616 status = sx126x_tx_modulation_workaround(nctx, SX126X_PKT_TYPE_LORA, params->bw);
617 // WORKAROUND END
618 }
619
620 return status;
621}
622
623
625 sx126x_status_t status = SX126X_STATUS_ERROR;
626
627 uint8_t buf[SX126X_SIZE_SET_PKT_PARAMS_LORA] = { 0 };
628
629 buf[0] = SX126X_SET_PKT_PARAMS;
630
631 buf[1] = (uint8_t)(params->preamble_len_in_symb >> 8);
632 buf[2] = (uint8_t)(params->preamble_len_in_symb >> 0);
633 buf[3] = (uint8_t)(params->header_type);
634 buf[4] = params->pld_len_in_bytes;
635 buf[5] = (uint8_t)(params->crc_is_on ? 1 : 0);
636 buf[6] = (uint8_t)(params->invert_iq_is_on ? 1 : 0);
637
638 status = (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_PKT_PARAMS_LORA, 0, 0);
639
640 // WORKAROUND - Optimizing the Inverted IQ Operation, see datasheet DS_SX1261-2_V1.2 §15.4
641 if (status == SX126X_STATUS_OK) {
642 uint8_t reg_value = 0;
643
644 status = sx126x_read_register(nctx, SX126X_REG_IRQ_POLARITY, &reg_value, 1);
645 if (status == SX126X_STATUS_OK) {
646 if (params->invert_iq_is_on == true) {
647 reg_value &= ~(1 << 2); // Bit 2 set to 0 when using inverted IQ polarity
648 } else {
649 reg_value |= (1 << 2); // Bit 2 set to 1 when using standard IQ polarity
650 }
651 status = sx126x_write_register(nctx, SX126X_REG_IRQ_POLARITY, &reg_value, 1);
652 }
653 }
654 // WORKAROUND END
655
656 return status;
657}
658
660 uint8_t buf[SX126X_SIZE_SET_CAD_PARAMS] = { 0 };
661
662 buf[0] = SX126X_SET_CAD_PARAMS;
663
664 buf[1] = (uint8_t)params->cad_symb_nb;
665 buf[2] = params->cad_detect_peak;
666 buf[3] = params->cad_detect_min;
667 buf[4] = (uint8_t)params->cad_exit_mode;
668 buf[5] = (uint8_t)(params->cad_timeout >> 16);
669 buf[6] = (uint8_t)(params->cad_timeout >> 8);
670 buf[7] = (uint8_t)(params->cad_timeout >> 0);
671
672 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_CAD_PARAMS, 0, 0);
673}
674
675sx126x_status_t sx126x_set_buffer_base_address(struct network_context *nctx, const uint8_t tx_base_address,
676 const uint8_t rx_base_address) {
677 uint8_t buf[SX126X_SIZE_SET_BUFFER_BASE_ADDRESS] = { 0 };
678
679 buf[0] = SX126X_SET_BUFFER_BASE_ADDRESS;
680
681 buf[1] = tx_base_address;
682 buf[2] = rx_base_address;
683
684 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_BUFFER_BASE_ADDRESS, 0, 0);
685}
686
687sx126x_status_t sx126x_set_lora_symb_nb_timeout(struct network_context *nctx, const uint8_t nb_of_symbs) {
688 uint8_t buf[SX126X_SIZE_SET_LORA_SYMB_NUM_TIMEOUT] = { 0 };
689 sx126x_status_t status = SX126X_STATUS_ERROR;
690
691 buf[0] = SX126X_SET_LORA_SYMB_NUM_TIMEOUT;
692
693 buf[1] = nb_of_symbs;
694
695 status = (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_SET_LORA_SYMB_NUM_TIMEOUT, 0, 0);
696
697 if ((status == SX126X_STATUS_OK) && (nb_of_symbs >= 64)) {
698 uint8_t mant = nb_of_symbs >> 1;
699 uint8_t exp = 0;
700 uint8_t reg = 0;
701
702 while (mant > 31) {
703 mant >>= 2;
704 exp++;
705 }
706
707 reg = exp + (mant << 3);
708 status = sx126x_write_register(nctx, SX126X_REG_LR_SYNCH_TIMEOUT, &reg, 1);
709 }
710
711 return status;
712}
713
714//
715// Communication Status Information
716//
717
719 uint8_t buf[SX126X_SIZE_GET_STATUS] = { 0 };
720 uint8_t status_local = 0;
721 sx126x_status_t status = SX126X_STATUS_ERROR;
722
723 buf[0] = SX126X_GET_STATUS;
724
725 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_GET_STATUS, &status_local, 1);
726
727 if (status == SX126X_STATUS_OK) {
728 radio_status->cmd_status =
729 (sx126x_cmd_status_t)((status_local & SX126X_CMD_STATUS_MASK) >> SX126X_CMD_STATUS_POS);
730 radio_status->chip_mode =
731 (sx126x_chip_modes_t)((status_local & SX126X_CHIP_MODES_MASK) >> SX126X_CHIP_MODES_POS);
732 }
733
734 return status;
735}
736
738 uint8_t buf[SX126X_SIZE_GET_RX_BUFFER_STATUS] = { 0 };
739 uint8_t status_local[sizeof(sx126x_rx_buffer_status_t)] = { 0x00 };
740 sx126x_status_t status = SX126X_STATUS_ERROR;
741
742 buf[0] = SX126X_GET_RX_BUFFER_STATUS;
743
744 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_GET_RX_BUFFER_STATUS, status_local,
746
747 if (status == SX126X_STATUS_OK) {
748 rx_buffer_status->pld_len_in_bytes = status_local[0];
749 rx_buffer_status->buffer_start_pointer = status_local[1];
750 }
751
752 return status;
753}
754
756 uint8_t buf[SX126X_SIZE_GET_PKT_STATUS] = { 0 };
757 uint8_t pkt_status_local[sizeof(sx126x_pkt_status_lora_t)] = { 0x00 };
758 sx126x_status_t status = SX126X_STATUS_ERROR;
759
760 buf[0] = SX126X_GET_PKT_STATUS;
761
762 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_GET_PKT_STATUS, pkt_status_local,
764
765 if (status == SX126X_STATUS_OK) {
766 pkt_status->rssi_pkt_in_dbm = (int8_t)(-pkt_status_local[0] >> 1);
767 pkt_status->snr_pkt_in_db = (((int8_t)pkt_status_local[1]) + 2) >> 2;
768 pkt_status->signal_rssi_pkt_in_dbm = (int8_t)(-pkt_status_local[2] >> 1);
769 }
770
771 return status;
772}
773
774sx126x_status_t sx126x_get_rssi_inst(struct network_context *nctx, int16_t *rssi_in_dbm) {
775 uint8_t buf[SX126X_SIZE_GET_RSSI_INST] = { 0 };
776 uint8_t rssi_local = 0x00;
777 sx126x_status_t status = SX126X_STATUS_ERROR;
778
779 buf[0] = SX126X_GET_RSSI_INST;
780
781 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_GET_RSSI_INST, &rssi_local, 1);
782
783 if (status == SX126X_STATUS_OK) {
784 *rssi_in_dbm = (int8_t)(-rssi_local >> 1);
785 }
786
787 return status;
788}
789
790
792 uint8_t buf[SX126X_SIZE_GET_STATS] = { 0 };
793 uint8_t stats_local[sizeof(sx126x_stats_lora_t)] = { 0 };
794 sx126x_status_t status = SX126X_STATUS_ERROR;
795
796 buf[0] = SX126X_GET_STATS;
797
798 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_GET_STATS, stats_local,
799 sizeof(sx126x_stats_lora_t));
800
801 if (status == SX126X_STATUS_OK) {
802 stats->nb_pkt_received = ((uint16_t)stats_local[0] << 8) + (uint16_t)stats_local[1];
803 stats->nb_pkt_crc_error = ((uint16_t)stats_local[2] << 8) + (uint16_t)stats_local[3];
804 stats->nb_pkt_header_error = ((uint16_t)stats_local[4] << 8) + (uint16_t)stats_local[5];
805 }
806 return status;
807}
808
810 uint8_t buf[SX126X_SIZE_RESET_STATS] = { 0 };
811
812 buf[0] = SX126X_RESET_STATS;
813
814 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_RESET_STATS, 0, 0);
815}
816
817//
818// Miscellaneous
819//
820
822 return (sx126x_status_t)sx126x_hal_reset(nctx);
823}
824
825sx126x_status_t sx126x_get_device_errors(struct network_context *nctx, sx126x_errors_mask_t *errors) {
826 uint8_t buf[SX126X_SIZE_GET_DEVICE_ERRORS] = { 0 };
827 uint8_t errors_local[sizeof(sx126x_errors_mask_t)] = { 0x00 };
828 sx126x_status_t status = SX126X_STATUS_ERROR;
829
830 buf[0] = SX126X_GET_DEVICE_ERRORS;
831
832 status = (sx126x_status_t)sx126x_hal_read(nctx, buf, SX126X_SIZE_GET_DEVICE_ERRORS, errors_local,
833 sizeof(sx126x_errors_mask_t));
834
835 if (status == SX126X_STATUS_OK) {
836 *errors = ((sx126x_errors_mask_t)errors_local[0] << 8) + ((sx126x_errors_mask_t)errors_local[1] << 0);
837 }
838
839 return status;
840}
841
843 uint8_t buf[SX126X_SIZE_CLR_DEVICE_ERRORS] = { 0 };
844
845 buf[0] = SX126X_CLR_DEVICE_ERRORS;
846
847 return (sx126x_status_t)sx126x_hal_write(nctx, buf, SX126X_SIZE_CLR_DEVICE_ERRORS, 0, 0);
848}
849
851 uint32_t bw_in_hz = 0;
852
853 switch (bw) {
854 case SX126X_LORA_BW_007:
855 bw_in_hz = 7812UL;
856 break;
857 case SX126X_LORA_BW_010:
858 bw_in_hz = 10417UL;
859 break;
860 case SX126X_LORA_BW_015:
861 bw_in_hz = 15625UL;
862 break;
863 case SX126X_LORA_BW_020:
864 bw_in_hz = 20833UL;
865 break;
866 case SX126X_LORA_BW_031:
867 bw_in_hz = 31250UL;
868 break;
869 case SX126X_LORA_BW_041:
870 bw_in_hz = 41667UL;
871 break;
872 case SX126X_LORA_BW_062:
873 bw_in_hz = 62500UL;
874 break;
875 case SX126X_LORA_BW_125:
876 bw_in_hz = 125000UL;
877 break;
878 case SX126X_LORA_BW_250:
879 bw_in_hz = 250000UL;
880 break;
881 case SX126X_LORA_BW_500:
882 bw_in_hz = 500000UL;
883 break;
884 }
885
886 return bw_in_hz;
887}
888
890 const sx126x_mod_params_lora_t * mod_p) {
891 const int32_t pld_len_in_bytes = pkt_p->pld_len_in_bytes;
892 const int32_t sf = mod_p->sf;
893 const bool pld_is_fix = pkt_p->header_type == SX126X_LORA_PKT_IMPLICIT;
894 const int32_t cr_denom = mod_p->cr + 4;
895
896 int32_t ceil_denominator;
897 int32_t ceil_numerator =
898 (pld_len_in_bytes << 3) + (pkt_p->crc_is_on ? 16 : 0) - (4 * sf) + (pld_is_fix ? 0 : 20);
899
900 if (sf <= 6) {
901 ceil_denominator = 4 * sf;
902 } else {
903 ceil_numerator += 8;
904
905 if (mod_p->ldro) {
906 ceil_denominator = 4 * (sf - 2);
907 } else {
908 ceil_denominator = 4 * sf;
909 }
910 }
911
912 if (ceil_numerator < 0) {
913 ceil_numerator = 0;
914 }
915
916 // Perform integral ceil()
917 int32_t intermed =
918 ((ceil_numerator + ceil_denominator - 1) / ceil_denominator) * cr_denom + pkt_p->preamble_len_in_symb + 12;
919
920 if (sf <= 6) {
921 intermed += 2;
922 }
923
924 return (uint32_t)((4 * intermed + 1) * (1 << (sf - 2)));
925}
926
928 const sx126x_mod_params_lora_t * mod_p) {
929 uint32_t numerator = 1000U * sx126x_get_lora_time_on_air_numerator(pkt_p, mod_p);
930 uint32_t denominator = sx126x_get_lora_bw_in_hz(mod_p->bw);
931
932 // Perform integral ceil()
933 return (numerator + denominator - 1) / denominator;
934}
935
936sx126x_status_t sx126x_get_random_numbers(struct network_context *nctx, uint32_t *numbers, unsigned int n) {
937 sx126x_status_t status;
938
939 uint8_t tmp_ana_lna = 0x00;
940 uint8_t tmp_ana_mixer = 0x00;
941 uint8_t tmp = 0x00;
942
943 // Configure for random number generation
944 status = sx126x_read_register(nctx, SX126X_REG_ANA_LNA, &tmp_ana_lna, 1);
945 if (status != SX126X_STATUS_OK) {
946 return status;
947 }
948 tmp = tmp_ana_lna & ~(1 << 0);
949 status = sx126x_write_register(nctx, SX126X_REG_ANA_LNA, &tmp, 1);
950 if (status != SX126X_STATUS_OK) {
951 return status;
952 }
953
954 status = sx126x_read_register(nctx, SX126X_REG_ANA_MIXER, &tmp_ana_mixer, 1);
955 if (status != SX126X_STATUS_OK) {
956 return status;
957 }
958 tmp = tmp_ana_mixer & ~(1 << 7);
959 status = sx126x_write_register(nctx, SX126X_REG_ANA_MIXER, &tmp, 1);
960 if (status != SX126X_STATUS_OK) {
961 return status;
962 }
963
964 // Start RX continuous
965 status = sx126x_set_rx_with_timeout_in_rtc_step(nctx, 0xFFFFFF);
966 if (status != SX126X_STATUS_OK) {
967 return status;
968 }
969
970 // Store values
971 for (unsigned int i = 0; i < n; i++) {
972 status = sx126x_read_register(nctx, SX126X_REG_RNGBASEADDRESS, (uint8_t *)&numbers[i], 4);
973 if (status != SX126X_STATUS_OK) {
974 return status;
975 }
976 }
977
978 status = sx126x_set_standby(nctx, SX126X_STANDBY_CFG_RC);
979 if (status != SX126X_STATUS_OK) {
980 return status;
981 }
982
983 // Restore registers
984 status = sx126x_write_register(nctx, SX126X_REG_ANA_LNA, &tmp_ana_lna, 1);
985 if (status != SX126X_STATUS_OK) {
986 return status;
987 }
988 status = sx126x_write_register(nctx, SX126X_REG_ANA_MIXER, &tmp_ana_mixer, 1);
989
990 return status;
991}
992
993uint32_t sx126x_convert_freq_in_hz_to_pll_step(uint32_t freq_in_hz) {
994 uint32_t steps_int;
995 uint32_t steps_frac;
996
997 // Get integer and fractional parts of the frequency computed with a PLL step scaled value
998 steps_int = freq_in_hz / SX126X_PLL_STEP_SCALED;
999 steps_frac = freq_in_hz - (steps_int * SX126X_PLL_STEP_SCALED);
1000
1001 // Apply the scaling factor to retrieve a frequency in Hz (+ ceiling)
1002 return (steps_int << SX126X_PLL_STEP_SHIFT_AMOUNT) +
1003 (((steps_frac << SX126X_PLL_STEP_SHIFT_AMOUNT) + (SX126X_PLL_STEP_SCALED >> 1)) /
1005}
1006
1007uint32_t sx126x_convert_timeout_in_ms_to_rtc_step(uint32_t timeout_in_ms) {
1008 return (uint32_t)(timeout_in_ms * (SX126X_RTC_FREQ_IN_HZ / 1000));
1009}
1010
1011//
1012// Registers access
1013//
1014
1016 if (state == true) {
1017 return sx126x_write_register(nctx, SX126X_REG_RXGAIN, (const uint8_t[]) { 0x96 }, 1);
1018 } else {
1019 return sx126x_write_register(nctx, SX126X_REG_RXGAIN, (const uint8_t[]) { 0x94 }, 1);
1020 }
1021}
1022
1023sx126x_status_t sx126x_set_lora_sync_word(struct network_context *nctx, const uint8_t sync_word) {
1024 sx126x_status_t status = SX126X_STATUS_ERROR;
1025 uint8_t buffer[2] = { 0x00 };
1026
1027 status = sx126x_read_register(nctx, SX126X_REG_LR_SYNCWORD, buffer, 2);
1028
1029 if (status == SX126X_STATUS_OK) {
1030 buffer[0] = (buffer[0] & ~0xF0) + (sync_word & 0xF0);
1031 buffer[1] = (buffer[1] & ~0xF0) + ((sync_word & 0x0F) << 4);
1032
1033 status = sx126x_write_register(nctx, SX126X_REG_LR_SYNCWORD, buffer, 2);
1034 }
1035
1036 return status;
1037}
1038
1039
1040
1042 sx126x_status_t status = SX126X_STATUS_ERROR;
1043 uint8_t reg_value = 0x00;
1044
1045 status = sx126x_read_register(nctx, SX126X_REG_TX_CLAMP_CFG, &reg_value, 1);
1046
1047 if (status == SX126X_STATUS_OK) {
1048 reg_value |= SX126X_REG_TX_CLAMP_CFG_MASK;
1049 status = sx126x_write_register(nctx, SX126X_REG_TX_CLAMP_CFG, &reg_value, 1);
1050 }
1051
1052 return status;
1053}
1054
1055/*
1056 * -----------------------------------------------------------------------------
1057 * --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
1058 */
1059static sx126x_status_t sx126x_tx_modulation_workaround(struct network_context *nctx, sx126x_pkt_type_t pkt_type,
1060 sx126x_lora_bw_t bw) {
1061 sx126x_status_t status = SX126X_STATUS_ERROR;
1062 uint8_t reg_value = 0;
1063
1064 status = sx126x_read_register(nctx, SX126X_REG_TX_MODULATION, &reg_value, 1);
1065
1066 if (status == SX126X_STATUS_OK) {
1067 if (pkt_type == SX126X_PKT_TYPE_LORA) {
1068 if (bw == SX126X_LORA_BW_500) {
1069 reg_value &= ~(1 << 2); // Bit 2 set to 0 if the LoRa BW = 500 kHz
1070 } else {
1071 reg_value |= (1 << 2); // Bit 2 set to 1 for any other LoRa BW
1072 }
1073 } else {
1074 reg_value |= (1 << 2); // Bit 2 set to 1 for any (G)FSK configuration
1075 }
1076
1077 status = sx126x_write_register(nctx, SX126X_REG_TX_MODULATION, &reg_value, 1);
1078 }
1079 return status;
1080}
1081
1082
1083/* --- EOF ------------------------------------------------------------------ */
SX126X CAD parameters structure definition.
Definition: sx126x.h:443
sx126x_cad_symbs_t cad_symb_nb
CAD number of symbols.
Definition: sx126x.h:444
sx126x_cad_exit_modes_t cad_exit_mode
CAD exit mode.
Definition: sx126x.h:447
uint8_t cad_detect_min
CAD minimum detection.
Definition: sx126x.h:446
uint8_t cad_detect_peak
CAD peak detection.
Definition: sx126x.h:445
uint32_t cad_timeout
CAD timeout value.
Definition: sx126x.h:448
SX126X chip status structure definition.
Definition: sx126x.h:480
sx126x_chip_modes_t chip_mode
Current chip mode.
Definition: sx126x.h:482
sx126x_cmd_status_t cmd_status
Previous command status.
Definition: sx126x.h:481
SX126X LoRa modulation parameters structure definition.
Definition: sx126x.h:329
sx126x_lora_sf_t sf
LoRa Spreading Factor.
Definition: sx126x.h:330
sx126x_lora_cr_t cr
LoRa Coding Rate.
Definition: sx126x.h:332
uint8_t ldro
Low DataRate Optimization configuration.
Definition: sx126x.h:333
sx126x_lora_bw_t bw
LoRa Bandwidth.
Definition: sx126x.h:331
SX126X power amplifier configuration parameters structure definition.
Definition: sx126x.h:147
SX126X LoRa packet parameters structure definition.
Definition: sx126x.h:394
uint16_t preamble_len_in_symb
Preamble length in symbols.
Definition: sx126x.h:395
bool crc_is_on
CRC activation.
Definition: sx126x.h:398
bool invert_iq_is_on
IQ polarity setup.
Definition: sx126x.h:399
uint8_t pld_len_in_bytes
Payload length in bytes.
Definition: sx126x.h:397
sx126x_lora_pkt_len_modes_t header_type
Header type.
Definition: sx126x.h:396
SX126X LoRa packet status structure definition.
Definition: sx126x.h:514
int8_t signal_rssi_pkt_in_dbm
Estimation of RSSI (after despreading)
Definition: sx126x.h:517
int8_t rssi_pkt_in_dbm
RSSI of the last packet.
Definition: sx126x.h:515
int8_t snr_pkt_in_db
SNR of the last packet.
Definition: sx126x.h:516
SX126X RX buffer status structure definition.
Definition: sx126x.h:488
uint8_t buffer_start_pointer
Position of the first byte in the buffer.
Definition: sx126x.h:490
uint8_t pld_len_in_bytes
Number of bytes available in the buffer.
Definition: sx126x.h:489
SX126X LoRa reception statistics structure definition.
Definition: sx126x.h:532
sx126x_status_t sx126x_set_rf_freq_in_pll_steps(struct network_context *nctx, const uint32_t freq)
Set the RF frequency for future radio operations - parameter in PLL steps.
Definition: sx126x.c:551
#define SX126X_RTC_FREQ_IN_HZ
Internal frequency of the radio.
Definition: sx126x.c:60
#define SX126X_PLL_STEP_SCALED
PLL step - scaled with SX126X_PLL_STEP_SHIFT_AMOUNT.
Definition: sx126x.c:70
sx126x_status_t sx126x_set_dio3_as_tcxo_ctrl(struct network_context *nctx, const sx126x_tcxo_ctrl_voltages_t tcxo_voltage, const uint32_t timeout)
Configure the embedded TCXO switch control.
Definition: sx126x.c:526
sx126x_status_t sx126x_set_rx_with_timeout_in_rtc_step(struct network_context *nctx, const uint32_t timeout_in_rtc_step)
Set the chip in reception mode.
Definition: sx126x.c:290
sx126x_status_t sx126x_get_rssi_inst(struct network_context *nctx, int16_t *rssi_in_dbm)
Get the instantaneous RSSI value.
Definition: sx126x.c:774
sx126x_status_t sx126x_set_pkt_type(struct network_context *nctx, const sx126x_pkt_type_t pkt_type)
Set the packet type.
Definition: sx126x.c:564
sx126x_status_t sx126x_cfg_rx_boosted(struct network_context *nctx, const bool state)
Configure the boost mode in reception.
Definition: sx126x.c:1015
sx126x_status_t sx126x_set_rx_tx_fallback_mode(struct network_context *nctx, const sx126x_fallback_modes_t fallback_mode)
Set chip mode to be used after successful transmission or reception.
Definition: sx126x.c:386
sx126x_status_t sx126x_set_pa_cfg(struct network_context *nctx, const sx126x_pa_cfg_params_t *params)
Configure the PA (Power Amplifier)
Definition: sx126x.c:373
sx126x_status_t sx126x_set_standby(struct network_context *nctx, const sx126x_standby_cfg_t cfg)
Set the chip in stand-by mode.
Definition: sx126x.c:248
sx126x_status_t sx126x_get_lora_pkt_status(struct network_context *nctx, sx126x_pkt_status_lora_t *pkt_status)
Get the status of the last LoRa packet received.
Definition: sx126x.c:755
sx126x_status_t sx126x_get_status(struct network_context *nctx, sx126x_chip_status_t *radio_status)
Get the chip status.
Definition: sx126x.c:718
sx126x_status_t sx126x_set_lora_mod_params(struct network_context *nctx, const sx126x_mod_params_lora_t *params)
Set the modulation parameters for LoRa packets.
Definition: sx126x.c:600
sx126x_status_t sx126x_set_rf_freq(struct network_context *nctx, const uint32_t freq_in_hz)
Set the RF frequency for future radio operations.
Definition: sx126x.c:545
sx126x_status_t sx126x_set_tx(struct network_context *nctx, const uint32_t timeout_in_ms)
Set the chip in transmission mode.
Definition: sx126x.c:258
enum sx126x_commands_size_e sx126x_commands_size_t
uint32_t sx126x_get_lora_bw_in_hz(sx126x_lora_bw_t bw)
Get the actual value in Hertz of a given LoRa bandwidth.
Definition: sx126x.c:850
sx126x_status_t sx126x_read_register(struct network_context *nctx, const uint16_t address, uint8_t *buffer, const uint8_t size)
Read data from register memory space.
Definition: sx126x.c:412
uint32_t sx126x_convert_timeout_in_ms_to_rtc_step(uint32_t timeout_in_ms)
Get the number of RTC steps for a given timeout in millisecond.
Definition: sx126x.c:1007
sx126x_status_t sx126x_cfg_tx_clamp(struct network_context *nctx)
Configure the Tx PA clamp.
Definition: sx126x.c:1041
sx126x_status_t sx126x_get_irq_status(struct network_context *nctx, sx126x_irq_mask_t *irq)
Get system interrupt status.
Definition: sx126x.c:474
enum sx126x_commands_e sx126x_commands_t
sx126x_status_t sx126x_reset_stats(struct network_context *nctx)
Reset all the statistics for both Lora and GFSK communications.
Definition: sx126x.c:809
sx126x_status_t sx126x_write_register(struct network_context *nctx, const uint16_t address, const uint8_t *buffer, const uint8_t size)
Write data into register memory space.
Definition: sx126x.c:400
sx126x_status_t sx126x_set_reg_mode(struct network_context *nctx, const sx126x_reg_mod_t mode)
Configure the regulator mode to be used.
Definition: sx126x.c:328
sx126x_status_t sx126x_cal_img(struct network_context *nctx, const uint32_t freq_in_hz)
Perform device operating frequency band image rejection calibration.
Definition: sx126x.c:348
sx126x_status_t sx126x_get_device_errors(struct network_context *nctx, sx126x_errors_mask_t *errors)
Get the list of all active errors.
Definition: sx126x.c:825
uint32_t sx126x_get_lora_time_on_air_in_ms(const sx126x_pkt_params_lora_t *pkt_p, const sx126x_mod_params_lora_t *mod_p)
Get the time on air in ms for LoRa transmission.
Definition: sx126x.c:927
sx126x_status_t sx126x_cal(struct network_context *nctx, const sx126x_cal_mask_t param)
Perform the calibration of the requested blocks.
Definition: sx126x.c:338
sx126x_status_t sx126x_get_pkt_type(struct network_context *nctx, sx126x_pkt_type_t *pkt_type)
Get the current packet type.
Definition: sx126x.c:574
sx126x_status_t sx126x_get_and_clear_irq_status(struct network_context *nctx, sx126x_irq_mask_t *irq)
Clears any radio irq status flags that are set and returns the flags that were cleared.
Definition: sx126x.c:502
sx126x_status_t sx126x_reset(struct network_context *nctx)
Perform a hard reset of the chip.
Definition: sx126x.c:821
sx126x_status_t sx126x_set_rx_duty_cycle_with_timings_in_rtc_step(struct network_context *nctx, const uint32_t rx_time_in_rtc_step, const uint32_t sleep_time_in_rtc_step)
Set the chip in reception mode with duty cycling.
Definition: sx126x.c:302
sx126x_status_t sx126x_write_buffer(struct network_context *nctx, const uint8_t offset, const uint8_t *buffer, const uint8_t size)
Write data into radio Tx buffer memory space.
Definition: sx126x.c:426
sx126x_commands_size_e
Definition: sx126x.c:133
sx126x_status_t sx126x_read_buffer(struct network_context *nctx, const uint8_t offset, uint8_t *buffer, const uint8_t size)
Read data from radio Rx buffer memory space.
Definition: sx126x.c:437
sx126x_status_t sx126x_get_rx_buffer_status(struct network_context *nctx, sx126x_rx_buffer_status_t *rx_buffer_status)
Get the current Rx buffer status for both LoRa and GFSK Rx operations.
Definition: sx126x.c:737
sx126x_status_t sx126x_set_dio_irq_params(struct network_context *nctx, const uint16_t irq_mask, const uint16_t dio1_mask, const uint16_t dio2_mask, const uint16_t dio3_mask)
Set which interrupt signals are redirected to the dedicated DIO pin.
Definition: sx126x.c:453
sx126x_status_t sx126x_clear_device_errors(struct network_context *nctx)
Clear all active errors.
Definition: sx126x.c:842
sx126x_status_t sx126x_set_dio2_as_rf_sw_ctrl(struct network_context *nctx, const bool enable)
Configure the embedded RF switch control.
Definition: sx126x.c:516
sx126x_status_t sx126x_get_random_numbers(struct network_context *nctx, uint32_t *numbers, unsigned int n)
Generate one or more 32-bit random numbers.
Definition: sx126x.c:936
sx126x_status_t sx126x_set_buffer_base_address(struct network_context *nctx, const uint8_t tx_base_address, const uint8_t rx_base_address)
Set buffer start addresses for both Tx and Rx operations.
Definition: sx126x.c:675
uint32_t sx126x_convert_freq_in_hz_to_pll_step(uint32_t freq_in_hz)
Get the number of PLL steps for a given frequency in Hertz.
Definition: sx126x.c:993
sx126x_status_t sx126x_set_tx_params(struct network_context *nctx, const int8_t pwr_in_dbm, const sx126x_ramp_time_t ramp_time)
Set the parameters for TX power and power amplifier ramp time.
Definition: sx126x.c:587
sx126x_status_t sx126x_get_lora_stats(struct network_context *nctx, sx126x_stats_lora_t *stats)
Get the statistics about LoRa communication.
Definition: sx126x.c:791
uint32_t sx126x_get_lora_time_on_air_numerator(const sx126x_pkt_params_lora_t *pkt_p, const sx126x_mod_params_lora_t *mod_p)
Compute the numerator for LoRa time-on-air computation.
Definition: sx126x.c:889
sx126x_status_t sx126x_set_cad(struct network_context *nctx)
Set the chip in CAD (Channel Activity Detection) mode.
Definition: sx126x.c:320
#define SX126X_PLL_STEP_SHIFT_AMOUNT
Scaling factor used to perform fixed-point operations.
Definition: sx126x.c:65
sx126x_status_t sx126x_set_lora_pkt_params(struct network_context *nctx, const sx126x_pkt_params_lora_t *params)
Set the packet parameters for LoRa packets.
Definition: sx126x.c:624
sx126x_commands_e
Definition: sx126x.c:80
sx126x_status_t sx126x_set_rx(struct network_context *nctx, const uint32_t timeout_in_ms)
Set the chip in reception mode.
Definition: sx126x.c:280
sx126x_status_t sx126x_set_lora_sync_word(struct network_context *nctx, const uint8_t sync_word)
Configure the sync word used in LoRa packet.
Definition: sx126x.c:1023
sx126x_status_t sx126x_set_cad_params(struct network_context *nctx, const sx126x_cad_params_t *params)
Set the parameters for CAD operation.
Definition: sx126x.c:659
sx126x_status_t sx126x_set_tx_with_timeout_in_rtc_step(struct network_context *nctx, const uint32_t timeout_in_rtc_step)
Set the chip in transmission mode.
Definition: sx126x.c:268
sx126x_status_t sx126x_clear_irq_status(struct network_context *nctx, const sx126x_irq_mask_t irq_mask)
Clear selected system interrupts.
Definition: sx126x.c:491
SX126x radio driver definition.
enum sx126x_lora_bw_e sx126x_lora_bw_t
SX126X LoRa bandwidth enumeration definition.
enum sx126x_cmd_status_e sx126x_cmd_status_t
SX126X command status enumeration definition.
enum sx126x_status_e sx126x_status_t
SX126X APIs return status enumeration definition.
#define SX126X_MAX_TIMEOUT_IN_MS
Maximum value for parameter timeout_in_ms in both functions sx126x_set_rx and sx126x_set_tx.
Definition: sx126x.h:66
enum sx126x_pkt_types_e sx126x_pkt_type_t
SX126X packet types enumeration definition.
enum sx126x_ramp_time_e sx126x_ramp_time_t
SX126X power amplifier ramp-up timings enumeration definition.
enum sx126x_chip_modes_e sx126x_chip_modes_t
SX126X chip mode enumeration definition.
enum sx126x_tcxo_ctrl_voltages_e sx126x_tcxo_ctrl_voltages_t
SX126X TCXO control voltages enumeration definition.
@ SX126X_LORA_PKT_IMPLICIT
Header not included in the packet.
Definition: sx126x.h:388
enum sx126x_fallback_modes_e sx126x_fallback_modes_t
SX126X fallback modes enumeration definition.
struct sx126x_rx_buffer_status_s sx126x_rx_buffer_status_t
SX126X RX buffer status structure definition.
struct sx126x_stats_lora_s sx126x_stats_lora_t
SX126X LoRa reception statistics structure definition.
enum sx126x_reg_mods_e sx126x_reg_mod_t
SX126X power regulator modes enumeration definition.
struct sx126x_pkt_status_lora_s sx126x_pkt_status_lora_t
SX126X LoRa packet status structure definition.
Hardware Abstraction Layer for SX126x.
sx126x_hal_status_t sx126x_hal_reset(struct network_context *nctx)
Definition: bus.c:102
sx126x_hal_status_t sx126x_hal_write(struct network_context *nctx, const uint8_t *command, const uint16_t command_length, const uint8_t *data, const uint16_t data_length)
Definition: bus.c:64
sx126x_hal_status_t sx126x_hal_read(struct network_context *nctx, const uint8_t *command, const uint16_t command_length, uint8_t *data, const uint16_t data_length)
Definition: bus.c:34
SX126x register definitions.
#define SX126X_REG_RXGAIN
Definition: sx126x_regs.h:102
#define SX126X_REG_IRQ_POLARITY
WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15....
Definition: sx126x_regs.h:117
#define SX126X_REG_LR_SYNCWORD
The addresses of the register holding LoRa Modem SyncWord value 0x1424: LoRaWAN private network,...
Definition: sx126x_regs.h:80
#define SX126X_REG_TX_CLAMP_CFG
WORKAROUND - Better resistance to antenna mismatch, see DS_SX1261-2_V1.2 datasheet chapter 15....
Definition: sx126x_regs.h:127
#define SX126X_REG_RNGBASEADDRESS
Definition: sx126x_regs.h:85
#define SX126X_REG_ANA_LNA
Definition: sx126x_regs.h:90
#define SX126X_REG_TX_MODULATION
WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see DS_SX1261-2_V1.2 datasheet chapter 1...
Definition: sx126x_regs.h:122
#define SX126X_REG_ANA_MIXER
Definition: sx126x_regs.h:95
#define SX126X_REG_LR_SYNCH_TIMEOUT
Number of symbols given as SX126X_REG_LR_SYNCH_TIMEOUT[7:3] * 2 ^ (2*SX126X_REG_LR_SYNCH_TIMEOUT[2:0]...
Definition: sx126x_regs.h:186