Skip to content

Commit 3eee368

Browse files
authored
Merge pull request #21684 from fabian18/pr/sx126x_dio2_dio3
drivers/sx126x: add support for Dio2 and Dio3
2 parents 34c9084 + e15a65e commit 3eee368

File tree

4 files changed

+168
-25
lines changed

4 files changed

+168
-25
lines changed

drivers/include/sx126x.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,33 @@ typedef enum {
7878
SX126X_TYPE_STM32WL,
7979
} sx126x_type_t;
8080

81+
/**
82+
* @brief Dio2 pin mode
83+
*/
84+
typedef enum {
85+
SX126X_DIO2_UNUSED, /**< Not used */
86+
SX126X_DIO2_IRQ, /**< IRQ pin (ToDo) */
87+
SX126X_DIO2_RF_SWITCH, /**< RF switch control pin */
88+
} sx126x_dio2_mode_t;
89+
90+
/**
91+
* @brief Dio3 pin mode
92+
*/
93+
typedef enum {
94+
SX126X_DIO3_UNUSED, /**< Not used */
95+
SX126X_DIO3_IRQ, /**< IRQ pin (ToDo) */
96+
SX126X_DIO3_TCXO, /**< TCXO control pin */
97+
} sx126x_dio3_mode_t;
98+
99+
/**
100+
* @brief Mask of all available interrupts
101+
*/
102+
#define SX126X_IRQ_MASK_ALL (SX126X_IRQ_TX_DONE | SX126X_IRQ_RX_DONE | \
103+
SX126X_IRQ_PREAMBLE_DETECTED | SX126X_IRQ_SYNC_WORD_VALID | \
104+
SX126X_IRQ_HEADER_VALID | SX126X_IRQ_HEADER_ERROR | \
105+
SX126X_IRQ_CRC_ERROR | SX126X_IRQ_CAD_DONE | \
106+
SX126X_IRQ_CAD_DETECTED | SX126X_IRQ_TIMEOUT)
107+
81108
/**
82109
* @brief Device initialization parameters
83110
*/
@@ -87,6 +114,17 @@ typedef struct {
87114
gpio_t reset_pin; /**< Reset pin */
88115
gpio_t busy_pin; /**< Busy pin */
89116
gpio_t dio1_pin; /**< Dio1 pin */
117+
#if IS_USED(MODULE_SX126X_DIO2)
118+
sx126x_dio2_mode_t dio2_mode; /**< Dio2 mode */
119+
#endif
120+
#if IS_USED(MODULE_SX126X_DIO3)
121+
sx126x_dio3_mode_t dio3_mode; /**< Dio3 mode */
122+
struct {
123+
unsigned tcxo_volt :8; /**< TCXO voltage (see sx126x_tcxo_ctrl_voltages_t)*/
124+
unsigned tcxo_timeout :24; /**< TCXO timeout to wait for 32MHz coming from TXC0,
125+
Delay duration = Delay(23:0) * 15.625 μs */
126+
} dio3_arg;
127+
#endif
90128
sx126x_reg_mod_t regulator; /**< Power regulator mode */
91129
sx126x_type_t type; /**< Variant of sx126x */
92130
#if IS_USED(MODULE_SX126X_RF_SWITCH)

drivers/sx126x/Makefile.include

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ PSEUDOMODULES += sx126x_stm32wl
77

88
# include RF switch implemented in the board for use with sx126x
99
PSEUDOMODULES += sx126x_rf_switch
10+
PSEUDOMODULES += sx126x_dio2
11+
PSEUDOMODULES += sx126x_dio3
1012

1113
USEMODULE_INCLUDES_sx126x := $(LAST_MAKEFILEDIR)/include
1214
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_sx126x)

drivers/sx126x/include/sx126x_params.h

