RadioHead
RH_SX126x.h
1// SX126X.h
2//
3// Definitions for the Semtech SX126X series of LoRa capable radios
4// https://wiki.seeedstudio.com/LoRa_E5_mini/
5// https://www.rfsolutions.co.uk/downloads/1537522406DS_SX1261-2_V1.1_SEMTECH.pdf
6// https://cdn.sparkfun.com/assets/6/b/5/1/4/SX1262_datasheet.pdf
7// https://files.seeedstudio.com/products/317990687/res/LoRa-E5+module+datasheet_V1.0.pdf
8// https://forum.seeedstudio.com/t/lora-e5-register-settings-for-oscillators/262635
9// file:///home/mikem/Downloads/es0506-stm32wle5xx-stm32wle4xx-device-errata-stmicroelectronics.pdf
10// Author: Mike McCauley (mikem@airspayce.com)
11// Copyright (C) 2023 Mike McCauley
12//
13
14#ifndef RH_SX126x_h
15#define RH_SX126x_h
16
17#include <RHSPIDriver.h>
18
19// This is the maximum number of interrupts the driver can support
20// Most Arduinos can handle 2, Megas can handle more
21#define RH_SX126x_NUM_INTERRUPTS 3
22
23// Max number of octets the LORA Rx/Tx FIFO can hold
24#define RH_SX126x_FIFO_SIZE 255
25
26// This is the maximum number of bytes that can be carried by the LORA.
27// We use some for headers, keeping fewer for RadioHead messages
28#define RH_SX126x_MAX_PAYLOAD_LEN RH_SX126x_FIFO_SIZE
29
30// The length of the headers we add.
31// The headers are inside the LORA's payload
32#define RH_SX126x_HEADER_LEN 4
33
34// This is the maximum message length that can be supported by this driver.
35// Can be pre-defined to a smaller size (to save SRAM) prior to including this header
36// Here we allow for 1 byte message length, 4 bytes headers, user data and 2 bytes of FCS
37#ifndef RH_SX126x_MAX_MESSAGE_LEN
38 #define RH_SX126x_MAX_MESSAGE_LEN (RH_SX126x_MAX_PAYLOAD_LEN - RH_SX126x_HEADER_LEN)
39#endif
40
41// Radio chip internal crystal frequency
42#define RH_SX126x_XTAL_FREQ 32000000.0
43
44// The Frequency Synthesizer step = RH_SX126x_XTAL_FREQ / 2^^25
45#define RH_SX126x_FSTEP (RH_SX126x_XTAL_FREQ / 33554432)
46
47// Operational Modes Functions
48#define RH_SX126x_CMD_NOP 0x00
49#define RH_SX126x_CMD_SET_SLEEP 0x84
50#define RH_SX126x_CMD_SET_STANDBY 0x80
51#define RH_SX126x_CMD_SET_FS 0xC1
52#define RH_SX126x_CMD_SET_TX 0x83
53#define RH_SX126x_CMD_SET_RX 0x82
54#define RH_SX126x_CMD_SET_STOP_TIMER_ON_PREAMBLE 0x9F
55#define RH_SX126x_CMD_SET_RX_DUTY_CYCLE 0x94
56#define RH_SX126x_CMD_SET_CAD 0xC5
57#define RH_SX126x_CMD_SET_TX_CONTINUOUS_WAVE 0xD1
58#define RH_SX126x_CMD_SET_TX_INFINITE_PREAMBLE 0xD2
59#define RH_SX126x_CMD_SET_REGULATOR_MODE 0x96
60#define RH_SX126x_CMD_CALIBRATE 0x89
61#define RH_SX126x_CMD_CALIBRATE_IMAGE 0x98
62#define RH_SX126x_CMD_SET_PA_CFG 0x95
63#define RH_SX126x_CMD_SET_RX_TX_FALLBACK_MODE 0x93
64
65// Registers and buffer Access
66#define RH_SX126x_CMD_WRITE_REGISTER 0x0D
67#define RH_SX126x_CMD_READ_REGISTER 0x1D
68#define RH_SX126x_CMD_WRITE_BUFFER 0x0E
69#define RH_SX126x_CMD_READ_BUFFER 0x1E
70
71// DIO and IRQ Control Functions
72#define RH_SX126x_CMD_SET_DIO_IRQ_PARAMS 0x08
73#define RH_SX126x_CMD_GET_IRQ_STATUS 0x12
74#define RH_SX126x_CMD_CLR_IRQ_STATUS 0x02
75#define RH_SX126x_CMD_SET_DIO2_AS_RF_SWITCH_CTRL 0x9D
76#define RH_SX126x_CMD_SET_DIO3_AS_TCXO_CTRL 0x97
77
78// RF Modulation and Packet-Related Functions
79#define RH_SX126x_CMD_SET_RF_FREQUENCY 0x86
80#define RH_SX126x_CMD_SET_PKT_TYPE 0x8A
81#define RH_SX126x_CMD_GET_PKT_TYPE 0x11
82#define RH_SX126x_CMD_SET_TX_PARAMS 0x8E
83#define RH_SX126x_CMD_SET_MODULATION_PARAMS 0x8B
84#define RH_SX126x_CMD_SET_PKT_PARAMS 0x8C
85#define RH_SX126x_CMD_SET_CAD_PARAMS 0x88
86#define RH_SX126x_CMD_SET_BUFFER_BASE_ADDRESS 0x8F
87#define RH_SX126x_CMD_SET_LORA_SYMB_NUM_TIMEOUT 0xA0
88
89// Communication Status Information
90#define RH_SX126x_CMD_GET_STATUS 0xC0
91#define RH_SX126x_CMD_GET_RX_BUFFER_STATUS 0x13
92#define RH_SX126x_CMD_GET_PKT_STATUS 0x14
93#define RH_SX126x_CMD_GET_RSSI_INST 0x15
94#define RH_SX126x_CMD_GET_STATS 0x10
95#define RH_SX126x_CMD_RESET_STATS 0x00
96
97// Miscellaneous
98#define RH_SX126x_CMD_GET_DEVICE_ERRORS 0x17
99#define RH_SX126x_CMD_CLR_DEVICE_ERRORS 0x07
100
101// Registers
102
103// Base address of the register retention list, 3 bytes
104#define RH_SX126x_REG_RETENTION_LIST_BASE_ADDRESS 0x029F
105
106#define RH_SX126x_REG_VERSION_STRING 0x0320
107#define RH_SX126x_REG_HOPPING_ENABLE 0x0385
108#define RH_SX126x_REG_LR_FHSS_PACKET_LENGTH 0x0386
109#define RH_SX126x_REG_LR_FHSS_NUM_HOPPING_BLOCKS 0x0387
110#define RH_SX126x_REG_LR_FHSS_NUM_SYMBOLS_FREQX_MSB(X) (0x0388 + (X)*6)
111#define RH_SX126x_REG_LR_FHSS_NUM_SYMBOLS_FREQX_LSB(X) (0x0389 + (X)*6)
112#define RH_SX126x_REG_LR_FHSS_FREQX_0(X) (0x038A + (X)*6)
113#define RH_SX126x_REG_LR_FHSS_FREQX_1(X) (0x038B + (X)*6)
114#define RH_SX126x_REG_LR_FHSS_FREQX_2(X) (0x038C + (X)*6)
115#define RH_SX126x_REG_LR_FHSS_FREQX_3(X) (0x038D + (X)*6)
116#define RH_SX126x_REG_SPECTRAL_SCAN_RESULT 0x0401
117
118// Output disable
119#define RH_SX126x_REG_OUT_DIS_REG 0x0580
120#define RH_SX126x_REG_OUT_DIS_REG_DIO3_POS ( 3U )
121#define RH_SX126x_REG_OUT_DIS_REG_DIO3_MASK ( 0x01UL << SX126X_REG_OUT_DIS_REG_DIO3_POS )
122
123#define RH_SX126x_REG_DIOX_DRIVE_STRENGTH 0x0582
124
125// Input enable
126#define RH_SX126x_REG_IN_EN_REG 0x0583
127#define RH_SX126x_REG_IN_EN_REG_DIO3_POS ( 3U )
128#define RH_SX126x_REG_IN_EN_REG_DIO3_MASK ( 0x01UL << SX126X_REG_IN_EN_REG_DIO3_POS )
129
130#define RH_SX126x_REG_DIOX_PULLUP 0x0584
131#define RH_SX126x_REG_DIOX_PULLDOWN 0x0585
132
133// TX bitbang B
134#define RH_SX126x_REG_BITBANG_B_REG 0x0587
135#define RH_SX126x_REG_BITBANG_B_REG_ENABLE_POS ( 0U )
136#define RH_SX126x_REG_BITBANG_B_REG_ENABLE_MASK ( 0x0FUL << SX126X_REG_BITBANG_B_REG_ENABLE_POS )
137#define RH_SX126x_REG_BITBANG_B_REG_ENABLE_VAL ( 0x0CUL << SX126X_REG_BITBANG_B_REG_ENABLE_POS )
138
139#define RH_SX126x_REG_PATCH_UPDATE_ENABLE 0x0610
140
141// TX bitbang A
142#define RH_SX126x_REG_BITBANG_A_REG 0x0680
143#define RH_SX126x_REG_BITBANG_A_REG_ENABLE_POS ( 4U )
144#define RH_SX126x_REG_BITBANG_A_REG_ENABLE_MASK ( 0x07UL << SX126X_REG_BITBANG_A_REG_ENABLE_POS )
145#define RH_SX126x_REG_BITBANG_A_REG_ENABLE_VAL ( 0x01UL << SX126X_REG_BITBANG_A_REG_ENABLE_POS )
146
147// The address of the register holding the first byte defining the whitening seed. 2 bytes
148#define RH_SX126x_REG_WHITSEEDBASEADDRESS 0x06B8
149
150// RX/TX payload length
151#define RH_SX126x_REG_RXTX_PAYLOAD_LEN 0x06BB
152
153// The address of the register holding the first byte defining the CRC seed. 2 bytes
154#define RH_SX126x_REG_CRCSEEDBASEADDRESS 0x06BC
155
156// The address of the register holding the first byte defining the CRC polynomial. 2 bytes
157#define RH_SX126x_REG_CRCPOLYBASEADDRESS 0x06BE
158
159// The addresses of the registers holding SyncWords values, 8 bytes
160#define RH_SX126x_REG_SYNCWORDBASEADDRESS 0x06C0
161
162// GFSK node address
163// Reset value is 0x00
164#define RH_SX126x_REG_GFSK_NODE_ADDRESS 0x06CD
165
166// GFSK broadcast address
167// Reset value is 0x00
168#define RH_SX126x_REG_GFSK_BROADCAST_ADDRESS 0x06CE
169
170#define RH_SX126x_REG_PAYLOAD_LENGTH 0x0702
171#define RH_SX126x_REG_PACKET_PARAMS 0x0704
172
173// Number of symbols given as SX126X_REG_LR_SYNCH_TIMEOUT[7:3] * 2 ^ (2*SX126X_REG_LR_SYNCH_TIMEOUT[2:0] + 1)
174#define RH_SX126x_REG_LR_SYNCH_TIMEOUT 0x0706
175
176// WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4
177#define RH_SX126x_REG_IQ_POLARITY 0x0736
178
179// The addresses of the register holding LoRa Modem SyncWord value, 2 bytes
180// 0x1424: LoRaWAN private network,
181// 0x3444: LoRaWAN public network
182#define RH_SX126x_REG_LR_SYNCWORD 0x0740
183
184// The address of the register holding the coding rate configuration extracted from a received LoRa header
185#define RH_SX126x_REG_LR_HEADER_CR 0x0749
186#define RH_SX126x_REG_LR_HEADER_CR_POS ( 4U )
187#define RH_SX126x_REG_LR_HEADER_CR_MASK ( 0x07UL << SX126X_REG_LR_HEADER_CR_POS )
188
189// The address of the register holding the CRC configuration extracted from a received LoRa header
190#define RH_SX126x_REG_FREQ_ERROR 0x076B
191#define RH_SX126x_REG_LR_HEADER_CRC 0x076B
192#define RH_SX126x_REG_LR_HEADER_CRC_POS ( 4U )
193#define RH_SX126x_REG_LR_HEADER_CRC_MASK ( 0x01UL << SX126X_REG_LR_HEADER_CRC_POS )
194
195#define RH_SX126x_REG_SPECTRAL_SCAN_STATUS 0x07CD
196
197// RX address pointer
198#define RH_SX126x_REG_RX_ADDRESS_POINTER 0x0803
199
200// The address of the register giving a 32-bit random number, 4 bytes
201#define RH_SX126x_REG_RNGBASEADDRESS 0x0819
202
203// WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see DS_SX1261-2_V1.2 datasheet chapter 15.1
204#define RH_SX126x_REG_TX_MODULATION 0x0889
205
206#define RH_SX126x_REG_RF_FREQUENCY_0 0x088B
207#define RH_SX126x_REG_RF_FREQUENCY_1 0x088C
208#define RH_SX126x_REG_RF_FREQUENCY_2 0x088D
209#define RH_SX126x_REG_RF_FREQUENCY_3 0x088E
210
211#define RH_SX126x_REG_RSSI_AVG_WINDOW 0x089B
212
213// The address of the register holding RX Gain value
214// 0x94: power saving,
215// 0x96: rx boosted
216#define RH_SX126x_REG_RXGAIN 0x08AC
217
218// WORKAROUND - Better resistance to antenna mismatch, see DS_SX1261-2_V1.2 datasheet chapter 15.2
219#define RH_SX126x_REG_TX_CLAMP_CFG 0x08D8
220#define RH_SX126x_REG_TX_CLAMP_CFG_POS ( 1U )
221#define RH_SX126x_REG_TX_CLAMP_CFG_MASK ( 0x0FUL << SX126X_REG_TX_CLAMP_CFG_POS )
222
223// The address of the register used to disable the LNA
224#define RH_SX126x_REG_ANA_LNA 0x08E2
225
226#define RH_SX126x_REG_LNA_CAP_TUNE_N 0x08E3
227#define RH_SX126x_REG_LNA_CAP_TUNE_P 0x08E4
228
229// The address of the register used to disable the mixer
230#define RH_SX126x_REG_ANA_MIXER 0x08E5
231
232// Set the current max value in the over current protection
233#define RH_SX126x_REG_OCP 0x08E7
234
235// RTC control
236#define RH_SX126x_REG_RTC_CTRL 0x0902
237
238// Change the value on the device internal trimming capacitor, 2 bytes
239#define RH_SX126x_REG_XTATRIM 0x0911
240
241// Value of the trimming cap on XTB pin This register should only be
242// changed while the radio is in STDBY_XOSC mode
243#define RH_SX126x_REG_DIO3_OUTPUT_VOLTAGE 0x0920
244
245// Event clear
246#define RH_SX126x_REG_EVT_CLR 0x0944
247#define RH_SX126x_REG_EVT_CLR_TIMEOUT_POS ( 1U )
248#define RH_SX126x_REG_EVT_CLR_TIMEOUT_MASK ( 0x01UL << SX126X_REG_EVT_CLR_TIMEOUT_POS )
249
250#define RH_SX126x_REG_PATCH_MEMORY_BASE 0x8000
251
252// Values used in commands and registers
253// RH_SX126x_CMD_SET_SLEEP
254#define RH_SX126x_SLEEP_START_COLD 0b00000000 // sleep mode: cold start, configuration is lost (default)
255#define RH_SX126x_SLEEP_START_WARM 0b00000100 // warm start, configuration is retained
256#define RH_SX126x_SLEEP_RTC_OFF 0b00000000 // wake on RTC timeout: disabled
257#define RH_SX126x_SLEEP_RTC_ON 0b00000001 // enabled
258
259// RH_SX126x_CMD_SET_STANDBY
260#define RH_SX126x_STANDBY_RC 0x00 // standby mode: 13 MHz RC oscillator
261#define RH_SX126x_STANDBY_XOSC 0x01 // 32 MHz crystal oscillator
262
263// RH_SX126x_CMD_SET_RX
264#define RH_SX126x_RX_TIMEOUT_NONE 0x000000 // Rx timeout duration: no timeout (Rx single mode)
265#define RH_SX126x_RX_TIMEOUT_INF 0xFFFFFF // infinite (Rx continuous mode)
266
267// RH_SX126x_CMD_SET_TX
268#define RH_SX126x_TX_TIMEOUT_NONE 0x000000 // Tx timeout duration: no timeout (Tx single mode)
269
270// RH_SX126x_CMD_STOP_TIMER_ON_PREAMBLE
271#define RH_SX126x_STOP_ON_PREAMBLE_OFF 0x00 // stop timer on: sync word or header (default)
272#define RH_SX126x_STOP_ON_PREAMBLE_ON 0x01 // preamble detection
273
274// RH_SX126x_CMD_SET_REGULATOR_MODE
275#define RH_SX126x_REGULATOR_LDO 0x00 // set regulator mode: LDO (default)
276#define RH_SX126x_REGULATOR_DC_DC 0x01 // DC-DC
277
278// RH_SX126x_CMD_CALIBRATE
279#define RH_SX126x_CALIBRATE_IMAGE_OFF 0b00000000 // image calibration: disabled
280#define RH_SX126x_CALIBRATE_IMAGE_ON 0b01000000 // enabled
281#define RH_SX126x_CALIBRATE_ADC_BULK_P_OFF 0b00000000 // ADC bulk P calibration: disabled
282#define RH_SX126x_CALIBRATE_ADC_BULK_P_ON 0b00100000 // enabled
283#define RH_SX126x_CALIBRATE_ADC_BULK_N_OFF 0b00000000 // ADC bulk N calibration: disabled
284#define RH_SX126x_CALIBRATE_ADC_BULK_N_ON 0b00010000 // enabled
285#define RH_SX126x_CALIBRATE_ADC_PULSE_OFF 0b00000000 // ADC pulse calibration: disabled
286#define RH_SX126x_CALIBRATE_ADC_PULSE_ON 0b00001000 // enabled
287#define RH_SX126x_CALIBRATE_PLL_OFF 0b00000000 // PLL calibration: disabled
288#define RH_SX126x_CALIBRATE_PLL_ON 0b00000100 // enabled
289#define RH_SX126x_CALIBRATE_RC13M_OFF 0b00000000 // 13 MHz RC osc. calibration: disabled
290#define RH_SX126x_CALIBRATE_RC13M_ON 0b00000010 // enabled
291#define RH_SX126x_CALIBRATE_RC64K_OFF 0b00000000 // 64 kHz RC osc. calibration: disabled
292#define RH_SX126x_CALIBRATE_RC64K_ON 0b00000001 // enabled
293#define RH_SX126x_CALIBRATE_ALL 0b01111111 // calibrate all blocks
294
295// RH_SX126x_CMD_CALIBRATE_IMAGE
296#define RH_SX126x_CAL_IMG_430_MHZ_1 0x6B
297#define RH_SX126x_CAL_IMG_430_MHZ_2 0x6F
298#define RH_SX126x_CAL_IMG_470_MHZ_1 0x75
299#define RH_SX126x_CAL_IMG_470_MHZ_2 0x81
300#define RH_SX126x_CAL_IMG_779_MHZ_1 0xC1
301#define RH_SX126x_CAL_IMG_779_MHZ_2 0xC5
302#define RH_SX126x_CAL_IMG_863_MHZ_1 0xD7
303#define RH_SX126x_CAL_IMG_863_MHZ_2 0xDB
304#define RH_SX126x_CAL_IMG_902_MHZ_1 0xE1
305#define RH_SX126x_CAL_IMG_902_MHZ_2 0xE9
306
307// RH_SX126x_CMD_SET_PA_CONFIG
308#define RH_SX126x_PA_CONFIG_HP_MAX 0x07
309
310#define RH_SX126x_PA_CONFIG_DEVICE_SEL_SX1261 0x01
311#define RH_SX126x_PA_CONFIG_DEVICE_SEL_SX1262 0x00
312
313#define RH_SX126x_PA_CONFIG_PA_LUT 0x01
314#define RH_SX126x_PA_CONFIG_SX1262_8 0x00
315
316// RH_SX126x_CMD_SET_RX_TX_FALLBACK_MODE
317#define RH_SX126x_RX_TX_FALLBACK_MODE_FS 0x40 // after Rx/Tx go to: FS mode
318#define RH_SX126x_RX_TX_FALLBACK_MODE_STDBY_XOSC 0x30 // standby with crystal oscillator
319#define RH_SX126x_RX_TX_FALLBACK_MODE_STDBY_RC 0x20 // standby with RC oscillator (default)
320
321// RH_SX126x_CMD_SET_DIO_IRQ_PARAMS
322#define RH_SX126x_IRQ_LR_FHSS_HOP 0b0100000000000000 // PA ramped up during LR-FHSS hop
323#define RH_SX126x_IRQ_TIMEOUT 0b0000001000000000 // Rx or Tx timeout
324#define RH_SX126x_IRQ_CAD_DETECTED 0b0000000100000000 // channel activity detected
325#define RH_SX126x_IRQ_CAD_DONE 0b0000000010000000 // channel activity detection finished
326#define RH_SX126x_IRQ_CRC_ERR 0b0000000001000000 // wrong CRC received
327#define RH_SX126x_IRQ_HEADER_ERR 0b0000000000100000 // LoRa header CRC error
328#define RH_SX126x_IRQ_HEADER_VALID 0b0000000000010000 // valid LoRa header received
329#define RH_SX126x_IRQ_SYNC_WORD_VALID 0b0000000000001000 // valid sync word detected
330#define RH_SX126x_IRQ_PREAMBLE_DETECTED 0b0000000000000100 // preamble detected
331#define RH_SX126x_IRQ_RX_DONE 0b0000000000000010 // packet received
332#define RH_SX126x_IRQ_TX_DONE 0b0000000000000001 // packet transmission completed
333#define RH_SX126x_IRQ_RX_DEFAULT 0b0000001001100010 // default for Rx (RX_DONE, TIMEOUT, CRC_ERR and HEADER_ERR)
334#define RH_SX126x_IRQ_ALL 0b0100001111111111 // all interrupts
335#define RH_SX126x_IRQ_NONE 0b0000000000000000 // no interrupts
336
337// RH_SX126x_CMD_SET_DIO2_AS_RF_SWITCH_CTRL
338#define RH_SX126x_DIO2_AS_IRQ 0x00 // DIO2 configuration: IRQ
339#define RH_SX126x_DIO2_AS_RF_SWITCH 0x01 // RF switch control
340
341// RH_SX126x_CMD_SET_DIO3_AS_TCXO_CTRL
342#define RH_SX126x_DIO3_OUTPUT_1_6 0x00 // DIO3 voltage output for TCXO: 1.6 V
343#define RH_SX126x_DIO3_OUTPUT_1_7 0x01 // 1.7 V
344#define RH_SX126x_DIO3_OUTPUT_1_8 0x02 // 1.8 V
345#define RH_SX126x_DIO3_OUTPUT_2_2 0x03 // 2.2 V
346#define RH_SX126x_DIO3_OUTPUT_2_4 0x04 // 2.4 V
347#define RH_SX126x_DIO3_OUTPUT_2_7 0x05 // 2.7 V
348#define RH_SX126x_DIO3_OUTPUT_3_0 0x06 // 3.0 V
349#define RH_SX126x_DIO3_OUTPUT_3_3 0x07 // 3.3 V
350
351// RH_SX126x_CMD_SET_PACKET_TYPE
352#define RH_SX126x_PACKET_TYPE_GFSK 0x00 // packet type: GFSK
353#define RH_SX126x_PACKET_TYPE_LORA 0x01 // LoRa
354#define RH_SX126x_PACKET_TYPE_LR_FHSS 0x03 // LR-FHSS
355
356// RH_SX126x_CMD_SET_TX_PARAMS
357#define RH_SX126x_PA_RAMP_10U 0x00 // ramp time: 10 us
358#define RH_SX126x_PA_RAMP_20U 0x01 // 20 us
359#define RH_SX126x_PA_RAMP_40U 0x02 // 40 us
360#define RH_SX126x_PA_RAMP_80U 0x03 // 80 us
361#define RH_SX126x_PA_RAMP_200U 0x04 // 200 us
362#define RH_SX126x_PA_RAMP_800U 0x05 // 800 us
363#define RH_SX126x_PA_RAMP_1700U 0x06 // 1700 us
364#define RH_SX126x_PA_RAMP_3400U 0x07 // 3400 us
365
366// RH_SX126x_CMD_SET_MODULATION_PARAMS
367// GFSK bandwidths
368#define RH_SX126x_GFSK_RX_BW_4_8 0x1F // 4.8 kHz
369#define RH_SX126x_GFSK_RX_BW_5_8 0x17 // 5.8 kHz
370#define RH_SX126x_GFSK_RX_BW_7_3 0x0F // 7.3 kHz
371#define RH_SX126x_GFSK_RX_BW_9_7 0x1E // 9.7 kHz
372#define RH_SX126x_GFSK_RX_BW_11_7 0x16 // 11.7 kHz
373#define RH_SX126x_GFSK_RX_BW_14_6 0x0E // 14.6 kHz
374#define RH_SX126x_GFSK_RX_BW_19_5 0x1D // 19.5 kHz
375#define RH_SX126x_GFSK_RX_BW_23_4 0x15 // 23.4 kHz
376#define RH_SX126x_GFSK_RX_BW_29_3 0x0D // 29.3 kHz
377#define RH_SX126x_GFSK_RX_BW_39_0 0x1C // 39.0 kHz
378#define RH_SX126x_GFSK_RX_BW_46_9 0x14 // 46.9 kHz
379#define RH_SX126x_GFSK_RX_BW_58_6 0x0C // 58.6 kHz
380#define RH_SX126x_GFSK_RX_BW_78_2 0x1B // 78.2 kHz
381#define RH_SX126x_GFSK_RX_BW_93_8 0x13 // 93.8 kHz
382#define RH_SX126x_GFSK_RX_BW_117_3 0x0B // 117.3 kHz
383#define RH_SX126x_GFSK_RX_BW_156_2 0x1A // 156.2 kHz
384#define RH_SX126x_GFSK_RX_BW_187_2 0x12 // 187.2 kHz
385#define RH_SX126x_GFSK_RX_BW_234_3 0x0A // 234.3 kHz
386#define RH_SX126x_GFSK_RX_BW_312_0 0x19 // 312.0 kHz
387#define RH_SX126x_GFSK_RX_BW_373_6 0x11 // 373.6 kHz
388#define RH_SX126x_GFSK_RX_BW_467_0 0x09 // 467.0 kHz
389// LORA bandwidths
390#define RH_SX126x_LORA_BW_7_8 0x00 // 7.8 kHz
391#define RH_SX126x_LORA_BW_10_4 0x08 // 10.4 kHz
392#define RH_SX126x_LORA_BW_15_6 0x01 // 15.6 kHz
393#define RH_SX126x_LORA_BW_20_8 0x09 // 20.8 kHz
394#define RH_SX126x_LORA_BW_31_25 0x02 // 31.25 kHz
395#define RH_SX126x_LORA_BW_41_7 0x0A // 41.7 kHz
396#define RH_SX126x_LORA_BW_62_5 0x03 // 62.5 kHz
397#define RH_SX126x_LORA_BW_125_0 0x04 // 125.0 kHz
398#define RH_SX126x_LORA_BW_250_0 0x05 // 250.0 kHz
399#define RH_SX126x_LORA_BW_500_0 0x06 // 500.0 kHz
400// LORA Coding rates
401#define RH_SX126x_LORA_CR_4_5 0x01 // 4/5
402#define RH_SX126x_LORA_CR_4_6 0x02 // 4/6
403#define RH_SX126x_LORA_CR_4_7 0x03 // 4/7
404#define RH_SX126x_LORA_CR_4_8 0x04 // 4/8
405// LORA Spreading Factors, actually powers of 2
406#define RH_SX126x_LORA_SF_32 5 // SF5
407#define RH_SX126x_LORA_SF_64 6 // SF6
408#define RH_SX126x_LORA_SF_128 7 // SF7
409#define RH_SX126x_LORA_SF_256 8 // SF8
410#define RH_SX126x_LORA_SF_512 9 // SF9
411#define RH_SX126x_LORA_SF_1024 10 // SF10
412#define RH_SX126x_LORA_SF_2048 11 // SF11
413#define RH_SX126x_LORA_SF_4096 12 // SF12
414
415#define RH_SX126x_LORA_LOW_DATA_RATE_OPTIMIZE_OFF 0x00 // LoRa low data rate optimization: disabled
416#define RH_SX126x_LORA_LOW_DATA_RATE_OPTIMIZE_ON 0x01 // enabled
417
418// RH_SX126x_CMD_SET_PACKET_PARAMS
419#define RH_SX126x_GFSK_PREAMBLE_DETECT_OFF 0x00 // GFSK minimum preamble length before reception starts: detector disabled
420#define RH_SX126x_GFSK_PREAMBLE_DETECT_8 0x04 // 8 bits
421#define RH_SX126x_GFSK_PREAMBLE_DETECT_16 0x05 // 16 bits
422#define RH_SX126x_GFSK_PREAMBLE_DETECT_24 0x06 // 24 bits
423#define RH_SX126x_GFSK_PREAMBLE_DETECT_32 0x07 // 32 bits
424#define RH_SX126x_GFSK_ADDRESS_FILT_OFF 0x00 // GFSK address filtering: disabled
425#define RH_SX126x_GFSK_ADDRESS_FILT_NODE 0x01 // node only
426#define RH_SX126x_GFSK_ADDRESS_FILT_NODE_BROADCAST 0x02 // node and broadcast
427#define RH_SX126x_GFSK_PACKET_FIXED 0x00 // GFSK packet type: fixed (payload length known in advance to both sides)
428#define RH_SX126x_GFSK_PACKET_VARIABLE 0x01 // variable (payload length added to packet)
429#define RH_SX126x_GFSK_CRC_OFF 0x01 // GFSK packet CRC: disabled
430#define RH_SX126x_GFSK_CRC_1_BYTE 0x00 // 1 byte
431#define RH_SX126x_GFSK_CRC_2_BYTE 0x02 // 2 byte
432#define RH_SX126x_GFSK_CRC_1_BYTE_INV 0x04 // 1 byte, inverted
433#define RH_SX126x_GFSK_CRC_2_BYTE_INV 0x06 // 2 byte, inverted
434#define RH_SX126x_GFSK_WHITENING_OFF 0x00 // GFSK data whitening: disabled
435#define RH_SX126x_GFSK_WHITENING_ON 0x01 // enabled
436#define RH_SX126x_LORA_PACKET_VARIABLE 0x00
437#define RH_SX126x_LORA_PACKET_FIXED 0x01
438#define RH_SX126x_LORA_HEADER_EXPLICIT 0x00 // LoRa header mode: explicit
439#define RH_SX126x_LORA_HEADER_IMPLICIT 0x01 // implicit
440#define RH_SX126x_LORA_CRC_OFF 0x00 // LoRa CRC mode: disabled
441#define RH_SX126x_LORA_CRC_ON 0x01 // enabled
442#define RH_SX126x_LORA_IQ_STANDARD 0x00 // LoRa IQ setup: standard
443#define RH_SX126x_LORA_IQ_INVERTED 0x01 // inverted
444
445// RH_SX126x_CMD_SET_CAD_PARAMS
446#define RH_SX126x_CAD_ON_1_SYMB 0x00 // number of symbols used for CAD: 1
447#define RH_SX126x_CAD_ON_2_SYMB 0x01 // 2
448#define RH_SX126x_CAD_ON_4_SYMB 0x02 // 4
449#define RH_SX126x_CAD_ON_8_SYMB 0x03 // 8
450#define RH_SX126x_CAD_ON_16_SYMB 0x04 // 16
451#define RH_SX126x_CAD_GOTO_STDBY 0x00 // after CAD is done, always go to STDBY_RC mode
452#define RH_SX126x_CAD_GOTO_RX 0x01 // after CAD is done, go to Rx mode if activity is detected
453#define RH_SX126x_CAD_PARAM_DEFAULT 0xFF // used by the CAD methods to specify default parameter value
454#define RH_SX126x_CAD_PARAM_DET_MIN 10 // default detMin CAD parameter
455
456// RH_SX126x_CMD_GET_STATUS
457#define RH_SX126x_STATUS_MODE_STDBY_RC 0b00100000 // current chip mode: STDBY_RC
458#define RH_SX126x_STATUS_MODE_STDBY_XOSC 0b00110000 // STDBY_XOSC
459#define RH_SX126x_STATUS_MODE_FS 0b01000000 // FS
460#define RH_SX126x_STATUS_MODE_RX 0b01010000 // RX
461#define RH_SX126x_STATUS_MODE_TX 0b01100000 // TX
462#define RH_SX126x_STATUS_DATA_AVAILABLE 0b00000100 // command status: packet received and data can be retrieved
463#define RH_SX126x_STATUS_CMD_TIMEOUT 0b00000110 // SPI command timed out
464#define RH_SX126x_STATUS_CMD_INVALID 0b00001000 // invalid SPI command
465#define RH_SX126x_STATUS_CMD_FAILED 0b00001010 // SPI command failed to execute
466#define RH_SX126x_STATUS_TX_DONE 0b00001100 // packet transmission done
467#define RH_SX126x_STATUS_SPI_FAILED 0b11111111 // SPI transaction failed
468
469// RH_SX126x_CMD_GET_PACKET_STATUS
470#define RH_SX126x_GFSK_RX_STATUS_PREAMBLE_ERR 0b10000000 // GFSK Rx status: preamble error
471#define RH_SX126x_GFSK_RX_STATUS_SYNC_ERR 0b01000000 // sync word error
472#define RH_SX126x_GFSK_RX_STATUS_ADRS_ERR 0b00100000 // address error
473#define RH_SX126x_GFSK_RX_STATUS_CRC_ERR 0b00010000 // CRC error
474#define RH_SX126x_GFSK_RX_STATUS_LENGTH_ERR 0b00001000 // length error
475#define RH_SX126x_GFSK_RX_STATUS_ABORT_ERR 0b00000100 // abort error
476#define RH_SX126x_GFSK_RX_STATUS_PACKET_RECEIVED 0b00000010 // packet received
477#define RH_SX126x_GFSK_RX_STATUS_PACKET_SENT 0b00000001 // packet sent
478
479// RH_SX126x_CMD_GET_DEVICE_ERRORS
480#define RH_SX126x_PA_RAMP_ERR 0b100000000 // device errors: PA ramping failed
481#define RH_SX126x_PLL_LOCK_ERR 0b001000000 // PLL failed to lock
482#define RH_SX126x_XOSC_START_ERR 0b000100000 // crystal oscillator failed to start
483#define RH_SX126x_IMG_CALIB_ERR 0b000010000 // image calibration failed
484#define RH_SX126x_ADC_CALIB_ERR 0b000001000 // ADC calibration failed
485#define RH_SX126x_PLL_CALIB_ERR 0b000000100 // PLL calibration failed
486#define RH_SX126x_RC13M_CALIB_ERR 0b000000010 // RC13M calibration failed
487#define RH_SX126x_RC64K_CALIB_ERR 0b000000001 // RC64K calibration failed
488
489// RH_SX126x_CMD_SET_LBT_SCAN_PARAMS + RH_SX126x_CMD_SET_SPECTR_SCAN_PARAMS
490#define RH_SX126x_SCAN_INTERVAL_7_68_US 10 // RSSI reading interval: 7.68 us
491#define RH_SX126x_SCAN_INTERVAL_8_20_US 11 // 8.20 us
492#define RH_SX126x_SCAN_INTERVAL_8_68_US 12 // 8.68 us
493
494// SX126X SPI register variables
495// RH_SX126x_REG_HOPPING_ENABLE
496#define RH_SX126x_HOPPING_ENABLED 0b00000001 // intra-packet hopping for LR-FHSS: enabled
497#define RH_SX126x_HOPPING_DISABLED 0b00000000 // (disabled)
498
499// RH_SX126x_REG_LORA_SYNC_WORD_MSB + LSB
500#define RH_SX126x_SYNC_WORD_PUBLIC 0x34 // actually 0x3444 NOTE: The low nibbles in each byte (0x_4_4) are masked out since apparently, they're reserved.
501#define RH_SX126x_SYNC_WORD_PRIVATE 0x12 // actually 0x1424 You couldn't make this up if you tried.
502
503// RH_SX126x_REG_TX_BITBANG_ENABLE_1
504#define RH_SX126x_TX_BITBANG_1_DISABLED 0b00000000 // Tx bitbang: disabled (default)
505#define RH_SX126x_TX_BITBANG_1_ENABLED 0b00010000 // enabled
506
507// RH_SX126x_REG_TX_BITBANG_ENABLE_0
508#define RH_SX126x_TX_BITBANG_0_DISABLED 0b00000000 // Tx bitbang: disabled (default)
509#define RH_SX126x_TX_BITBANG_0_ENABLED 0b00001100 // enabled
510
511// RH_SX126x_REG_DIOX_OUT_ENABLE
512#define RH_SX126x_DIO1_OUT_DISABLED 0b00000010 // DIO1 output: disabled
513#define RH_SX126x_DIO1_OUT_ENABLED 0b00000000 // enabled
514#define RH_SX126x_DIO2_OUT_DISABLED 0b00000100 // DIO2 output: disabled
515#define RH_SX126x_DIO2_OUT_ENABLED 0b00000000 // enabled
516#define RH_SX126x_DIO3_OUT_DISABLED 0b00001000 // DIO3 output: disabled
517#define RH_SX126x_DIO3_OUT_ENABLED 0b00000000 // enabled
518
519// RH_SX126x_REG_DIOX_IN_ENABLE
520#define RH_SX126x_DIO1_IN_DISABLED 0b00000000 // DIO1 input: disabled
521#define RH_SX126x_DIO1_IN_ENABLED 0b00000010 // enabled
522#define RH_SX126x_DIO2_IN_DISABLED 0b00000000 // DIO2 input: disabled
523#define RH_SX126x_DIO2_IN_ENABLED 0b00000100 // enabled
524#define RH_SX126x_DIO3_IN_DISABLED 0b00000000 // DIO3 input: disabled
525#define RH_SX126x_DIO3_IN_ENABLED 0b00001000 // enabled
526
527// RH_SX126x_REG_RX_GAIN
528#define RH_SX126x_RX_GAIN_BOOSTED 0x96 // Rx gain: boosted
529#define RH_SX126x_RX_GAIN_POWER_SAVING 0x94 // power saving
530#define RH_SX126x_RX_GAIN_SPECTRAL_SCAN 0xCB // spectral scan
531
532// RH_SX126x_REG_PATCH_UPDATE_ENABLE
533#define RH_SX126x_PATCH_UPDATE_DISABLED 0b00000000 // patch update: disabled
534#define RH_SX126x_PATCH_UPDATE_ENABLED 0b00010000 // enabled
535
536// RH_SX126x_REG_SPECTRAL_SCAN_STATUS
537#define RH_SX126x_SPECTRAL_SCAN_NONE 0x00 // spectral scan status: none
538#define RH_SX126x_SPECTRAL_SCAN_ONGOING 0x0F // ongoing
539#define RH_SX126x_SPECTRAL_SCAN_ABORTED 0xF0 // aborted
540#define RH_SX126x_SPECTRAL_SCAN_COMPLETED 0xFF // completed
541
542// RH_SX126x_REG_RSSI_AVG_WINDOW
543#define RH_SX126x_SPECTRAL_SCAN_WINDOW_DEFAULT (0x05 << 2) // default RSSI average window
544
545// RH_SX126x_REG_ANA_LNA
546#define RH_SX126x_LNA_RNG_DISABLED 0b00000001 // random number: disabled
547#define RH_SX126x_LNA_RNG_ENABLED 0b00000000 // enabled
548
549// RH_SX126x_REG_ANA_MIXER
550#define RH_SX126x_MIXER_RNG_DISABLED 0b00000001 // random number: disabled
551#define RH_SX126x_MIXER_RNG_ENABLED 0b00000000 // enabled
552
553// size of the spectral scan result
554#define RH_SX126x_SPECTRAL_SCAN_RES_SIZE (33)
555
556
557
558
559
560/////////////////////////////////////////////////////////////////////
561/*! \class RH_SX126x RH_SX126x.h <RH_SX126x.h>
562\brief Driver to send and receive unaddressed, unreliable datagrams via a
563Semtech SX126X family LoRa capable radio transceivers, and compatible radios like the LLCC68
564
565Works with NiceRF LoRa1262-915 and Teensy 3.1. Also with LLCC68 in Ra-01SC module and Teensy 3.1.
566Also with Heltec Cube Cell HTCC-AB01 and Teensy 3.1.
567Will probably work with any other SX1262 module.
568
569\par Overview
570
571This class provides basic functions for sending and receiving unaddressed,
572unreliable datagrams of arbitrary length to 251 octets per packet.
573
574Manager classes may use this class to implement reliable, addressed datagrams and streams,
575mesh routers, repeaters, translators etc.
576
577Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
578modulation scheme.
579
580Predefined modulation schemes are available for various LoRa
581modulation speeds and bandwidths. GFSK modulation is also supported.
582
583The SX126x family of radio chips are available as discrete components with an SPI interface.
584In some hardware (eg the STM32WLE5xx STM32WLE4xx processors) the radio
585is built into a microprocessor.
586
587\par Packet Format
588
589All messages sent and received by this RH_SX126x Driver conform to this packet format, which is compatible with RH_RF95:
590
591- LoRa mode:
592- 8 symbol PREAMBLE
593- Explicit header with header CRC (default CCITT, handled internally by the radio)
594- 4 octets HEADER: (TO, FROM, ID, FLAGS)
595- 0 to 251 octets DATA
596- CRC (default CCITT, handled internally by the radio)
597
598\par Interrupts
599
600The RH_SX126x driver uses interrupts to react to events in the radio,
601such as the reception of a new packet, or the completion of
602transmission of a packet. The driver configures the radio so the
603required interrupt is generated by the radio's DIO1 pin. The
604RH_SX126x driver interrupt service routine reads status from and
605writes data to the the radio module via an SPI interface. It is very
606important therefore, that if you are using the RH_SX126x driver with
607another SPI based deviced, that you disable interrupts while you
608transfer data to and from that other device. Use cli() to disable
609interrupts and sei() to reenable them. (however note that the
610RH_STM32WLx subclass uses the dedicated internal SPI interface that is
611connected only to the radio).
612
613\par Memory
614
615The RH_SX126x driver requires non-trivial amounts of memory. The sample
616programs all compile to about 35 kbytes each, which will fit in the
617flash proram memory of most Arduinos. However, the RAM requirements are
618more critical. Therefore, you should be vary sparing with RAM use in
619programs that use the RH_SX126x driver.
620
621\par Compatibility with RH_RF95
622
623The predefined modulation schemes have been shown to interoperate with
624the RH_RF95 driver with similarly named modulation schemes.
625
626For example the (default) RH_SX126x::LoRa_Bw125Cr45Sf128 is compatible
627with the (default) RH_RF95::Bw125Cr45Sf128.
628
629The RH_SX126x driver sets the LoRa Sync word to 0x1424, which is compatible with single byte 0x12 default for RH_RF95.
630// https://forum.lora-developers.semtech.com/t/sx1272-and-sx1262-lora-sync-word-compatibility/988/13
631
632\par Transmitter Power
633
634We measured the RF power output from a Wio-E5 mini at 868.0 MHz, with
635the radio set to continuous CW transmission using
636setTxContinuous(). On this chip that implies the high power amplifier.
637We set various power outputs with setTxPower() from -9 to 22 and
638measured the RF output power with a HP 5342A Microwave Frequency
639Counter. Note that the drivers setTxPower() sets the optimum
640transmitter control registers per section 13.1.14.1 of the datasheet
641SX1262_datasheet.pdf
642
643\code
644Program power Measured power
645 dBm dBm
646 -9 -5.0
647 0 -2.9
648 5 6.9
649 10 8.9
650 15 13.3
651 16 14.1
652 17 14.6
653 18 16.7
654 19 17.3
655 20 17.8
656 21 18.7
657 22 19.4
658\endcode
659
660With the transmitter frequency set to 868.0 MHz, the actual centre
661frequency measured with the HP 5342A Microwave Frequency Counter on 2
662instances of Wio-E5 mini were 867.999826 and 867.999652 MHz.
663
664\par Differences between models
665
666SX126x compatible chips are available in at least 4 types:
667
668-SX1261 Has only one (low power) PA, -17 to +15 dBm
669
670-SX1262 Has only one (high power) PA, -9 to +22 dBm
671
672-SX1268 Has 2 PAs, low power (-17 to +15 dBm) and high power (-9 to +22 dBm)
673
674-STM32WLE5JC has 2 PAs, low power (-17 to +15 dBm) and high power (-9 to +22 dBm).
675
676-LLCC68 is almost identical to SX1262/SX1268 except that some spreading factors and bandwidths
677 are not supported.
678 see https://docs.ai-thinker.com/en/Ra-01SC/index.html and
679 https://aithinker-static.oss-cn-shenzhen.aliyuncs.com/docs/_media_old/ra-01sc_specification.pdf
680
681Even if the radio has 2 PAs, depending on your radio module, maybe
682only one is connected. It also includes a dedicated SPI interface for
683the radio plus some internllay connected reset and interrupt pins
684
685Some radio modules might also include an antenna switch, and the
686driver MUST be configured so that it knows how to turn any
687control pins on and off for receiving and transmitting. See setRadioPinConfig().
688
689\par Configuring the driver for your particular type of radio
690
691You will almost certainly have to configure this driver to suit the
692particular radio hardware in your system. Its boring but you MUST pay
693attention to this otherwise you may not be able to transmit or receive
694successfully.
695
696This issues you will have to consider are:
697
698- What model radio do you have?
699
700- What SPI bus is the radio connected to?
701
702- Is there a TCXO to configure?
703
704- What pin is used for the SPI slave select for the radio chip?
705
706- Is the radio reset pin connected to the CPU?
707
708- Are there any pins required to be set to control the external radio
709 interface, such as RF switches, external PAs etc,
710
711If you are using a ST Microelectronics STM32WLE5xx or STM32WLE4xx
712processors and its built in radio, you can use the RH_STM32WLx and
713ignore most or all of these issues.
714
715If you are using a Heltec CubeCell, such as HTCC-AB01, initialise the driver with:
716\code
717RH_SX126x driver(RADIO_NSS, RADIO_DIO_1, RADIO_BUSY, RADIO_RESET);
718\endcode
719
720\par Range
721
722No range tests have yet been conducted.
723
724\par Connecting SX126x modules to Arduino
725
726Note, if you are using a STM32WLE5JC, see the intructions for that in RH_STM32WLx.h
727
728\par Connecting a NiceRF LoRa1262-915 to a Teensy 3.1:
729
730https://www.nicerf.com/lora-module/915mhz-lora-module-lora1262.html
731
732We got one on a breakout board
733which already has a small helical antenna connected.
734The module appears to contain a 3.3V TCXO, and an antenna switch connected to DIO2
735You should be able to use a
736similar pinout for any 3.3V Arduino compatible board.
737
738
739\code
740 Teensy 3.1 G-Nice RF LoRa1262-915
741 GND----------GND (Ground)
742 3V3----------VCC (3.3V in)
743 pin D7-----------DIO1 (radio interrupt request out, active high)
744 pin D8-----------BUSY (radio busy output, active high)
745 pin D9-----------NRESET (radio reset in: pulled low for 2ms at startup)
746 SS pin D10----------NSS (chip select in)
747 SCK pin D13----------SCK (SPI clock in)
748 MOSI pin D11----------MOSI (SPI Data in)
749 MISO pin D12----------MISO (SPI Data out)
750
751With these connections you can then use the constructor:
752
753RH_SX126x driver(SS, 7, 8, 9);
754\endcode
755
756RAKwireless RAK4360/RAK4361
757
758RHHardwareSPI uses the default LoRa radio SPI pins as defined by the platform. You can use the contructor:
759
760\code
761RH_SX126x driver(42, 47, 46, 38); // NSS, DIO1, BUSY, NRESET
762\endcode
763
764
765\par Connecting an Ra-01SC module containing a LLCC68 radio
766
767This module from AI-Thinker has an LLCC68 chip and an antenna switch connected to DIO2.
768It does not have a TCXO, just a conventional crystal.
769Use the same connections and constructor as for the NiceRF LoRa1262-915 above.
770
771The LLCC68 is almost identical to the SX1262/SX1268 except that some spreading factors and bandwidths
772are not supported.
773
774
775*/
776
777class RH_SX126x : public RHSPIDriver
778{
779public:
780 /// Packet types the modem can be configured for
781 typedef enum
782 {
783 PacketTypeLoRa = 0, ///< Use LoRA packets
784 PacketTypeGFSK, ///< Use GFSK packets
785 } PacketType;
786
787 /// \brief Defines register values for a set of modem configuration registers
788 ///
789 /// Defines register values for a set of modem configuration registers
790 /// that can be passed to setModulationParameters() if none of the choices in
791 /// ModemConfigChoice suit your need setModemRegisters() writes the
792 /// register values from this structure to the appropriate registers
793 /// to set the desired spreading factor, coding rate and bandwidth
794 typedef struct
795 {
796 PacketType packetType;
797 uint8_t p1; ///< Value for setModulationParameters parameter 1
798 uint8_t p2; ///< Value for setModulationParameters parameter 2
799 uint8_t p3; ///< Value for setModulationParameters parameter 3
800 uint8_t p4; ///< Value for setModulationParameters parameter 4
801 uint8_t p5; ///< Value for setModulationParameters parameter 5
802 uint8_t p6; ///< Value for setModulationParameters parameter 6
803 uint8_t p7; ///< Value for setModulationParameters parameter 7
804 uint8_t p8; ///< Value for setModulationParameters parameter 8
805 } ModemConfig;
806
807 /// Choices for setModemConfig() for a selected subset of common
808 /// data rates. If you need another configuration,
809 /// determine the necessary settings and call setModemRegisters() with your
810 /// desired settings. It might be helpful to use the LoRa calculator mentioned in
811 /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
812 /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
813 /// definitions and not their integer equivalents: its possible that new values will be
814 /// introduced in later versions (though we will try to avoid it).
815 /// Caution: if you are using slow packet rates and long packets with RHReliableDatagram or subclasses
816 /// you may need to change the RHReliableDatagram timeout for reliable operations.
817 /// Caution: for some slow rates nad with ReliableDatagrams you may need to increase the reply timeout
818 /// with manager.setTimeout() to
819 /// deal with the long transmission times.
820 /// Caution: SX1276 family errata suggests alternate settings for some LoRa registers when 500kHz bandwidth
821 /// is in use. See the Semtech SX1276/77/78 Errata Note. These are not implemented by RH_SX126x.
822 /// In general, the LoRa_* configurations are compatible with the similarly named RH_RF95 configurations
823 typedef enum
824 {
825 LoRa_Bw125Cr45Sf128 = 0, ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range
826 LoRa_Bw500Cr45Sf128, ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range
827 LoRa_Bw31_25Cr48Sf512, ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range
828 LoRa_Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, low data rate, CRC on. Slow+long range
829 LoRa_Bw125Cr45Sf2048, ///< Bw = 125 kHz, Cr = 4/5, Sf = 2048chips/symbol, CRC on. Slow+long range
831
832 /// Structures and enums for Tx/Rx pin configuration
833 /// These structures allow you to specify what pins are to be automaticall set or cleared to control radio power amp and receivers
834 /// and how there are to be set for each radio mode, IDLE, TX or RX.
835 /// They can be used to automatically configure any RF switch or external power amp etc.
836 /// You will probably need these to configure the driver for your specific hardware
837 typedef enum
838 {
839 RadioPinConfigMode_EOT = 0, // End of table. Must be the last item in the pin configuration table
840 RadioPinConfigMode_IDLE, // This config is for the radio idle
841 RadioPinConfigMode_RX, // This config is for receiving
842 RadioPinConfigMode_TX_LOW_POWER, // This config is for transmitting with low power PA
843 RadioPinConfigMode_TX_HIGH_POWER, // This config is for transmitting with high power PA
845
846 // Maximum bumber of entries permitted in a RadioPinConfigTable
847 #define RH_SX126x_MAX_RADIO_PIN_CONFIG_MODES (RadioPinConfigMode_TX_HIGH_POWER + 1)
848
849 // The number of pins that might need to be controlled
850 #define RH_SX126x_MAX_RADIO_CONTROL_PINS (3)
851
852 // Tells how to set the pins in PinConfig for each a particular transmit or receive condition
853 typedef struct
854 {
855 /// The type of radio condition for these pin settings. PinConfigEntry_EOT for last item in table
856 RadioPinConfigMode mode = RadioPinConfigMode_EOT;
857 /// The state (HIGH or LOW) to set each of the radio control pins to when this state is reached
858 bool pinState[RH_SX126x_MAX_RADIO_CONTROL_PINS];
860
861 /// Pointer to structure can be passed to the contructor or setRadioPinConfig() to configure the
862 /// how various pins are to be set to configure your radio hardware (RF swithes etc) for various radio modes.
863 typedef struct
864 {
865 /// Pin number of each pin to be automcatically controlled
866 uint8_t pinNumber[RH_SX126x_MAX_RADIO_CONTROL_PINS]; // Pin number or RH_INVALID_PIN
867 /// One entry for each radio state supported by your hardware
868 // The last entry must have mode = RadioPinConfigMode_EOT
869 RadioPinConfigEntry configState[RH_SX126x_MAX_RADIO_PIN_CONFIG_MODES];
871
872 /// Constructor. You can have multiple instances, but each instance must have its own
873 /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
874 /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
875 /// distinct interrupt lines, one for each instance.
876 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RH_RF22 before
877 /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
878 /// \param[in] interruptPin The interrupt Pin number that is connected to the RFM DIO0 interrupt line.
879 /// Defaults to pin 2, as required by Anarduino MinWirelessLoRa module.
880 /// Caution: You must specify an interrupt capable pin.
881 /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
882 /// On Leonardo pins 0, 1, 2 or 3. On Mega2560 pins 2, 3, 18, 19, 20, 21. On Due and Teensy, any digital pin.
883 /// On Arduino Zero from arduino.cc, any digital pin other than 4.
884 /// On Arduino M0 Pro from arduino.org, any digital pin other than 2.
885 /// On other Arduinos pins 2 or 3.
886 /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
887 /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
888 /// On other boards, any digital pin may be used.
889 /// \param[in] busyPin Pin number of pin connected to the radio's busy pin. The radio sets the busy pin high while it is busy
890 /// If this is not set to RH_INVALID_PIN (the default) then this module will wait for the busy pin to go low before
891 /// initialting the next SPI transfer. It is strongly recommended that you use this.
892 /// \param[in] resetPin Pin number of the pin connected to the radio's reset pin. If this is not set to RH_INVALID_PIN (the default) then this module will
893 /// assert the reset pin low for 2 ms during init() in order to reset the radio. It is strongly recommended that you use this
894 /// \param[in] spi Pointer to the SPI interface object to use.
895 /// \param[in] radioPinConfig pinter to a strucure that describes what pins are to be automatically set when changing
896 /// the radio mode. This can be used to configure any external RF switches, RF amplifiers etc.
897 /// Defaults to the standard Arduino hardware SPI interface
898 RH_SX126x(uint8_t slaveSelectPin = SS, uint8_t interruptPin = 2, uint8_t busyPin = RH_INVALID_PIN, uint8_t resetPin = RH_INVALID_PIN,
899 RHGenericSPI& spi = hardware_spi, RadioPinConfig* radioPinConfig = NULL);
900
901 /// Initialise the Driver transport hardware and software.
902 /// Leaves the radio in idle mode,
903 /// with default configuration of: 915.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
904 /// \return true if initialisation succeeded.
905 virtual bool init();
906
907 /// Prints the value of selected radio chip registers
908 /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
909 /// For debugging purposes only.
910 /// \param[in] address The register adddress of the first register to print
911 /// \param[in] count The number of registers to print
912 /// \return true on success
913 bool printRegisters(uint16_t address, uint8_t count);
914
915 /// Sets all the registers required to configure the data modem in the radio, including the bandwidth,
916 /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the
917 /// canned configurations in ModemConfigChoice suit you.
918 /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
919 /// \return true if modem was successfully reconfigured
920 bool setModemRegisters(const ModemConfig* config);
921
922 /// Select one of the predefined modem configurations. If you need a modem configuration not provided
923 /// here, use setModemRegisters() with your own ModemConfig.
924 /// Caution: the slowest protocols may require a radio module with TCXO temperature controlled oscillator
925 /// for reliable operation.
926 /// \param[in] index The configuration choice.
927 /// \return true if index is a valid choice.
929
930 /// Tests whether a new message is available from the Driver.
931 /// On most drivers, this will also put the Driver into RHModeRx mode until
932 /// a message is actually received by the transport, when it will be returned to RHModeIdle.
933 /// This can be called multiple times in a timeout loop
934 /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
935 virtual bool available();
936
937 /// Turns the receiver on if it not already on.
938 /// If there is a valid message available, copy it to buf and return true
939 /// else return false.
940 /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
941 /// You should be sure to call this function frequently enough to not miss any messages
942 /// It is recommended that you call it in your main loop.
943 /// \param[in] buf Location to copy the received message
944 /// \param[in,out] len Pointer to the number of octets available in buf. The number be reset to the actual number of octets copied.
945 /// \return true if a valid message was copied to buf
946 virtual bool recv(uint8_t* buf, uint8_t* len);
947
948 /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
949 /// Then optionally waits for Channel Activity Detection (CAD)
950 /// to show the channnel is clear (if the radio supports CAD) by calling waitCAD().
951 /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
952 /// of 0 is permitted.
953 /// \param[in] data Array of data to be sent
954 /// \param[in] len Number of bytes of data to send
955 /// specify the maximum time in ms to wait. If 0 (the default) do not wait for CAD before transmitting.
956 /// \return true if the message length was valid and it was correctly queued for transmit. Return false
957 /// if CAD was requested and the CAD timeout timed out before clear channel was detected.
958 virtual bool send(const uint8_t* data, uint8_t len);
959
960 /// Sets the length of the preamble
961 /// in bytes.
962 /// Caution: this should be set to the same
963 /// value on all nodes in your network. Default is 8.
964 /// Sets the message preamble length in RH_SX126x_REG_??_PREAMBLE_?SB
965 /// \param[in] bytes Preamble length in bytes.
966 void setPreambleLength(uint16_t bytes);
967
968 /// Returns the maximum message length
969 /// available in this Driver.
970 /// \return The maximum legal message length
971 virtual uint8_t maxMessageLength();
972
973 /// Sets the transmitter and receiver
974 /// centre frequency.
975 /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several
976 /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work
977 /// \param[i] calibrate set true if the radio modules are to be automatically recalibrated for this frequency
978 /// \return true if the selected frquency centre is within range, and the radio frequency is successfully set
979 bool setFrequency(float centre, bool calibrate = true);
980
981 /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
982 /// disables them.
983 void setModeIdle();
984
985 /// If current mode is Tx or Idle, changes it to Rx.
986 /// Starts the receiver in the SX126X/96/97/98.
987 void setModeRx();
988
989 /// If current mode is Rx or Idle, changes it to Rx. F
990 /// Starts the transmitter in the SX126X/96/97/98.
991 void setModeTx();
992
993 /// Sets the transmitter power output level
994 /// Be a good neighbour and set the lowest power level you need.
995 /// Caution: legal power limits may apply in certain countries.
996 /// After init(), the power will be set to 13dBm.
997 /// \param[in] power Transmitter power level in dBm.
998 /// For SX1261, limits are -17 to +15 dBm
999 /// For SX1262, limits are -9 to +22 dBm
1000 /// For STM32WLx with low power PA configured by radioPinConfig, same as SX1261.
1001 /// For STM32WLx with high power PA configured by radioPinConfig, same as SX1262.
1002 /// \return true if successful. Returns false if radioPinConfig has not been properly
1003 /// configured for the requested power setting
1004 virtual bool setTxPower(int8_t power);
1005
1006 /// Sets the radio into low-power sleep mode.
1007 /// If successful, the transport will stay in sleep mode until woken by
1008 /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)
1009 /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
1010 /// \return true if sleep mode was successfully entered.
1011 virtual bool sleep();
1012
1013 /// Use the radio's Channel Activity Detect (CAD) function to detect channel activity.
1014 /// Sets the SX126X radio into CAD mode and waits until CAD detection is complete.
1015 /// To be used in a listen-before-talk mechanism (Collision Avoidance)
1016 /// with a reasonable time backoff algorithm.
1017 /// This is called automatically by waitCAD().
1018 /// NOT YET WORKING.
1019 /// \return true if channel is in use.
1020 virtual bool isChannelActive();
1021
1022 /// Returns the Signal-to-noise ratio (SNR) of the last received message, as measured
1023 /// by the receiver.
1024 /// \return SNR of the last received message in dB
1025 int lastSNR();
1026
1027 // Support for configurable RX and TX pins
1028 void setRadioPinConfig(RadioPinConfig* config);
1029
1030 /// Set the radio into continuous transmission mode. A carrier
1031 /// wave will be transmitted on the configured centre frequency until available(), recv() or send() are called
1032 /// CAUTION: use this only for testing in controlled conditions with a dummy load. It may be illegal for you to transmit
1033 /// a continuous carrier wave to air.
1034 bool setTxContinuous();
1035
1036 /// Read and return the radio status byte
1037 uint8_t getStatus();
1038
1039 /// Return the last interrupt mask, for debugging
1040 uint16_t lastIrq() {return _lastirq;};
1041
1042 /// Return true if an interrupt has occurred since the last clearIflag(). For debugging
1043 bool getIflag() {return _iflag;};
1044
1045 /// Reset the interrupt flag. For debugging
1046 void clearIflag() {_iflag=false;};
1047
1048 /// REsets the last interrupt mask. For debugging
1049 void clearLastIrq() {_lastirq=0;};
1050
1051 /// Enable or disable the ability to detect CRC errors
1052 void enableCrcErrorIrq(bool enable);
1053
1054 /// Tells the driver to enable RAW mode, which prevents the transmissions of the 4 byte address header.
1055 void enableRawMode(bool enable);
1056
1057 /// Returns the frequency error from the last received packet
1058 float getFrequencyError();
1059
1060 /// Set the voltage to use for the TCXO oven
1061 /// and enable the TCXO. Do not call this unless you actually have a TCXO,
1062 /// otherwise the radio will not work correctly.
1063 bool setTCXO(float voltage, uint32_t delay);
1064
1065protected:
1066
1067 ///////////////////////////////////////////////////////////////////
1068 // Follow are low level functions for communicating with the SX126x
1069 // Caution should be used if accessing them in subclasses
1070
1071 /// Wait until the busy pin (if speecified in the contructor) is no longer low
1072 /// On timeout, prints an error to eSerial and returns false. Else returns true.
1073 virtual bool waitUntilNotBusy();
1074
1075
1076 /// Send a command with multi-byte data to the radio
1077 bool sendCommand(uint8_t command, uint8_t data[], uint8_t len);
1078
1079 /// Send a command with a single data byte to the radio
1080 bool sendCommand(uint8_t command, uint8_t value);
1081
1082 /// Send a command without any data to the radio
1083 bool sendCommand(uint8_t command);
1084
1085 /// Send a command to the radio and get a multi-byte respose
1086 bool getCommand(uint8_t command, uint8_t data[], uint8_t len);
1087
1088 /// Read multiple registers from the radio
1089 bool readRegisters(uint16_t address, uint8_t data[], uint8_t len);
1090
1091 /// Read and return a single register byte from the radio
1092 uint8_t readRegister(uint16_t address);
1093
1094 /// Write multibyte data to the given register and sunbsequent registers
1095 bool writeRegisters(uint16_t address, uint8_t data[], uint8_t len);
1096
1097 /// Write a single byte to the given register
1098 bool writeRegister(uint16_t address, uint8_t data);
1099
1100 /// Write multibyte data to the radio IO buffer at the current buffer address
1101 bool writeBuffer(uint8_t offset, const uint8_t data[], uint8_t len);
1102
1103 /// Write a single byte to the radio IO bufferat the current buffer address
1104 bool writeBuffer(uint8_t offset, const char* text);
1105
1106 /// Read multibyte data from the radio IO buffer at the current buffer address
1107 bool readBuffer(uint8_t offset, uint8_t data[], uint8_t len);
1108
1109 /// Set the radio Power Amplifier configuration
1110 bool setPaConfig(uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut);
1111
1112 /// Set the radio power output. CAUTION: for internal use only. Users should use setTxPower()
1113 bool setTxParams(uint8_t power, uint8_t rampTime);
1114
1115 /// Clear the radio error byte
1116 bool clearDeviceErrors();
1117
1118 /// Sets whether DIO2 is to be used to automatically control an external radio RF switch.
1119 /// Normall you should use the pinConfig in the constructor or setRadioPinConfig() to automatically control any
1120 /// radio control pins
1121 bool setDIO2AsRfSwitchCtrl(bool value);
1122
1123 /// Sets the mode that the radio will change to after a transmit or receive is complete
1124 bool setRxFallbackMode(uint8_t mode);
1125
1126 /// Set the low-level registers for any desired modulation scheme
1127 bool setModulationParameters(uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, uint8_t p7, uint8_t p8);
1128
1129 /// Set the low-level registers for the desired LoRA modulation scheme
1130 bool setModulationParametersLoRa(uint8_t sf, float bw, uint8_t cr, bool ldro);
1131
1132 /// Set the low-level registers for the desired GFSK modulation scheme
1133 bool setModulationParametersGFSK(uint32_t br, uint8_t sh, uint8_t rxBw, uint32_t freqDev);
1134
1135 /// Cause the radio to calibrate all its sections at the currently selected frequency
1136 bool calibrate(uint8_t calib_param);
1137
1138 /// Allows the user to calibrate the image rejection of the device for the device operating frequency band
1139 bool calibrateImage(uint8_t f1, uint8_t f2);
1140
1141 /// Set the 16 bit LoRa sync word
1142 bool setLoRaSyncWord(uint16_t sync);
1143
1144 /// Set the radio power amplifier over-current protection
1145 bool setOCPConfiguration(uint8_t setting);
1146
1147 /// Configures the radio to use an external temperature controlled crystal oscillator (TCXO) and the oven voltage to use.
1148 /// For low level internal use only
1149 bool setDIO3AsTcxoCtrl(uint8_t voltage, uint32_t delay);
1150
1151 /// Low level function to set the radio packet confiuration
1152 bool setPacketParams(uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, uint8_t p7, uint8_t p8, uint8_t p9);
1153
1154 /// Set the necessary radio packet parameters for a forthcoming transmission of payload_length bytes
1155 bool setPacketParametersLoRa(uint8_t payload_length);
1156
1157 /// Low level function to set the address wherge the next radBuffer or writeBuffer will occur
1158 bool setBufferBaseAddress(uint8_t txbase, uint8_t rxbase);
1159
1160 /// Set the radio to sleep mode. Automatically configures the radio control pins to the configuration RadioPinConfigMode_IDLE.
1161 bool setSleep(uint8_t config);
1162
1163 /// Set the radio to sleep mode. Automatically configures the radio control pins to the configuration RadioPinConfigMode_IDLE.
1164 bool setStandby(uint8_t config);
1165
1166 /// Set the radio to transmit mode. Automatically configures the radio control pins to the configuration required
1167 /// for the most recently requested power in setTxPower (RadioPinConfigMode_TX_HIGH_POWER or RadioPinConfigMode_TX_LOW_POWER )
1168 bool setTx(uint32_t timeout);
1169
1170 /// Starts the radio in Clear Air Detect (CAD) mode. CAUTION: NOT YET WORKING, always retuns false.
1171 bool setCad();
1172
1173 /// Set the radio to receive mode. Automatically configures the radio control pins to the configuration RadioPinConfigMode_RX.
1174 bool setRx(uint32_t timeout);
1175
1176 /// Sets whether radios receiver gain boost should be enabled instead of the default power saving mode.
1177 bool setRxBoostMode(bool boost, bool retain);
1178
1179 /// Sets the chip regulator mode to either LDO or DC-DC SMPS.
1180 /// Set to DC-DC SMPS by default
1181 bool setRegulatorMode(uint8_t mode);
1182
1183 /// Configures the conditions under which the radio will enable an interrupt, and for which DIO pins
1184 bool setDioIrqParams(uint16_t irqmask, uint16_t dio1mask, uint16_t dio2mask, uint16_t dio3mask);
1185
1186 /// Clear the radio IRQ state
1187 bool clearIrqStatus(uint16_t mask);
1188
1189 /// Return the radio IRQ state
1190 uint16_t getIrqStatus();
1191
1192 /// return the current packet type
1193 uint8_t getPacketType();
1194
1195 /// From SX1262_datasheet.pdf: "When exchanging LoRa® packets with inverted IQ polarity,
1196 /// some packet losses may be observed for longer packet". THis function enables the workaround described in that section
1197 void setInvertIQ(bool invertIQ);
1198
1199 /// Per SX1262_datasheet.pdf Rev 1.2 section 15.2, this fixes an error in the radio Power Amplifier clamping
1200 bool fixPAClamping(bool enable);
1201
1202 /// Do whatever is necesary to establish the interrupt handler. Subclasses may have different needs
1203 virtual bool setupInterruptHandler();
1204
1205 /// This is a low level function to handle the interrupts for one instance of RH_SX126x.
1206 /// Called automatically by isr*()
1207 /// Should not need to be called by user code.
1208 void handleInterrupt();
1209
1210 /// Examine the revceive buffer to determine whether the message is for this node
1211 void validateRxBuf();
1212
1213 /// Clear our local receive buffer
1214 void clearRxBuf();
1215
1216 /// Called by RH_SX126x when the radio mode is about to change to a new setting.
1217 /// Can be used by subclasses to implement antenna switching etc.
1218 /// \param[in] mode RHMode the new mode about to take effect
1219 /// \return true if the subclasses changes successful
1220 virtual bool modeWillChange(RHMode) {return true;}
1221
1222 /// Sets the pins configured in radioPinConfig as required for the desired mode.
1223 /// Called just before the radio is set to the new mode.
1224 /// \return true if succcessful, false is there is no radioPinConfig configuration,
1225 /// or no entry for the requested mode
1227
1228 /// Find the pin configuration entry for a desired radio mode
1229 virtual RadioPinConfigEntry* findRadioPinConfigEntry(RadioPinConfigMode mode);
1230
1231private:
1232 /// Low level interrupt service routine for device connected to interrupt 0
1233 static void isr0();
1234
1235 /// Low level interrupt service routine for device connected to interrupt 1
1236 static void isr1();
1237
1238 /// Low level interrupt service routine for device connected to interrupt 1
1239 static void isr2();
1240
1241 /// Array of instances connected to interrupts 0 and 1
1242 static RH_SX126x* _deviceForInterrupt[];
1243
1244 /// The configured interrupt pin connected to this instance
1245 uint8_t _interruptPin;
1246
1247 /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
1248 /// else 0xff
1249 uint8_t _myInterruptIndex;
1250
1251 /// Number of octets in the buffer
1252 volatile uint8_t _bufLen;
1253
1254 /// The receiver/transmitter buffer
1255 uint8_t _buf[RH_SX126x_MAX_PAYLOAD_LEN];
1256
1257 /// True when there is a valid message in the buffer
1258 volatile bool _rxBufValid;
1259
1260 /// True if we are using the HF port (779.0 MHz and above)
1261 bool _usingHFport;
1262
1263 /// Last measured SNR, dB
1264 int8_t _lastSNR;
1265
1266 /// If true, sends CRCs in every packet and requires a valid CRC in every received packet
1267 bool _enableCRC;
1268
1269 /// Sets the preamble length for LoRa packets
1270 uint16_t _preambleLength = 8;
1271
1272 /// Whether the modem is to be configured for INverted IQ
1273 bool _invertIQ = false;
1274
1275 /// The type of packet to configure the modem for
1276 PacketType _packetType = PacketTypeLoRa;
1277
1278 /// If the current LoRa bandwidth is 500kHz, we need to remeber this in order to implement the
1279 /// modulation quality workaround in setTx()
1280 bool _lorabw500 = false;
1281
1282 /// Support for optional configurable radio control pins for RX and TX modes
1283 RadioPinConfig* _radioPinConfig = NULL;
1284
1285 /// Remember what PA type is required, depending on device type and radio pin configurations
1286 RadioPinConfigMode _requiredPAMode = RadioPinConfigMode_IDLE; // One of PinConfigMode_TX_LOW_POWER PinConfigMode_TX_HIGH_POWER
1287
1288 /// Pin number of the radio BUSY pin, if available, else RH_INVALID_PIN
1289 uint8_t _busyPin;
1290
1291 /// Pin number of the radio NRESET pin, if available, else RH_INVALID_PIN
1292 uint8_t _resetPin;
1293
1294 /// Currently selected bandwidth, required for frequencey error calculations
1295 float _bandwidth = 0.0;
1296
1297 /// Whether we are in raw mode, bypassing address bytes prefix
1298 bool _raw = false;
1299
1300 /// Vale of the last interrupt flags, for debugging
1301 volatile uint16_t _lastirq;
1302
1303 /// Whether an interupt has occurred since the last clearIflag(). For debugging
1304 volatile bool _iflag = false;
1305
1306 // These are the interrupts we are willing to process
1307 uint16_t _irqMask = RH_SX126x_IRQ_CAD_DETECTED
1308 | RH_SX126x_IRQ_CAD_DONE
1309 | RH_SX126x_IRQ_CRC_ERR
1310 | RH_SX126x_IRQ_HEADER_ERR
1311 | RH_SX126x_IRQ_RX_DONE
1312 | RH_SX126x_IRQ_TX_DONE;
1313};
1314
1315/// @example sx1262_client.ino
1316/// @example sx1262_server.ino
1317
1318#endif
RHMode
Defines different operating modes for the transport hardware.
Definition RHGenericDriver.h:49
virtual RHMode mode()
Definition RHGenericDriver.cpp:165
Base class for SPI interfaces.
Definition RHGenericSPI.h:31
Base class for RadioHead drivers that use the SPI bus to communicate with its transport hardware.
Definition RHSPIDriver.h:39
Driver to send and receive unaddressed, unreliable datagrams via a Semtech SX126X family LoRa capable...
Definition RH_SX126x.h:778
bool setBufferBaseAddress(uint8_t txbase, uint8_t rxbase)
Low level function to set the address wherge the next radBuffer or writeBuffer will occur.
Definition RH_SX126x.cpp:1056
int lastSNR()
Definition RH_SX126x.cpp:538
bool printRegisters(uint16_t address, uint8_t count)
Definition RH_SX126x.cpp:849
bool setModulationParametersLoRa(uint8_t sf, float bw, uint8_t cr, bool ldro)
Set the low-level registers for the desired LoRA modulation scheme.
Definition RH_SX126x.cpp:922
bool setRx(uint32_t timeout)
Set the radio to receive mode. Automatically configures the radio control pins to the configuration R...
Definition RH_SX126x.cpp:1110
void clearIflag()
Reset the interrupt flag. For debugging.
Definition RH_SX126x.h:1046
bool setPacketParams(uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, uint8_t p7, uint8_t p8, uint8_t p9)
Low level function to set the radio packet confiuration.
Definition RH_SX126x.cpp:1035
virtual uint8_t maxMessageLength()
Definition RH_SX126x.cpp:404
void setModeTx()
Definition RH_SX126x.cpp:468
RadioPinConfigMode
Definition RH_SX126x.h:838
virtual bool recv(uint8_t *buf, uint8_t *len)
Definition RH_SX126x.cpp:335
bool readBuffer(uint8_t offset, uint8_t data[], uint8_t len)
Read multibyte data from the radio IO buffer at the current buffer address.
Definition RH_SX126x.cpp:718
bool setTxParams(uint8_t power, uint8_t rampTime)
Set the radio power output. CAUTION: for internal use only. Users should use setTxPower()
Definition RH_SX126x.cpp:740
virtual bool send(const uint8_t *data, uint8_t len)
Definition RH_SX126x.cpp:356
uint8_t readRegister(uint16_t address)
Read and return a single register byte from the radio.
Definition RH_SX126x.cpp:657
bool setRxBoostMode(bool boost, bool retain)
Sets whether radios receiver gain boost should be enabled instead of the default power saving mode.
Definition RH_SX126x.cpp:1145
void setInvertIQ(bool invertIQ)
Definition RH_SX126x.cpp:1195
virtual bool modeWillChange(RHMode)
Definition RH_SX126x.h:1220
bool setRegulatorMode(uint8_t mode)
Definition RH_SX126x.cpp:1161
bool getIflag()
Return true if an interrupt has occurred since the last clearIflag(). For debugging.
Definition RH_SX126x.h:1043
bool setLoRaSyncWord(uint16_t sync)
Set the 16 bit LoRa sync word.
Definition RH_SX126x.cpp:990
bool setModulationParameters(uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, uint8_t p7, uint8_t p8)
Set the low-level registers for any desired modulation scheme.
Definition RH_SX126x.cpp:880
void setModeRx()
Definition RH_SX126x.cpp:457
bool setPacketParametersLoRa(uint8_t payload_length)
Set the necessary radio packet parameters for a forthcoming transmission of payload_length bytes.
Definition RH_SX126x.cpp:1041
bool setCad()
Starts the radio in Clear Air Detect (CAD) mode. CAUTION: NOT YET WORKING, always retuns false.
Definition RH_SX126x.cpp:1125
virtual bool sleep()
Definition RH_SX126x.cpp:446
bool setFrequency(float centre, bool calibrate=true)
Definition RH_SX126x.cpp:409
bool clearDeviceErrors()
Clear the radio error byte.
Definition RH_SX126x.cpp:864
virtual bool waitUntilNotBusy()
Definition RH_SX126x.cpp:548
virtual bool isChannelActive()
Definition RH_SX126x.cpp:522
bool setPaConfig(uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut)
Set the radio Power Amplifier configuration.
Definition RH_SX126x.cpp:734
void clearLastIrq()
REsets the last interrupt mask. For debugging.
Definition RH_SX126x.h:1049
ModemConfigChoice
Definition RH_SX126x.h:824
@ LoRa_Bw31_25Cr48Sf512
Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range.
Definition RH_SX126x.h:827
@ LoRa_Bw500Cr45Sf128
Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range.
Definition RH_SX126x.h:826
@ LoRa_Bw125Cr48Sf4096
Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, low data rate, CRC on. Slow+long range.
Definition RH_SX126x.h:828
@ LoRa_Bw125Cr45Sf128
Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range.
Definition RH_SX126x.h:825
@ LoRa_Bw125Cr45Sf2048
Bw = 125 kHz, Cr = 4/5, Sf = 2048chips/symbol, CRC on. Slow+long range.
Definition RH_SX126x.h:829
void setModeIdle()
Definition RH_SX126x.cpp:436
virtual bool available()
Definition RH_SX126x.cpp:313
bool readRegisters(uint16_t address, uint8_t data[], uint8_t len)
Read multiple registers from the radio.
Definition RH_SX126x.cpp:640
void handleInterrupt()
Definition RH_SX126x.cpp:204
bool setModemRegisters(const ModemConfig *config)
Definition RH_SX126x.cpp:480
uint16_t getIrqStatus()
Return the radio IRQ state.
Definition RH_SX126x.cpp:1181
bool setDIO3AsTcxoCtrl(uint8_t voltage, uint32_t delay)
Definition RH_SX126x.cpp:1001
PacketType
Packet types the modem can be configured for.
Definition RH_SX126x.h:782
@ PacketTypeLoRa
Use LoRA packets.
Definition RH_SX126x.h:783
@ PacketTypeGFSK
Use GFSK packets.
Definition RH_SX126x.h:784
virtual bool setRadioPinsForMode(RadioPinConfigMode mode)
Definition RH_SX126x.cpp:1212
bool setStandby(uint8_t config)
Set the radio to sleep mode. Automatically configures the radio control pins to the configuration Rad...
Definition RH_SX126x.cpp:1069
bool setSleep(uint8_t config)
Set the radio to sleep mode. Automatically configures the radio control pins to the configuration Rad...
Definition RH_SX126x.cpp:1062
bool writeBuffer(uint8_t offset, const uint8_t data[], uint8_t len)
Write multibyte data to the radio IO buffer at the current buffer address.
Definition RH_SX126x.cpp:698
bool setOCPConfiguration(uint8_t setting)
Set the radio power amplifier over-current protection.
Definition RH_SX126x.cpp:996
bool setTx(uint32_t timeout)
Definition RH_SX126x.cpp:1076
bool setDioIrqParams(uint16_t irqmask, uint16_t dio1mask, uint16_t dio2mask, uint16_t dio3mask)
Configures the conditions under which the radio will enable an interrupt, and for which DIO pins.
Definition RH_SX126x.cpp:1166
virtual bool setupInterruptHandler()
Do whatever is necesary to establish the interrupt handler. Subclasses may have different needs.
Definition RH_SX126x.cpp:145
bool sendCommand(uint8_t command, uint8_t data[], uint8_t len)
Send a command with multi-byte data to the radio.
Definition RH_SX126x.cpp:582
bool getCommand(uint8_t command, uint8_t data[], uint8_t len)
Send a command to the radio and get a multi-byte respose.
Definition RH_SX126x.cpp:626
uint8_t getPacketType()
return the current packet type
Definition RH_SX126x.cpp:1188
uint16_t lastIrq()
Return the last interrupt mask, for debugging.
Definition RH_SX126x.h:1040
bool clearIrqStatus(uint16_t mask)
Clear the radio IRQ state.
Definition RH_SX126x.cpp:1175
bool setRxFallbackMode(uint8_t mode)
Sets the mode that the radio will change to after a transmit or receive is complete.
Definition RH_SX126x.cpp:875
void enableRawMode(bool enable)
Tells the driver to enable RAW mode, which prevents the transmissions of the 4 byte address header.
Definition RH_SX126x.cpp:139
bool fixPAClamping(bool enable)
Per SX1262_datasheet.pdf Rev 1.2 section 15.2, this fixes an error in the radio Power Amplifier clamp...
Definition RH_SX126x.cpp:1200
virtual bool init()
Definition RH_SX126x.cpp:59
virtual RadioPinConfigEntry * findRadioPinConfigEntry(RadioPinConfigMode mode)
Find the pin configuration entry for a desired radio mode.
Definition RH_SX126x.cpp:1247
void validateRxBuf()
Examine the revceive buffer to determine whether the message is for this node.
Definition RH_SX126x.cpp:295
bool setModulationParametersGFSK(uint32_t br, uint8_t sh, uint8_t rxBw, uint32_t freqDev)
Set the low-level registers for the desired GFSK modulation scheme.
Definition RH_SX126x.cpp:973
void setPreambleLength(uint16_t bytes)
Definition RH_SX126x.cpp:517
bool setTCXO(float voltage, uint32_t delay)
Definition RH_SX126x.cpp:1010
bool writeRegisters(uint16_t address, uint8_t data[], uint8_t len)
Write multibyte data to the given register and sunbsequent registers.
Definition RH_SX126x.cpp:664
bool setTxContinuous()
Definition RH_SX126x.cpp:1104
void enableCrcErrorIrq(bool enable)
Enable or disable the ability to detect CRC errors.
Definition RH_SX126x.cpp:130
bool writeRegister(uint16_t address, uint8_t data)
Write a single byte to the given register.
Definition RH_SX126x.cpp:691
bool calibrate(uint8_t calib_param)
Cause the radio to calibrate all its sections at the currently selected frequency.
Definition RH_SX126x.cpp:979
bool calibrateImage(uint8_t f1, uint8_t f2)
Allows the user to calibrate the image rejection of the device for the device operating frequency ban...
Definition RH_SX126x.cpp:984
bool setDIO2AsRfSwitchCtrl(bool value)
Definition RH_SX126x.cpp:870
virtual bool setTxPower(int8_t power)
Definition RH_SX126x.cpp:746
uint8_t getStatus()
Read and return the radio status byte.
Definition RH_SX126x.cpp:569
float getFrequencyError()
Returns the frequency error from the last received packet.
Definition RH_SX126x.cpp:1263
void clearRxBuf()
Clear our local receive buffer.
Definition RH_SX126x.cpp:326
bool setModemConfig(ModemConfigChoice index)
Definition RH_SX126x.cpp:506
Defines register values for a set of modem configuration registers.
Definition RH_SX126x.h:795
uint8_t p4
Value for setModulationParameters parameter 4.
Definition RH_SX126x.h:800
uint8_t p8
Value for setModulationParameters parameter 8.
Definition RH_SX126x.h:804
uint8_t p5
Value for setModulationParameters parameter 5.
Definition RH_SX126x.h:801
uint8_t p7
Value for setModulationParameters parameter 7.
Definition RH_SX126x.h:803
uint8_t p1
Value for setModulationParameters parameter 1.
Definition RH_SX126x.h:797
uint8_t p2
Value for setModulationParameters parameter 2.
Definition RH_SX126x.h:798
uint8_t p3
Value for setModulationParameters parameter 3.
Definition RH_SX126x.h:799
uint8_t p6
Value for setModulationParameters parameter 6.
Definition RH_SX126x.h:802
Definition RH_SX126x.h:854
Definition RH_SX126x.h:864