ESPHome 2026.8.0-dev
Loading...
Searching...
No Matches
sx126x.cpp
Go to the documentation of this file.
1#include "sx126x.h"
2#include "esphome/core/hal.h"
3#include "esphome/core/log.h"
4
5namespace esphome::sx126x {
6
7static const char *const TAG = "sx126x";
8static const uint16_t RAMP[8] = {10, 20, 40, 80, 200, 800, 1700, 3400};
9static const uint32_t BW_HZ[31] = {4800, 5800, 7300, 9700, 11700, 14600, 19500, 23400, 29300, 39000, 46900,
10 58600, 78200, 93800, 117300, 156200, 187200, 234300, 312000, 373600, 467000, 7810,
11 10420, 15630, 20830, 31250, 41670, 62500, 125000, 250000, 500000};
12static const uint8_t BW_LORA[10] = {LORA_BW_7810, LORA_BW_10420, LORA_BW_15630, LORA_BW_20830, LORA_BW_31250,
14static const uint8_t BW_FSK[21] = {
18
19static constexpr uint32_t RESET_DELAY_HIGH_US = 5000;
20static constexpr uint32_t RESET_DELAY_LOW_US = 2000;
21static constexpr uint32_t SWITCHING_DELAY_US = 1;
22static constexpr uint32_t TRANSMIT_TIMEOUT_MS = 4000;
23static constexpr uint32_t BUSY_TIMEOUT_MS = 20;
24
25// OCP (Over Current Protection) values
26static constexpr uint8_t OCP_80MA = 0x18; // 80 mA max current
27static constexpr uint8_t OCP_140MA = 0x38; // 140 mA max current
28
29// LoRa low data rate optimization threshold
30static constexpr float LOW_DATA_RATE_OPTIMIZE_THRESHOLD = 16.38f; // 16.38 ms
31
32uint8_t SX126x::read_fifo_(uint8_t offset, std::vector<uint8_t> &packet) {
33 this->enable();
34 this->wait_busy_();
36 this->transfer_byte(offset);
37 uint8_t status = this->transfer_byte(0x00);
38 for (uint8_t &byte : packet) {
39 byte = this->transfer_byte(0x00);
40 }
41 this->disable();
42 return status;
43}
44
45void SX126x::write_fifo_(uint8_t offset, const std::vector<uint8_t> &packet) {
46 this->enable();
47 this->wait_busy_();
49 this->transfer_byte(offset);
50 for (const uint8_t &byte : packet) {
51 this->transfer_byte(byte);
52 }
53 this->disable();
54 delayMicroseconds(SWITCHING_DELAY_US);
55}
56
57uint8_t SX126x::read_opcode_(uint8_t opcode, uint8_t *data, uint8_t size) {
58 this->enable();
59 this->wait_busy_();
60 this->transfer_byte(opcode);
61 uint8_t status = this->transfer_byte(0x00);
62 for (int32_t i = 0; i < size; i++) {
63 data[i] = this->transfer_byte(0x00);
64 }
65 this->disable();
66 return status;
67}
68
69void SX126x::write_opcode_(uint8_t opcode, uint8_t *data, uint8_t size) {
70 this->enable();
71 this->wait_busy_();
72 this->transfer_byte(opcode);
73 for (int32_t i = 0; i < size; i++) {
74 this->transfer_byte(data[i]);
75 }
76 this->disable();
77 delayMicroseconds(SWITCHING_DELAY_US);
78}
79
80void SX126x::read_register_(uint16_t reg, uint8_t *data, uint8_t size) {
81 this->enable();
82 this->wait_busy_();
84 this->write_byte((reg >> 8) & 0xFF);
85 this->write_byte((reg >> 0) & 0xFF);
86 this->write_byte(0x00);
87 for (int32_t i = 0; i < size; i++) {
88 data[i] = this->transfer_byte(0x00);
89 }
90 this->disable();
91}
92
93void SX126x::write_register_(uint16_t reg, uint8_t *data, uint8_t size) {
94 this->enable();
95 this->wait_busy_();
97 this->write_byte((reg >> 8) & 0xFF);
98 this->write_byte((reg >> 0) & 0xFF);
99 for (int32_t i = 0; i < size; i++) {
100 this->transfer_byte(data[i]);
101 }
102 this->disable();
103 delayMicroseconds(SWITCHING_DELAY_US);
104}
105
107
109 // setup pins
110 this->busy_pin_->setup();
111 this->rst_pin_->setup();
112 this->dio1_pin_->setup();
113 if (this->dio1_pin_->is_internal()) {
114 static_cast<InternalGPIOPin *>(this->dio1_pin_)
115 ->attach_interrupt(&SX126x::gpio_intr, this, gpio::INTERRUPT_RISING_EDGE);
116 }
117
118 // start spi
119 this->spi_setup();
120
121 // configure rf
122 this->configure();
123}
124
126 uint8_t buf[8];
127
128 // toggle chip reset
129 this->rst_pin_->digital_write(true);
130 delayMicroseconds(RESET_DELAY_HIGH_US);
131 this->rst_pin_->digital_write(false);
132 delayMicroseconds(RESET_DELAY_LOW_US);
133 this->rst_pin_->digital_write(true);
134 delayMicroseconds(RESET_DELAY_HIGH_US);
135
136 // wakeup
137 this->read_opcode_(RADIO_GET_STATUS, nullptr, 0);
138
139 // config tcxo
140 if (this->tcxo_voltage_ != TCXO_CTRL_NONE) {
141 uint32_t delay = this->tcxo_delay_ >> 6;
142 buf[0] = this->tcxo_voltage_;
143 buf[1] = (delay >> 16) & 0xFF;
144 buf[2] = (delay >> 8) & 0xFF;
145 buf[3] = (delay >> 0) & 0xFF;
146 this->write_opcode_(RADIO_SET_TCXOMODE, buf, 4);
147 buf[0] = 0x7F;
148 this->write_opcode_(RADIO_CALIBRATE, buf, 1);
149 }
150
151 // clear errors
152 buf[0] = 0x00;
153 buf[1] = 0x00;
154 this->write_opcode_(RADIO_CLR_ERROR, buf, 2);
155
156 // rf switch
157 if (this->rf_switch_) {
158 buf[0] = 0x01;
160 }
161
162 // check silicon version to make sure hw is ok
163 this->read_register_(REG_VERSION_STRING, (uint8_t *) this->version_, sizeof(this->version_));
164 this->version_[sizeof(this->version_) - 1] = '\0';
165 if (strncmp(this->version_, "SX126", 5) != 0 && strncmp(this->version_, "LLCC68", 6) != 0) {
166 this->mark_failed();
167 return;
168 }
169
170 // setup packet type
171 buf[0] = this->modulation_;
172 this->write_opcode_(RADIO_SET_PACKETTYPE, buf, 1);
173
174 // calibrate image
175 this->run_image_cal();
176
177 // set frequency
178 uint64_t freq = ((uint64_t) this->frequency_ << 25) / XTAL_FREQ;
179 buf[0] = (uint8_t) ((freq >> 24) & 0xFF);
180 buf[1] = (uint8_t) ((freq >> 16) & 0xFF);
181 buf[2] = (uint8_t) ((freq >> 8) & 0xFF);
182 buf[3] = (uint8_t) (freq & 0xFF);
184
185 // configure pa
186 int8_t pa_power = this->pa_power_;
187 if (this->hw_version_ == "sx1261") {
188 // the following values were taken from section 13.1.14.1 table 13-21
189 // in rev 2.1 of the datasheet
190 if (pa_power == 15) {
191 uint8_t cfg[4] = {0x06, 0x00, 0x01, 0x01};
192 this->write_opcode_(RADIO_SET_PACONFIG, cfg, 4);
193 } else {
194 uint8_t cfg[4] = {0x04, 0x00, 0x01, 0x01};
195 this->write_opcode_(RADIO_SET_PACONFIG, cfg, 4);
196 }
197 pa_power = std::max(pa_power, (int8_t) -3);
198 pa_power = std::min(pa_power, (int8_t) 14);
199 buf[0] = OCP_80MA;
200 this->write_register_(REG_OCP, buf, 1);
201 } else {
202 // the following values were taken from section 13.1.14.1 table 13-21
203 // in rev 2.1 of the datasheet
204 uint8_t cfg[4] = {0x04, 0x07, 0x00, 0x01};
205 this->write_opcode_(RADIO_SET_PACONFIG, cfg, 4);
206 pa_power = std::max(pa_power, (int8_t) -3);
207 pa_power = std::min(pa_power, (int8_t) 22);
208 buf[0] = OCP_140MA;
209 this->write_register_(REG_OCP, buf, 1);
210 }
211 buf[0] = pa_power;
212 buf[1] = this->pa_ramp_;
213 this->write_opcode_(RADIO_SET_TXPARAMS, buf, 2);
214
215 // configure modem
216 if (this->modulation_ == PACKET_TYPE_LORA) {
217 // set modulation params
218 float duration = 1000.0f * (1UL << this->spreading_factor_) / BW_HZ[this->bandwidth_];
219 buf[0] = this->spreading_factor_;
220 buf[1] = BW_LORA[this->bandwidth_ - SX126X_BW_7810];
221 buf[2] = this->coding_rate_;
222 buf[3] = (duration > LOW_DATA_RATE_OPTIMIZE_THRESHOLD) ? 0x01 : 0x00;
224
225 // set packet params and sync word
227 if (this->sync_value_.size() == 2) {
228 this->write_register_(REG_LORA_SYNCWORD, this->sync_value_.data(), this->sync_value_.size());
229 }
230 } else {
231 // set modulation params
232 uint32_t bitrate = ((uint64_t) XTAL_FREQ * 32) / this->bitrate_;
233 uint32_t fdev = ((uint64_t) this->deviation_ << 25) / XTAL_FREQ;
234 buf[0] = (bitrate >> 16) & 0xFF;
235 buf[1] = (bitrate >> 8) & 0xFF;
236 buf[2] = (bitrate >> 0) & 0xFF;
237 buf[3] = this->shaping_;
238 buf[4] = BW_FSK[this->bandwidth_ - SX126X_BW_4800];
239 buf[5] = (fdev >> 16) & 0xFF;
240 buf[6] = (fdev >> 8) & 0xFF;
241 buf[7] = (fdev >> 0) & 0xFF;
243
244 // set crc params
245 if (this->crc_enable_) {
246 buf[0] = this->crc_initial_ >> 8;
247 buf[1] = this->crc_initial_ & 0xFF;
248 this->write_register_(REG_CRC_INITIAL, buf, 2);
249 buf[0] = this->crc_polynomial_ >> 8;
250 buf[1] = this->crc_polynomial_ & 0xFF;
251 this->write_register_(REG_CRC_POLYNOMIAL, buf, 2);
252 }
253
254 // set whitening params
255 if (this->whitening_enable_) {
256 // according to the datasheet, section 12 table 12-1 "The user should not
257 // change the value of the 7 MSB of this register"
259 buf[0] = (buf[0] & 0xFE) | ((this->whitening_initial_ >> 8) & 0x01);
260 buf[1] = this->whitening_initial_ & 0xFF;
262 }
263
264 // set packet params and sync word
266 if (!this->sync_value_.empty()) {
267 this->write_register_(REG_GFSK_SYNCWORD, this->sync_value_.data(), this->sync_value_.size());
268 }
269 }
270
271 // switch to rx or sleep
272 if (this->rx_start_) {
273 this->set_mode_rx();
274 } else {
275 this->set_mode_sleep();
276 }
277}
278
280 if (this->payload_length_ > 0) {
281 return this->payload_length_;
282 }
283 return 255;
284}
285
286void SX126x::set_packet_params_(uint8_t payload_length) {
287 uint8_t buf[9];
288 if (this->modulation_ == PACKET_TYPE_LORA) {
289 buf[0] = (this->preamble_size_ >> 8) & 0xFF;
290 buf[1] = (this->preamble_size_ >> 0) & 0xFF;
291 buf[2] = (this->payload_length_ > 0) ? 0x01 : 0x00;
292 buf[3] = payload_length;
293 buf[4] = (this->crc_enable_) ? 0x01 : 0x00;
294 buf[5] = 0x00;
296 } else {
297 uint16_t preamble_size = this->preamble_size_ * 8;
298 buf[0] = (preamble_size >> 8) & 0xFF;
299 buf[1] = (preamble_size >> 0) & 0xFF;
300 buf[2] = (this->preamble_detect_ > 0) ? ((this->preamble_detect_ - 1) | 0x04) : 0x00;
301 buf[3] = this->sync_value_.size() * 8;
302 buf[4] = 0x00;
303 buf[5] = (this->payload_length_ > 0) ? 0x00 : 0x01;
304 buf[6] = payload_length;
305 if (this->crc_enable_) {
306 buf[7] = (this->crc_inverted_ ? 0x04 : 0x00) + (this->crc_size_ & 0x02);
307 } else {
308 buf[7] = 0x01;
309 }
310 buf[8] = (this->whitening_enable_) ? 0x01 : 0x00;
312 }
313}
314
315SX126xError SX126x::transmit_packet(const std::vector<uint8_t> &packet) {
316 if (this->payload_length_ > 0 && this->payload_length_ != packet.size()) {
317 ESP_LOGE(TAG, "Packet size does not match config");
319 }
320 if (packet.empty() || packet.size() > this->get_max_packet_size()) {
321 ESP_LOGE(TAG, "Packet size out of range");
323 }
324
327 if (this->payload_length_ == 0) {
328 this->set_packet_params_(packet.size());
329 }
330 this->write_fifo_(0x00, packet);
331 this->set_mode_tx();
332
333 // wait until transmit completes, typically the delay will be less than 100 ms
334 uint32_t start = millis();
335 while (!this->dio1_pin_->digital_read()) {
336 if (millis() - start > TRANSMIT_TIMEOUT_MS) {
337 ESP_LOGE(TAG, "Transmit packet failure");
339 break;
340 }
341 }
342
343 uint8_t buf[2];
344 buf[0] = 0xFF;
345 buf[1] = 0xFF;
346 this->write_opcode_(RADIO_CLR_IRQSTATUS, buf, 2);
347 if (this->payload_length_ == 0) {
349 }
350 if (this->rx_start_) {
351 this->set_mode_rx();
352 } else {
353 this->set_mode_sleep();
354 }
355 return ret;
356}
357
358void SX126x::call_listeners_(const std::vector<uint8_t> &packet, float rssi, float snr) {
359 for (auto &listener : this->listeners_) {
360 listener->on_packet(packet, rssi, snr);
361 }
362 this->packet_trigger_.trigger(packet, rssi, snr);
363}
364
366 if (this->dio1_pin_->is_internal()) {
367 this->disable_loop();
368 }
369 if (!this->dio1_pin_->digital_read()) {
370 return;
371 }
372
373 uint16_t status;
374 uint8_t buf[3];
375 uint8_t rssi;
376 int8_t snr;
377 this->read_opcode_(RADIO_GET_IRQSTATUS, buf, 2);
378 this->write_opcode_(RADIO_CLR_IRQSTATUS, buf, 2);
379 status = (buf[0] << 8) | buf[1];
380 if ((status & IRQ_RX_DONE) == IRQ_RX_DONE) {
383 if (this->modulation_ == PACKET_TYPE_LORA) {
384 rssi = buf[0];
385 snr = buf[1];
386 } else {
387 rssi = buf[2];
388 snr = 0;
389 }
391 this->packet_.resize(buf[0]);
392 this->read_fifo_(buf[1], this->packet_);
393 this->call_listeners_(this->packet_, (float) rssi / -2.0f, (float) snr / 4.0f);
394 }
395 }
396}
397
399 // the following values were taken from section 9.2.1 table 9-2
400 // in rev 2.1 of the datasheet
401 uint8_t buf[2] = {0, 0};
402 if (this->frequency_ > 900000000) {
403 buf[0] = 0xE1;
404 buf[1] = 0xE9;
405 } else if (this->frequency_ > 850000000) {
406 buf[0] = 0xD7;
407 buf[1] = 0xDB;
408 } else if (this->frequency_ > 770000000) {
409 buf[0] = 0xC1;
410 buf[1] = 0xC5;
411 } else if (this->frequency_ > 460000000) {
412 buf[0] = 0x75;
413 buf[1] = 0x81;
414 } else if (this->frequency_ > 425000000) {
415 buf[0] = 0x6B;
416 buf[1] = 0x6F;
417 }
418 if (buf[0] > 0 && buf[1] > 0) {
419 this->write_opcode_(RADIO_CALIBRATEIMAGE, buf, 2);
420 }
421}
422
424 uint8_t buf[8];
425
426 // configure irq params
428 buf[0] = (irq >> 8) & 0xFF;
429 buf[1] = (irq >> 0) & 0xFF;
430 buf[2] = (irq >> 8) & 0xFF;
431 buf[3] = (irq >> 0) & 0xFF;
432 buf[4] = (IRQ_RADIO_NONE >> 8) & 0xFF;
433 buf[5] = (IRQ_RADIO_NONE >> 0) & 0xFF;
434 buf[6] = (IRQ_RADIO_NONE >> 8) & 0xFF;
435 buf[7] = (IRQ_RADIO_NONE >> 0) & 0xFF;
437
438 // set timeout to 0
439 buf[0] = 0x00;
441
442 // switch to continuous mode rx
443 buf[0] = 0xFF;
444 buf[1] = 0xFF;
445 buf[2] = 0xFF;
446 this->write_opcode_(RADIO_SET_RX, buf, 3);
447}
448
450 uint8_t buf[8];
451
452 // configure irq params
453 uint16_t irq = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
454 buf[0] = (irq >> 8) & 0xFF;
455 buf[1] = (irq >> 0) & 0xFF;
456 buf[2] = (irq >> 8) & 0xFF;
457 buf[3] = (irq >> 0) & 0xFF;
458 buf[4] = (IRQ_RADIO_NONE >> 8) & 0xFF;
459 buf[5] = (IRQ_RADIO_NONE >> 0) & 0xFF;
460 buf[6] = (IRQ_RADIO_NONE >> 8) & 0xFF;
461 buf[7] = (IRQ_RADIO_NONE >> 0) & 0xFF;
463
464 // switch to single mode tx
465 buf[0] = 0x00;
466 buf[1] = 0x00;
467 buf[2] = 0x00;
468 this->write_opcode_(RADIO_SET_TX, buf, 3);
469}
470
471void SX126x::set_mode_sleep(bool cold) {
472 // 0x04 = warm start (config retained), 0x00 = cold start (config lost, lowest power)
473 uint8_t buf[1];
474 buf[0] = cold ? 0x00 : 0x04;
475 this->write_opcode_(RADIO_SET_SLEEP, buf, 1);
476}
477
479 uint8_t buf[1];
480 buf[0] = mode;
481 this->write_opcode_(RADIO_SET_STANDBY, buf, 1);
482}
483
485 // wait if the device is busy, the maximum delay is only be a few ms
486 // with most commands taking only a few us
487 uint32_t start = millis();
488 while (this->busy_pin_->digital_read()) {
489 if (millis() - start > BUSY_TIMEOUT_MS) {
490 ESP_LOGE(TAG, "Wait busy timeout");
491 this->mark_failed();
492 break;
493 }
494 }
495}
496
498 ESP_LOGCONFIG(TAG, "SX126x:");
499 LOG_PIN(" CS Pin: ", this->cs_);
500 LOG_PIN(" BUSY Pin: ", this->busy_pin_);
501 LOG_PIN(" RST Pin: ", this->rst_pin_);
502 LOG_PIN(" DIO1 Pin: ", this->dio1_pin_);
503 ESP_LOGCONFIG(TAG,
504 " HW Version: %15s\n"
505 " Frequency: %" PRIu32 " Hz\n"
506 " Bandwidth: %" PRIu32 " Hz\n"
507 " PA Power: %" PRId8 " dBm\n"
508 " PA Ramp: %" PRIu16 " us\n"
509 " Payload Length: %" PRIu32 "\n"
510 " CRC Enable: %s\n"
511 " Rx Start: %s",
512 this->version_, this->frequency_, BW_HZ[this->bandwidth_], this->pa_power_, RAMP[this->pa_ramp_],
513 this->payload_length_, TRUEFALSE(this->crc_enable_), TRUEFALSE(this->rx_start_));
514 if (this->modulation_ == PACKET_TYPE_GFSK) {
515 const char *shaping = "NONE";
516 if (this->shaping_ == GAUSSIAN_BT_0_3) {
517 shaping = "GAUSSIAN_BT_0_3";
518 } else if (this->shaping_ == GAUSSIAN_BT_0_5) {
519 shaping = "GAUSSIAN_BT_0_5";
520 } else if (this->shaping_ == GAUSSIAN_BT_0_7) {
521 shaping = "GAUSSIAN_BT_0_7";
522 } else if (this->shaping_ == GAUSSIAN_BT_1_0) {
523 shaping = "GAUSSIAN_BT_1_0";
524 }
525 ESP_LOGCONFIG(TAG,
526 " Modulation: FSK\n"
527 " Deviation: %" PRIu32 " Hz\n"
528 " Shaping: %s\n"
529 " Preamble Size: %" PRIu16 "\n"
530 " Preamble Detect: %" PRIu16 "\n"
531 " Bitrate: %" PRIu32 "b/s",
532 this->deviation_, shaping, this->preamble_size_, this->preamble_detect_, this->bitrate_);
533 } else if (this->modulation_ == PACKET_TYPE_LORA) {
534 const char *cr = "4/8";
535 if (this->coding_rate_ == LORA_CR_4_5) {
536 cr = "4/5";
537 } else if (this->coding_rate_ == LORA_CR_4_6) {
538 cr = "4/6";
539 } else if (this->coding_rate_ == LORA_CR_4_7) {
540 cr = "4/7";
541 }
542 ESP_LOGCONFIG(TAG,
543 " Modulation: LORA\n"
544 " Spreading Factor: %" PRIu8 "\n"
545 " Coding Rate: %s\n"
546 " Preamble Size: %" PRIu16,
547 this->spreading_factor_, cr, this->preamble_size_);
548 }
549 if (!this->sync_value_.empty()) {
550 char hex_buf[17]; // 8 bytes max = 16 hex chars + null
551 ESP_LOGCONFIG(TAG, " Sync Value: 0x%s",
552 format_hex_to(hex_buf, this->sync_value_.data(), this->sync_value_.size()));
553 }
554 ESP_LOGCONFIG(TAG, " Whitening Enable: %s", TRUEFALSE(this->whitening_enable_));
555 if (this->whitening_enable_) {
556 ESP_LOGCONFIG(TAG, " Whitening Initial: 0x%03x", this->whitening_initial_);
557 }
558 if (this->is_failed()) {
559 ESP_LOGE(TAG, "Configuring SX126x failed");
560 }
561}
562
563} // namespace esphome::sx126x
BedjetMode mode
BedJet operating mode.
uint8_t status
Definition bl0942.h:8
void mark_failed()
Mark this component as failed.
bool is_failed() const
Definition component.h:272
void enable_loop_soon_any_context()
Thread and ISR-safe version of enable_loop() that can be called from any context.
void disable_loop()
Disable this component's loop.
virtual void setup()=0
virtual void digital_write(bool value)=0
virtual bool is_internal()
Definition gpio.h:81
virtual bool digital_read()=0
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
Inform the parent automation that the event has triggered.
Definition automation.h:461
uint8_t read_fifo_(uint8_t offset, std::vector< uint8_t > &packet)
Definition sx126x.cpp:32
void write_opcode_(uint8_t opcode, uint8_t *data, uint8_t size)
Definition sx126x.cpp:69
std::vector< uint8_t > sync_value_
Definition sx126x.h:120
std::vector< SX126xListener * > listeners_
Definition sx126x.h:118
size_t get_max_packet_size()
Definition sx126x.cpp:279
void set_mode_standby(SX126xStandbyMode mode)
Definition sx126x.cpp:478
static void IRAM_ATTR gpio_intr(SX126x *arg)
Definition sx126x.cpp:106
Trigger< std::vector< uint8_t >, float, float > packet_trigger_
Definition sx126x.h:117
uint8_t read_opcode_(uint8_t opcode, uint8_t *data, uint8_t size)
Definition sx126x.cpp:57
void dump_config() override
Definition sx126x.cpp:497
void read_register_(uint16_t reg, uint8_t *data, uint8_t size)
Definition sx126x.cpp:80
void write_register_(uint16_t reg, uint8_t *data, uint8_t size)
Definition sx126x.cpp:93
uint16_t crc_polynomial_
Definition sx126x.h:131
uint16_t preamble_size_
Definition sx126x.h:140
void loop() override
Definition sx126x.cpp:365
void set_packet_params_(uint8_t payload_length)
Definition sx126x.cpp:286
void call_listeners_(const std::vector< uint8_t > &packet, float rssi, float snr)
Definition sx126x.cpp:358
std::vector< uint8_t > packet_
Definition sx126x.h:119
uint16_t preamble_detect_
Definition sx126x.h:139
void setup() override
Definition sx126x.cpp:108
uint16_t whitening_initial_
Definition sx126x.h:134
std::string hw_version_
Definition sx126x.h:124
uint32_t payload_length_
Definition sx126x.h:137
SX126xError transmit_packet(const std::vector< uint8_t > &packet)
Definition sx126x.cpp:315
uint8_t spreading_factor_
Definition sx126x.h:146
void write_fifo_(uint8_t offset, const std::vector< uint8_t > &packet)
Definition sx126x.cpp:45
void set_mode_sleep(bool cold=false)
Definition sx126x.cpp:471
uint16_t preamble_size
uint8_t duration
Definition msa3xx.h:0
@ INTERRUPT_RISING_EDGE
Definition gpio.h:48
const char *const TAG
Definition spi.cpp:7
@ RADIO_SET_MODULATIONPARAMS
Definition sx126x_reg.h:31
@ RADIO_SET_LORASYMBTIMEOUT
Definition sx126x_reg.h:50
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Definition hal.cpp:48
uint16_t size
Definition helpers.cpp:25
void HOT delay(uint32_t ms)
Definition hal.cpp:85
uint32_t IRAM_ATTR HOT millis()
Definition hal.cpp:28
char * format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length)
Format byte array as lowercase hex to buffer (base implementation).
Definition helpers.cpp:334
static void uint32_t