Lines changed: 84 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ extern "C" {
6363
# define SX126X_PARAM_DIO1 GPIO_PIN(1, 4) /* D5 */
6464
#endif
6565

66-
#ifndef SX126X_PARAM_REGULATOR
66+
#if !defined(SX126X_PARAM_REGULATOR) || defined(DOXYGEN)
67+
/**
68+
* @brief Regulator type which can be
69+
* SX126X_REG_MODE_LDO or SX126X_REG_MODE_DCDC
70+
*/
6771
# define SX126X_PARAM_REGULATOR SX126X_REG_MODE_DCDC
6872
#endif
6973

@@ -75,6 +79,48 @@ extern "C" {
7579
# define SX126X_PARAM_TX_PA_MODE SX126X_RF_MODE_TX_LPA
7680
#endif
7781

82+
#if !defined(SX126X_PARAM_DIO2_MODE) || defined(DOXYGEN)
83+
/**
84+
* @brief DIO2 pin mode which can be
85+
* SX126X_DIO2_UNUSED, SX126X_DIO2_IRQ or SX126X_DIO2_RF_SWITCH
86+
*/
87+
# define SX126X_PARAM_DIO2_MODE SX126X_DIO2_UNUSED
88+
#endif
89+
90+
#if !defined(SX126X_PARAM_DIO3_MODE) || defined(DOXYGEN)
91+
/**
92+
* @brief DIO3 pin mode which can be
93+
* SX126X_DIO3_UNUSED, SX126X_DIO3_IRQ or SX126X_DIO3_TCXO
94+
*/
95+
# define SX126X_PARAM_DIO3_MODE SX126X_DIO3_UNUSED
96+
#endif
97+
98+
#if !defined(SX126X_PARAM_TCXO_VOLTAGE) || defined(DOXYGEN)
99+
/**
100+
* @brief TCXO voltage is configured to be 200 mV below the supply voltage.
101+
*
102+
* This means that even if tcxoVoltage is configured above the supply voltage,
103+
* the supply voltage will be limited by: VDDop > VTCXO + 200 mV
104+
*/
105+
# define SX126X_PARAM_TCXO_VOLTAGE SX126X_TCXO_CTRL_3_0V
106+
#endif
107+
108+
#if !defined(SX126X_PARAM_TCXO_TIMEOUT) || defined(DOXYGEN)
109+
/**
110+
* @brief Timeout for tcxo stabilization in 15.625 µs steps
111+
* The default value is 256 (4ms).
112+
*/
113+
# define SX126X_PARAM_TCXO_TIMEOUT 256
114+
#endif
115+
116+
#if !defined(SX126X_PARAM_DIO3_ARG) || defined(DOXYGEN)
117+
/**
118+
* @brief DIO3 argument if mode is SX126X_DIO3_TCXO
119+
*/
120+
# define SX126X_PARAM_DIO3_ARG { .tcxo_volt = SX126X_PARAM_TCXO_VOLTAGE, \
121+
.tcxo_timeout = SX126X_PARAM_TCXO_TIMEOUT }
122+
#endif
123+
78124
#ifndef SX126X_PARAM_TYPE
79125
# if IS_USED(MODULE_SX1261)
80126
# define SX126X_PARAM_TYPE SX126X_TYPE_SX1261
@@ -93,22 +139,49 @@ extern "C" {
93139

94140
#if IS_USED(MODULE_SX126X_RF_SWITCH)
95141
# define SX126X_SET_RF_MODE .set_rf_mode = SX126X_PARAM_SET_RF_MODE_CB,
96-
# define SX126X_TX_PA_MODE .tx_pa_mode = SX126X_PARAM_TX_PA_MODE
142+
# define SX126X_TX_PA_MODE .tx_pa_mode = SX126X_PARAM_TX_PA_MODE,
97143
#else
98144
# define SX126X_SET_RF_MODE
99145
# define SX126X_TX_PA_MODE
100146
#endif
101147

148+
#if IS_USED(MODULE_SX126X_DIO2) || defined(DOXYGEN)
149+
/**
150+
* @brief DIO2 pin mode
151+
*/
152+
# define SX126X_DIO2_MODE .dio2_mode = SX126X_PARAM_DIO2_MODE,
153+
#else
154+
# define SX126X_DIO2_MODE
155+
#endif
156+
157+
#if IS_USED(MODULE_SX126X_DIO3) || defined(DOXYGEN)
158+
/**
159+
* @brief DIO3 pin mode
160+
*/
161+
# define SX126X_DIO3_MODE .dio3_mode = SX126X_PARAM_DIO3_MODE,
162+
/**
163+
* @brief DIO3 pin argument
164+
*/
165+
# define SX126X_DIO3_ARG .dio3_arg = SX126X_PARAM_DIO3_ARG,
166+
#else
167+
# define SX126X_DIO3_MODE
168+
# define SX126X_DIO3_ARG
169+
#endif
170+
102171
#ifndef SX126X_PARAMS
103-
# define SX126X_PARAMS { .spi = SX126X_PARAM_SPI, \
104-
.nss_pin = SX126X_PARAM_SPI_NSS, \
105-
.reset_pin = SX126X_PARAM_RESET, \
106-
.busy_pin = SX126X_PARAM_BUSY, \
107-
.dio1_pin = SX126X_PARAM_DIO1, \
108-
.type = SX126X_PARAM_TYPE, \
109-
.regulator = SX126X_PARAM_REGULATOR, \
110-
SX126X_SET_RF_MODE \
111-
SX126X_TX_PA_MODE}
172+
# define SX126X_PARAMS { .spi = SX126X_PARAM_SPI, \
173+
.nss_pin = SX126X_PARAM_SPI_NSS, \
174+
.reset_pin = SX126X_PARAM_RESET, \
175+
.busy_pin = SX126X_PARAM_BUSY, \
176+
.dio1_pin = SX126X_PARAM_DIO1, \
177+
.type = SX126X_PARAM_TYPE, \
178+
.regulator = SX126X_PARAM_REGULATOR, \
179+
SX126X_SET_RF_MODE \
180+
SX126X_TX_PA_MODE \
181+
SX126X_DIO2_MODE \
182+
SX126X_DIO3_MODE \
183+
SX126X_DIO3_ARG \
184+
}
112185
#endif
113186

