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