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 transceiver.
564
565Works with NiceRF LoRa1262-915 and Teensy 3.1. Will probably work with any other SX1262 module.
566
567\par Overview
568
569This class provides basic functions for sending and receiving unaddressed,
570unreliable datagrams of arbitrary length to 251 octets per packet.
571
572Manager classes may use this class to implement reliable, addressed datagrams and streams,
573mesh routers, repeaters, translators etc.
574
575Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
576modulation scheme.
577
578Predefined modulation schemes are available for various LoRa
579modulation speeds and bandwidths. GFSK modulation is also supported.
580
581The SX126x family of radio chips are availabel as discrete comonents with an SPI interface.
582In some hardware (eg the STM32WLE5xx STM32WLE4xx processors) the radio
583is built into a microprocessor.
584
585\par Packet Format
586
587All messages sent and received by this RH_SX126x Driver conform to this packet format, which is compatible with RH_RF95:
588
589- LoRa mode:
590- 8 symbol PREAMBLE
591- Explicit header with header CRC (default CCITT, handled internally by the radio)
592- 4 octets HEADER: (TO, FROM, ID, FLAGS)
593- 0 to 251 octets DATA
594- CRC (default CCITT, handled internally by the radio)
595
596\par Interrupts
597
598The RH_SX126x driver uses interrupts to react to events in the radio,
599such as the reception of a new packet, or the completion of
600transmission of a packet. The driver configures the radio so the
601required interrupt is generated by the radio's DIO1 pin. The
602RH_SX126x driver interrupt service routine reads status from and
603writes data to the the radio module via an SPI interface. It is very
604important therefore, that if you are using the RH_SX126x driver with
605another SPI based deviced, that you disable interrupts while you
606transfer data to and from that other device. Use cli() to disable
607interrupts and sei() to reenable them. (however note that the
608RH_STM32WLx subclass uses the dedicated internal SPI interface that is
609connected only to the radio).
610
611\par Memory
612
613The RH_SX126x driver requires non-trivial amounts of memory. The sample
614programs all compile to about 35 kbytes each, which will fit in the
615flash proram memory of most Arduinos. However, the RAM requirements are
616more critical. Therefore, you should be vary sparing with RAM use in
617programs that use the RH_SX126x driver.
618
619\par Compatibility with RH_RF95
620
621The predefined modulation schemes have been show to interoperate with
622the RH_RF95 driver with similarly named modulation schemes.
623
624For example the (default) RH_SX126x::LoRa_Bw125Cr45Sf128 is compatible
625with the (default) RH_RF95::Bw125Cr45Sf128.
626
627The RH_SX126x driver sets the LoRa Sync word to 0x1424, which is compatible with single byte 0x12 default for RH_RF95.
628// https://forum.lora-developers.semtech.com/t/sx1272-and-sx1262-lora-sync-word-compatibility/988/13
629
630\par Transmitter Power
631
632We measured the RF power output from a Wio-E5 mini at 868.0 MHz, with
633the radio set to continuous CW transmission using
634setTxContinuous(). On this chip that implies the high power amplifier.
635We set various power outputs with setTxPower() from -9 to 22 and
636measured the RF output power with a HP 5342A Microwave Frequency
637Counter. Note that the drivers setTxPower() sets the optimum
638transmitter control registers per section 13.1.14.1 of the datasheet
639SX1262_datasheet.pdf
640
641\code
642Program power Measured power
643 dBm dBm
644 -9 -5.0
645 0 -2.9
646 5 6.9
647 10 8.9
648 15 13.3
649 16 14.1
650 17 14.6
651 18 16.7
652 19 17.3
653 20 17.8
654 21 18.7
655 22 19.4
656\endcode
657
658With the transmitter frequency set to 868.0 MHz, the actual centre
659frequency measured with the HP 5342A Microwave Frequency Counter on 2
660instances of Wio-E5 mini were 867.999826 and 867.999652 MHz.
661
662\par Differences between models
663
664SX126x compatible chips are available in at least 4 types:
665
666-SX1261 Has only one (low power) PA, -17 to +15 dBm
667
668-SX1262 Has only one (high power) PA, -9 to +22 dBm
669
670-SX1268 Has 2 PAs, low power (-17 to +15 dBm) and high power (-9 to +22 dBm)
671
672-STM32WLE5JC has 2 PAs, low power (-17 to +15 dBm) and high power (-9 to +22 dBm).
673
674Even if the radio has 2 PAs, depending on your radio module, maybe
675only one is connected. It also includes a dedicated SPI interface for
676the radio plus some internllay connected reset and interrupt pins
677
678Some radio modules might also include an antenna switch, and the
679driver MUST be configured so that it knows how to turn any
680control pins on and off for receiving and transmitting. See setRadioPinConfig().
681
682\par Configuring the driver for your particular type of radio
683
684You will almost certainly have to configure this driver to suit the
685particular radio hardware in your system. Its boring but you MUST pay
686attention to this otherwise you may not be able to transmit or receive
687successfully.
688
689This issues you will have to consider are:
690
691- What model radio do you have?
692
693- What SPI bus is the radio connected to?
694
695- Is there a TCXO to configure?
696
697- What pin is used for the SPI slave select for the radio chip?
698
699- Is the radio reset pin connected to the CPU?
700
701- Are there any pins required to be set to control the external radio
702 interface, such as RF switches, external PAs etc,
703
704If you are using a ST Microelectronics STM32WLE5xx or STM32WLE4xx
705processors and its built in radio, you can use the RH_STM32WLx and
706ignore most or all of these issues.
707
708If you are using a Heltec CubeCell, such as HTCC-AB01, initialise the driver with:
709\code
710RH_SX126x driver(RADIO_NSS, RADIO_DIO_1, RADIO_BUSY, RADIO_RESET);
711\endcode
712
713\par Range
714
715No range tests have yet been conducted.
716
717\par Connecting SX126x modules to Arduino
718
719Note, if you are using a STM32WLE5JC, see the intructions for that in RH_STM32WLx.h
720
721Connecting a NiceRF LoRa1262-915 to a Teensy 3.1:
722
723https://www.nicerf.com/lora-module/915mhz-lora-module-lora1262.html
724
725We got one on a breakout board
726which already has a small helical antenna connected. The module appears to contain a 3.3V TCXO, nd an antenna switch connected to DIO2
727You should be able to use a
728similar pinout for any 3.3V Arduino compatible board.
729
730
731\code
732 Teensy 3.1 G-Nice RF LoRa1262-915
733 GND----------GND (Ground)
734 3V3----------VCC (3.3V in)
735 pin D7-----------DIO1 (radio interrupt request out, active high)
736 pin D8-----------BUSY (radio busy output, active high)
737 pin D9-----------NRESET (radio reset in: pulled low for 2ms at startup)
738 SS pin D10----------NSS (chip select in)
739 SCK pin D13----------SCK (SPI clock in)
740 MOSI pin D11----------MOSI (SPI Data in)
741 MISO pin D12----------MISO (SPI Data out)
742
743With these connections you can then use the constructor:
744
745RH_SX126x driver(SS, 7, 8, 9);
746\endcode
747
748RAKwireless RAK4360/RAK4361
749
750RHHardwareSPI uses the default LoRa radio SPI pins as defined by the platform. You can use the contructor:
751
752\code
753RH_SX126x driver(42, 47, 46, 38); // NSS, DIO1, BUSY, NRESET
754\endcode
755
756
757
758
759
760*/
761
762class RH_SX126x : public RHSPIDriver
763{
764public:
765 /// Packet types the modem can be configured for
766 typedef enum
767 {
768 PacketTypeLoRa = 0, ///< Use LoRA packets
769 PacketTypeGFSK, ///< Use GFSK packets
770 } PacketType;
771
772 /// \brief Defines register values for a set of modem configuration registers
773 ///
774 /// Defines register values for a set of modem configuration registers
775 /// that can be passed to setModulationParameters() if none of the choices in
776 /// ModemConfigChoice suit your need setModemRegisters() writes the
777 /// register values from this structure to the appropriate registers
778 /// to set the desired spreading factor, coding rate and bandwidth
779 typedef struct
780 {
781 PacketType packetType;
782 uint8_t p1; ///< Value for setModulationParameters parameter 1
783 uint8_t p2; ///< Value for setModulationParameters parameter 2
784 uint8_t p3; ///< Value for setModulationParameters parameter 3
785 uint8_t p4; ///< Value for setModulationParameters parameter 4
786 uint8_t p5; ///< Value for setModulationParameters parameter 5
787 uint8_t p6; ///< Value for setModulationParameters parameter 6
788 uint8_t p7; ///< Value for setModulationParameters parameter 7
789 uint8_t p8; ///< Value for setModulationParameters parameter 8
790 } ModemConfig;
791
792 /// Choices for setModemConfig() for a selected subset of common
793 /// data rates. If you need another configuration,
794 /// determine the necessary settings and call setModemRegisters() with your
795 /// desired settings. It might be helpful to use the LoRa calculator mentioned in
796 /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
797 /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
798 /// definitions and not their integer equivalents: its possible that new values will be
799 /// introduced in later versions (though we will try to avoid it).
800 /// Caution: if you are using slow packet rates and long packets with RHReliableDatagram or subclasses
801 /// you may need to change the RHReliableDatagram timeout for reliable operations.
802 /// Caution: for some slow rates nad with ReliableDatagrams you may need to increase the reply timeout
803 /// with manager.setTimeout() to
804 /// deal with the long transmission times.
805 /// Caution: SX1276 family errata suggests alternate settings for some LoRa registers when 500kHz bandwidth
806 /// is in use. See the Semtech SX1276/77/78 Errata Note. These are not implemented by RH_SX126x.
807 /// In general, the LoRa_* configurations are compatible with the similarly named RH_RF95 configurations
808 typedef enum
809 {
810 LoRa_Bw125Cr45Sf128 = 0, ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range
811 LoRa_Bw500Cr45Sf128, ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range
812 LoRa_Bw31_25Cr48Sf512, ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range
813 LoRa_Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, low data rate, CRC on. Slow+long range
814 LoRa_Bw125Cr45Sf2048, ///< Bw = 125 kHz, Cr = 4/5, Sf = 2048chips/symbol, CRC on. Slow+long range
816
817 /// Structures and enums for Tx/Rx pin configuration
818 /// These structures allow you to specify what pins are to be automaticall set or cleared to control radio power amp and receivers
819 /// and how there are to be set for each radio mode, IDLE, TX or RX.
820 /// They can be used to automatically configure any RF switch or external power amp etc.
821 /// You will probably need these to configure the driver for your specific hardware
822 typedef enum
823 {
824 RadioPinConfigMode_EOT = 0, // End of table. Must be the last item in the pin configuration table
825 RadioPinConfigMode_IDLE, // This config is for the radio idle
826 RadioPinConfigMode_RX, // This config is for receiving
827 RadioPinConfigMode_TX_LOW_POWER, // This config is for transmitting with low power PA
828 RadioPinConfigMode_TX_HIGH_POWER, // This config is for transmitting with high power PA
830
831 // Maximum bumber of entries permitted in a RadioPinConfigTable
832 #define RH_SX126x_MAX_RADIO_PIN_CONFIG_MODES (RadioPinConfigMode_TX_HIGH_POWER + 1)
833
834 // The number of pins that might need to be controlled
835 #define RH_SX126x_MAX_RADIO_CONTROL_PINS (3)
836
837 // Tells how to set the pins in PinConfig for each a particular transmit or receive condition
838 typedef struct
839 {
840 /// The type of radio condition for these pin settings. PinConfigEntry_EOT for last item in table
841 RadioPinConfigMode mode = RadioPinConfigMode_EOT;
842 /// The state (HIGH or LOW) to set each of the radio control pins to when this state is reached
843 bool pinState[RH_SX126x_MAX_RADIO_CONTROL_PINS];
845
846 /// Pointer to structure can be passed to the contructor or setRadioPinConfig() to configure the
847 /// how various pins are to be set to configure your radio hardware (RF swithes etc) for various radio modes.
848 typedef struct
849 {
850 /// Pin number of each pin to be automcatically controlled
851 uint8_t pinNumber[RH_SX126x_MAX_RADIO_CONTROL_PINS]; // Pin number or RH_INVALID_PIN
852 /// One entry for each radio state supported by your hardware
853 // The last entry must have mode = RadioPinConfigMode_EOT
854 RadioPinConfigEntry configState[RH_SX126x_MAX_RADIO_PIN_CONFIG_MODES];
856
857 /// Constructor. You can have multiple instances, but each instance must have its own
858 /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
859 /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
860 /// distinct interrupt lines, one for each instance.
861 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RH_RF22 before
862 /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
863 /// \param[in] interruptPin The interrupt Pin number that is connected to the RFM DIO0 interrupt line.
864 /// Defaults to pin 2, as required by Anarduino MinWirelessLoRa module.
865 /// Caution: You must specify an interrupt capable pin.
866 /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
867 /// On Leonardo pins 0, 1, 2 or 3. On Mega2560 pins 2, 3, 18, 19, 20, 21. On Due and Teensy, any digital pin.
868 /// On Arduino Zero from arduino.cc, any digital pin other than 4.
869 /// On Arduino M0 Pro from arduino.org, any digital pin other than 2.
870 /// On other Arduinos pins 2 or 3.
871 /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
872 /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
873 /// On other boards, any digital pin may be used.
874 /// \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
875 /// If this is not set to RH_INVALID_PIN (the default) then this module will wait for the busy pin to go low before
876 /// initialting the next SPI transfer. It is strongly recommended that you use this.
877 /// \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
878 /// assert the reset pin low for 2 ms during init() in order to reset the radio. It is strongly recommended that you use this
879 /// \param[in] spi Pointer to the SPI interface object to use.
880 /// \param[in] radioPinConfig pinter to a strucure that describes what pins are to be automatically set when changing
881 /// the radio mode. This can be used to configure any external RF switches, RF amplifiers etc.
882 /// Defaults to the standard Arduino hardware SPI interface
883 RH_SX126x(uint8_t slaveSelectPin = SS, uint8_t interruptPin = 2, uint8_t busyPin = RH_INVALID_PIN, uint8_t resetPin = RH_INVALID_PIN,
884 RHGenericSPI& spi = hardware_spi, RadioPinConfig* radioPinConfig = NULL);
885
886 /// Initialise the Driver transport hardware and software.
887 /// Leaves the radio in idle mode,
888 /// with default configuration of: 915.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
889 /// \return true if initialisation succeeded.
890 virtual bool init();
891
892 /// Prints the value of selected radio chip registers
893 /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
894 /// For debugging purposes only.
895 /// \param[in] address The register adddress of the first register to print
896 /// \param[in] count The number of registers to print
897 /// \return true on success
898 bool printRegisters(uint16_t address, uint8_t count);
899
900 /// Sets all the registers required to configure the data modem in the radio, including the bandwidth,
901 /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the
902 /// canned configurations in ModemConfigChoice suit you.
903 /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
904 /// \return true if modem was successfully reconfigured
905 bool setModemRegisters(const ModemConfig* config);
906
907 /// Select one of the predefined modem configurations. If you need a modem configuration not provided
908 /// here, use setModemRegisters() with your own ModemConfig.
909 /// Caution: the slowest protocols may require a radio module with TCXO temperature controlled oscillator
910 /// for reliable operation.
911 /// \param[in] index The configuration choice.
912 /// \return true if index is a valid choice.
914
915 /// Tests whether a new message is available from the Driver.
916 /// On most drivers, this will also put the Driver into RHModeRx mode until
917 /// a message is actually received by the transport, when it will be returned to RHModeIdle.
918 /// This can be called multiple times in a timeout loop
919 /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
920 virtual bool available();
921
922 /// Turns the receiver on if it not already on.
923 /// If there is a valid message available, copy it to buf and return true
924 /// else return false.
925 /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
926 /// You should be sure to call this function frequently enough to not miss any messages
927 /// It is recommended that you call it in your main loop.
928 /// \param[in] buf Location to copy the received message
929 /// \param[in,out] len Pointer to the number of octets available in buf. The number be reset to the actual number of octets copied.
930 /// \return true if a valid message was copied to buf
931 virtual bool recv(uint8_t* buf, uint8_t* len);
932
933 /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
934 /// Then optionally waits for Channel Activity Detection (CAD)
935 /// to show the channnel is clear (if the radio supports CAD) by calling waitCAD().
936 /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
937 /// of 0 is permitted.
938 /// \param[in] data Array of data to be sent
939 /// \param[in] len Number of bytes of data to send
940 /// specify the maximum time in ms to wait. If 0 (the default) do not wait for CAD before transmitting.
941 /// \return true if the message length was valid and it was correctly queued for transmit. Return false
942 /// if CAD was requested and the CAD timeout timed out before clear channel was detected.
943 virtual bool send(const uint8_t* data, uint8_t len);
944
945 /// Sets the length of the preamble
946 /// in bytes.
947 /// Caution: this should be set to the same
948 /// value on all nodes in your network. Default is 8.
949 /// Sets the message preamble length in RH_SX126x_REG_??_PREAMBLE_?SB
950 /// \param[in] bytes Preamble length in bytes.
951 void setPreambleLength(uint16_t bytes);
952
953 /// Returns the maximum message length
954 /// available in this Driver.
955 /// \return The maximum legal message length
956 virtual uint8_t maxMessageLength();
957
958 /// Sets the transmitter and receiver
959 /// centre frequency.
960 /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several
961 /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work
962 /// \param[i] calibrate set true if the radio modules are to be automatically recalibrated for this frequency
963 /// \return true if the selected frquency centre is within range, and the radio frequency is successfully set
964 bool setFrequency(float centre, bool calibrate = true);
965
966 /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
967 /// disables them.
968 void setModeIdle();
969
970 /// If current mode is Tx or Idle, changes it to Rx.
971 /// Starts the receiver in the SX126X/96/97/98.
972 void setModeRx();
973
974 /// If current mode is Rx or Idle, changes it to Rx. F
975 /// Starts the transmitter in the SX126X/96/97/98.
976 void setModeTx();
977
978 /// Sets the transmitter power output level
979 /// Be a good neighbour and set the lowest power level you need.
980 /// Caution: legal power limits may apply in certain countries.
981 /// After init(), the power will be set to 13dBm.
982 /// \param[in] power Transmitter power level in dBm.
983 /// For SX1261, limits are -17 to +15 dBm
984 /// For SX1262, limits are -9 to +22 dBm
985 /// For STM32WLx with low power PA configured by radioPinConfig, same as SX1261.
986 /// For STM32WLx with high power PA configured by radioPinConfig, same as SX1262.
987 /// \return true if successful. Returns false if radioPinConfig has not been properly
988 /// configured for the requested power setting
989 virtual bool setTxPower(int8_t power);
990
991 /// Sets the radio into low-power sleep mode.
992 /// If successful, the transport will stay in sleep mode until woken by
993 /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)
994 /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
995 /// \return true if sleep mode was successfully entered.
996 virtual bool sleep();
997
998 /// Use the radio's Channel Activity Detect (CAD) function to detect channel activity.
999 /// Sets the SX126X radio into CAD mode and waits until CAD detection is complete.
1000 /// To be used in a listen-before-talk mechanism (Collision Avoidance)
1001 /// with a reasonable time backoff algorithm.
1002 /// This is called automatically by waitCAD().
1003 /// NOT YET WORKING.
1004 /// \return true if channel is in use.
1005 virtual bool isChannelActive();
1006
1007 /// Returns the Signal-to-noise ratio (SNR) of the last received message, as measured
1008 /// by the receiver.
1009 /// \return SNR of the last received message in dB
1010 int lastSNR();
1011
1012 // Support for configurable RX and TX pins
1013 void setRadioPinConfig(RadioPinConfig* config);
1014
1015 /// Set the radio into continuous transmission mode. A carrier
1016 /// wave will be transmitted on the configured centre frequency until available(), recv() or send() are called
1017 /// CAUTION: use this only for testing in controlled conditions with a dummy load. It may be illegal for you to transmit
1018 /// a continuous carrier wave to air.
1019 bool setTxContinuous();
1020
1021 /// Read and return the radio status byte
1022 uint8_t getStatus();
1023
1024 /// Return the last interrupt mask, for debugging
1025 uint16_t lastIrq() {return _lastirq;};
1026
1027 /// Return true if an interrupt has occurred since the last clearIflag(). For debugging
1028 bool getIflag() {return _iflag;};
1029
1030 /// Reset the interrupt flag. For debugging
1031 void clearIflag() {_iflag=false;};
1032
1033 /// REsets the last interrupt mask. For debugging
1034 void clearLastIrq() {_lastirq=0;};
1035
1036 /// Enable or disable the ability to detect CRC errors
1037 void enableCrcErrorIrq(bool enable);
1038
1039 /// Tells the driver to enable RAW mode, which prevents the transmissions of the 4 byte address header.
1040 void enableRawMode(bool enable);
1041
1042 /// Returns the frequency error from the last received packet
1043 float getFrequencyError();
1044
1045protected:
1046
1047 ///////////////////////////////////////////////////////////////////
1048 // Follow are low level functions for communicating with the SX126x
1049 // Caution should be used if accessing them in subclasses
1050
1051 /// Wait until the busy pin (if speecified in the contructor) is no longer low
1052 /// On timeout, prints an error to eSerial and returns false. Else returns true.
1053 virtual bool waitUntilNotBusy();
1054
1055
1056 /// Send a command with multi-byte data to the radio
1057 bool sendCommand(uint8_t command, uint8_t data[], uint8_t len);
1058
1059 /// Send a command with a single data byte to the radio
1060 bool sendCommand(uint8_t command, uint8_t value);
1061
1062 /// Send a command without any data to the radio
1063 bool sendCommand(uint8_t command);
1064
1065 /// Send a command to the radio and get a multi-byte respose
1066 bool getCommand(uint8_t command, uint8_t data[], uint8_t len);
1067
1068 /// Read multiple registers from the radio
1069 bool readRegisters(uint16_t address, uint8_t data[], uint8_t len);
1070
1071 /// Read and return a single register byte from the radio
1072 uint8_t readRegister(uint16_t address);
1073
1074 /// Write multibyte data to the given register and sunbsequent registers
1075 bool writeRegisters(uint16_t address, uint8_t data[], uint8_t len);
1076
1077 /// Write a single byte to the given register
1078 bool writeRegister(uint16_t address, uint8_t data);
1079
1080 /// Write multibyte data to the radio IO buffer at the current buffer address
1081 bool writeBuffer(uint8_t offset, const uint8_t data[], uint8_t len);
1082
1083 /// Write a single byte to the radio IO bufferat the current buffer address
1084 bool writeBuffer(uint8_t offset, const char* text);
1085
1086 /// Read multibyte data from the radio IO buffer at the current buffer address
1087 bool readBuffer(uint8_t offset, uint8_t data[], uint8_t len);
1088
1089 /// Set the radio Power Amplifier configuration
1090 bool setPaConfig(uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut);
1091
1092 /// Set the radio power output. CAUTION: for internal use only. Users should use setTxPower()
1093 bool setTxParams(uint8_t power, uint8_t rampTime);
1094
1095 /// Clear the radio error byte
1096 bool clearDeviceErrors();
1097
1098 /// Sets whether DIO2 is to be used to automatically control an external radio RF switch.
1099 /// Normall you should use the pinConfig in the constructor or setRadioPinConfig() to automatically control any
1100 /// radio control pins
1101 bool setDIO2AsRfSwitchCtrl(bool value);
1102
1103 /// Sets the mode that the radio will change to after a transmit or receive is complete
1104 bool setRxFallbackMode(uint8_t mode);
1105
1106 /// Set the low-level registers for any desired modulation scheme
1107 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);
1108
1109 /// Set the low-level registers for the desired LoRA modulation scheme
1110 bool setModulationParametersLoRa(uint8_t sf, float bw, uint8_t cr, bool ldro);
1111
1112 /// Set the low-level registers for the desired GFSK modulation scheme
1113 bool setModulationParametersGFSK(uint32_t br, uint8_t sh, uint8_t rxBw, uint32_t freqDev);
1114
1115 /// Cause the radio to calibrate all its sections at the currently selected frequency
1116 bool calibrate(uint8_t calib_param);
1117
1118 /// Allows the user to calibrate the image rejection of the device for the device operating frequency band
1119 bool calibrateImage(uint8_t f1, uint8_t f2);
1120
1121 /// Set the 16 bit LoRa sync word
1122 bool setLoRaSyncWord(uint16_t sync);
1123
1124 /// Set the radio power amplifier over-current protection
1125 bool setOCPConfiguration(uint8_t setting);
1126
1127 /// Configures the radio to use an external temperature controlled crystal oscillator (TCXO) and the oven voltage to use.
1128 /// For low level internal use only
1129 bool setDIO3AsTcxoCtrl(uint8_t voltage, uint32_t delay);
1130
1131 /// Set the voltage to use for the TCXO oven
1132 bool setTCXO(float voltage, uint32_t delay);
1133
1134 /// Low level function to set the radio packet confiuration
1135 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);
1136
1137 /// Set the necessary radio packet parameters for a forthcoming transmission of payload_length bytes
1138 bool setPacketParametersLoRa(uint8_t payload_length);
1139
1140 /// Low level function to set the address wherge the next radBuffer or writeBuffer will occur
1141 bool setBufferBaseAddress(uint8_t txbase, uint8_t rxbase);
1142
1143 /// Set the radio to sleep mode. Automatically configures the radio control pins to the configuration RadioPinConfigMode_IDLE.
1144 bool setSleep(uint8_t config);
1145
1146 /// Set the radio to sleep mode. Automatically configures the radio control pins to the configuration RadioPinConfigMode_IDLE.
1147 bool setStandby(uint8_t config);
1148
1149 /// Set the radio to transmit mode. Automatically configures the radio control pins to the configuration required
1150 /// for the most recently requested power in setTxPower (RadioPinConfigMode_TX_HIGH_POWER or RadioPinConfigMode_TX_LOW_POWER )
1151 bool setTx(uint32_t timeout);
1152
1153 /// Starts the radio in Clear Air Detect (CAD) mode. CAUTION: NOT YET WORKING, always retuns false.
1154 bool setCad();
1155
1156 /// Set the radio to receive mode. Automatically configures the radio control pins to the configuration RadioPinConfigMode_RX.
1157 bool setRx(uint32_t timeout);
1158
1159 /// Sets whether radios receiver gain boost should be enabled instead of the default power saving mode.
1160 bool setRxBoostMode(bool boost, bool retain);
1161
1162 /// Sets the chip regulator mode to either LDO or DC-DC SMPS.
1163 /// Set to DC-DC SMPS by default
1164 bool setRegulatorMode(uint8_t mode);
1165
1166 /// Configures the conditions under which the radio will enable an interrupt, and for which DIO pins
1167 bool setDioIrqParams(uint16_t irqmask, uint16_t dio1mask, uint16_t dio2mask, uint16_t dio3mask);
1168
1169 /// Clear the radio IRQ state
1170 bool clearIrqStatus(uint16_t mask);
1171
1172 /// Return the radio IRQ state
1173 uint16_t getIrqStatus();
1174
1175 /// return the current packet type
1176 uint8_t getPacketType();
1177
1178 /// From SX1262_datasheet.pdf: "When exchanging LoRa® packets with inverted IQ polarity,
1179 /// some packet losses may be observed for longer packet". THis function enables the workaround described in that section
1180 void setInvertIQ(bool invertIQ);
1181
1182 /// Per SX1262_datasheet.pdf Rev 1.2 section 15.2, this fixes an error in the radio Power Amplifier clamping
1183 bool fixPAClamping(bool enable);
1184
1185 /// Do whatever is necesary to establish the interrupt handler. Subclasses may have different needs
1186 virtual bool setupInterruptHandler();
1187
1188 /// This is a low level function to handle the interrupts for one instance of RH_SX126x.
1189 /// Called automatically by isr*()
1190 /// Should not need to be called by user code.
1191 void handleInterrupt();
1192
1193 /// Examine the revceive buffer to determine whether the message is for this node
1194 void validateRxBuf();
1195
1196 /// Clear our local receive buffer
1197 void clearRxBuf();
1198
1199 /// Called by RH_SX126x when the radio mode is about to change to a new setting.
1200 /// Can be used by subclasses to implement antenna switching etc.
1201 /// \param[in] mode RHMode the new mode about to take effect
1202 /// \return true if the subclasses changes successful
1203 virtual bool modeWillChange(RHMode) {return true;}
1204
1205 /// Sets the pins configured in radioPinConfig as required for the desired mode.
1206 /// Called just before the radio is set to the new mode.
1207 /// \return true if succcessful, false is there is no radioPinConfig configuration,
1208 /// or no entry for the requested mode
1210
1211 /// Find the pin configuration entry for a desired radio mode
1212 virtual RadioPinConfigEntry* findRadioPinConfigEntry(RadioPinConfigMode mode);
1213
1214private:
1215 /// Low level interrupt service routine for device connected to interrupt 0
1216 static void isr0();
1217
1218 /// Low level interrupt service routine for device connected to interrupt 1
1219 static void isr1();
1220
1221 /// Low level interrupt service routine for device connected to interrupt 1
1222 static void isr2();
1223
1224 /// Array of instances connected to interrupts 0 and 1
1225 static RH_SX126x* _deviceForInterrupt[];
1226
1227 /// The configured interrupt pin connected to this instance
1228 uint8_t _interruptPin;
1229
1230 /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
1231 /// else 0xff
1232 uint8_t _myInterruptIndex;
1233
1234 /// Number of octets in the buffer
1235 volatile uint8_t _bufLen;
1236
1237 /// The receiver/transmitter buffer
1238 uint8_t _buf[RH_SX126x_MAX_PAYLOAD_LEN];
1239
1240 /// True when there is a valid message in the buffer
1241 volatile bool _rxBufValid;
1242
1243 /// True if we are using the HF port (779.0 MHz and above)
1244 bool _usingHFport;
1245
1246 /// Last measured SNR, dB
1247 int8_t _lastSNR;
1248
1249 /// If true, sends CRCs in every packet and requires a valid CRC in every received packet
1250 bool _enableCRC;
1251
1252 /// Sets the preamble length for LoRa packets
1253 uint16_t _preambleLength = 8;
1254
1255 /// Whether the modem is to be configured for INverted IQ
1256 bool _invertIQ = false;
1257
1258 /// The type of packet to configure the modem for
1259 PacketType _packetType = PacketTypeLoRa;
1260
1261 /// If the current LoRa bandwidth is 500kHz, we need to remeber this in order to implement the
1262 /// modulation quality workaround in setTx()
1263 bool _lorabw500 = false;
1264
1265 /// Support for optional configurable radio control pins for RX and TX modes
1266 RadioPinConfig* _radioPinConfig = NULL;
1267
1268 /// Remember what PA type is required, depending on device type and radio pin configurations
1269 RadioPinConfigMode _requiredPAMode = RadioPinConfigMode_IDLE; // One of PinConfigMode_TX_LOW_POWER PinConfigMode_TX_HIGH_POWER
1270
1271 /// Pin number of the radio BUSY pin, if available, else RH_INVALID_PIN
1272 uint8_t _busyPin;
1273
1274 /// Pin number of the radio NRESET pin, if available, else RH_INVALID_PIN
1275 uint8_t _resetPin;
1276
1277 /// Currently selected bandwidth, required for frequencey error calculations
1278 float _bandwidth = 0.0;
1279
1280 /// Whether we are in raw mode, bypassing address bytes prefix
1281 bool _raw = false;
1282
1283 /// Vale of the last interrupt flags, for debugging
1284 volatile uint16_t _lastirq;
1285
1286 /// Whether an interupt has occurred since the last clearIflag(). For debugging
1287 volatile bool _iflag = false;
1288
1289 // These are the interrupts we are willing to process
1290 uint16_t _irqMask = RH_SX126x_IRQ_CAD_DETECTED
1291 | RH_SX126x_IRQ_CAD_DONE
1292 | RH_SX126x_IRQ_CRC_ERR
1293 | RH_SX126x_IRQ_HEADER_ERR
1294 | RH_SX126x_IRQ_RX_DONE
1295 | RH_SX126x_IRQ_TX_DONE;
1296};
1297
1298/// @example sx1262_client.ino
1299/// @example sx1262_server.ino
1300
1301#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:763
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:1052
int lastSNR()
Definition RH_SX126x.cpp:534
bool printRegisters(uint16_t address, uint8_t count)
Definition RH_SX126x.cpp:845
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:918
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:1106
void clearIflag()
Reset the interrupt flag. For debugging.
Definition RH_SX126x.h:1031
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:1031
virtual uint8_t maxMessageLength()
Definition RH_SX126x.cpp:400
void setModeTx()
Definition RH_SX126x.cpp:464
RadioPinConfigMode
Definition RH_SX126x.h:823
virtual bool recv(uint8_t *buf, uint8_t *len)
Definition RH_SX126x.cpp:331
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:714
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:736
virtual bool send(const uint8_t *data, uint8_t len)
Definition RH_SX126x.cpp:352
uint8_t readRegister(uint16_t address)
Read and return a single register byte from the radio.
Definition RH_SX126x.cpp:653
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:1141
void setInvertIQ(bool invertIQ)
Definition RH_SX126x.cpp:1191
virtual bool modeWillChange(RHMode)
Definition RH_SX126x.h:1203
bool setRegulatorMode(uint8_t mode)
Definition RH_SX126x.cpp:1157
bool getIflag()
Return true if an interrupt has occurred since the last clearIflag(). For debugging.
Definition RH_SX126x.h:1028
bool setLoRaSyncWord(uint16_t sync)
Set the 16 bit LoRa sync word.
Definition RH_SX126x.cpp:986
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:876
void setModeRx()
Definition RH_SX126x.cpp:453
bool setPacketParametersLoRa(uint8_t payload_length)
Set the necessary radio packet parameters for a forthcoming transmission of payload_length bytes.
Definition RH_SX126x.cpp:1037
bool setCad()
Starts the radio in Clear Air Detect (CAD) mode. CAUTION: NOT YET WORKING, always retuns false.
Definition RH_SX126x.cpp:1121
virtual bool sleep()
Definition RH_SX126x.cpp:442
bool setFrequency(float centre, bool calibrate=true)
Definition RH_SX126x.cpp:405
bool clearDeviceErrors()
Clear the radio error byte.
Definition RH_SX126x.cpp:860
virtual bool waitUntilNotBusy()
Definition RH_SX126x.cpp:544
virtual bool isChannelActive()
Definition RH_SX126x.cpp:518
bool setPaConfig(uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut)
Set the radio Power Amplifier configuration.
Definition RH_SX126x.cpp:730
void clearLastIrq()
REsets the last interrupt mask. For debugging.
Definition RH_SX126x.h:1034
ModemConfigChoice
Definition RH_SX126x.h:809
@ LoRa_Bw31_25Cr48Sf512
Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range.
Definition RH_SX126x.h:812
@ LoRa_Bw500Cr45Sf128
Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range.
Definition RH_SX126x.h:811
@ LoRa_Bw125Cr48Sf4096
Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, low data rate, CRC on. Slow+long range.
Definition RH_SX126x.h:813
@ LoRa_Bw125Cr45Sf128
Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range.
Definition RH_SX126x.h:810
@ LoRa_Bw125Cr45Sf2048
Bw = 125 kHz, Cr = 4/5, Sf = 2048chips/symbol, CRC on. Slow+long range.
Definition RH_SX126x.h:814
void setModeIdle()
Definition RH_SX126x.cpp:432
virtual bool available()
Definition RH_SX126x.cpp:309
bool readRegisters(uint16_t address, uint8_t data[], uint8_t len)
Read multiple registers from the radio.
Definition RH_SX126x.cpp:636
void handleInterrupt()
Definition RH_SX126x.cpp:200
bool setModemRegisters(const ModemConfig *config)
Definition RH_SX126x.cpp:476
uint16_t getIrqStatus()
Return the radio IRQ state.
Definition RH_SX126x.cpp:1177
bool setDIO3AsTcxoCtrl(uint8_t voltage, uint32_t delay)
Definition RH_SX126x.cpp:997
PacketType
Packet types the modem can be configured for.
Definition RH_SX126x.h:767
@ PacketTypeLoRa
Use LoRA packets.
Definition RH_SX126x.h:768
@ PacketTypeGFSK
Use GFSK packets.
Definition RH_SX126x.h:769
virtual bool setRadioPinsForMode(RadioPinConfigMode mode)
Definition RH_SX126x.cpp:1208
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:1065
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:1058
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:694
bool setOCPConfiguration(uint8_t setting)
Set the radio power amplifier over-current protection.
Definition RH_SX126x.cpp:992
bool setTx(uint32_t timeout)
Definition RH_SX126x.cpp:1072
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:1162
virtual bool setupInterruptHandler()
Do whatever is necesary to establish the interrupt handler. Subclasses may have different needs.
Definition RH_SX126x.cpp:141
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:578
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:622
uint8_t getPacketType()
return the current packet type
Definition RH_SX126x.cpp:1184
uint16_t lastIrq()
Return the last interrupt mask, for debugging.
Definition RH_SX126x.h:1025
bool clearIrqStatus(uint16_t mask)
Clear the radio IRQ state.
Definition RH_SX126x.cpp:1171
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:871
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:135
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:1196
virtual bool init()
Definition RH_SX126x.cpp:58
virtual RadioPinConfigEntry * findRadioPinConfigEntry(RadioPinConfigMode mode)
Find the pin configuration entry for a desired radio mode.
Definition RH_SX126x.cpp:1243
void validateRxBuf()
Examine the revceive buffer to determine whether the message is for this node.
Definition RH_SX126x.cpp:291
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:969
void setPreambleLength(uint16_t bytes)
Definition RH_SX126x.cpp:513
bool setTCXO(float voltage, uint32_t delay)
Set the voltage to use for the TCXO oven.
Definition RH_SX126x.cpp:1006
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:660
bool setTxContinuous()
Definition RH_SX126x.cpp:1100
void enableCrcErrorIrq(bool enable)
Enable or disable the ability to detect CRC errors.
Definition RH_SX126x.cpp:126
bool writeRegister(uint16_t address, uint8_t data)
Write a single byte to the given register.
Definition RH_SX126x.cpp:687
bool calibrate(uint8_t calib_param)
Cause the radio to calibrate all its sections at the currently selected frequency.
Definition RH_SX126x.cpp:975
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:980
bool setDIO2AsRfSwitchCtrl(bool value)
Definition RH_SX126x.cpp:866
virtual bool setTxPower(int8_t power)
Definition RH_SX126x.cpp:742
uint8_t getStatus()
Read and return the radio status byte.
Definition RH_SX126x.cpp:565
float getFrequencyError()
Returns the frequency error from the last received packet.
Definition RH_SX126x.cpp:1259
void clearRxBuf()
Clear our local receive buffer.
Definition RH_SX126x.cpp:322
bool setModemConfig(ModemConfigChoice index)
Definition RH_SX126x.cpp:502
Defines register values for a set of modem configuration registers.
Definition RH_SX126x.h:780
uint8_t p4
Value for setModulationParameters parameter 4.
Definition RH_SX126x.h:785
uint8_t p8
Value for setModulationParameters parameter 8.
Definition RH_SX126x.h:789
uint8_t p5
Value for setModulationParameters parameter 5.
Definition RH_SX126x.h:786
uint8_t p7
Value for setModulationParameters parameter 7.
Definition RH_SX126x.h:788
uint8_t p1
Value for setModulationParameters parameter 1.
Definition RH_SX126x.h:782
uint8_t p2
Value for setModulationParameters parameter 2.
Definition RH_SX126x.h:783
uint8_t p3
Value for setModulationParameters parameter 3.
Definition RH_SX126x.h:784
uint8_t p6
Value for setModulationParameters parameter 6.
Definition RH_SX126x.h:787
Definition RH_SX126x.h:839
Definition RH_SX126x.h:849