GPIO retrabalhada e PABOOST selecionavel

Committer:
MatteusCarr
Date:
Thu May 20 21:24:36 2021 +0000
Revision:
6:f0616e516844
Parent:
0:561d07a737bc
Atualizacao SX1272 LoRaRadio, retrabalho e PABOOST

Who changed what in which revision?

UserRevisionLine numberNew contents of line
brunnobbco 0:561d07a737bc 1 /**
brunnobbco 0:561d07a737bc 2 / _____) _ | |
brunnobbco 0:561d07a737bc 3 ( (____ _____ ____ _| |_ _____ ____| |__
brunnobbco 0:561d07a737bc 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
brunnobbco 0:561d07a737bc 5 _____) ) ____| | | || |_| ____( (___| | | |
brunnobbco 0:561d07a737bc 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
brunnobbco 0:561d07a737bc 7 (C)2015 Semtech
brunnobbco 0:561d07a737bc 8 ___ _____ _ ___ _ _____ ___ ___ ___ ___
brunnobbco 0:561d07a737bc 9 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
brunnobbco 0:561d07a737bc 10 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
brunnobbco 0:561d07a737bc 11 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
brunnobbco 0:561d07a737bc 12 embedded.connectivity.solutions===============
brunnobbco 0:561d07a737bc 13
brunnobbco 0:561d07a737bc 14 Description: LoRaWAN stack layer that controls both MAC and PHY underneath
brunnobbco 0:561d07a737bc 15
brunnobbco 0:561d07a737bc 16 License: Revised BSD License, see LICENSE.TXT file include in the project
brunnobbco 0:561d07a737bc 17
brunnobbco 0:561d07a737bc 18 Maintainer: Miguel Luis, Gregory Cristian & Gilbert Menth
brunnobbco 0:561d07a737bc 19
brunnobbco 0:561d07a737bc 20 Copyright (c) 2019, Arm Limited and affiliates.
brunnobbco 0:561d07a737bc 21
brunnobbco 0:561d07a737bc 22 SPDX-License-Identifier: BSD-3-Clause
brunnobbco 0:561d07a737bc 23 */
brunnobbco 0:561d07a737bc 24
brunnobbco 0:561d07a737bc 25 #include <math.h>
brunnobbco 0:561d07a737bc 26 #include "mbed_wait_api.h"
brunnobbco 0:561d07a737bc 27 #include "Timer.h"
brunnobbco 0:561d07a737bc 28 #include "SX126X_LoRaRadio.h"
brunnobbco 0:561d07a737bc 29
brunnobbco 0:561d07a737bc 30 #ifdef MBED_CONF_SX126X_LORA_DRIVER_SPI_FREQUENCY
brunnobbco 0:561d07a737bc 31 #define SPI_FREQUENCY MBED_CONF_SX126X_LORA_DRIVER_SPI_FREQUENCY
brunnobbco 0:561d07a737bc 32 #else
brunnobbco 0:561d07a737bc 33 #define SPI_FREQUENCY 16000000
brunnobbco 0:561d07a737bc 34 #endif
brunnobbco 0:561d07a737bc 35
brunnobbco 0:561d07a737bc 36 using namespace mbed;
brunnobbco 0:561d07a737bc 37 #ifdef MBED_CONF_RTOS_PRESENT
brunnobbco 0:561d07a737bc 38 using namespace rtos;
brunnobbco 0:561d07a737bc 39 /**
brunnobbco 0:561d07a737bc 40 * Signals
brunnobbco 0:561d07a737bc 41 */
brunnobbco 0:561d07a737bc 42 #define SIG_INTERRUPT 0x02
brunnobbco 0:561d07a737bc 43 #endif
brunnobbco 0:561d07a737bc 44
brunnobbco 0:561d07a737bc 45 /*!
brunnobbco 0:561d07a737bc 46 * FSK bandwidth definition
brunnobbco 0:561d07a737bc 47 */
brunnobbco 0:561d07a737bc 48 typedef struct
brunnobbco 0:561d07a737bc 49 {
brunnobbco 0:561d07a737bc 50 uint32_t bandwidth;
brunnobbco 0:561d07a737bc 51 uint8_t register_value;
brunnobbco 0:561d07a737bc 52 } fsk_bw_t;
brunnobbco 0:561d07a737bc 53
brunnobbco 0:561d07a737bc 54 static const fsk_bw_t fsk_bandwidths[] =
brunnobbco 0:561d07a737bc 55 {
brunnobbco 0:561d07a737bc 56 { 4800 , 0x1F },
brunnobbco 0:561d07a737bc 57 { 5800 , 0x17 },
brunnobbco 0:561d07a737bc 58 { 7300 , 0x0F },
brunnobbco 0:561d07a737bc 59 { 9700 , 0x1E },
brunnobbco 0:561d07a737bc 60 { 11700 , 0x16 },
brunnobbco 0:561d07a737bc 61 { 14600 , 0x0E },
brunnobbco 0:561d07a737bc 62 { 19500 , 0x1D },
brunnobbco 0:561d07a737bc 63 { 23400 , 0x15 },
brunnobbco 0:561d07a737bc 64 { 29300 , 0x0D },
brunnobbco 0:561d07a737bc 65 { 39000 , 0x1C },
brunnobbco 0:561d07a737bc 66 { 46900 , 0x14 },
brunnobbco 0:561d07a737bc 67 { 58600 , 0x0C },
brunnobbco 0:561d07a737bc 68 { 78200 , 0x1B },
brunnobbco 0:561d07a737bc 69 { 93800 , 0x13 },
brunnobbco 0:561d07a737bc 70 { 117300, 0x0B },
brunnobbco 0:561d07a737bc 71 { 156200, 0x1A },
brunnobbco 0:561d07a737bc 72 { 187200, 0x12 },
brunnobbco 0:561d07a737bc 73 { 234300, 0x0A },
brunnobbco 0:561d07a737bc 74 { 312000, 0x19 },
brunnobbco 0:561d07a737bc 75 { 373600, 0x11 },
brunnobbco 0:561d07a737bc 76 { 467000, 0x09 },
brunnobbco 0:561d07a737bc 77 { 500000, 0x00 }, // Invalid Bandwidth
brunnobbco 0:561d07a737bc 78 };
brunnobbco 0:561d07a737bc 79
brunnobbco 0:561d07a737bc 80 const uint8_t sync_word[] = {0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00,0x00};
brunnobbco 0:561d07a737bc 81
brunnobbco 0:561d07a737bc 82 // in ms SF12 SF11 SF10 SF9 SF8 SF7
brunnobbco 0:561d07a737bc 83 const float lora_symbol_time[3][6] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024 }, // 125 KHz
brunnobbco 0:561d07a737bc 84 { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512 }, // 250 KHz
brunnobbco 0:561d07a737bc 85 { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256 }}; // 500 KHz
brunnobbco 0:561d07a737bc 86
brunnobbco 0:561d07a737bc 87 SX126X_LoRaRadio::SX126X_LoRaRadio(PinName mosi,
brunnobbco 0:561d07a737bc 88 PinName miso,
brunnobbco 0:561d07a737bc 89 PinName sclk,
brunnobbco 0:561d07a737bc 90 PinName nss,
brunnobbco 0:561d07a737bc 91 PinName reset,
brunnobbco 0:561d07a737bc 92 PinName dio1,
brunnobbco 0:561d07a737bc 93 PinName busy,
brunnobbco 0:561d07a737bc 94 PinName freq_select,
brunnobbco 0:561d07a737bc 95 PinName device_select,
brunnobbco 0:561d07a737bc 96 PinName crystal_select,
brunnobbco 0:561d07a737bc 97 PinName ant_switch)
brunnobbco 0:561d07a737bc 98 : _spi(mosi, miso, sclk),
brunnobbco 0:561d07a737bc 99 _chip_select(nss, 1),
brunnobbco 0:561d07a737bc 100 _reset_ctl(reset),
brunnobbco 0:561d07a737bc 101 _dio1_ctl(dio1, PullNone),
brunnobbco 0:561d07a737bc 102 _busy(busy, PullNone),
brunnobbco 0:561d07a737bc 103 _freq_select(freq_select),
brunnobbco 0:561d07a737bc 104 _dev_select(device_select),
brunnobbco 0:561d07a737bc 105 _crystal_select(crystal_select, PullDown),
brunnobbco 0:561d07a737bc 106 _ant_switch(ant_switch, PIN_INPUT, PullUp, 0)
brunnobbco 0:561d07a737bc 107 #ifdef MBED_CONF_RTOS_PRESENT
brunnobbco 0:561d07a737bc 108 , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX126X")
brunnobbco 0:561d07a737bc 109 #endif
brunnobbco 0:561d07a737bc 110 {
brunnobbco 0:561d07a737bc 111 _radio_events = NULL;
brunnobbco 0:561d07a737bc 112 _reset_ctl = 1;
brunnobbco 0:561d07a737bc 113 _image_calibrated = false;
brunnobbco 0:561d07a737bc 114 _force_image_calibration = false;
brunnobbco 0:561d07a737bc 115 _active_modem = MODEM_LORA;
brunnobbco 0:561d07a737bc 116
brunnobbco 0:561d07a737bc 117 #ifdef MBED_CONF_RTOS_PRESENT
brunnobbco 0:561d07a737bc 118 irq_thread.start(callback(this, &SX126X_LoRaRadio::rf_irq_task));
brunnobbco 0:561d07a737bc 119 #endif
brunnobbco 0:561d07a737bc 120 }
brunnobbco 0:561d07a737bc 121
brunnobbco 0:561d07a737bc 122 SX126X_LoRaRadio::~SX126X_LoRaRadio()
brunnobbco 0:561d07a737bc 123 {
brunnobbco 0:561d07a737bc 124
brunnobbco 0:561d07a737bc 125 }
brunnobbco 0:561d07a737bc 126
brunnobbco 0:561d07a737bc 127 /**
brunnobbco 0:561d07a737bc 128 * Acquire lock
brunnobbco 0:561d07a737bc 129 */
brunnobbco 0:561d07a737bc 130 void SX126X_LoRaRadio::lock(void)
brunnobbco 0:561d07a737bc 131 {
brunnobbco 0:561d07a737bc 132 mutex.lock();
brunnobbco 0:561d07a737bc 133 }
brunnobbco 0:561d07a737bc 134
brunnobbco 0:561d07a737bc 135 /**
brunnobbco 0:561d07a737bc 136 * Release lock
brunnobbco 0:561d07a737bc 137 */
brunnobbco 0:561d07a737bc 138 void SX126X_LoRaRadio::unlock(void)
brunnobbco 0:561d07a737bc 139 {
brunnobbco 0:561d07a737bc 140 mutex.unlock();
brunnobbco 0:561d07a737bc 141 }
brunnobbco 0:561d07a737bc 142
brunnobbco 0:561d07a737bc 143 #ifdef MBED_CONF_RTOS_PRESENT
brunnobbco 0:561d07a737bc 144 /**
brunnobbco 0:561d07a737bc 145 * Thread task handling IRQs
brunnobbco 0:561d07a737bc 146 */
brunnobbco 0:561d07a737bc 147 void SX126X_LoRaRadio::rf_irq_task(void)
brunnobbco 0:561d07a737bc 148 {
brunnobbco 0:561d07a737bc 149 for (;;) {
brunnobbco 0:561d07a737bc 150 uint32_t flags = ThisThread::flags_wait_any(0x7FFFFFFF);
brunnobbco 0:561d07a737bc 151
brunnobbco 0:561d07a737bc 152 lock();
brunnobbco 0:561d07a737bc 153 if (flags & SIG_INTERRUPT) {
brunnobbco 0:561d07a737bc 154 handle_dio1_irq();
brunnobbco 0:561d07a737bc 155 }
brunnobbco 0:561d07a737bc 156 unlock();
brunnobbco 0:561d07a737bc 157 }
brunnobbco 0:561d07a737bc 158 }
brunnobbco 0:561d07a737bc 159 #endif
brunnobbco 0:561d07a737bc 160
brunnobbco 0:561d07a737bc 161 void SX126X_LoRaRadio::dio1_irq_isr()
brunnobbco 0:561d07a737bc 162 {
brunnobbco 0:561d07a737bc 163 #ifdef MBED_CONF_RTOS_PRESENT
brunnobbco 0:561d07a737bc 164 irq_thread.flags_set(SIG_INTERRUPT);
brunnobbco 0:561d07a737bc 165 #else
brunnobbco 0:561d07a737bc 166 handle_dio1_irq();
brunnobbco 0:561d07a737bc 167 #endif
brunnobbco 0:561d07a737bc 168 }
brunnobbco 0:561d07a737bc 169
brunnobbco 0:561d07a737bc 170 uint16_t SX126X_LoRaRadio::get_irq_status(void)
brunnobbco 0:561d07a737bc 171 {
brunnobbco 0:561d07a737bc 172 uint8_t status[2];
brunnobbco 0:561d07a737bc 173
brunnobbco 0:561d07a737bc 174 read_opmode_command((uint8_t) RADIO_GET_IRQSTATUS, status, 2);
brunnobbco 0:561d07a737bc 175 return (status[0] << 8) | status[1];
brunnobbco 0:561d07a737bc 176 }
brunnobbco 0:561d07a737bc 177
brunnobbco 0:561d07a737bc 178 void SX126X_LoRaRadio::clear_irq_status(uint16_t irq)
brunnobbco 0:561d07a737bc 179 {
brunnobbco 0:561d07a737bc 180 uint8_t buf[2];
brunnobbco 0:561d07a737bc 181
brunnobbco 0:561d07a737bc 182 buf[0] = (uint8_t) (((uint16_t) irq >> 8) & 0x00FF);
brunnobbco 0:561d07a737bc 183 buf[1] = (uint8_t) ((uint16_t) irq & 0x00FF);
brunnobbco 0:561d07a737bc 184 write_opmode_command((uint8_t) RADIO_CLR_IRQSTATUS, buf, 2);
brunnobbco 0:561d07a737bc 185 }
brunnobbco 0:561d07a737bc 186
brunnobbco 0:561d07a737bc 187 //TODO - Better do CAD here. CAD code is already part of the driver
brunnobbco 0:561d07a737bc 188 // It needs to be hooked up to the stack (this API will need change
brunnobbco 0:561d07a737bc 189 // and the stack will need changes too)
brunnobbco 0:561d07a737bc 190 bool SX126X_LoRaRadio::perform_carrier_sense(radio_modems_t modem,
brunnobbco 0:561d07a737bc 191 uint32_t freq,
brunnobbco 0:561d07a737bc 192 int16_t rssi_threshold,
brunnobbco 0:561d07a737bc 193 uint32_t max_carrier_sense_time)
brunnobbco 0:561d07a737bc 194 {
brunnobbco 0:561d07a737bc 195 bool status = true;
brunnobbco 0:561d07a737bc 196 int16_t rssi = 0;
brunnobbco 0:561d07a737bc 197
brunnobbco 0:561d07a737bc 198 set_modem(modem);
brunnobbco 0:561d07a737bc 199 set_channel(freq);
brunnobbco 0:561d07a737bc 200 _reception_mode = RECEPTION_MODE_OTHER;
brunnobbco 0:561d07a737bc 201 _rx_timeout = 0x00000000;
brunnobbco 0:561d07a737bc 202 receive();
brunnobbco 0:561d07a737bc 203
brunnobbco 0:561d07a737bc 204 // hold on a bit, radio turn-around time
brunnobbco 0:561d07a737bc 205 wait_ms(1);
brunnobbco 0:561d07a737bc 206
brunnobbco 0:561d07a737bc 207 Timer elapsed_time;
brunnobbco 0:561d07a737bc 208 elapsed_time.start();
brunnobbco 0:561d07a737bc 209
brunnobbco 0:561d07a737bc 210 // Perform carrier sense for maxCarrierSenseTime
brunnobbco 0:561d07a737bc 211 while (elapsed_time.read_ms() < (int) max_carrier_sense_time) {
brunnobbco 0:561d07a737bc 212 rssi = get_rssi();
brunnobbco 0:561d07a737bc 213
brunnobbco 0:561d07a737bc 214 if (rssi > rssi_threshold) {
brunnobbco 0:561d07a737bc 215 status = false;
brunnobbco 0:561d07a737bc 216 break;
brunnobbco 0:561d07a737bc 217 }
brunnobbco 0:561d07a737bc 218 }
brunnobbco 0:561d07a737bc 219
brunnobbco 0:561d07a737bc 220 sleep();
brunnobbco 0:561d07a737bc 221 return status;
brunnobbco 0:561d07a737bc 222 }
brunnobbco 0:561d07a737bc 223
brunnobbco 0:561d07a737bc 224 void SX126X_LoRaRadio::start_cad(void)
brunnobbco 0:561d07a737bc 225 {
brunnobbco 0:561d07a737bc 226 // TODO: CAD is more advanced in SX126X. We will need API change in LoRaRadio
brunnobbco 0:561d07a737bc 227 // for this to act properly
brunnobbco 0:561d07a737bc 228 }
brunnobbco 0:561d07a737bc 229
brunnobbco 0:561d07a737bc 230 /**
brunnobbco 0:561d07a737bc 231 * TODO: The purpose of this API is unclear.
brunnobbco 0:561d07a737bc 232 * Need to start an internal discussion.
brunnobbco 0:561d07a737bc 233 */
brunnobbco 0:561d07a737bc 234 bool SX126X_LoRaRadio::check_rf_frequency(uint32_t frequency)
brunnobbco 0:561d07a737bc 235 {
brunnobbco 0:561d07a737bc 236 // Implement check. Currently all frequencies are supported ? What band ?
brunnobbco 0:561d07a737bc 237 return true;
brunnobbco 0:561d07a737bc 238 }
brunnobbco 0:561d07a737bc 239
brunnobbco 0:561d07a737bc 240 void SX126X_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power,
brunnobbco 0:561d07a737bc 241 uint16_t time)
brunnobbco 0:561d07a737bc 242 {
brunnobbco 0:561d07a737bc 243 // This is useless. We even removed the support from our MAC layer.
brunnobbco 0:561d07a737bc 244 }
brunnobbco 0:561d07a737bc 245
brunnobbco 0:561d07a737bc 246 void SX126X_LoRaRadio::handle_dio1_irq()
brunnobbco 0:561d07a737bc 247 {
brunnobbco 0:561d07a737bc 248 uint16_t irq_status = get_irq_status();
brunnobbco 0:561d07a737bc 249 clear_irq_status(IRQ_RADIO_ALL);
brunnobbco 0:561d07a737bc 250
brunnobbco 0:561d07a737bc 251 if ((irq_status & IRQ_TX_DONE) == IRQ_TX_DONE) {
brunnobbco 0:561d07a737bc 252 if (_radio_events->tx_done) {
brunnobbco 0:561d07a737bc 253 _radio_events->tx_done();
brunnobbco 0:561d07a737bc 254 }
brunnobbco 0:561d07a737bc 255 }
brunnobbco 0:561d07a737bc 256
brunnobbco 0:561d07a737bc 257 if ((irq_status & IRQ_RX_DONE) == IRQ_RX_DONE) {
brunnobbco 0:561d07a737bc 258 if ((irq_status & IRQ_CRC_ERROR) == IRQ_CRC_ERROR) {
brunnobbco 0:561d07a737bc 259 if (_radio_events && _radio_events->rx_error) {
brunnobbco 0:561d07a737bc 260 _radio_events->rx_error();
brunnobbco 0:561d07a737bc 261 }
brunnobbco 0:561d07a737bc 262 } else {
brunnobbco 0:561d07a737bc 263 if (_radio_events->rx_done) {
brunnobbco 0:561d07a737bc 264 uint8_t offset = 0;
brunnobbco 0:561d07a737bc 265 uint8_t payload_len = 0;
brunnobbco 0:561d07a737bc 266 int16_t rssi = 0;
brunnobbco 0:561d07a737bc 267 int8_t snr = 0;
brunnobbco 0:561d07a737bc 268 packet_status_t pkt_status;
brunnobbco 0:561d07a737bc 269
brunnobbco 0:561d07a737bc 270 get_rx_buffer_status(&payload_len, &offset);
brunnobbco 0:561d07a737bc 271 read_fifo(_data_buffer, payload_len, offset);
brunnobbco 0:561d07a737bc 272 get_packet_status(&pkt_status);
brunnobbco 0:561d07a737bc 273 if (pkt_status.modem_type == MODEM_FSK) {
brunnobbco 0:561d07a737bc 274 rssi = pkt_status.params.gfsk.rssi_sync;
brunnobbco 0:561d07a737bc 275 } else {
brunnobbco 0:561d07a737bc 276 rssi = pkt_status.params.lora.rssi_pkt;
brunnobbco 0:561d07a737bc 277 snr = pkt_status.params.lora.snr_pkt;
brunnobbco 0:561d07a737bc 278 }
brunnobbco 0:561d07a737bc 279
brunnobbco 0:561d07a737bc 280 _radio_events->rx_done(_data_buffer, payload_len, rssi, snr);
brunnobbco 0:561d07a737bc 281 }
brunnobbco 0:561d07a737bc 282 }
brunnobbco 0:561d07a737bc 283 }
brunnobbco 0:561d07a737bc 284
brunnobbco 0:561d07a737bc 285 if ((irq_status & IRQ_CAD_DONE) == IRQ_CAD_DONE) {
brunnobbco 0:561d07a737bc 286 if (_radio_events->cad_done) {
brunnobbco 0:561d07a737bc 287 _radio_events->cad_done((irq_status & IRQ_CAD_ACTIVITY_DETECTED)
brunnobbco 0:561d07a737bc 288 == IRQ_CAD_ACTIVITY_DETECTED);
brunnobbco 0:561d07a737bc 289 }
brunnobbco 0:561d07a737bc 290 }
brunnobbco 0:561d07a737bc 291
brunnobbco 0:561d07a737bc 292 if ((irq_status & IRQ_RX_TX_TIMEOUT) == IRQ_RX_TX_TIMEOUT) {
brunnobbco 0:561d07a737bc 293 if ((_radio_events->tx_timeout) && (_operation_mode == MODE_TX)) {
brunnobbco 0:561d07a737bc 294 _radio_events->tx_timeout();
brunnobbco 0:561d07a737bc 295 } else if ((_radio_events && _radio_events->rx_timeout) && (_operation_mode == MODE_RX)) {
brunnobbco 0:561d07a737bc 296 _radio_events->rx_timeout();
brunnobbco 0:561d07a737bc 297 }
brunnobbco 0:561d07a737bc 298 }
brunnobbco 0:561d07a737bc 299 }
brunnobbco 0:561d07a737bc 300
brunnobbco 0:561d07a737bc 301 void SX126X_LoRaRadio::set_device_ready(void)
brunnobbco 0:561d07a737bc 302 {
brunnobbco 0:561d07a737bc 303 if (_operation_mode == MODE_SLEEP) {
brunnobbco 0:561d07a737bc 304 wakeup();
brunnobbco 0:561d07a737bc 305 }
brunnobbco 0:561d07a737bc 306 }
brunnobbco 0:561d07a737bc 307
brunnobbco 0:561d07a737bc 308 void SX126X_LoRaRadio::calibrate_image(uint32_t freq)
brunnobbco 0:561d07a737bc 309 {
brunnobbco 0:561d07a737bc 310 uint8_t cal_freq[2];
brunnobbco 0:561d07a737bc 311
brunnobbco 0:561d07a737bc 312 if (freq > 900000000) {
brunnobbco 0:561d07a737bc 313 cal_freq[0] = 0xE1;
brunnobbco 0:561d07a737bc 314 cal_freq[1] = 0xE9;
brunnobbco 0:561d07a737bc 315 } else if (freq > 850000000) {
brunnobbco 0:561d07a737bc 316 cal_freq[0] = 0xD7;
brunnobbco 0:561d07a737bc 317 cal_freq[1] = 0xD8;
brunnobbco 0:561d07a737bc 318 } else if (freq > 770000000) {
brunnobbco 0:561d07a737bc 319 cal_freq[0] = 0xC1;
brunnobbco 0:561d07a737bc 320 cal_freq[1] = 0xC5;
brunnobbco 0:561d07a737bc 321 } else if (freq > 460000000) {
brunnobbco 0:561d07a737bc 322 cal_freq[0] = 0x75;
brunnobbco 0:561d07a737bc 323 cal_freq[1] = 0x81;
brunnobbco 0:561d07a737bc 324 } else if (freq > 425000000) {
brunnobbco 0:561d07a737bc 325 cal_freq[0] = 0x6B;
brunnobbco 0:561d07a737bc 326 cal_freq[1] = 0x6F;
brunnobbco 0:561d07a737bc 327 }
brunnobbco 0:561d07a737bc 328
brunnobbco 0:561d07a737bc 329 write_opmode_command((uint8_t) RADIO_CALIBRATEIMAGE, cal_freq, 2);
brunnobbco 0:561d07a737bc 330
brunnobbco 0:561d07a737bc 331 _image_calibrated = true;
brunnobbco 0:561d07a737bc 332 }
brunnobbco 0:561d07a737bc 333
brunnobbco 0:561d07a737bc 334 void SX126X_LoRaRadio::set_channel(uint32_t frequency)
brunnobbco 0:561d07a737bc 335 {
brunnobbco 0:561d07a737bc 336 #if MBED_CONF_SX126X_LORA_DRIVER_SLEEP_MODE == 1
brunnobbco 0:561d07a737bc 337 // At this point, we are not sure what is the Modem type, set both
brunnobbco 0:561d07a737bc 338 _mod_params.params.lora.operational_frequency = frequency;
brunnobbco 0:561d07a737bc 339 _mod_params.params.gfsk.operational_frequency = frequency;
brunnobbco 0:561d07a737bc 340 #endif
brunnobbco 0:561d07a737bc 341
brunnobbco 0:561d07a737bc 342 uint8_t buf[4];
brunnobbco 0:561d07a737bc 343 uint32_t freq = 0;
brunnobbco 0:561d07a737bc 344
brunnobbco 0:561d07a737bc 345 if ( _force_image_calibration || !_image_calibrated) {
brunnobbco 0:561d07a737bc 346 calibrate_image(frequency);
brunnobbco 0:561d07a737bc 347 _image_calibrated = true;
brunnobbco 0:561d07a737bc 348 }
brunnobbco 0:561d07a737bc 349
brunnobbco 0:561d07a737bc 350 freq = (uint32_t) ceil(((float) frequency / (float) FREQ_STEP));
brunnobbco 0:561d07a737bc 351 buf[0] = (uint8_t) ((freq >> 24) & 0xFF);
brunnobbco 0:561d07a737bc 352 buf[1] = (uint8_t) ((freq >> 16) & 0xFF);
brunnobbco 0:561d07a737bc 353 buf[2] = (uint8_t) ((freq >> 8) & 0xFF);
brunnobbco 0:561d07a737bc 354 buf[3] = (uint8_t) (freq & 0xFF);
brunnobbco 0:561d07a737bc 355
brunnobbco 0:561d07a737bc 356 write_opmode_command((uint8_t) RADIO_SET_RFFREQUENCY, buf, 4);
brunnobbco 0:561d07a737bc 357 }
brunnobbco 0:561d07a737bc 358
brunnobbco 0:561d07a737bc 359 /**
brunnobbco 0:561d07a737bc 360 * Put radio in Standby mode
brunnobbco 0:561d07a737bc 361 */
brunnobbco 0:561d07a737bc 362 void SX126X_LoRaRadio::standby(void)
brunnobbco 0:561d07a737bc 363 {
brunnobbco 0:561d07a737bc 364 if (_operation_mode == MODE_STDBY_RC) {
brunnobbco 0:561d07a737bc 365 return;
brunnobbco 0:561d07a737bc 366 }
brunnobbco 0:561d07a737bc 367
brunnobbco 0:561d07a737bc 368 set_device_ready();
brunnobbco 0:561d07a737bc 369 uint8_t standby_mode = MBED_CONF_SX126X_LORA_DRIVER_STANDBY_MODE;
brunnobbco 0:561d07a737bc 370 write_opmode_command((uint8_t) RADIO_SET_STANDBY, &standby_mode, 1);
brunnobbco 0:561d07a737bc 371
brunnobbco 0:561d07a737bc 372 if (standby_mode == STDBY_RC) {
brunnobbco 0:561d07a737bc 373 _operation_mode = MODE_STDBY_RC;
brunnobbco 0:561d07a737bc 374 } else {
brunnobbco 0:561d07a737bc 375 _operation_mode = MODE_STDBY_XOSC;
brunnobbco 0:561d07a737bc 376 }
brunnobbco 0:561d07a737bc 377 }
brunnobbco 0:561d07a737bc 378
brunnobbco 0:561d07a737bc 379 void SX126X_LoRaRadio::set_dio2_as_rfswitch_ctrl(uint8_t enable)
brunnobbco 0:561d07a737bc 380 {
brunnobbco 0:561d07a737bc 381 write_opmode_command(RADIO_SET_RFSWITCHMODE, &enable, 1);
brunnobbco 0:561d07a737bc 382 }
brunnobbco 0:561d07a737bc 383
brunnobbco 0:561d07a737bc 384 void SX126X_LoRaRadio::set_dio3_as_tcxo_ctrl(radio_TCXO_ctrl_voltage_t voltage,
brunnobbco 0:561d07a737bc 385 uint32_t timeout)
brunnobbco 0:561d07a737bc 386 {
brunnobbco 0:561d07a737bc 387 uint8_t buf[4];
brunnobbco 0:561d07a737bc 388
brunnobbco 0:561d07a737bc 389 buf[0] = voltage & 0x07;
brunnobbco 0:561d07a737bc 390 buf[1] = (uint8_t) ((timeout >> 16) & 0xFF);
brunnobbco 0:561d07a737bc 391 buf[2] = (uint8_t) ((timeout >> 8) & 0xFF);
brunnobbco 0:561d07a737bc 392 buf[3] = (uint8_t) (timeout & 0xFF);
brunnobbco 0:561d07a737bc 393
brunnobbco 0:561d07a737bc 394 write_opmode_command(RADIO_SET_TCXOMODE, buf, 4);
brunnobbco 0:561d07a737bc 395 }
brunnobbco 0:561d07a737bc 396
brunnobbco 0:561d07a737bc 397 void SX126X_LoRaRadio::init_radio(radio_events_t *events)
brunnobbco 0:561d07a737bc 398 {
brunnobbco 0:561d07a737bc 399 _radio_events = events;
brunnobbco 0:561d07a737bc 400
brunnobbco 0:561d07a737bc 401 // attach DIO1 interrupt line to its respective ISR
brunnobbco 0:561d07a737bc 402 _dio1_ctl.rise(callback(this, &SX126X_LoRaRadio::dio1_irq_isr));
brunnobbco 0:561d07a737bc 403
brunnobbco 0:561d07a737bc 404 uint8_t freq_support = get_frequency_support();
brunnobbco 0:561d07a737bc 405
brunnobbco 0:561d07a737bc 406 // Hold chip-select high
brunnobbco 0:561d07a737bc 407 _chip_select = 1;
brunnobbco 0:561d07a737bc 408 _spi.format(8, 0);
brunnobbco 0:561d07a737bc 409 _spi.frequency(SPI_FREQUENCY);
brunnobbco 0:561d07a737bc 410 // 100 us wait to settle down
brunnobbco 0:561d07a737bc 411 wait_us(100);
brunnobbco 0:561d07a737bc 412
brunnobbco 0:561d07a737bc 413 radio_reset();
brunnobbco 0:561d07a737bc 414
brunnobbco 0:561d07a737bc 415 #if MBED_CONF_LORA_PUBLIC_NETWORK
brunnobbco 0:561d07a737bc 416 _network_mode_public = true;
brunnobbco 0:561d07a737bc 417 #else
brunnobbco 0:561d07a737bc 418 _network_mode_public = false;
brunnobbco 0:561d07a737bc 419 #endif
brunnobbco 0:561d07a737bc 420
brunnobbco 0:561d07a737bc 421 // this is a POR sequence
brunnobbco 0:561d07a737bc 422 cold_start_wakeup();
brunnobbco 0:561d07a737bc 423 }
brunnobbco 0:561d07a737bc 424
brunnobbco 0:561d07a737bc 425 void SX126X_LoRaRadio::cold_start_wakeup()
brunnobbco 0:561d07a737bc 426 {
brunnobbco 0:561d07a737bc 427 uint8_t regulator_mode = MBED_CONF_SX126X_LORA_DRIVER_REGULATOR_MODE;
brunnobbco 0:561d07a737bc 428 write_opmode_command(RADIO_SET_REGULATORMODE, &regulator_mode, 1);
brunnobbco 0:561d07a737bc 429 set_buffer_base_addr(0x00, 0x00);
brunnobbco 0:561d07a737bc 430
brunnobbco 0:561d07a737bc 431 if (_crystal_select.is_connected() && _crystal_select == 0) {
brunnobbco 0:561d07a737bc 432 caliberation_params_t calib_param;
brunnobbco 0:561d07a737bc 433 set_dio3_as_tcxo_ctrl(TCXO_CTRL_1_7V, 320); //5 ms
brunnobbco 0:561d07a737bc 434 calib_param.value = 0x7F;
brunnobbco 0:561d07a737bc 435 write_opmode_command(RADIO_CALIBRATE, &calib_param.value, 1);
brunnobbco 0:561d07a737bc 436 }
brunnobbco 0:561d07a737bc 437
brunnobbco 0:561d07a737bc 438 set_dio2_as_rfswitch_ctrl(true);
brunnobbco 0:561d07a737bc 439
brunnobbco 0:561d07a737bc 440 _operation_mode = MODE_STDBY_RC;
brunnobbco 0:561d07a737bc 441
brunnobbco 0:561d07a737bc 442 set_modem(_active_modem);
brunnobbco 0:561d07a737bc 443
brunnobbco 0:561d07a737bc 444 if (_active_modem == MODEM_LORA) {
brunnobbco 0:561d07a737bc 445 set_public_network(_network_mode_public);
brunnobbco 0:561d07a737bc 446 }
brunnobbco 0:561d07a737bc 447 }
brunnobbco 0:561d07a737bc 448
brunnobbco 0:561d07a737bc 449 void SX126X_LoRaRadio::set_public_network(bool enable)
brunnobbco 0:561d07a737bc 450 {
brunnobbco 0:561d07a737bc 451 if (enable) {
brunnobbco 0:561d07a737bc 452 // Change LoRa modem SyncWord
brunnobbco 0:561d07a737bc 453 write_to_register(REG_LR_SYNCWORD, (LORA_MAC_PUBLIC_SYNCWORD >> 8) & 0xFF);
brunnobbco 0:561d07a737bc 454 write_to_register(REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF);
brunnobbco 0:561d07a737bc 455 } else {
brunnobbco 0:561d07a737bc 456 // Change LoRa modem SyncWord
brunnobbco 0:561d07a737bc 457 write_to_register(REG_LR_SYNCWORD, (LORA_MAC_PRIVATE_SYNCWORD >> 8) & 0xFF);
brunnobbco 0:561d07a737bc 458 write_to_register(REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF);
brunnobbco 0:561d07a737bc 459 }
brunnobbco 0:561d07a737bc 460 }
brunnobbco 0:561d07a737bc 461
brunnobbco 0:561d07a737bc 462 uint32_t SX126X_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len)
brunnobbco 0:561d07a737bc 463 {
brunnobbco 0:561d07a737bc 464 uint32_t air_time = 0;
brunnobbco 0:561d07a737bc 465
brunnobbco 0:561d07a737bc 466 switch (modem) {
brunnobbco 0:561d07a737bc 467 case MODEM_FSK: {
brunnobbco 0:561d07a737bc 468 air_time = rint((8 * (_packet_params.params.gfsk.preamble_length
brunnobbco 0:561d07a737bc 469 + (_packet_params.params.gfsk.syncword_length >> 3)
brunnobbco 0:561d07a737bc 470 + ((_packet_params.params.gfsk.header_type
brunnobbco 0:561d07a737bc 471 == RADIO_PACKET_FIXED_LENGTH) ? 0.0f : 1.0f) + pkt_len
brunnobbco 0:561d07a737bc 472 + ((_packet_params.params.gfsk.crc_length == RADIO_CRC_2_BYTES) ? 2.0f : 0.0f))
brunnobbco 0:561d07a737bc 473 / _mod_params.params.gfsk.bit_rate) * 1000);
brunnobbco 0:561d07a737bc 474 }
brunnobbco 0:561d07a737bc 475 break;
brunnobbco 0:561d07a737bc 476 case MODEM_LORA: {
brunnobbco 0:561d07a737bc 477 float ts = lora_symbol_time[_mod_params.params.lora.bandwidth - 4][12
brunnobbco 0:561d07a737bc 478 - _mod_params.params.lora.spreading_factor];
brunnobbco 0:561d07a737bc 479 // time of preamble
brunnobbco 0:561d07a737bc 480 float t_preamble = (_packet_params.params.lora.preamble_length + 4.25f) * ts;
brunnobbco 0:561d07a737bc 481 // Symbol length of payload and time
brunnobbco 0:561d07a737bc 482 float tmp = ceil((8 * pkt_len - 4 * _mod_params.params.lora.spreading_factor
brunnobbco 0:561d07a737bc 483 + 28 + 16 * _packet_params.params.lora.crc_mode
brunnobbco 0:561d07a737bc 484 - ((_packet_params.params.lora.header_type == LORA_PACKET_FIXED_LENGTH) ? 20 : 0))
brunnobbco 0:561d07a737bc 485 / (float) (4 * (_mod_params.params.lora.spreading_factor
brunnobbco 0:561d07a737bc 486 - ((_mod_params.params.lora.low_datarate_optimization > 0) ? 2 : 0))))
brunnobbco 0:561d07a737bc 487 * ((_mod_params.params.lora.coding_rate % 4) + 4);
brunnobbco 0:561d07a737bc 488 float n_payload = 8 + ((tmp > 0) ? tmp : 0);
brunnobbco 0:561d07a737bc 489 float t_payload = n_payload * ts;
brunnobbco 0:561d07a737bc 490 // Time on air
brunnobbco 0:561d07a737bc 491 float tOnAir = t_preamble + t_payload;
brunnobbco 0:561d07a737bc 492 // return milliseconds (as ts is in milliseconds)
brunnobbco 0:561d07a737bc 493 air_time = floor(tOnAir + 0.999);
brunnobbco 0:561d07a737bc 494 }
brunnobbco 0:561d07a737bc 495 break;
brunnobbco 0:561d07a737bc 496 }
brunnobbco 0:561d07a737bc 497
brunnobbco 0:561d07a737bc 498 return air_time;
brunnobbco 0:561d07a737bc 499 }
brunnobbco 0:561d07a737bc 500
brunnobbco 0:561d07a737bc 501 void SX126X_LoRaRadio::radio_reset()
brunnobbco 0:561d07a737bc 502 {
brunnobbco 0:561d07a737bc 503 _reset_ctl.output();
brunnobbco 0:561d07a737bc 504 _reset_ctl = 0;
brunnobbco 0:561d07a737bc 505 // should be enough, required is 50-100 us
brunnobbco 0:561d07a737bc 506 wait_ms(2);
brunnobbco 0:561d07a737bc 507 _reset_ctl.input();
brunnobbco 0:561d07a737bc 508 // give some time for automatic image calibration
brunnobbco 0:561d07a737bc 509 wait_ms(6);
brunnobbco 0:561d07a737bc 510 }
brunnobbco 0:561d07a737bc 511
brunnobbco 0:561d07a737bc 512 void SX126X_LoRaRadio::wakeup()
brunnobbco 0:561d07a737bc 513 {
brunnobbco 0:561d07a737bc 514 // hold the NSS low, this should wakeup the chip.
brunnobbco 0:561d07a737bc 515 // now we should wait for the _busy line to go low
brunnobbco 0:561d07a737bc 516 if (_operation_mode == MODE_SLEEP) {
brunnobbco 0:561d07a737bc 517 _chip_select = 0;
brunnobbco 0:561d07a737bc 518 wait_us(100);
brunnobbco 0:561d07a737bc 519 _chip_select = 1;
brunnobbco 0:561d07a737bc 520 //wait_us(100);
brunnobbco 0:561d07a737bc 521 #if MBED_CONF_SX126X_LORA_DRIVER_SLEEP_MODE == 1
brunnobbco 0:561d07a737bc 522 wait_us(3500);
brunnobbco 0:561d07a737bc 523 // whenever we wakeup from Cold sleep state, we need to perform
brunnobbco 0:561d07a737bc 524 // image calibration
brunnobbco 0:561d07a737bc 525 _force_image_calibration = true;
brunnobbco 0:561d07a737bc 526 cold_start_wakeup();
brunnobbco 0:561d07a737bc 527 #endif
brunnobbco 0:561d07a737bc 528 }
brunnobbco 0:561d07a737bc 529 }
brunnobbco 0:561d07a737bc 530
brunnobbco 0:561d07a737bc 531 void SX126X_LoRaRadio::sleep(void)
brunnobbco 0:561d07a737bc 532 {
brunnobbco 0:561d07a737bc 533 // warm start, power consumption 600 nA
brunnobbco 0:561d07a737bc 534 uint8_t sleep_state = 0x04;
brunnobbco 0:561d07a737bc 535 _operation_mode = MODE_SLEEP;
brunnobbco 0:561d07a737bc 536
brunnobbco 0:561d07a737bc 537 #if MBED_CONF_SX126X_LORA_DRIVER_SLEEP_MODE == 1
brunnobbco 0:561d07a737bc 538 // cold start, power consumption 160 nA
brunnobbco 0:561d07a737bc 539 sleep_state = 0x00;
brunnobbco 0:561d07a737bc 540 #endif
brunnobbco 0:561d07a737bc 541
brunnobbco 0:561d07a737bc 542 write_opmode_command(RADIO_SET_SLEEP, &sleep_state, 1);
brunnobbco 0:561d07a737bc 543 wait_ms(2);
brunnobbco 0:561d07a737bc 544 }
brunnobbco 0:561d07a737bc 545
brunnobbco 0:561d07a737bc 546 uint32_t SX126X_LoRaRadio::random(void)
brunnobbco 0:561d07a737bc 547 {
brunnobbco 0:561d07a737bc 548 set_modem(MODEM_LORA);
brunnobbco 0:561d07a737bc 549 uint8_t buf[] = {0, 0, 0, 0};
brunnobbco 0:561d07a737bc 550
brunnobbco 0:561d07a737bc 551 // Set radio in continuous reception
brunnobbco 0:561d07a737bc 552 _reception_mode = RECEPTION_MODE_OTHER;
brunnobbco 0:561d07a737bc 553 _rx_timeout = 0xFFFFFFFF;
brunnobbco 0:561d07a737bc 554 receive();
brunnobbco 0:561d07a737bc 555 wait_ms(1);
brunnobbco 0:561d07a737bc 556 read_register(RANDOM_NUMBER_GENERATORBASEADDR, buf, 4);
brunnobbco 0:561d07a737bc 557 standby();
brunnobbco 0:561d07a737bc 558
brunnobbco 0:561d07a737bc 559 return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
brunnobbco 0:561d07a737bc 560 }
brunnobbco 0:561d07a737bc 561
brunnobbco 0:561d07a737bc 562 void SX126X_LoRaRadio::write_opmode_command(uint8_t cmd, uint8_t *buffer, uint16_t size)
brunnobbco 0:561d07a737bc 563 {
brunnobbco 0:561d07a737bc 564 _chip_select = 0;
brunnobbco 0:561d07a737bc 565
brunnobbco 0:561d07a737bc 566 while (_busy) {
brunnobbco 0:561d07a737bc 567 // do nothing
brunnobbco 0:561d07a737bc 568 }
brunnobbco 0:561d07a737bc 569
brunnobbco 0:561d07a737bc 570 _spi.write(cmd);
brunnobbco 0:561d07a737bc 571
brunnobbco 0:561d07a737bc 572 for (int i = 0; i < size; i++) {
brunnobbco 0:561d07a737bc 573 _spi.write(buffer[i]);
brunnobbco 0:561d07a737bc 574 }
brunnobbco 0:561d07a737bc 575
brunnobbco 0:561d07a737bc 576 _chip_select = 1;
brunnobbco 0:561d07a737bc 577 }
brunnobbco 0:561d07a737bc 578
brunnobbco 0:561d07a737bc 579 void SX126X_LoRaRadio::read_opmode_command(uint8_t cmd,
brunnobbco 0:561d07a737bc 580 uint8_t *buffer, uint16_t size)
brunnobbco 0:561d07a737bc 581 {
brunnobbco 0:561d07a737bc 582 _chip_select = 0;
brunnobbco 0:561d07a737bc 583
brunnobbco 0:561d07a737bc 584 while (_busy) {
brunnobbco 0:561d07a737bc 585 // do nothing
brunnobbco 0:561d07a737bc 586 }
brunnobbco 0:561d07a737bc 587
brunnobbco 0:561d07a737bc 588 _spi.write(cmd);
brunnobbco 0:561d07a737bc 589 _spi.write(0);
brunnobbco 0:561d07a737bc 590
brunnobbco 0:561d07a737bc 591 for (int i = 0; i < size; i++) {
brunnobbco 0:561d07a737bc 592 buffer[i] = _spi.write(0);
brunnobbco 0:561d07a737bc 593 }
brunnobbco 0:561d07a737bc 594
brunnobbco 0:561d07a737bc 595 _chip_select = 1;
brunnobbco 0:561d07a737bc 596 }
brunnobbco 0:561d07a737bc 597
brunnobbco 0:561d07a737bc 598 void SX126X_LoRaRadio::write_to_register(uint16_t addr, uint8_t data)
brunnobbco 0:561d07a737bc 599 {
brunnobbco 0:561d07a737bc 600 write_to_register(addr, &data, 1);
brunnobbco 0:561d07a737bc 601 }
brunnobbco 0:561d07a737bc 602
brunnobbco 0:561d07a737bc 603 void SX126X_LoRaRadio::write_to_register(uint16_t addr, uint8_t *data,
brunnobbco 0:561d07a737bc 604 uint8_t size)
brunnobbco 0:561d07a737bc 605 {
brunnobbco 0:561d07a737bc 606 _chip_select = 0;
brunnobbco 0:561d07a737bc 607
brunnobbco 0:561d07a737bc 608 _spi.write(RADIO_WRITE_REGISTER);
brunnobbco 0:561d07a737bc 609 _spi.write((addr & 0xFF00) >> 8);
brunnobbco 0:561d07a737bc 610 _spi.write(addr & 0x00FF);
brunnobbco 0:561d07a737bc 611
brunnobbco 0:561d07a737bc 612 for (int i = 0; i < size; i++) {
brunnobbco 0:561d07a737bc 613 _spi.write(data[i]);
brunnobbco 0:561d07a737bc 614 }
brunnobbco 0:561d07a737bc 615
brunnobbco 0:561d07a737bc 616 _chip_select = 1;
brunnobbco 0:561d07a737bc 617 }
brunnobbco 0:561d07a737bc 618
brunnobbco 0:561d07a737bc 619 uint8_t SX126X_LoRaRadio::read_register(uint16_t addr)
brunnobbco 0:561d07a737bc 620 {
brunnobbco 0:561d07a737bc 621 uint8_t data;
brunnobbco 0:561d07a737bc 622 read_register(addr, &data, 1);
brunnobbco 0:561d07a737bc 623 return data;
brunnobbco 0:561d07a737bc 624
brunnobbco 0:561d07a737bc 625 }
brunnobbco 0:561d07a737bc 626
brunnobbco 0:561d07a737bc 627 void SX126X_LoRaRadio::read_register(uint16_t addr, uint8_t *buffer,
brunnobbco 0:561d07a737bc 628 uint8_t size)
brunnobbco 0:561d07a737bc 629 {
brunnobbco 0:561d07a737bc 630 _chip_select = 0;
brunnobbco 0:561d07a737bc 631
brunnobbco 0:561d07a737bc 632 _spi.write(RADIO_READ_REGISTER);
brunnobbco 0:561d07a737bc 633 _spi.write((addr & 0xFF00) >> 8);
brunnobbco 0:561d07a737bc 634 _spi.write(addr & 0x00FF);
brunnobbco 0:561d07a737bc 635 _spi.write(0);
brunnobbco 0:561d07a737bc 636
brunnobbco 0:561d07a737bc 637 for (int i = 0; i < size; i++) {
brunnobbco 0:561d07a737bc 638 buffer[i] = _spi.write(0);
brunnobbco 0:561d07a737bc 639 }
brunnobbco 0:561d07a737bc 640
brunnobbco 0:561d07a737bc 641 _chip_select = 1;
brunnobbco 0:561d07a737bc 642 }
brunnobbco 0:561d07a737bc 643
brunnobbco 0:561d07a737bc 644 void SX126X_LoRaRadio::write_fifo(uint8_t *buffer, uint8_t size)
brunnobbco 0:561d07a737bc 645 {
brunnobbco 0:561d07a737bc 646 _chip_select = 0;
brunnobbco 0:561d07a737bc 647
brunnobbco 0:561d07a737bc 648 _spi.write(RADIO_WRITE_BUFFER);
brunnobbco 0:561d07a737bc 649 _spi.write(0);
brunnobbco 0:561d07a737bc 650
brunnobbco 0:561d07a737bc 651 for (int i = 0; i < size; i++) {
brunnobbco 0:561d07a737bc 652 _spi.write(buffer[i]);
brunnobbco 0:561d07a737bc 653 }
brunnobbco 0:561d07a737bc 654
brunnobbco 0:561d07a737bc 655 _chip_select = 1;
brunnobbco 0:561d07a737bc 656 }
brunnobbco 0:561d07a737bc 657
brunnobbco 0:561d07a737bc 658 void SX126X_LoRaRadio::set_modem(uint8_t modem)
brunnobbco 0:561d07a737bc 659 {
brunnobbco 0:561d07a737bc 660 _active_modem = modem;
brunnobbco 0:561d07a737bc 661
brunnobbco 0:561d07a737bc 662 // setting modem type must happen in stnadby mode
brunnobbco 0:561d07a737bc 663 if (_operation_mode != MODE_STDBY_RC) {
brunnobbco 0:561d07a737bc 664 standby();
brunnobbco 0:561d07a737bc 665 }
brunnobbco 0:561d07a737bc 666
brunnobbco 0:561d07a737bc 667 write_opmode_command(RADIO_SET_PACKETTYPE, &_active_modem, 1);
brunnobbco 0:561d07a737bc 668 }
brunnobbco 0:561d07a737bc 669
brunnobbco 0:561d07a737bc 670 uint8_t SX126X_LoRaRadio::get_modem()
brunnobbco 0:561d07a737bc 671 {
brunnobbco 0:561d07a737bc 672 return _active_modem;
brunnobbco 0:561d07a737bc 673 }
brunnobbco 0:561d07a737bc 674
brunnobbco 0:561d07a737bc 675 void SX126X_LoRaRadio::read_fifo(uint8_t *buffer, uint8_t size, uint8_t offset)
brunnobbco 0:561d07a737bc 676 {
brunnobbco 0:561d07a737bc 677 _chip_select = 0;
brunnobbco 0:561d07a737bc 678
brunnobbco 0:561d07a737bc 679 _spi.write(RADIO_READ_BUFFER);
brunnobbco 0:561d07a737bc 680 _spi.write(offset);
brunnobbco 0:561d07a737bc 681 _spi.write(0);
brunnobbco 0:561d07a737bc 682
brunnobbco 0:561d07a737bc 683 for (int i = 0; i < size; i++) {
brunnobbco 0:561d07a737bc 684 buffer[i] = _spi.write(0);
brunnobbco 0:561d07a737bc 685 }
brunnobbco 0:561d07a737bc 686
brunnobbco 0:561d07a737bc 687 _chip_select = 1;
brunnobbco 0:561d07a737bc 688 }
brunnobbco 0:561d07a737bc 689
brunnobbco 0:561d07a737bc 690 uint8_t SX126X_LoRaRadio::get_device_variant(void)
brunnobbco 0:561d07a737bc 691 {
brunnobbco 0:561d07a737bc 692 uint16_t val = 0;
brunnobbco 0:561d07a737bc 693 val = _dev_select.read_u16();
brunnobbco 0:561d07a737bc 694
brunnobbco 0:561d07a737bc 695 if (val <= 0x2000) {
brunnobbco 0:561d07a737bc 696 return SX1262;
brunnobbco 0:561d07a737bc 697 } else if (val <= 0xA000) {
brunnobbco 0:561d07a737bc 698 return SX1268;
brunnobbco 0:561d07a737bc 699 } else {
brunnobbco 0:561d07a737bc 700 return SX1261;
brunnobbco 0:561d07a737bc 701 }
brunnobbco 0:561d07a737bc 702 }
brunnobbco 0:561d07a737bc 703
brunnobbco 0:561d07a737bc 704 uint8_t SX126X_LoRaRadio::get_frequency_support(void)
brunnobbco 0:561d07a737bc 705 {
brunnobbco 0:561d07a737bc 706 uint16_t val = 0;
brunnobbco 0:561d07a737bc 707 val = _freq_select.read_u16();
brunnobbco 0:561d07a737bc 708
brunnobbco 0:561d07a737bc 709 if (val < 100) {
brunnobbco 0:561d07a737bc 710 return ( MATCHING_FREQ_915);
brunnobbco 0:561d07a737bc 711 } else if (val <= 0x3000) {
brunnobbco 0:561d07a737bc 712 return ( MATCHING_FREQ_780);
brunnobbco 0:561d07a737bc 713 } else if (val <= 0x4900) { // 0x4724
brunnobbco 0:561d07a737bc 714 return ( MATCHING_FREQ_490);
brunnobbco 0:561d07a737bc 715 } else if (val <= 1) {
brunnobbco 0:561d07a737bc 716 return ( MATCHING_FREQ_434);
brunnobbco 0:561d07a737bc 717 } else if (val <= 1) {
brunnobbco 0:561d07a737bc 718 return ( MATCHING_FREQ_280);
brunnobbco 0:561d07a737bc 719 } else if (val <= 0xF000) {
brunnobbco 0:561d07a737bc 720 return ( MATCHING_FREQ_169);
brunnobbco 0:561d07a737bc 721 } else {
brunnobbco 0:561d07a737bc 722 return ( MATCHING_FREQ_868);
brunnobbco 0:561d07a737bc 723 }
brunnobbco 0:561d07a737bc 724 }
brunnobbco 0:561d07a737bc 725
brunnobbco 0:561d07a737bc 726 uint8_t SX126X_LoRaRadio::get_fsk_bw_reg_val(uint32_t bandwidth)
brunnobbco 0:561d07a737bc 727 {
brunnobbco 0:561d07a737bc 728 uint8_t i;
brunnobbco 0:561d07a737bc 729
brunnobbco 0:561d07a737bc 730 for (i = 0; i < (sizeof(fsk_bandwidths) / sizeof(fsk_bw_t)) - 1; i++) {
brunnobbco 0:561d07a737bc 731 if ((bandwidth >= fsk_bandwidths[i].bandwidth)
brunnobbco 0:561d07a737bc 732 && (bandwidth < fsk_bandwidths[i + 1].bandwidth)) {
brunnobbco 0:561d07a737bc 733 return fsk_bandwidths[i].register_value;
brunnobbco 0:561d07a737bc 734 }
brunnobbco 0:561d07a737bc 735 }
brunnobbco 0:561d07a737bc 736 // ERROR: Value not found
brunnobbco 0:561d07a737bc 737 // This should never happen
brunnobbco 0:561d07a737bc 738 while (1);
brunnobbco 0:561d07a737bc 739 }
brunnobbco 0:561d07a737bc 740
brunnobbco 0:561d07a737bc 741 void SX126X_LoRaRadio::set_max_payload_length(radio_modems_t modem, uint8_t max)
brunnobbco 0:561d07a737bc 742 {
brunnobbco 0:561d07a737bc 743 if (modem == MODEM_LORA) {
brunnobbco 0:561d07a737bc 744 _packet_params.params.lora.payload_length = max;
brunnobbco 0:561d07a737bc 745 } else {
brunnobbco 0:561d07a737bc 746 _packet_params.params.gfsk.payload_length = max;
brunnobbco 0:561d07a737bc 747 }
brunnobbco 0:561d07a737bc 748 }
brunnobbco 0:561d07a737bc 749
brunnobbco 0:561d07a737bc 750 void SX126X_LoRaRadio::set_tx_config(radio_modems_t modem,
brunnobbco 0:561d07a737bc 751 int8_t power,
brunnobbco 0:561d07a737bc 752 uint32_t fdev,
brunnobbco 0:561d07a737bc 753 uint32_t bandwidth,
brunnobbco 0:561d07a737bc 754 uint32_t datarate,
brunnobbco 0:561d07a737bc 755 uint8_t coderate,
brunnobbco 0:561d07a737bc 756 uint16_t preamble_len,
brunnobbco 0:561d07a737bc 757 bool fix_len,
brunnobbco 0:561d07a737bc 758 bool crc_on,
brunnobbco 0:561d07a737bc 759 bool freq_hop_on,
brunnobbco 0:561d07a737bc 760 uint8_t hop_period,
brunnobbco 0:561d07a737bc 761 bool iq_inverted,
brunnobbco 0:561d07a737bc 762 uint32_t timeout)
brunnobbco 0:561d07a737bc 763 {
brunnobbco 0:561d07a737bc 764
brunnobbco 0:561d07a737bc 765 uint8_t modem_type = (uint8_t) modem;
brunnobbco 0:561d07a737bc 766 switch (modem_type) {
brunnobbco 0:561d07a737bc 767 case MODEM_FSK:
brunnobbco 0:561d07a737bc 768 _mod_params.modem_type = MODEM_FSK;
brunnobbco 0:561d07a737bc 769 _mod_params.params.gfsk.bit_rate = datarate;
brunnobbco 0:561d07a737bc 770
brunnobbco 0:561d07a737bc 771 _mod_params.params.gfsk.modulation_shaping = MOD_SHAPING_G_BT_1;
brunnobbco 0:561d07a737bc 772 _mod_params.params.gfsk.bandwidth = get_fsk_bw_reg_val(bandwidth);
brunnobbco 0:561d07a737bc 773 _mod_params.params.gfsk.fdev = fdev;
brunnobbco 0:561d07a737bc 774
brunnobbco 0:561d07a737bc 775 _packet_params.modem_type = MODEM_FSK;
brunnobbco 0:561d07a737bc 776 _packet_params.params.gfsk.preamble_length = (preamble_len << 3); // convert byte into bit
brunnobbco 0:561d07a737bc 777 _packet_params.params.gfsk.preamble_min_detect = RADIO_PREAMBLE_DETECTOR_08_BITS;
brunnobbco 0:561d07a737bc 778 _packet_params.params.gfsk.syncword_length = 3 << 3; // convert byte into bit
brunnobbco 0:561d07a737bc 779 _packet_params.params.gfsk.addr_comp = RADIO_ADDRESSCOMP_FILT_OFF;
brunnobbco 0:561d07a737bc 780 _packet_params.params.gfsk.header_type = (fix_len == true) ?
brunnobbco 0:561d07a737bc 781 RADIO_PACKET_FIXED_LENGTH :
brunnobbco 0:561d07a737bc 782 RADIO_PACKET_VARIABLE_LENGTH;
brunnobbco 0:561d07a737bc 783
brunnobbco 0:561d07a737bc 784 if (crc_on) {
brunnobbco 0:561d07a737bc 785 _packet_params.params.gfsk.crc_length = RADIO_CRC_2_BYTES_CCIT;
brunnobbco 0:561d07a737bc 786 } else {
brunnobbco 0:561d07a737bc 787 _packet_params.params.gfsk.crc_length = RADIO_CRC_OFF;
brunnobbco 0:561d07a737bc 788 }
brunnobbco 0:561d07a737bc 789 _packet_params.params.gfsk.whitening_mode = RADIO_DC_FREEWHITENING;
brunnobbco 0:561d07a737bc 790
brunnobbco 0:561d07a737bc 791 set_modem(MODEM_FSK);
brunnobbco 0:561d07a737bc 792
brunnobbco 0:561d07a737bc 793 write_to_register(REG_LR_SYNCWORDBASEADDRESS, (uint8_t *) sync_word, 8);
brunnobbco 0:561d07a737bc 794 set_whitening_seed(0x01FF);
brunnobbco 0:561d07a737bc 795 break;
brunnobbco 0:561d07a737bc 796
brunnobbco 0:561d07a737bc 797 case MODEM_LORA:
brunnobbco 0:561d07a737bc 798 _mod_params.modem_type = MODEM_LORA;
brunnobbco 0:561d07a737bc 799 _mod_params.params.lora.spreading_factor = (lora_spread_factors_t) datarate;
brunnobbco 0:561d07a737bc 800 _mod_params.params.lora.bandwidth = (lora_bandwidths_t) lora_bandwidhts[bandwidth];
brunnobbco 0:561d07a737bc 801 _mod_params.params.lora.coding_rate = (lora_coding_tates_t) coderate;
brunnobbco 0:561d07a737bc 802
brunnobbco 0:561d07a737bc 803 if (((bandwidth == 0) && ((datarate == 11) || (datarate == 12)))
brunnobbco 0:561d07a737bc 804 || ((bandwidth == 1) && (datarate == 12))) {
brunnobbco 0:561d07a737bc 805 _mod_params.params.lora.low_datarate_optimization = 0x01;
brunnobbco 0:561d07a737bc 806 } else {
brunnobbco 0:561d07a737bc 807 _mod_params.params.lora.low_datarate_optimization = 0x00;
brunnobbco 0:561d07a737bc 808 }
brunnobbco 0:561d07a737bc 809
brunnobbco 0:561d07a737bc 810 _packet_params.modem_type = MODEM_LORA;
brunnobbco 0:561d07a737bc 811
brunnobbco 0:561d07a737bc 812 if ((_mod_params.params.lora.spreading_factor == LORA_SF5)
brunnobbco 0:561d07a737bc 813 || (_mod_params.params.lora.spreading_factor == LORA_SF6)) {
brunnobbco 0:561d07a737bc 814 if (preamble_len < 12) {
brunnobbco 0:561d07a737bc 815 _packet_params.params.lora.preamble_length = 12;
brunnobbco 0:561d07a737bc 816 } else {
brunnobbco 0:561d07a737bc 817 _packet_params.params.lora.preamble_length = preamble_len;
brunnobbco 0:561d07a737bc 818 }
brunnobbco 0:561d07a737bc 819 } else {
brunnobbco 0:561d07a737bc 820 _packet_params.params.lora.preamble_length = preamble_len;
brunnobbco 0:561d07a737bc 821 }
brunnobbco 0:561d07a737bc 822
brunnobbco 0:561d07a737bc 823 _packet_params.params.lora.header_type = (lora_pkt_length_t) fix_len;
brunnobbco 0:561d07a737bc 824 _packet_params.params.lora.crc_mode = (lora_crc_mode_t) crc_on;
brunnobbco 0:561d07a737bc 825 _packet_params.params.lora.invert_IQ = (lora_IQ_mode_t) iq_inverted;
brunnobbco 0:561d07a737bc 826
brunnobbco 0:561d07a737bc 827 set_modem(MODEM_LORA);
brunnobbco 0:561d07a737bc 828
brunnobbco 0:561d07a737bc 829 break;
brunnobbco 0:561d07a737bc 830 }
brunnobbco 0:561d07a737bc 831
brunnobbco 0:561d07a737bc 832 _tx_power = power;
brunnobbco 0:561d07a737bc 833 _tx_timeout = timeout;
brunnobbco 0:561d07a737bc 834 }
brunnobbco 0:561d07a737bc 835
brunnobbco 0:561d07a737bc 836 void SX126X_LoRaRadio::set_rx_config(radio_modems_t modem,
brunnobbco 0:561d07a737bc 837 uint32_t bandwidth,
brunnobbco 0:561d07a737bc 838 uint32_t datarate,
brunnobbco 0:561d07a737bc 839 uint8_t coderate,
brunnobbco 0:561d07a737bc 840 uint32_t bandwidthAfc,
brunnobbco 0:561d07a737bc 841 uint16_t preamble_len,
brunnobbco 0:561d07a737bc 842 uint16_t symb_timeout,
brunnobbco 0:561d07a737bc 843 bool fix_len,
brunnobbco 0:561d07a737bc 844 uint8_t payload_len,
brunnobbco 0:561d07a737bc 845 bool crc_on,
brunnobbco 0:561d07a737bc 846 bool freq_hop_on,
brunnobbco 0:561d07a737bc 847 uint8_t hop_period,
brunnobbco 0:561d07a737bc 848 bool iq_inverted,
brunnobbco 0:561d07a737bc 849 bool rx_continuous)
brunnobbco 0:561d07a737bc 850 {
brunnobbco 0:561d07a737bc 851 uint8_t max_payload_len;
brunnobbco 0:561d07a737bc 852 (void) freq_hop_on;
brunnobbco 0:561d07a737bc 853 (void) hop_period;
brunnobbco 0:561d07a737bc 854
brunnobbco 0:561d07a737bc 855 if (rx_continuous) {
brunnobbco 0:561d07a737bc 856 _reception_mode = RECEPTION_MODE_CONTINUOUS;
brunnobbco 0:561d07a737bc 857 } else {
brunnobbco 0:561d07a737bc 858 _reception_mode = RECEPTION_MODE_SINGLE;
brunnobbco 0:561d07a737bc 859 }
brunnobbco 0:561d07a737bc 860
brunnobbco 0:561d07a737bc 861 if (fix_len == true) {
brunnobbco 0:561d07a737bc 862 max_payload_len = payload_len;
brunnobbco 0:561d07a737bc 863 } else {
brunnobbco 0:561d07a737bc 864 max_payload_len = 0xFF;
brunnobbco 0:561d07a737bc 865 }
brunnobbco 0:561d07a737bc 866
brunnobbco 0:561d07a737bc 867 uint8_t modem_type = (uint8_t) modem;
brunnobbco 0:561d07a737bc 868
brunnobbco 0:561d07a737bc 869 switch (modem_type) {
brunnobbco 0:561d07a737bc 870 case MODEM_FSK: {
brunnobbco 0:561d07a737bc 871 _mod_params.modem_type = MODEM_FSK;
brunnobbco 0:561d07a737bc 872 _mod_params.params.gfsk.bit_rate = datarate;
brunnobbco 0:561d07a737bc 873 _mod_params.params.gfsk.modulation_shaping = MOD_SHAPING_G_BT_1;
brunnobbco 0:561d07a737bc 874 _mod_params.params.gfsk.bandwidth = get_fsk_bw_reg_val(bandwidth);
brunnobbco 0:561d07a737bc 875
brunnobbco 0:561d07a737bc 876 _packet_params.modem_type = MODEM_FSK;
brunnobbco 0:561d07a737bc 877 _packet_params.params.gfsk.preamble_length = (preamble_len << 3); // convert byte into bit
brunnobbco 0:561d07a737bc 878 _packet_params.params.gfsk.preamble_min_detect =
brunnobbco 0:561d07a737bc 879 RADIO_PREAMBLE_DETECTOR_08_BITS;
brunnobbco 0:561d07a737bc 880 _packet_params.params.gfsk.syncword_length = 3 << 3; // convert byte into bit
brunnobbco 0:561d07a737bc 881 _packet_params.params.gfsk.addr_comp = RADIO_ADDRESSCOMP_FILT_OFF;
brunnobbco 0:561d07a737bc 882 _packet_params.params.gfsk.header_type =
brunnobbco 0:561d07a737bc 883 (fix_len == true) ?
brunnobbco 0:561d07a737bc 884 RADIO_PACKET_FIXED_LENGTH :
brunnobbco 0:561d07a737bc 885 RADIO_PACKET_VARIABLE_LENGTH;
brunnobbco 0:561d07a737bc 886 _packet_params.params.gfsk.payload_length = max_payload_len;
brunnobbco 0:561d07a737bc 887
brunnobbco 0:561d07a737bc 888 if (crc_on) {
brunnobbco 0:561d07a737bc 889 _packet_params.params.gfsk.crc_length = RADIO_CRC_2_BYTES_CCIT;
brunnobbco 0:561d07a737bc 890 } else {
brunnobbco 0:561d07a737bc 891 _packet_params.params.gfsk.crc_length = RADIO_CRC_OFF;
brunnobbco 0:561d07a737bc 892 }
brunnobbco 0:561d07a737bc 893
brunnobbco 0:561d07a737bc 894 _packet_params.params.gfsk.whitening_mode = RADIO_DC_FREEWHITENING;
brunnobbco 0:561d07a737bc 895
brunnobbco 0:561d07a737bc 896 set_modem(MODEM_FSK);
brunnobbco 0:561d07a737bc 897
brunnobbco 0:561d07a737bc 898 write_to_register(REG_LR_SYNCWORDBASEADDRESS, (uint8_t *) sync_word, 8);
brunnobbco 0:561d07a737bc 899 set_whitening_seed(0x01FF);
brunnobbco 0:561d07a737bc 900
brunnobbco 0:561d07a737bc 901 _rx_timeout = (uint32_t) (symb_timeout
brunnobbco 0:561d07a737bc 902 * ((1.0 / (float) datarate) * 8.0) * 1000);
brunnobbco 0:561d07a737bc 903
brunnobbco 0:561d07a737bc 904 break;
brunnobbco 0:561d07a737bc 905 }
brunnobbco 0:561d07a737bc 906
brunnobbco 0:561d07a737bc 907 case MODEM_LORA: {
brunnobbco 0:561d07a737bc 908 _rx_timeout_in_symbols = symb_timeout;
brunnobbco 0:561d07a737bc 909 _mod_params.modem_type = MODEM_LORA;
brunnobbco 0:561d07a737bc 910 _mod_params.params.lora.spreading_factor =
brunnobbco 0:561d07a737bc 911 (lora_spread_factors_t) datarate;
brunnobbco 0:561d07a737bc 912 _mod_params.params.lora.bandwidth = (lora_bandwidths_t) lora_bandwidhts[bandwidth];
brunnobbco 0:561d07a737bc 913 _mod_params.params.lora.coding_rate =
brunnobbco 0:561d07a737bc 914 (lora_coding_tates_t) coderate;
brunnobbco 0:561d07a737bc 915
brunnobbco 0:561d07a737bc 916 if (((bandwidth == 0) && ((datarate == 11) || (datarate == 12)))
brunnobbco 0:561d07a737bc 917 || ((bandwidth == 1) && (datarate == 12))) {
brunnobbco 0:561d07a737bc 918 _mod_params.params.lora.low_datarate_optimization = 0x01;
brunnobbco 0:561d07a737bc 919 } else {
brunnobbco 0:561d07a737bc 920 _mod_params.params.lora.low_datarate_optimization = 0x00;
brunnobbco 0:561d07a737bc 921 }
brunnobbco 0:561d07a737bc 922
brunnobbco 0:561d07a737bc 923 _packet_params.modem_type = MODEM_LORA;
brunnobbco 0:561d07a737bc 924
brunnobbco 0:561d07a737bc 925 if ((_mod_params.params.lora.spreading_factor == LORA_SF5)
brunnobbco 0:561d07a737bc 926 || (_mod_params.params.lora.spreading_factor == LORA_SF6)) {
brunnobbco 0:561d07a737bc 927 if (preamble_len < 12) {
brunnobbco 0:561d07a737bc 928 _packet_params.params.lora.preamble_length = 12;
brunnobbco 0:561d07a737bc 929 } else {
brunnobbco 0:561d07a737bc 930 _packet_params.params.lora.preamble_length = preamble_len;
brunnobbco 0:561d07a737bc 931 }
brunnobbco 0:561d07a737bc 932 } else {
brunnobbco 0:561d07a737bc 933 _packet_params.params.lora.preamble_length = preamble_len;
brunnobbco 0:561d07a737bc 934 }
brunnobbco 0:561d07a737bc 935
brunnobbco 0:561d07a737bc 936 _packet_params.params.lora.header_type = (lora_pkt_length_t) fix_len;
brunnobbco 0:561d07a737bc 937 _packet_params.params.lora.payload_length = max_payload_len;
brunnobbco 0:561d07a737bc 938 _packet_params.params.lora.crc_mode = (lora_crc_mode_t) crc_on;
brunnobbco 0:561d07a737bc 939 _packet_params.params.lora.invert_IQ = (lora_IQ_mode_t) iq_inverted;
brunnobbco 0:561d07a737bc 940
brunnobbco 0:561d07a737bc 941 set_modem(MODEM_LORA);
brunnobbco 0:561d07a737bc 942
brunnobbco 0:561d07a737bc 943 if (_reception_mode == RECEPTION_MODE_CONTINUOUS) {
brunnobbco 0:561d07a737bc 944 _rx_timeout = 0xFFFFFFFF;
brunnobbco 0:561d07a737bc 945 } else {
brunnobbco 0:561d07a737bc 946 _rx_timeout = 0x00000000;
brunnobbco 0:561d07a737bc 947 }
brunnobbco 0:561d07a737bc 948
brunnobbco 0:561d07a737bc 949 break;
brunnobbco 0:561d07a737bc 950 }
brunnobbco 0:561d07a737bc 951
brunnobbco 0:561d07a737bc 952 default:
brunnobbco 0:561d07a737bc 953 break;
brunnobbco 0:561d07a737bc 954 }
brunnobbco 0:561d07a737bc 955 }
brunnobbco 0:561d07a737bc 956
brunnobbco 0:561d07a737bc 957 void SX126X_LoRaRadio::configure_dio_irq(uint16_t irq_mask, uint16_t dio1_mask,
brunnobbco 0:561d07a737bc 958 uint16_t dio2_mask, uint16_t dio3_mask)
brunnobbco 0:561d07a737bc 959 {
brunnobbco 0:561d07a737bc 960 uint8_t buf[8];
brunnobbco 0:561d07a737bc 961
brunnobbco 0:561d07a737bc 962 buf[0] = (uint8_t) ((irq_mask >> 8) & 0x00FF);
brunnobbco 0:561d07a737bc 963 buf[1] = (uint8_t) (irq_mask & 0x00FF);
brunnobbco 0:561d07a737bc 964 buf[2] = (uint8_t) ((dio1_mask >> 8) & 0x00FF);
brunnobbco 0:561d07a737bc 965 buf[3] = (uint8_t) (dio1_mask & 0x00FF);
brunnobbco 0:561d07a737bc 966 buf[4] = (uint8_t) ((dio2_mask >> 8) & 0x00FF);
brunnobbco 0:561d07a737bc 967 buf[5] = (uint8_t) (dio2_mask & 0x00FF);
brunnobbco 0:561d07a737bc 968 buf[6] = (uint8_t) ((dio3_mask >> 8) & 0x00FF);
brunnobbco 0:561d07a737bc 969 buf[7] = (uint8_t) (dio3_mask & 0x00FF);
brunnobbco 0:561d07a737bc 970
brunnobbco 0:561d07a737bc 971 write_opmode_command((uint8_t) RADIO_CFG_DIOIRQ, buf, 8);
brunnobbco 0:561d07a737bc 972 }
brunnobbco 0:561d07a737bc 973
brunnobbco 0:561d07a737bc 974 void SX126X_LoRaRadio::send(uint8_t *buffer, uint8_t size)
brunnobbco 0:561d07a737bc 975 {
brunnobbco 0:561d07a737bc 976 set_tx_power(_tx_power);
brunnobbco 0:561d07a737bc 977 configure_dio_irq(IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT,
brunnobbco 0:561d07a737bc 978 IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT,
brunnobbco 0:561d07a737bc 979 IRQ_RADIO_NONE,
brunnobbco 0:561d07a737bc 980 IRQ_RADIO_NONE );
brunnobbco 0:561d07a737bc 981
brunnobbco 0:561d07a737bc 982 set_modulation_params(&_mod_params);
brunnobbco 0:561d07a737bc 983 set_packet_params(&_packet_params);
brunnobbco 0:561d07a737bc 984
brunnobbco 0:561d07a737bc 985 write_fifo(buffer, size);
brunnobbco 0:561d07a737bc 986 uint8_t buf[3];
brunnobbco 0:561d07a737bc 987
brunnobbco 0:561d07a737bc 988 // _tx_timeout in ms should be converted to us and then divided by
brunnobbco 0:561d07a737bc 989 // 15.625 us. Check data-sheet 13.1.4 SetTX() section.
brunnobbco 0:561d07a737bc 990 uint32_t timeout_scalled = ceil((_tx_timeout * 1000) / 15.625);
brunnobbco 0:561d07a737bc 991
brunnobbco 0:561d07a737bc 992 buf[0] = (uint8_t) ((timeout_scalled >> 16) & 0xFF);
brunnobbco 0:561d07a737bc 993 buf[1] = (uint8_t) ((timeout_scalled >> 8) & 0xFF);
brunnobbco 0:561d07a737bc 994 buf[2] = (uint8_t) (timeout_scalled & 0xFF);
brunnobbco 0:561d07a737bc 995
brunnobbco 0:561d07a737bc 996 write_opmode_command(RADIO_SET_TX, buf, 3);
brunnobbco 0:561d07a737bc 997
brunnobbco 0:561d07a737bc 998 _operation_mode = MODE_TX;
brunnobbco 0:561d07a737bc 999 }
brunnobbco 0:561d07a737bc 1000
brunnobbco 0:561d07a737bc 1001
brunnobbco 0:561d07a737bc 1002 void SX126X_LoRaRadio::receive(void)
brunnobbco 0:561d07a737bc 1003 {
brunnobbco 0:561d07a737bc 1004 if (get_modem() == MODEM_LORA && _reception_mode != RECEPTION_MODE_CONTINUOUS) {
brunnobbco 0:561d07a737bc 1005 // Data-sheet Table 13-11: StopOnPreambParam
brunnobbco 0:561d07a737bc 1006 // We will use radio's internal timer to mark no reception. This behaviour
brunnobbco 0:561d07a737bc 1007 // is different from SX1272/SX1276 where we are relying on radio to stop
brunnobbco 0:561d07a737bc 1008 // at preamble detection.
brunnobbco 0:561d07a737bc 1009 // 0x00 means Timer will be stopped on SyncWord(FSK) or Header (LoRa) detection
brunnobbco 0:561d07a737bc 1010 // 0x01 means Timer is stopped on preamble detection
brunnobbco 0:561d07a737bc 1011 uint8_t stop_at_preamble = 0x01;
brunnobbco 0:561d07a737bc 1012 write_opmode_command(RADIO_SET_STOPRXTIMERONPREAMBLE, &stop_at_preamble, 1);
brunnobbco 0:561d07a737bc 1013 // Data-sheet 13.4.9 SetLoRaSymbNumTimeout
brunnobbco 0:561d07a737bc 1014 write_opmode_command(RADIO_SET_LORASYMBTIMEOUT, &_rx_timeout_in_symbols, 1);
brunnobbco 0:561d07a737bc 1015 }
brunnobbco 0:561d07a737bc 1016
brunnobbco 0:561d07a737bc 1017 if (_reception_mode != RECEPTION_MODE_OTHER) {
brunnobbco 0:561d07a737bc 1018 configure_dio_irq(IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR ,
brunnobbco 0:561d07a737bc 1019 IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR ,
brunnobbco 0:561d07a737bc 1020 IRQ_RADIO_NONE,
brunnobbco 0:561d07a737bc 1021 IRQ_RADIO_NONE);
brunnobbco 0:561d07a737bc 1022 set_modulation_params(&_mod_params);
brunnobbco 0:561d07a737bc 1023 set_packet_params(&_packet_params);
brunnobbco 0:561d07a737bc 1024 }
brunnobbco 0:561d07a737bc 1025
brunnobbco 0:561d07a737bc 1026 uint8_t buf[3];
brunnobbco 0:561d07a737bc 1027
brunnobbco 0:561d07a737bc 1028 #if MBED_CONF_SX126X_LORA_DRIVER_BOOST_RX
brunnobbco 0:561d07a737bc 1029 write_to_register(REG_RX_GAIN, 0x96);
brunnobbco 0:561d07a737bc 1030 #endif
brunnobbco 0:561d07a737bc 1031
brunnobbco 0:561d07a737bc 1032 buf[0] = (uint8_t) ((_rx_timeout >> 16) & 0xFF);
brunnobbco 0:561d07a737bc 1033 buf[1] = (uint8_t) ((_rx_timeout >> 8) & 0xFF);
brunnobbco 0:561d07a737bc 1034 buf[2] = (uint8_t) (_rx_timeout & 0xFF);
brunnobbco 0:561d07a737bc 1035
brunnobbco 0:561d07a737bc 1036 write_opmode_command(RADIO_SET_RX, buf, 3);
brunnobbco 0:561d07a737bc 1037
brunnobbco 0:561d07a737bc 1038 _operation_mode = MODE_RX;
brunnobbco 0:561d07a737bc 1039 }
brunnobbco 0:561d07a737bc 1040
brunnobbco 0:561d07a737bc 1041 // check data-sheet 13.1.14.1 PA optimal settings
brunnobbco 0:561d07a737bc 1042 void SX126X_LoRaRadio::set_tx_power(int8_t power)
brunnobbco 0:561d07a737bc 1043 {
brunnobbco 0:561d07a737bc 1044 uint8_t buf[2];
brunnobbco 0:561d07a737bc 1045
brunnobbco 0:561d07a737bc 1046 if (get_device_variant() == SX1261) {
brunnobbco 0:561d07a737bc 1047 if (power >= 14) {
brunnobbco 0:561d07a737bc 1048 set_pa_config(0x04, 0x00, 0x01, 0x01);
brunnobbco 0:561d07a737bc 1049 power = 14;
brunnobbco 0:561d07a737bc 1050 } else if (power < 14){
brunnobbco 0:561d07a737bc 1051 set_pa_config(0x01, 0x00, 0x01, 0x01);
brunnobbco 0:561d07a737bc 1052 }
brunnobbco 0:561d07a737bc 1053
brunnobbco 0:561d07a737bc 1054 if (power < -3) {
brunnobbco 0:561d07a737bc 1055 power = -3;
brunnobbco 0:561d07a737bc 1056 }
brunnobbco 0:561d07a737bc 1057 write_to_register(REG_OCP, 0x18); // current max is 80 mA for the whole device
brunnobbco 0:561d07a737bc 1058 } else {
brunnobbco 0:561d07a737bc 1059 // sx1262 or sx1268
brunnobbco 0:561d07a737bc 1060 if (power > 22) {
brunnobbco 0:561d07a737bc 1061 power = 22;
brunnobbco 0:561d07a737bc 1062 } else if (power < -3) {
brunnobbco 0:561d07a737bc 1063 power = -3;
brunnobbco 0:561d07a737bc 1064 }
brunnobbco 0:561d07a737bc 1065
brunnobbco 0:561d07a737bc 1066 if (power <= 14) {
brunnobbco 0:561d07a737bc 1067 set_pa_config(0x02, 0x02, 0x00, 0x01);
brunnobbco 0:561d07a737bc 1068 } else {
brunnobbco 0:561d07a737bc 1069 set_pa_config(0x04, 0x07, 0x00, 0x01);
brunnobbco 0:561d07a737bc 1070 }
brunnobbco 0:561d07a737bc 1071
brunnobbco 0:561d07a737bc 1072 write_to_register(REG_OCP, 0x38); // current max 160mA for the whole device
brunnobbco 0:561d07a737bc 1073 }
brunnobbco 0:561d07a737bc 1074
brunnobbco 0:561d07a737bc 1075 buf[0] = power;
brunnobbco 0:561d07a737bc 1076
brunnobbco 0:561d07a737bc 1077 if (_crystal_select.is_connected() && _crystal_select == 0) {
brunnobbco 0:561d07a737bc 1078 // TCXO
brunnobbco 0:561d07a737bc 1079 buf[1] = RADIO_RAMP_200_US;
brunnobbco 0:561d07a737bc 1080 } else {
brunnobbco 0:561d07a737bc 1081 // XTAL
brunnobbco 0:561d07a737bc 1082 buf[1] = RADIO_RAMP_20_US;
brunnobbco 0:561d07a737bc 1083 }
brunnobbco 0:561d07a737bc 1084
brunnobbco 0:561d07a737bc 1085 write_opmode_command(RADIO_SET_TXPARAMS, buf, 2);
brunnobbco 0:561d07a737bc 1086 }
brunnobbco 0:561d07a737bc 1087
brunnobbco 0:561d07a737bc 1088 void SX126X_LoRaRadio::set_modulation_params(modulation_params_t *params)
brunnobbco 0:561d07a737bc 1089 {
brunnobbco 0:561d07a737bc 1090 uint8_t n;
brunnobbco 0:561d07a737bc 1091 uint32_t temp = 0;
brunnobbco 0:561d07a737bc 1092 uint8_t buf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
brunnobbco 0:561d07a737bc 1093
brunnobbco 0:561d07a737bc 1094 // Check if required configuration corresponds to the stored packet type
brunnobbco 0:561d07a737bc 1095 // If not, silently update radio packet type
brunnobbco 0:561d07a737bc 1096 if (_active_modem != params->modem_type) {
brunnobbco 0:561d07a737bc 1097 set_modem(params->modem_type);
brunnobbco 0:561d07a737bc 1098 }
brunnobbco 0:561d07a737bc 1099
brunnobbco 0:561d07a737bc 1100 switch (params->modem_type) {
brunnobbco 0:561d07a737bc 1101 case MODEM_FSK:
brunnobbco 0:561d07a737bc 1102 n = 8;
brunnobbco 0:561d07a737bc 1103 temp = (uint32_t) (32 * ((float) XTAL_FREQ / (float) params->params.gfsk.bit_rate));
brunnobbco 0:561d07a737bc 1104 buf[0] = (temp >> 16) & 0xFF;
brunnobbco 0:561d07a737bc 1105 buf[1] = (temp >> 8) & 0xFF;
brunnobbco 0:561d07a737bc 1106 buf[2] = temp & 0xFF;
brunnobbco 0:561d07a737bc 1107 buf[3] = params->params.gfsk.modulation_shaping;
brunnobbco 0:561d07a737bc 1108 buf[4] = params->params.gfsk.bandwidth;
brunnobbco 0:561d07a737bc 1109 temp = (uint32_t) ((float) params->params.gfsk.fdev / (float) FREQ_STEP);
brunnobbco 0:561d07a737bc 1110 buf[5] = (temp >> 16) & 0xFF;
brunnobbco 0:561d07a737bc 1111 buf[6] = (temp >> 8) & 0xFF;
brunnobbco 0:561d07a737bc 1112 buf[7] = (temp & 0xFF);
brunnobbco 0:561d07a737bc 1113 write_opmode_command(RADIO_SET_MODULATIONPARAMS, buf, n);
brunnobbco 0:561d07a737bc 1114 break;
brunnobbco 0:561d07a737bc 1115
brunnobbco 0:561d07a737bc 1116 case MODEM_LORA:
brunnobbco 0:561d07a737bc 1117 n = 4;
brunnobbco 0:561d07a737bc 1118 buf[0] = params->params.lora.spreading_factor;
brunnobbco 0:561d07a737bc 1119 buf[1] = params->params.lora.bandwidth;
brunnobbco 0:561d07a737bc 1120 buf[2] = params->params.lora.coding_rate;
brunnobbco 0:561d07a737bc 1121 buf[3] = params->params.lora.low_datarate_optimization;
brunnobbco 0:561d07a737bc 1122
brunnobbco 0:561d07a737bc 1123 write_opmode_command(RADIO_SET_MODULATIONPARAMS, buf, n);
brunnobbco 0:561d07a737bc 1124 break;
brunnobbco 0:561d07a737bc 1125
brunnobbco 0:561d07a737bc 1126 default:
brunnobbco 0:561d07a737bc 1127 return;
brunnobbco 0:561d07a737bc 1128 }
brunnobbco 0:561d07a737bc 1129 }
brunnobbco 0:561d07a737bc 1130
brunnobbco 0:561d07a737bc 1131 void SX126X_LoRaRadio::set_pa_config(uint8_t pa_DC, uint8_t hp_max,
brunnobbco 0:561d07a737bc 1132 uint8_t device_type, uint8_t pa_LUT )
brunnobbco 0:561d07a737bc 1133 {
brunnobbco 0:561d07a737bc 1134 uint8_t buf[4];
brunnobbco 0:561d07a737bc 1135
brunnobbco 0:561d07a737bc 1136 buf[0] = pa_DC;
brunnobbco 0:561d07a737bc 1137 buf[1] = hp_max;
brunnobbco 0:561d07a737bc 1138 buf[2] = device_type;
brunnobbco 0:561d07a737bc 1139 buf[3] = pa_LUT;
brunnobbco 0:561d07a737bc 1140 write_opmode_command(RADIO_SET_PACONFIG, buf, 4);
brunnobbco 0:561d07a737bc 1141 }
brunnobbco 0:561d07a737bc 1142
brunnobbco 0:561d07a737bc 1143 void SX126X_LoRaRadio::set_crc_seed(uint16_t seed)
brunnobbco 0:561d07a737bc 1144 {
brunnobbco 0:561d07a737bc 1145 if (_active_modem == MODEM_FSK) {
brunnobbco 0:561d07a737bc 1146 uint8_t buf[2];
brunnobbco 0:561d07a737bc 1147 buf[0] = (uint8_t) ((seed >> 8) & 0xFF);
brunnobbco 0:561d07a737bc 1148 buf[1] = (uint8_t) (seed & 0xFF);
brunnobbco 0:561d07a737bc 1149 write_to_register(REG_LR_CRCSEEDBASEADDR, buf, 2);
brunnobbco 0:561d07a737bc 1150 }
brunnobbco 0:561d07a737bc 1151 }
brunnobbco 0:561d07a737bc 1152
brunnobbco 0:561d07a737bc 1153 void SX126X_LoRaRadio::set_crc_polynomial(uint16_t polynomial)
brunnobbco 0:561d07a737bc 1154 {
brunnobbco 0:561d07a737bc 1155 if (_active_modem == MODEM_FSK) {
brunnobbco 0:561d07a737bc 1156 uint8_t buf[2];
brunnobbco 0:561d07a737bc 1157 buf[0] = (uint8_t) ((polynomial >> 8) & 0xFF);
brunnobbco 0:561d07a737bc 1158 buf[1] = (uint8_t) (polynomial & 0xFF);
brunnobbco 0:561d07a737bc 1159 write_to_register(REG_LR_CRCPOLYBASEADDR, buf, 2);
brunnobbco 0:561d07a737bc 1160 }
brunnobbco 0:561d07a737bc 1161 }
brunnobbco 0:561d07a737bc 1162
brunnobbco 0:561d07a737bc 1163 void SX126X_LoRaRadio::set_whitening_seed(uint16_t seed)
brunnobbco 0:561d07a737bc 1164 {
brunnobbco 0:561d07a737bc 1165 if (_active_modem == MODEM_FSK) {
brunnobbco 0:561d07a737bc 1166 uint8_t reg_value = read_register(REG_LR_WHITSEEDBASEADDR_MSB) & 0xFE;
brunnobbco 0:561d07a737bc 1167 reg_value = ((seed >> 8) & 0x01) | reg_value;
brunnobbco 0:561d07a737bc 1168 write_to_register(REG_LR_WHITSEEDBASEADDR_MSB, reg_value); // only 1 bit.
brunnobbco 0:561d07a737bc 1169 write_to_register(REG_LR_WHITSEEDBASEADDR_LSB, (uint8_t) seed);
brunnobbco 0:561d07a737bc 1170 }
brunnobbco 0:561d07a737bc 1171 }
brunnobbco 0:561d07a737bc 1172
brunnobbco 0:561d07a737bc 1173 void SX126X_LoRaRadio::set_packet_params(packet_params_t *packet_params)
brunnobbco 0:561d07a737bc 1174 {
brunnobbco 0:561d07a737bc 1175 uint8_t n;
brunnobbco 0:561d07a737bc 1176 uint8_t crc_val = 0;
brunnobbco 0:561d07a737bc 1177 uint8_t buf[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
brunnobbco 0:561d07a737bc 1178
brunnobbco 0:561d07a737bc 1179 // Check if required configuration corresponds to the stored packet type
brunnobbco 0:561d07a737bc 1180 // If not, silently update radio packet type
brunnobbco 0:561d07a737bc 1181 if (_active_modem != packet_params->modem_type) {
brunnobbco 0:561d07a737bc 1182 set_modem(packet_params->modem_type);
brunnobbco 0:561d07a737bc 1183 }
brunnobbco 0:561d07a737bc 1184
brunnobbco 0:561d07a737bc 1185 switch (packet_params->modem_type) {
brunnobbco 0:561d07a737bc 1186 case MODEM_FSK:
brunnobbco 0:561d07a737bc 1187 if (packet_params->params.gfsk.crc_length == RADIO_CRC_2_BYTES_IBM) {
brunnobbco 0:561d07a737bc 1188 set_crc_seed(CRC_IBM_SEED);
brunnobbco 0:561d07a737bc 1189 set_crc_polynomial(CRC_POLYNOMIAL_IBM);
brunnobbco 0:561d07a737bc 1190 crc_val = RADIO_CRC_2_BYTES;
brunnobbco 0:561d07a737bc 1191 } else if (packet_params->params.gfsk.crc_length == RADIO_CRC_2_BYTES_CCIT) {
brunnobbco 0:561d07a737bc 1192 set_crc_seed(CRC_CCITT_SEED);
brunnobbco 0:561d07a737bc 1193 set_crc_polynomial(CRC_POLYNOMIAL_CCITT);
brunnobbco 0:561d07a737bc 1194 crc_val = RADIO_CRC_2_BYTES_INV;
brunnobbco 0:561d07a737bc 1195 } else {
brunnobbco 0:561d07a737bc 1196 crc_val = packet_params->params.gfsk.crc_length;
brunnobbco 0:561d07a737bc 1197 }
brunnobbco 0:561d07a737bc 1198 n = 9;
brunnobbco 0:561d07a737bc 1199 buf[0] = (packet_params->params.gfsk.preamble_length >> 8) & 0xFF;
brunnobbco 0:561d07a737bc 1200 buf[1] = packet_params->params.gfsk.preamble_length;
brunnobbco 0:561d07a737bc 1201 buf[2] = packet_params->params.gfsk.preamble_min_detect;
brunnobbco 0:561d07a737bc 1202 buf[3] = (packet_params->params.gfsk.syncword_length /*<< 3*/); // convert from byte to bit
brunnobbco 0:561d07a737bc 1203 buf[4] = packet_params->params.gfsk.addr_comp;
brunnobbco 0:561d07a737bc 1204 buf[5] = packet_params->params.gfsk.header_type;
brunnobbco 0:561d07a737bc 1205 buf[6] = packet_params->params.gfsk.payload_length;
brunnobbco 0:561d07a737bc 1206 buf[7] = crc_val;
brunnobbco 0:561d07a737bc 1207 buf[8] = packet_params->params.gfsk.whitening_mode;
brunnobbco 0:561d07a737bc 1208 break;
brunnobbco 0:561d07a737bc 1209
brunnobbco 0:561d07a737bc 1210 case MODEM_LORA:
brunnobbco 0:561d07a737bc 1211 n = 6;
brunnobbco 0:561d07a737bc 1212 buf[0] = (packet_params->params.lora.preamble_length >> 8) & 0xFF;
brunnobbco 0:561d07a737bc 1213 buf[1] = packet_params->params.lora.preamble_length;
brunnobbco 0:561d07a737bc 1214 buf[2] = packet_params->params.lora.header_type;
brunnobbco 0:561d07a737bc 1215 buf[3] = packet_params->params.lora.payload_length;
brunnobbco 0:561d07a737bc 1216 buf[4] = packet_params->params.lora.crc_mode;
brunnobbco 0:561d07a737bc 1217 buf[5] = packet_params->params.lora.invert_IQ;
brunnobbco 0:561d07a737bc 1218 break;
brunnobbco 0:561d07a737bc 1219 default:
brunnobbco 0:561d07a737bc 1220 return;
brunnobbco 0:561d07a737bc 1221 }
brunnobbco 0:561d07a737bc 1222 write_opmode_command(RADIO_SET_PACKETPARAMS, buf, n);
brunnobbco 0:561d07a737bc 1223 }
brunnobbco 0:561d07a737bc 1224
brunnobbco 0:561d07a737bc 1225 void SX126X_LoRaRadio::set_cad_params(lora_cad_symbols_t nb_symbols,
brunnobbco 0:561d07a737bc 1226 uint8_t det_peak, uint8_t det_min,
brunnobbco 0:561d07a737bc 1227 cad_exit_modes_t exit_mode,
brunnobbco 0:561d07a737bc 1228 uint32_t timeout)
brunnobbco 0:561d07a737bc 1229 {
brunnobbco 0:561d07a737bc 1230 uint8_t buf[7];
brunnobbco 0:561d07a737bc 1231
brunnobbco 0:561d07a737bc 1232 buf[0] = (uint8_t) nb_symbols;
brunnobbco 0:561d07a737bc 1233 buf[1] = det_peak;
brunnobbco 0:561d07a737bc 1234 buf[2] = det_min;
brunnobbco 0:561d07a737bc 1235 buf[3] = (uint8_t) exit_mode;
brunnobbco 0:561d07a737bc 1236 buf[4] = (uint8_t) ((timeout >> 16) & 0xFF);
brunnobbco 0:561d07a737bc 1237 buf[5] = (uint8_t) ((timeout >> 8) & 0xFF);
brunnobbco 0:561d07a737bc 1238 buf[6] = (uint8_t) (timeout & 0xFF);
brunnobbco 0:561d07a737bc 1239 write_opmode_command((uint8_t) RADIO_SET_CADPARAMS, buf, 7);
brunnobbco 0:561d07a737bc 1240
brunnobbco 0:561d07a737bc 1241 _operation_mode = MODE_CAD;
brunnobbco 0:561d07a737bc 1242 }
brunnobbco 0:561d07a737bc 1243
brunnobbco 0:561d07a737bc 1244 void SX126X_LoRaRadio::set_buffer_base_addr(uint8_t tx_base_addr, uint8_t rx_base_addr)
brunnobbco 0:561d07a737bc 1245 {
brunnobbco 0:561d07a737bc 1246 uint8_t buf[2];
brunnobbco 0:561d07a737bc 1247
brunnobbco 0:561d07a737bc 1248 buf[0] = tx_base_addr;
brunnobbco 0:561d07a737bc 1249 buf[1] = rx_base_addr;
brunnobbco 0:561d07a737bc 1250 write_opmode_command((uint8_t) RADIO_SET_BUFFERBASEADDRESS, buf, 2);
brunnobbco 0:561d07a737bc 1251 }
brunnobbco 0:561d07a737bc 1252
brunnobbco 0:561d07a737bc 1253 uint8_t SX126X_LoRaRadio::get_status(void)
brunnobbco 0:561d07a737bc 1254 {
brunnobbco 0:561d07a737bc 1255 if (_operation_mode != MODE_STDBY_RC || _operation_mode != MODE_SLEEP) {
brunnobbco 0:561d07a737bc 1256 return 0;
brunnobbco 0:561d07a737bc 1257 }
brunnobbco 0:561d07a737bc 1258
brunnobbco 0:561d07a737bc 1259 return 0xFF;
brunnobbco 0:561d07a737bc 1260 }
brunnobbco 0:561d07a737bc 1261
brunnobbco 0:561d07a737bc 1262 int8_t SX126X_LoRaRadio::get_rssi()
brunnobbco 0:561d07a737bc 1263 {
brunnobbco 0:561d07a737bc 1264 uint8_t buf[1];
brunnobbco 0:561d07a737bc 1265 int8_t rssi = 0;
brunnobbco 0:561d07a737bc 1266
brunnobbco 0:561d07a737bc 1267 read_opmode_command((uint8_t) RADIO_GET_RSSIINST, buf, 1);
brunnobbco 0:561d07a737bc 1268 rssi = -buf[0] >> 1;
brunnobbco 0:561d07a737bc 1269 return rssi;
brunnobbco 0:561d07a737bc 1270 }
brunnobbco 0:561d07a737bc 1271
brunnobbco 0:561d07a737bc 1272 void SX126X_LoRaRadio::get_rx_buffer_status(uint8_t *payload_len,
brunnobbco 0:561d07a737bc 1273 uint8_t *start_ptr)
brunnobbco 0:561d07a737bc 1274 {
brunnobbco 0:561d07a737bc 1275 uint8_t status[2];
brunnobbco 0:561d07a737bc 1276
brunnobbco 0:561d07a737bc 1277 read_opmode_command((uint8_t) RADIO_GET_RXBUFFERSTATUS, status, 2);
brunnobbco 0:561d07a737bc 1278
brunnobbco 0:561d07a737bc 1279 // In case of LORA fixed header, the payloadLength is obtained by reading
brunnobbco 0:561d07a737bc 1280 // the register REG_LR_PAYLOADLENGTH
brunnobbco 0:561d07a737bc 1281 if ((get_modem() == MODEM_LORA) &&
brunnobbco 0:561d07a737bc 1282 (read_register(REG_LR_PACKETPARAMS) >> 7 == 1)) {
brunnobbco 0:561d07a737bc 1283 *payload_len = read_register(REG_LR_PAYLOADLENGTH);
brunnobbco 0:561d07a737bc 1284 } else {
brunnobbco 0:561d07a737bc 1285 *payload_len = status[0];
brunnobbco 0:561d07a737bc 1286 }
brunnobbco 0:561d07a737bc 1287
brunnobbco 0:561d07a737bc 1288 *start_ptr = status[1];
brunnobbco 0:561d07a737bc 1289 }
brunnobbco 0:561d07a737bc 1290
brunnobbco 0:561d07a737bc 1291 void SX126X_LoRaRadio::get_packet_status(packet_status_t *pkt_status)
brunnobbco 0:561d07a737bc 1292 {
brunnobbco 0:561d07a737bc 1293 uint8_t status[3];
brunnobbco 0:561d07a737bc 1294
brunnobbco 0:561d07a737bc 1295 read_opmode_command((uint8_t) RADIO_GET_PACKETSTATUS, status, 3);
brunnobbco 0:561d07a737bc 1296
brunnobbco 0:561d07a737bc 1297 pkt_status->modem_type = (radio_modems_t) get_modem();
brunnobbco 0:561d07a737bc 1298 switch (pkt_status->modem_type) {
brunnobbco 0:561d07a737bc 1299 case MODEM_FSK:
brunnobbco 0:561d07a737bc 1300 pkt_status->params.gfsk.rx_status = status[0];
brunnobbco 0:561d07a737bc 1301 pkt_status->params.gfsk.rssi_sync = -status[1] >> 1;
brunnobbco 0:561d07a737bc 1302 pkt_status->params.gfsk.rssi_avg = -status[2] >> 1;
brunnobbco 0:561d07a737bc 1303 pkt_status->params.gfsk.freq_error = 0;
brunnobbco 0:561d07a737bc 1304 break;
brunnobbco 0:561d07a737bc 1305
brunnobbco 0:561d07a737bc 1306 case MODEM_LORA:
brunnobbco 0:561d07a737bc 1307 pkt_status->params.lora.rssi_pkt = -status[0] >> 1;
brunnobbco 0:561d07a737bc 1308 // Returns SNR value [dB] rounded to the nearest integer value
brunnobbco 0:561d07a737bc 1309 pkt_status->params.lora.snr_pkt = (((int8_t) status[1]) + 2) >> 2;
brunnobbco 0:561d07a737bc 1310 pkt_status->params.lora.signal_rssi_pkt = -status[2] >> 1;
brunnobbco 0:561d07a737bc 1311 break;
brunnobbco 0:561d07a737bc 1312
brunnobbco 0:561d07a737bc 1313 default:
brunnobbco 0:561d07a737bc 1314 // In that specific case, we set everything in the pkt_status to zeros
brunnobbco 0:561d07a737bc 1315 // and reset the packet type accordingly
brunnobbco 0:561d07a737bc 1316 memset(pkt_status, 0, sizeof(packet_status_t));
brunnobbco 0:561d07a737bc 1317 break;
brunnobbco 0:561d07a737bc 1318 }
brunnobbco 0:561d07a737bc 1319 }
brunnobbco 0:561d07a737bc 1320
brunnobbco 0:561d07a737bc 1321 radio_error_t SX126X_LoRaRadio::get_device_errors(void)
brunnobbco 0:561d07a737bc 1322 {
brunnobbco 0:561d07a737bc 1323 radio_error_t error;
brunnobbco 0:561d07a737bc 1324
brunnobbco 0:561d07a737bc 1325 read_opmode_command((uint8_t) RADIO_GET_ERROR, (uint8_t *)&error, 2);
brunnobbco 0:561d07a737bc 1326 return error;
brunnobbco 0:561d07a737bc 1327 }
brunnobbco 0:561d07a737bc 1328
brunnobbco 0:561d07a737bc 1329 void SX126X_LoRaRadio::clear_device_errors(void)
brunnobbco 0:561d07a737bc 1330 {
brunnobbco 0:561d07a737bc 1331 uint8_t buf[2] = {0x00, 0x00};
brunnobbco 0:561d07a737bc 1332 write_opmode_command((uint8_t) RADIO_CLR_ERROR, buf, 2);
brunnobbco 0:561d07a737bc 1333 }
brunnobbco 0:561d07a737bc 1334