114187
/**@}*/

drivers/sx126x/sx126x.c

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "periph/spi.h"
2727

2828
#include "sx126x.h"
29+
#include "sx126x_regs.h"
2930
#include "sx126x_params.h"
3031
#include "sx126x_internal.h"
3132

@@ -189,21 +190,50 @@ int sx126x_init(sx126x_t *dev)
189190
/* Initialize radio with the default parameters */
190191
sx126x_init_default_config(dev);
191192

192-
/* Configure available IRQs */
193-
const uint16_t irq_mask = (
194-
SX126X_IRQ_TX_DONE |
195-
SX126X_IRQ_RX_DONE |
196-
SX126X_IRQ_PREAMBLE_DETECTED |
197-
SX126X_IRQ_SYNC_WORD_VALID |
198-
SX126X_IRQ_HEADER_VALID |
199-
SX126X_IRQ_HEADER_ERROR |
200-
SX126X_IRQ_CRC_ERROR |
201-
SX126X_IRQ_CAD_DONE |
202-
SX126X_IRQ_CAD_DETECTED |
203-
SX126X_IRQ_TIMEOUT
204-
);
193+
#if IS_USED(MODULE_SX126X_DIO2)
194+
if (dev->params->dio2_mode == SX126X_DIO2_RF_SWITCH) {
195+
sx126x_set_dio2_as_rf_sw_ctrl(dev, true);
196+
}
197+
#endif
198+
#if IS_USED(MODULE_SX126X_DIO3)
199+
if (dev->params->dio3_mode == SX126X_DIO3_TCXO) {
200+
sx126x_set_dio3_as_tcxo_ctrl(dev, dev->params->u_dio3_arg.tcxo_volt,
201+
dev->params->u_dio3_arg.tcx0_timeout);
202+
203+
/* Once the command SetDIO3AsTCXOCtrl(...) is sent to the device,
204+
the register controlling the internal cap on XTA will be automatically
205+
changed to 0x2F (33.4 pF) to filter any spurious injection which could occur
206+
and be propagated to the PLL.- Verify that. */
207+
uint8_t trimming_capacitor_values[2] = { 0 };
208+
sx126x_read_register(dev, SX126X_REG_XTATRIM,
209+
trimming_capacitor_values,
210+
sizeof(trimming_capacitor_values));
211+
/* 11.3 pF + x * 0.47pF = 33.4pF | x = 0x2f*/
212+
if (trimming_capacitor_values[0] != 0x2f) {
213+
DEBUG("[sx126x] warning: failed to set TCXO control: SX126X_REG_XTATRIM=%02x\n",
214+
trimming_capacitor_values[0]);
215+
}
216+
DEBUG("[sx126x] XTA capacitor ~ %upF\n",
217+
(unsigned)(0.5f + (11.3f + trimming_capacitor_values[0] * 0.47f)));
218+
DEBUG("[sx126x] XTB capacitor ~ %upF\n",
219+
(unsigned)(0.5f + (11.3f + trimming_capacitor_values[1] * 0.47f)));
220+
221+
/* When the 32 MHz clock is coming from a TCXO, the calibration will fail
222+
and the user should request a complete calibration after calling the function
223+
SetDIO3AsTcxoCtrl(...). */
224+
sx126x_cal(dev, SX126X_CAL_ALL);
225+
}
226+
#endif
227+
/* The user can specify the use of DC-DC by using the command SetRegulatorMode(...).
228+
This operation must be carried out in STDBY_RC mode only.*/
229+
sx126x_set_reg_mode(dev, dev->params->regulator);
230+
231+
/* Initialize radio with the default parameters */
232+
sx126x_init_default_config(dev);
233+
234+
sx126x_set_standby(dev, SX126X_STANDBY_CFG_XOSC);
205235

206-
sx126x_set_dio_irq_params(dev, irq_mask, irq_mask, 0, 0);
236+
sx126x_set_dio_irq_params(dev, SX126X_IRQ_MASK_ALL, SX126X_IRQ_MASK_ALL, 0, 0);
207237

208238
if (IS_ACTIVE(ENABLE_DEBUG)) {
209239
sx126x_pkt_type_t pkt_type;

0 commit comments

Comments
 (0)