SingingCat 0
application
init_chip.c
1#include "sx1262/sx1262.h"
2#include "sx1262/sx126x.h"
3#include "sx1262/sx126x_hal.h"
4#include "mculibrary.h"
5#include "irq_router.h"
6#include "networkif.h"
7
8static volatile int is_in_rx_mode = 0;
9byte sx1262_initialized = 0;
10extern int sx1262_transmit_fail_counter;
11void sx1262_set_lora_packet_type(void *ctx) {
12 uint8_t xbuf[16];
13
14 xbuf[0] = 0x8A; // set packet type
15 xbuf[1] = 1;
16 sx126x_hal_write(ctx, (const uint8_t *)&xbuf, 2, NULL, 0); // set packet type
17}
18
19void sx1262_set_packet_params(void *ctx, int payload_size) {
20 uint8_t xbuf[16];
21
22 //setpacketparams
23 xbuf[0] = 0x8C; // setpacketparams
24 xbuf[1] = 0;
25 xbuf[2] = 12; // preamble length
26 xbuf[3] = 00; // 0==variable length (explicit header) | 1==fixed length (implicit header)
27 xbuf[4] = payload_size; // payload size
28 xbuf[5] = 1; // crc on
29 xbuf[6] = 0; // invert IQ (?)
30 sx126x_hal_write(ctx, (const uint8_t *)&xbuf, 7, NULL, 0); // set packet parameters
31}
32void sx1262_set_lora_parameters(void *ctx) {
33 struct sx126x_mod_params_lora_s lp = { .sf = SX126X_LORA_SF8, .bw = SX126X_LORA_BW_250, .cr = SX126X_LORA_CR_4_7, .ldro = 1 };
34
36}
37static char *int2str(int status, int comp, char *name) {
38 if (status != comp) {
39 return NULL;
40 }
41 return name;
42}
43char *chip_status_name(sx126x_chip_modes_t status) {
44 char *res;
45
46 if ((res = int2str(status, SX126X_CHIP_MODE_UNUSED, "UNUSED")) != NULL) {
47 return res;
48 }
49 if ((res = int2str(status, SX126X_CHIP_MODE_RFU, "RFU")) != NULL) {
50 return res;
51 }
52 if ((res = int2str(status, SX126X_CHIP_MODE_STBY_RC, "STBY_RC")) != NULL) {
53 return res;
54 }
55 if ((res = int2str(status, SX126X_CHIP_MODE_STBY_XOSC, "STBY_XOSC")) != NULL) {
56 return res;
57 }
58 if ((res = int2str(status, SX126X_CHIP_MODE_FS, "FS")) != NULL) {
59 return res;
60 }
61 if ((res = int2str(status, SX126X_CHIP_MODE_RX, "RX")) != NULL) {
62 return res;
63 }
64 if ((res = int2str(status, SX126X_CHIP_MODE_TX, "TX")) != NULL) {
65 return res;
66 }
67
68
69 return "foo";
70}
71char *chip_com_name(sx126x_cmd_status_t status) {
72 char *res;
73
74 if ((res = int2str(status, SX126X_CMD_STATUS_RESERVED, "RESERVED")) != NULL) {
75 return res;
76 }
77 if ((res = int2str(status, SX126X_CMD_STATUS_RFU, "RFU")) != NULL) {
78 return res;
79 }
80 if ((res = int2str(status, SX126X_CMD_STATUS_DATA_AVAILABLE, "DATA_AVAILABLE")) != NULL) {
81 return res;
82 }
83 if ((res = int2str(status, SX126X_CMD_STATUS_CMD_TIMEOUT, "CMD_TIMEOUT")) != NULL) {
84 return res;
85 }
86 if ((res = int2str(status, SX126X_CMD_STATUS_CMD_PROCESS_ERROR, "CMD_PROCESS_ERROR")) != NULL) {
87 return res;
88 }
89 if ((res = int2str(status, SX126X_CMD_STATUS_CMD_EXEC_FAILURE, "CMD_EXEC_FAILURE")) != NULL) {
90 return res;
91 }
92 if ((res = int2str(status, SX126X_CMD_STATUS_CMD_TX_DONE, "CMD_TX_DONE")) != NULL) {
93 return res;
94 }
95 return "foo";
96}
97
98// return cmd_status
99int print_chip_status(void *ctx, int include_mode) {
100 struct sx126x_chip_status_s rs;
101
102 sx126x_get_status(ctx, &rs);
103#ifdef SX126X_DEBUG
104 if (include_mode) {
105 printf("[sx1262] Chip Status:\r\n");
106 printf("[sx1262] Cmd :0x%x (%s)\r\n", rs.cmd_status, chip_com_name(rs.cmd_status));
107 printf("[sx1262] Mode :0x%x (%s)\r\n", rs.chip_mode, chip_status_name(rs.chip_mode));
108 } else {
109 printf("[sx1262] Chip Cmd Status:0x%x (%s)\r\n", rs.cmd_status, chip_com_name(rs.cmd_status));
110 }
111#endif
112 return rs.cmd_status;
113}
114void print_errors(void *ctx) {
115 uint16_t errors;
116
117 sx126x_get_device_errors(ctx, &errors);
118 printf("[sx1262] Errors: %p\r\n", errors);
119}
120int check_register(void *ctx, uint16_t reg, int comp) {
121 uint8_t buf[128];
122
124 sx126x_read_register(ctx, reg, buf, 1);
125 if (buf[0] != comp) {
126 printf("[sx1262] Register 0x%p should be 0x%x, but is 0x%x\r\n", reg, comp, buf[0]);
127 return 1;
128 }
129 if (print_chip_status(ctx, 1) != 0) {
130 // could not exec_command?? this seems to happen all the time
131 // return 2;
132 }
133 return 0;
134}
135int probe_chip(void *ctx) {
136 printf("[sx1262] probing chip...\r\n");
137 uint8_t buf[128];
138
139 sx1262_clear_rx_mode();
141 if (check_register(ctx, 0x6BF, 0x21)) {
142 return 1;
143 }
144 if (check_register(ctx, 0x6BC, 0x1D)) {
145 return 3;
146 }
147
148 buf[0] = 0x6C;
149 sx126x_write_register(ctx, 0x6BF, &buf[0], 1);
150 if (check_register(ctx, 0x6BF, 0x6C)) {
151 return 5;
152 }
153
154 buf[0] = 0x21;
155 sx126x_write_register(ctx, 0x6BF, &buf[0], 1);
156
157 printf("[sx1262] Chip probed successfully\r\n\r\n");
158 return 0;
159}
160
161int config_pins(struct network_context *nctx, byte reinit) {
162 int r;
163 int mask = 0xFFFF;
164
165 sx1262_clear_rx_mode();
166
167 if (reinit) {
168 mask = 0;
169 }
170 /********************* configure pins and spi etc ***************************/
171 r = mculib_pin_in(nctx->mculib_handle, SX1262_BUSY, HAL_PIN_FASTEST, HAL_PUSHPULL_NONE); // BUSY
172 MCULIB_ERR_RET("BUSYPIN", (r & mask));
173
174 r = mculib_pin_in(nctx->mculib_handle, SX1262_DIO1, HAL_PIN_FASTEST, HAL_PUSHPULL_NONE); // DIO1
175 MCULIB_ERR_RET("DIOPIN", (r & mask));
176 r = register_softirq(nctx->mculib_handle, SX1262_DIO1, &sx1262_irq, nctx);
177 if ((reinit == 0) && (r != 0)) {
178 printf("[sx1262] failed to register irq (%i)\r\n", r);
179 return r;
180 }
181
182 r = mculib_pin_out(nctx->mculib_handle, SX1262_CSN, HAL_PIN_FASTEST); // CSN
183 MCULIB_ERR_RET("CSNPIN", (r & mask));
184
185 r = mculib_pin_out(nctx->mculib_handle, SX1262_RESET, HAL_PIN_FASTEST);
186 MCULIB_ERR_RET("RESETPIN", (r & mask));
187
188 r = mculib_spi_master_enable2(nctx->mculib_handle, 2, 0, 0, 0, SPI_DIR_RW); // port #2, wide=0, CPOL=0,CPHA=0
189 MCULIB_ERR_RET("SPIEN", (r & mask));
190
191 r = mculib_pin_set(nctx->mculib_handle, SX1262_RESET, 0);
192 MCULIB_ERR_RET("RESET0", (r & mask));
193 Delay(100);
194 r = mculib_pin_set(nctx->mculib_handle, SX1262_RESET, 1);
195 MCULIB_ERR_RET("RESET1", (r & mask));
196 print_chip_status(NULL, 1);
197 r = mculib_pin_set(nctx->mculib_handle, SX1262_CSN, 1);
198 MCULIB_ERR_RET("CSN1", (r & mask));
199 sx1262_transmit_fail_counter = 0;
200 sx1262_done_transmit();
201 return 0;
202}
203int sx1262_probe(struct network_context *nctx) {
204 int r = config_pins(nctx, 0);
205
206 sx1262_clear_rx_mode();
207
208 if (r != 0) {
209 return r;
210 }
211 r = probe_chip(nctx);
212 if (r != 0) {
213 printf("[sx1262] Probe FAILURE (%i)!!!!\r\n", r);
214 return 1;
215 }
216
217 return 0;
218}
219
220// if reinit != 0, ignore pin assignment errors (assume they have been allocated previously)
221int sx1262_init_or_reinit(struct network_context *nctx, byte reinit) {
222 printf("[sx1262] Init sx1262...\r\n");
223 int r;
224
225 sx1262_clear_rx_mode();
226
227 r = config_pins(nctx, reinit);
228 if (r != 0) {
229 return r;
230 }
231 /********************* test chip ***************************/
232 r = probe_chip(nctx);
233 if (r != 0) {
234 printf("[sx1262] Probe FAILURE (%i)!!!!\r\n", r);
235 return 1;
236 }
237 /********************* configure the chip ***************************/
238 printf("[sx1262] Configuring chip...\r\n");
239
240 sx126x_set_dio3_as_tcxo_ctrl(nctx, SX126X_TCXO_CTRL_3_3V, 1000);
241 print_chip_status(nctx, 0);
243 r = sx126x_set_reg_mode(nctx, SX126X_REG_MODE_DCDC);
244 printf("[sx1262] Reg mode: %i\r\n", r);
245 print_chip_status(nctx, 0);
246 sx1262_switch_to_rx();
247
248 uint16_t irq_mask;
249
250 irq_mask = 0;
251 irq_mask |= (1 << 0);
252 irq_mask |= (1 << 1);
253 irq_mask |= (1 << 7); // carrier detect
254 irq_mask |= (1 << 8); // carrier lost
255 irq_mask |= (1 << 9);
256 sx126x_set_dio_irq_params(nctx, irq_mask, 0xFFFF, 0, 0);
257 print_chip_status(nctx, 1);
258 // this seems to break rx?
259 // sx1262_done_transmit();
260 sx1262_initialized = 1;
261 printf("[sx1262] Chip configured\r\n");
262 nic_set_transmit_status(nctx, 1);
263 return 0;
264}
265int sx1262_init(struct network_context *nctx) {
266 sx1262_clear_rx_mode();
267 return sx1262_init_or_reinit(nctx, 0);
268}
269// warning! nctx might be NUL!!
270void sx1262_switch_to_rx(struct network_context *nctx) {
271 struct sx126x_chip_status_s rs;
272
273 sx126x_get_status(nctx, &rs);
274 if (rs.chip_mode == SX126X_CHIP_MODE_RX) {
275 return;
276 }
277 printf("[sx1262] switching to rx mode\r\n");
278 sx1262_set_lora_packet_type(nctx);
279 sx1262_set_lora_parameters(nctx);
280 sx126x_set_rf_freq(nctx, 868000000);
282 sx1262_set_packet_params(nctx, 0);
283 struct sx126x_pa_cfg_params_s pa_params = { .pa_duty_cycle = 0x04, .hp_max = 0x07, .device_sel = 0, .pa_lut = 1 };
284
285 sx126x_set_pa_cfg(nctx, &pa_params);
287 //print_chip_status(nctx, 0);
288
289
290 for (;;) {
291 //printf("Setting RX Mode\r\n");
293 struct sx126x_chip_status_s rs;
294 sx126x_get_status(nctx, &rs);
295 // printf("Chip mode: 0x%x (%s), Cmd Status: 0x%x (%s)\r\n", rs.chip_mode, chip_status_name(rs.chip_mode), rs.cmd_status, chip_com_name(rs.cmd_status));
296 //print_errors(nctx);
298 if (rs.chip_mode == SX126X_CHIP_MODE_RX) {
299 break;
300 }
301 Delay(100);
302 }
303 is_in_rx_mode = 1;
304}
305void sx1262_clear_rx_mode() {
306 is_in_rx_mode = 0;
307}
308int sx1262_stop(struct network_context *ctx) {
309 uint8_t xbuf[16];
310
311 sx1262_clear_rx_mode();
312
313 xbuf[0] = 0x84; // set sleep mode
314 xbuf[1] = 1;
315 sx126x_hal_write(ctx, (const uint8_t *)&xbuf, 1, NULL, 0); // set packet type
316 mculib_pin_set(ctx->mculib_handle, SX1262_CSN, 1); // if this goes low, we actually wake up the chip again
317
318 mculib_pin_release(ctx->mculib_handle, SX1262_BUSY);
319 mculib_pin_release(ctx->mculib_handle, SX1262_DIO1);
320 mculib_pin_release(ctx->mculib_handle, SX1262_RESET);
321 mculib_spi_disable(ctx->mculib_handle, 2);
322 nic_set_transmit_status(ctx, 0);
323 return 0;
324}
SX126X chip status structure definition.
Definition: sx126x.h:480
SX126X LoRa modulation parameters structure definition.
Definition: sx126x.h:329
sx126x_lora_sf_t sf
LoRa Spreading Factor.
Definition: sx126x.h:330
SX126X power amplifier configuration parameters structure definition.
Definition: sx126x.h:147
SX126x radio driver definition.
sx126x_status_t sx126x_set_dio3_as_tcxo_ctrl(struct network_context *nctx, const sx126x_tcxo_ctrl_voltages_t tcxo_voltage, const uint32_t timeout)
Configure the embedded TCXO switch control.
Definition: sx126x.c:526
sx126x_status_t sx126x_set_rx_with_timeout_in_rtc_step(struct network_context *nctx, const uint32_t timeout_in_rtc_step)
Set the chip in reception mode.
Definition: sx126x.c:290
enum sx126x_cmd_status_e sx126x_cmd_status_t
SX126X command status enumeration definition.
sx126x_status_t sx126x_set_pa_cfg(struct network_context *nctx, const sx126x_pa_cfg_params_t *params)
Configure the PA (Power Amplifier)
Definition: sx126x.c:373
sx126x_status_t sx126x_get_status(struct network_context *nctx, sx126x_chip_status_t *radio_status)
Get the chip status.
Definition: sx126x.c:718
sx126x_status_t sx126x_set_lora_mod_params(struct network_context *nctx, const sx126x_mod_params_lora_t *params)
Set the modulation parameters for LoRa packets.
Definition: sx126x.c:600
sx126x_status_t sx126x_set_rf_freq(struct network_context *nctx, const uint32_t freq_in_hz)
Set the RF frequency for future radio operations.
Definition: sx126x.c:545
sx126x_status_t sx126x_read_register(struct network_context *nctx, const uint16_t address, uint8_t *buffer, const uint8_t size)
Read data from register memory space.
Definition: sx126x.c:412
#define SX126X_RX_SINGLE_MODE
Timeout parameter in sx126x_set_rx_with_timeout_in_rtc_step to set the chip in reception until a rece...
Definition: sx126x.h:72
sx126x_status_t sx126x_write_register(struct network_context *nctx, const uint16_t address, const uint8_t *buffer, const uint8_t size)
Write data into register memory space.
Definition: sx126x.c:400
sx126x_status_t sx126x_set_reg_mode(struct network_context *nctx, const sx126x_reg_mod_t mode)
Configure the regulator mode to be used.
Definition: sx126x.c:328
sx126x_status_t sx126x_get_device_errors(struct network_context *nctx, sx126x_errors_mask_t *errors)
Get the list of all active errors.
Definition: sx126x.c:825
enum sx126x_chip_modes_e sx126x_chip_modes_t
SX126X chip mode enumeration definition.
sx126x_status_t sx126x_set_dio_irq_params(struct network_context *nctx, const uint16_t irq_mask, const uint16_t dio1_mask, const uint16_t dio2_mask, const uint16_t dio3_mask)
Set which interrupt signals are redirected to the dedicated DIO pin.
Definition: sx126x.c:453
sx126x_status_t sx126x_clear_device_errors(struct network_context *nctx)
Clear all active errors.
Definition: sx126x.c:842
sx126x_status_t sx126x_set_dio2_as_rf_sw_ctrl(struct network_context *nctx, const bool enable)
Configure the embedded RF switch control.
Definition: sx126x.c:516
sx126x_status_t sx126x_set_buffer_base_address(struct network_context *nctx, const uint8_t tx_base_address, const uint8_t rx_base_address)
Set buffer start addresses for both Tx and Rx operations.
Definition: sx126x.c:675
Hardware Abstraction Layer for SX126x.
sx126x_hal_status_t sx126x_hal_write(struct network_context *nctx, const uint8_t *command, const uint16_t command_length, const uint8_t *data, const uint16_t data_length)
Definition: bus.c:64