├── LICENCE-BSD-3-Clause ├── LICENSE ├── README.md ├── SX126X ├── SX126X_LoRaRadio.cpp ├── SX126X_LoRaRadio.h ├── SleepMode.txt ├── mbed_lib.json └── sx126x_ds.h ├── SX1272 ├── README.md ├── SX1272_LoRaRadio.cpp ├── SX1272_LoRaRadio.h ├── mbed_lib.json └── registers │ ├── sx1272Regs-Fsk.h │ └── sx1272Regs-LoRa.h └── SX1276 ├── README.md ├── SX1276_LoRaRadio.cpp ├── SX1276_LoRaRadio.h ├── mbed_lib.json └── registers ├── sx1276Regs-Fsk.h └── sx1276Regs-LoRa.h /LICENCE-BSD-3-Clause: -------------------------------------------------------------------------------- 1 | Copyright 2017 Arm Limited and affiliates. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. Neither the name of the copyright holder nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | --- Revised BSD License --- 2 | Copyright (c) 2013, SEMTECH S.A. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of the Semtech corporation nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mbed enabled Semtech LoRa/FSK radio drivers. 2 | 3 | ## NOTE! This repository is deprecated. 4 | 5 | From mbed-os 6.0 onwards, these drivers are included in mbed-os as components. To enable your driver just enable the driver in mbed_app.json as e.g `"target.components_add": ["SX126X"],` 6 | -------------------------------------------------------------------------------- /SX126X/SX126X_LoRaRadio.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2015 Semtech 8 | ___ _____ _ ___ _ _____ ___ ___ ___ ___ 9 | / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 10 | \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 11 | |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 12 | embedded.connectivity.solutions=============== 13 | 14 | Description: LoRaWAN stack layer that controls both MAC and PHY underneath 15 | 16 | License: Revised BSD License, see LICENSE.TXT file include in the project 17 | 18 | Maintainer: Miguel Luis, Gregory Cristian & Gilbert Menth 19 | 20 | Copyright (c) 2019, Arm Limited and affiliates. 21 | 22 | SPDX-License-Identifier: BSD-3-Clause 23 | */ 24 | 25 | #include 26 | #include "ThisThread.h" 27 | #include "mbed_wait_api.h" 28 | #include "Timer.h" 29 | #include "SX126X_LoRaRadio.h" 30 | 31 | #ifdef MBED_CONF_SX126X_LORA_DRIVER_SPI_FREQUENCY 32 | #define SPI_FREQUENCY MBED_CONF_SX126X_LORA_DRIVER_SPI_FREQUENCY 33 | #else 34 | #define SPI_FREQUENCY 16000000 35 | #endif 36 | 37 | using namespace mbed; 38 | using namespace rtos; 39 | 40 | #ifdef MBED_CONF_RTOS_PRESENT 41 | /** 42 | * Signals 43 | */ 44 | #define SIG_INTERRUPT 0x02 45 | #endif 46 | 47 | /*! 48 | * FSK bandwidth definition 49 | */ 50 | typedef struct { 51 | uint32_t bandwidth; 52 | uint8_t register_value; 53 | } fsk_bw_t; 54 | 55 | static const fsk_bw_t fsk_bandwidths[] = { 56 | { 4800, 0x1F }, 57 | { 5800, 0x17 }, 58 | { 7300, 0x0F }, 59 | { 9700, 0x1E }, 60 | { 11700, 0x16 }, 61 | { 14600, 0x0E }, 62 | { 19500, 0x1D }, 63 | { 23400, 0x15 }, 64 | { 29300, 0x0D }, 65 | { 39000, 0x1C }, 66 | { 46900, 0x14 }, 67 | { 58600, 0x0C }, 68 | { 78200, 0x1B }, 69 | { 93800, 0x13 }, 70 | { 117300, 0x0B }, 71 | { 156200, 0x1A }, 72 | { 187200, 0x12 }, 73 | { 234300, 0x0A }, 74 | { 312000, 0x19 }, 75 | { 373600, 0x11 }, 76 | { 467000, 0x09 }, 77 | { 500000, 0x00 }, // Invalid Bandwidth 78 | }; 79 | 80 | const uint8_t sync_word[] = {0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00}; 81 | 82 | // in ms SF12 SF11 SF10 SF9 SF8 SF7 83 | const float lora_symbol_time[3][6] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024 }, // 125 KHz 84 | { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512 }, // 250 KHz 85 | { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256 } 86 | }; // 500 KHz 87 | 88 | SX126X_LoRaRadio::SX126X_LoRaRadio(PinName mosi, 89 | PinName miso, 90 | PinName sclk, 91 | PinName nss, 92 | PinName reset, 93 | PinName dio1, 94 | PinName busy, 95 | PinName freq_select, 96 | PinName device_select, 97 | PinName crystal_select, 98 | PinName ant_switch) 99 | : _spi(mosi, miso, sclk), 100 | _chip_select(nss, 1), 101 | _reset_ctl(reset), 102 | _dio1_ctl(dio1, PullNone), 103 | _busy(busy, PullNone), 104 | _freq_select(freq_select), 105 | _dev_select(device_select), 106 | _crystal_select(crystal_select, PullDown), 107 | _ant_switch(ant_switch, PIN_INPUT, PullUp, 0) 108 | #ifdef MBED_CONF_RTOS_PRESENT 109 | , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX126X") 110 | #endif 111 | { 112 | _radio_events = NULL; 113 | _reset_ctl = 1; 114 | _image_calibrated = false; 115 | _force_image_calibration = false; 116 | _active_modem = MODEM_LORA; 117 | 118 | #ifdef MBED_CONF_RTOS_PRESENT 119 | irq_thread.start(callback(this, &SX126X_LoRaRadio::rf_irq_task)); 120 | #endif 121 | } 122 | 123 | SX126X_LoRaRadio::~SX126X_LoRaRadio() 124 | { 125 | 126 | } 127 | 128 | /** 129 | * Acquire lock 130 | */ 131 | void SX126X_LoRaRadio::lock(void) 132 | { 133 | mutex.lock(); 134 | } 135 | 136 | /** 137 | * Release lock 138 | */ 139 | void SX126X_LoRaRadio::unlock(void) 140 | { 141 | mutex.unlock(); 142 | } 143 | 144 | #ifdef MBED_CONF_RTOS_PRESENT 145 | /** 146 | * Thread task handling IRQs 147 | */ 148 | void SX126X_LoRaRadio::rf_irq_task(void) 149 | { 150 | for (;;) { 151 | uint32_t flags = ThisThread::flags_wait_any(0x7FFFFFFF); 152 | 153 | lock(); 154 | if (flags & SIG_INTERRUPT) { 155 | handle_dio1_irq(); 156 | } 157 | unlock(); 158 | } 159 | } 160 | #endif 161 | 162 | void SX126X_LoRaRadio::dio1_irq_isr() 163 | { 164 | #ifdef MBED_CONF_RTOS_PRESENT 165 | irq_thread.flags_set(SIG_INTERRUPT); 166 | #else 167 | handle_dio1_irq(); 168 | #endif 169 | } 170 | 171 | uint16_t SX126X_LoRaRadio::get_irq_status(void) 172 | { 173 | uint8_t status[2]; 174 | 175 | read_opmode_command((uint8_t) RADIO_GET_IRQSTATUS, status, 2); 176 | return (status[0] << 8) | status[1]; 177 | } 178 | 179 | void SX126X_LoRaRadio::clear_irq_status(uint16_t irq) 180 | { 181 | uint8_t buf[2]; 182 | 183 | buf[0] = (uint8_t)(((uint16_t) irq >> 8) & 0x00FF); 184 | buf[1] = (uint8_t)((uint16_t) irq & 0x00FF); 185 | write_opmode_command((uint8_t) RADIO_CLR_IRQSTATUS, buf, 2); 186 | } 187 | 188 | //TODO - Better do CAD here. CAD code is already part of the driver 189 | // It needs to be hooked up to the stack (this API will need change 190 | // and the stack will need changes too) 191 | bool SX126X_LoRaRadio::perform_carrier_sense(radio_modems_t modem, 192 | uint32_t freq, 193 | int16_t rssi_threshold, 194 | uint32_t max_carrier_sense_time) 195 | { 196 | bool status = true; 197 | int16_t rssi = 0; 198 | 199 | set_modem(modem); 200 | set_channel(freq); 201 | _reception_mode = RECEPTION_MODE_OTHER; 202 | _rx_timeout = 0x00000000; 203 | receive(); 204 | 205 | // hold on a bit, radio turn-around time 206 | ThisThread::sleep_for(1); 207 | 208 | Timer elapsed_time; 209 | elapsed_time.start(); 210 | 211 | // Perform carrier sense for maxCarrierSenseTime 212 | while (elapsed_time.read_ms() < (int) max_carrier_sense_time) { 213 | rssi = get_rssi(); 214 | 215 | if (rssi > rssi_threshold) { 216 | status = false; 217 | break; 218 | } 219 | } 220 | 221 | sleep(); 222 | return status; 223 | } 224 | 225 | void SX126X_LoRaRadio::start_cad(void) 226 | { 227 | // TODO: CAD is more advanced in SX126X. We will need API change in LoRaRadio 228 | // for this to act properly 229 | } 230 | 231 | /** 232 | * TODO: The purpose of this API is unclear. 233 | * Need to start an internal discussion. 234 | */ 235 | bool SX126X_LoRaRadio::check_rf_frequency(uint32_t frequency) 236 | { 237 | // Implement check. Currently all frequencies are supported ? What band ? 238 | return true; 239 | } 240 | 241 | void SX126X_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, 242 | uint16_t time) 243 | { 244 | // This is useless. We even removed the support from our MAC layer. 245 | } 246 | 247 | void SX126X_LoRaRadio::handle_dio1_irq() 248 | { 249 | uint16_t irq_status = get_irq_status(); 250 | clear_irq_status(IRQ_RADIO_ALL); 251 | 252 | if ((irq_status & IRQ_TX_DONE) == IRQ_TX_DONE) { 253 | if (_radio_events->tx_done) { 254 | _radio_events->tx_done(); 255 | } 256 | } 257 | 258 | if ((irq_status & IRQ_RX_DONE) == IRQ_RX_DONE) { 259 | if ((irq_status & IRQ_CRC_ERROR) == IRQ_CRC_ERROR) { 260 | if (_radio_events && _radio_events->rx_error) { 261 | _radio_events->rx_error(); 262 | } 263 | } else { 264 | if (_radio_events->rx_done) { 265 | uint8_t offset = 0; 266 | uint8_t payload_len = 0; 267 | int16_t rssi = 0; 268 | int8_t snr = 0; 269 | packet_status_t pkt_status; 270 | 271 | get_rx_buffer_status(&payload_len, &offset); 272 | read_fifo(_data_buffer, payload_len, offset); 273 | get_packet_status(&pkt_status); 274 | if (pkt_status.modem_type == MODEM_FSK) { 275 | rssi = pkt_status.params.gfsk.rssi_sync; 276 | } else { 277 | rssi = pkt_status.params.lora.rssi_pkt; 278 | snr = pkt_status.params.lora.snr_pkt; 279 | } 280 | 281 | _radio_events->rx_done(_data_buffer, payload_len, rssi, snr); 282 | } 283 | } 284 | } 285 | 286 | if ((irq_status & IRQ_CAD_DONE) == IRQ_CAD_DONE) { 287 | if (_radio_events->cad_done) { 288 | _radio_events->cad_done((irq_status & IRQ_CAD_ACTIVITY_DETECTED) 289 | == IRQ_CAD_ACTIVITY_DETECTED); 290 | } 291 | } 292 | 293 | if ((irq_status & IRQ_RX_TX_TIMEOUT) == IRQ_RX_TX_TIMEOUT) { 294 | if ((_radio_events->tx_timeout) && (_operation_mode == MODE_TX)) { 295 | _radio_events->tx_timeout(); 296 | } else if ((_radio_events && _radio_events->rx_timeout) && (_operation_mode == MODE_RX)) { 297 | _radio_events->rx_timeout(); 298 | } 299 | } 300 | } 301 | 302 | void SX126X_LoRaRadio::set_device_ready(void) 303 | { 304 | if (_operation_mode == MODE_SLEEP) { 305 | wakeup(); 306 | } 307 | } 308 | 309 | void SX126X_LoRaRadio::calibrate_image(uint32_t freq) 310 | { 311 | uint8_t cal_freq[2]; 312 | 313 | if (freq > 900000000) { 314 | cal_freq[0] = 0xE1; 315 | cal_freq[1] = 0xE9; 316 | } else if (freq > 850000000) { 317 | cal_freq[0] = 0xD7; 318 | cal_freq[1] = 0xD8; 319 | } else if (freq > 770000000) { 320 | cal_freq[0] = 0xC1; 321 | cal_freq[1] = 0xC5; 322 | } else if (freq > 460000000) { 323 | cal_freq[0] = 0x75; 324 | cal_freq[1] = 0x81; 325 | } else if (freq > 425000000) { 326 | cal_freq[0] = 0x6B; 327 | cal_freq[1] = 0x6F; 328 | } 329 | 330 | write_opmode_command((uint8_t) RADIO_CALIBRATEIMAGE, cal_freq, 2); 331 | 332 | _image_calibrated = true; 333 | } 334 | 335 | void SX126X_LoRaRadio::set_channel(uint32_t frequency) 336 | { 337 | #if MBED_CONF_SX126X_LORA_DRIVER_SLEEP_MODE == 1 338 | // At this point, we are not sure what is the Modem type, set both 339 | _mod_params.params.lora.operational_frequency = frequency; 340 | _mod_params.params.gfsk.operational_frequency = frequency; 341 | #endif 342 | 343 | uint8_t buf[4]; 344 | uint32_t freq = 0; 345 | 346 | if (_force_image_calibration || !_image_calibrated) { 347 | calibrate_image(frequency); 348 | _image_calibrated = true; 349 | } 350 | 351 | freq = (uint32_t) ceil(((float) frequency / (float) FREQ_STEP)); 352 | buf[0] = (uint8_t)((freq >> 24) & 0xFF); 353 | buf[1] = (uint8_t)((freq >> 16) & 0xFF); 354 | buf[2] = (uint8_t)((freq >> 8) & 0xFF); 355 | buf[3] = (uint8_t)(freq & 0xFF); 356 | 357 | write_opmode_command((uint8_t) RADIO_SET_RFFREQUENCY, buf, 4); 358 | } 359 | 360 | /** 361 | * Put radio in Standby mode 362 | */ 363 | void SX126X_LoRaRadio::standby(void) 364 | { 365 | if (_operation_mode == MODE_STDBY_RC) { 366 | return; 367 | } 368 | 369 | set_device_ready(); 370 | uint8_t standby_mode = MBED_CONF_SX126X_LORA_DRIVER_STANDBY_MODE; 371 | write_opmode_command((uint8_t) RADIO_SET_STANDBY, &standby_mode, 1); 372 | 373 | if (standby_mode == STDBY_RC) { 374 | _operation_mode = MODE_STDBY_RC; 375 | } else { 376 | _operation_mode = MODE_STDBY_XOSC; 377 | } 378 | } 379 | 380 | void SX126X_LoRaRadio::set_dio2_as_rfswitch_ctrl(uint8_t enable) 381 | { 382 | write_opmode_command(RADIO_SET_RFSWITCHMODE, &enable, 1); 383 | } 384 | 385 | void SX126X_LoRaRadio::set_dio3_as_tcxo_ctrl(radio_TCXO_ctrl_voltage_t voltage, 386 | uint32_t timeout) 387 | { 388 | uint8_t buf[4]; 389 | 390 | buf[0] = voltage & 0x07; 391 | buf[1] = (uint8_t)((timeout >> 16) & 0xFF); 392 | buf[2] = (uint8_t)((timeout >> 8) & 0xFF); 393 | buf[3] = (uint8_t)(timeout & 0xFF); 394 | 395 | write_opmode_command(RADIO_SET_TCXOMODE, buf, 4); 396 | } 397 | 398 | void SX126X_LoRaRadio::init_radio(radio_events_t *events) 399 | { 400 | _radio_events = events; 401 | 402 | // attach DIO1 interrupt line to its respective ISR 403 | _dio1_ctl.rise(callback(this, &SX126X_LoRaRadio::dio1_irq_isr)); 404 | 405 | uint8_t freq_support = get_frequency_support(); 406 | 407 | // Hold chip-select high 408 | _chip_select = 1; 409 | _spi.format(8, 0); 410 | _spi.frequency(SPI_FREQUENCY); 411 | // 100 us wait to settle down 412 | wait_us(100); 413 | 414 | radio_reset(); 415 | 416 | #if MBED_CONF_LORA_PUBLIC_NETWORK 417 | _network_mode_public = true; 418 | #else 419 | _network_mode_public = false; 420 | #endif 421 | 422 | // this is a POR sequence 423 | cold_start_wakeup(); 424 | } 425 | 426 | void SX126X_LoRaRadio::cold_start_wakeup() 427 | { 428 | uint8_t regulator_mode = MBED_CONF_SX126X_LORA_DRIVER_REGULATOR_MODE; 429 | write_opmode_command(RADIO_SET_REGULATORMODE, ®ulator_mode, 1); 430 | set_buffer_base_addr(0x00, 0x00); 431 | 432 | if (_crystal_select.is_connected() && _crystal_select == 0) { 433 | caliberation_params_t calib_param; 434 | set_dio3_as_tcxo_ctrl(TCXO_CTRL_1_7V, 320); //5 ms 435 | calib_param.value = 0x7F; 436 | write_opmode_command(RADIO_CALIBRATE, &calib_param.value, 1); 437 | } 438 | 439 | set_dio2_as_rfswitch_ctrl(true); 440 | 441 | _operation_mode = MODE_STDBY_RC; 442 | 443 | set_modem(_active_modem); 444 | 445 | if (_active_modem == MODEM_LORA) { 446 | set_public_network(_network_mode_public); 447 | } 448 | } 449 | 450 | void SX126X_LoRaRadio::set_public_network(bool enable) 451 | { 452 | if (enable) { 453 | // Change LoRa modem SyncWord 454 | write_to_register(REG_LR_SYNCWORD, (LORA_MAC_PUBLIC_SYNCWORD >> 8) & 0xFF); 455 | write_to_register(REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF); 456 | } else { 457 | // Change LoRa modem SyncWord 458 | write_to_register(REG_LR_SYNCWORD, (LORA_MAC_PRIVATE_SYNCWORD >> 8) & 0xFF); 459 | write_to_register(REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF); 460 | } 461 | } 462 | 463 | uint32_t SX126X_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) 464 | { 465 | uint32_t air_time = 0; 466 | 467 | switch (modem) { 468 | case MODEM_FSK: { 469 | air_time = rint((8 * (_packet_params.params.gfsk.preamble_length 470 | + (_packet_params.params.gfsk.syncword_length >> 3) 471 | + ((_packet_params.params.gfsk.header_type 472 | == RADIO_PACKET_FIXED_LENGTH) ? 0.0f : 1.0f) + pkt_len 473 | + ((_packet_params.params.gfsk.crc_length == RADIO_CRC_2_BYTES) ? 2.0f : 0.0f)) 474 | / _mod_params.params.gfsk.bit_rate) * 1000); 475 | } 476 | break; 477 | case MODEM_LORA: { 478 | float ts = lora_symbol_time[_mod_params.params.lora.bandwidth - 4][12 479 | - _mod_params.params.lora.spreading_factor]; 480 | // time of preamble 481 | float t_preamble = (_packet_params.params.lora.preamble_length + 4.25f) * ts; 482 | // Symbol length of payload and time 483 | float tmp = ceil((8 * pkt_len - 4 * _mod_params.params.lora.spreading_factor 484 | + 28 + 16 * _packet_params.params.lora.crc_mode 485 | - ((_packet_params.params.lora.header_type == LORA_PACKET_FIXED_LENGTH) ? 20 : 0)) 486 | / (float)(4 * (_mod_params.params.lora.spreading_factor 487 | - ((_mod_params.params.lora.low_datarate_optimization > 0) ? 2 : 0)))) 488 | * ((_mod_params.params.lora.coding_rate % 4) + 4); 489 | float n_payload = 8 + ((tmp > 0) ? tmp : 0); 490 | float t_payload = n_payload * ts; 491 | // Time on air 492 | float tOnAir = t_preamble + t_payload; 493 | // return milliseconds (as ts is in milliseconds) 494 | air_time = floor(tOnAir + 0.999); 495 | } 496 | break; 497 | } 498 | 499 | return air_time; 500 | } 501 | 502 | void SX126X_LoRaRadio::radio_reset() 503 | { 504 | _reset_ctl.output(); 505 | _reset_ctl = 0; 506 | // should be enough, required is 50-100 us 507 | ThisThread::sleep_for(2); 508 | _reset_ctl.input(); 509 | // give some time for automatic image calibration 510 | ThisThread::sleep_for(6); 511 | } 512 | 513 | void SX126X_LoRaRadio::wakeup() 514 | { 515 | // hold the NSS low, this should wakeup the chip. 516 | // now we should wait for the _busy line to go low 517 | if (_operation_mode == MODE_SLEEP) { 518 | _chip_select = 0; 519 | wait_us(100); 520 | _chip_select = 1; 521 | //wait_us(100); 522 | #if MBED_CONF_SX126X_LORA_DRIVER_SLEEP_MODE == 1 523 | wait_us(3500); 524 | // whenever we wakeup from Cold sleep state, we need to perform 525 | // image calibration 526 | _force_image_calibration = true; 527 | cold_start_wakeup(); 528 | #endif 529 | } 530 | } 531 | 532 | void SX126X_LoRaRadio::sleep(void) 533 | { 534 | // warm start, power consumption 600 nA 535 | uint8_t sleep_state = 0x04; 536 | _operation_mode = MODE_SLEEP; 537 | 538 | #if MBED_CONF_SX126X_LORA_DRIVER_SLEEP_MODE == 1 539 | // cold start, power consumption 160 nA 540 | sleep_state = 0x00; 541 | #endif 542 | 543 | write_opmode_command(RADIO_SET_SLEEP, &sleep_state, 1); 544 | ThisThread::sleep_for(2); 545 | } 546 | 547 | uint32_t SX126X_LoRaRadio::random(void) 548 | { 549 | set_modem(MODEM_LORA); 550 | uint8_t buf[] = {0, 0, 0, 0}; 551 | 552 | // Set radio in continuous reception 553 | _reception_mode = RECEPTION_MODE_OTHER; 554 | _rx_timeout = 0xFFFFFFFF; 555 | receive(); 556 | ThisThread::sleep_for(1); 557 | read_register(RANDOM_NUMBER_GENERATORBASEADDR, buf, 4); 558 | standby(); 559 | 560 | return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; 561 | } 562 | 563 | void SX126X_LoRaRadio::write_opmode_command(uint8_t cmd, uint8_t *buffer, uint16_t size) 564 | { 565 | _chip_select = 0; 566 | 567 | while (_busy) { 568 | // do nothing 569 | } 570 | 571 | _spi.write(cmd); 572 | 573 | for (int i = 0; i < size; i++) { 574 | _spi.write(buffer[i]); 575 | } 576 | 577 | _chip_select = 1; 578 | } 579 | 580 | void SX126X_LoRaRadio::read_opmode_command(uint8_t cmd, 581 | uint8_t *buffer, uint16_t size) 582 | { 583 | _chip_select = 0; 584 | 585 | while (_busy) { 586 | // do nothing 587 | } 588 | 589 | _spi.write(cmd); 590 | _spi.write(0); 591 | 592 | for (int i = 0; i < size; i++) { 593 | buffer[i] = _spi.write(0); 594 | } 595 | 596 | _chip_select = 1; 597 | } 598 | 599 | void SX126X_LoRaRadio::write_to_register(uint16_t addr, uint8_t data) 600 | { 601 | write_to_register(addr, &data, 1); 602 | } 603 | 604 | void SX126X_LoRaRadio::write_to_register(uint16_t addr, uint8_t *data, 605 | uint8_t size) 606 | { 607 | _chip_select = 0; 608 | 609 | _spi.write(RADIO_WRITE_REGISTER); 610 | _spi.write((addr & 0xFF00) >> 8); 611 | _spi.write(addr & 0x00FF); 612 | 613 | for (int i = 0; i < size; i++) { 614 | _spi.write(data[i]); 615 | } 616 | 617 | _chip_select = 1; 618 | } 619 | 620 | uint8_t SX126X_LoRaRadio::read_register(uint16_t addr) 621 | { 622 | uint8_t data; 623 | read_register(addr, &data, 1); 624 | return data; 625 | 626 | } 627 | 628 | void SX126X_LoRaRadio::read_register(uint16_t addr, uint8_t *buffer, 629 | uint8_t size) 630 | { 631 | _chip_select = 0; 632 | 633 | _spi.write(RADIO_READ_REGISTER); 634 | _spi.write((addr & 0xFF00) >> 8); 635 | _spi.write(addr & 0x00FF); 636 | _spi.write(0); 637 | 638 | for (int i = 0; i < size; i++) { 639 | buffer[i] = _spi.write(0); 640 | } 641 | 642 | _chip_select = 1; 643 | } 644 | 645 | void SX126X_LoRaRadio::write_fifo(uint8_t *buffer, uint8_t size) 646 | { 647 | _chip_select = 0; 648 | 649 | _spi.write(RADIO_WRITE_BUFFER); 650 | _spi.write(0); 651 | 652 | for (int i = 0; i < size; i++) { 653 | _spi.write(buffer[i]); 654 | } 655 | 656 | _chip_select = 1; 657 | } 658 | 659 | void SX126X_LoRaRadio::set_modem(uint8_t modem) 660 | { 661 | _active_modem = modem; 662 | 663 | // setting modem type must happen in stnadby mode 664 | if (_operation_mode != MODE_STDBY_RC) { 665 | standby(); 666 | } 667 | 668 | write_opmode_command(RADIO_SET_PACKETTYPE, &_active_modem, 1); 669 | } 670 | 671 | uint8_t SX126X_LoRaRadio::get_modem() 672 | { 673 | return _active_modem; 674 | } 675 | 676 | void SX126X_LoRaRadio::read_fifo(uint8_t *buffer, uint8_t size, uint8_t offset) 677 | { 678 | _chip_select = 0; 679 | 680 | _spi.write(RADIO_READ_BUFFER); 681 | _spi.write(offset); 682 | _spi.write(0); 683 | 684 | for (int i = 0; i < size; i++) { 685 | buffer[i] = _spi.write(0); 686 | } 687 | 688 | _chip_select = 1; 689 | } 690 | 691 | uint8_t SX126X_LoRaRadio::get_device_variant(void) 692 | { 693 | uint16_t val = 0; 694 | val = _dev_select.read_u16(); 695 | 696 | if (val <= 0x2000) { 697 | return SX1262; 698 | } else if (val <= 0xA000) { 699 | return SX1268; 700 | } else { 701 | return SX1261; 702 | } 703 | } 704 | 705 | uint8_t SX126X_LoRaRadio::get_frequency_support(void) 706 | { 707 | uint16_t val = 0; 708 | val = _freq_select.read_u16(); 709 | 710 | if (val < 100) { 711 | return (MATCHING_FREQ_915); 712 | } else if (val <= 0x3000) { 713 | return (MATCHING_FREQ_780); 714 | } else if (val <= 0x4900) { // 0x4724 715 | return (MATCHING_FREQ_490); 716 | } else if (val <= 1) { 717 | return (MATCHING_FREQ_434); 718 | } else if (val <= 1) { 719 | return (MATCHING_FREQ_280); 720 | } else if (val <= 0xF000) { 721 | return (MATCHING_FREQ_169); 722 | } else { 723 | return (MATCHING_FREQ_868); 724 | } 725 | } 726 | 727 | uint8_t SX126X_LoRaRadio::get_fsk_bw_reg_val(uint32_t bandwidth) 728 | { 729 | uint8_t i; 730 | 731 | for (i = 0; i < (sizeof(fsk_bandwidths) / sizeof(fsk_bw_t)) - 1; i++) { 732 | if ((bandwidth >= fsk_bandwidths[i].bandwidth) 733 | && (bandwidth < fsk_bandwidths[i + 1].bandwidth)) { 734 | return fsk_bandwidths[i].register_value; 735 | } 736 | } 737 | // ERROR: Value not found 738 | // This should never happen 739 | while (1); 740 | } 741 | 742 | void SX126X_LoRaRadio::set_max_payload_length(radio_modems_t modem, uint8_t max) 743 | { 744 | if (modem == MODEM_LORA) { 745 | _packet_params.params.lora.payload_length = max; 746 | } else { 747 | _packet_params.params.gfsk.payload_length = max; 748 | } 749 | } 750 | 751 | void SX126X_LoRaRadio::set_tx_config(radio_modems_t modem, 752 | int8_t power, 753 | uint32_t fdev, 754 | uint32_t bandwidth, 755 | uint32_t datarate, 756 | uint8_t coderate, 757 | uint16_t preamble_len, 758 | bool fix_len, 759 | bool crc_on, 760 | bool freq_hop_on, 761 | uint8_t hop_period, 762 | bool iq_inverted, 763 | uint32_t timeout) 764 | { 765 | 766 | uint8_t modem_type = (uint8_t) modem; 767 | switch (modem_type) { 768 | case MODEM_FSK: 769 | _mod_params.modem_type = MODEM_FSK; 770 | _mod_params.params.gfsk.bit_rate = datarate; 771 | 772 | _mod_params.params.gfsk.modulation_shaping = MOD_SHAPING_G_BT_1; 773 | _mod_params.params.gfsk.bandwidth = get_fsk_bw_reg_val(bandwidth); 774 | _mod_params.params.gfsk.fdev = fdev; 775 | 776 | _packet_params.modem_type = MODEM_FSK; 777 | _packet_params.params.gfsk.preamble_length = (preamble_len << 3); // convert byte into bit 778 | _packet_params.params.gfsk.preamble_min_detect = RADIO_PREAMBLE_DETECTOR_08_BITS; 779 | _packet_params.params.gfsk.syncword_length = 3 << 3; // convert byte into bit 780 | _packet_params.params.gfsk.addr_comp = RADIO_ADDRESSCOMP_FILT_OFF; 781 | _packet_params.params.gfsk.header_type = (fix_len == true) ? 782 | RADIO_PACKET_FIXED_LENGTH : 783 | RADIO_PACKET_VARIABLE_LENGTH; 784 | 785 | if (crc_on) { 786 | _packet_params.params.gfsk.crc_length = RADIO_CRC_2_BYTES_CCIT; 787 | } else { 788 | _packet_params.params.gfsk.crc_length = RADIO_CRC_OFF; 789 | } 790 | _packet_params.params.gfsk.whitening_mode = RADIO_DC_FREEWHITENING; 791 | 792 | set_modem(MODEM_FSK); 793 | 794 | write_to_register(REG_LR_SYNCWORDBASEADDRESS, (uint8_t *) sync_word, 8); 795 | set_whitening_seed(0x01FF); 796 | break; 797 | 798 | case MODEM_LORA: 799 | _mod_params.modem_type = MODEM_LORA; 800 | _mod_params.params.lora.spreading_factor = (lora_spread_factors_t) datarate; 801 | _mod_params.params.lora.bandwidth = (lora_bandwidths_t) lora_bandwidhts[bandwidth]; 802 | _mod_params.params.lora.coding_rate = (lora_coding_tates_t) coderate; 803 | 804 | if (((bandwidth == 0) && ((datarate == 11) || (datarate == 12))) 805 | || ((bandwidth == 1) && (datarate == 12))) { 806 | _mod_params.params.lora.low_datarate_optimization = 0x01; 807 | } else { 808 | _mod_params.params.lora.low_datarate_optimization = 0x00; 809 | } 810 | 811 | _packet_params.modem_type = MODEM_LORA; 812 | 813 | if ((_mod_params.params.lora.spreading_factor == LORA_SF5) 814 | || (_mod_params.params.lora.spreading_factor == LORA_SF6)) { 815 | if (preamble_len < 12) { 816 | _packet_params.params.lora.preamble_length = 12; 817 | } else { 818 | _packet_params.params.lora.preamble_length = preamble_len; 819 | } 820 | } else { 821 | _packet_params.params.lora.preamble_length = preamble_len; 822 | } 823 | 824 | _packet_params.params.lora.header_type = (lora_pkt_length_t) fix_len; 825 | _packet_params.params.lora.crc_mode = (lora_crc_mode_t) crc_on; 826 | _packet_params.params.lora.invert_IQ = (lora_IQ_mode_t) iq_inverted; 827 | 828 | set_modem(MODEM_LORA); 829 | 830 | break; 831 | } 832 | 833 | _tx_power = power; 834 | _tx_timeout = timeout; 835 | } 836 | 837 | void SX126X_LoRaRadio::set_rx_config(radio_modems_t modem, 838 | uint32_t bandwidth, 839 | uint32_t datarate, 840 | uint8_t coderate, 841 | uint32_t bandwidthAfc, 842 | uint16_t preamble_len, 843 | uint16_t symb_timeout, 844 | bool fix_len, 845 | uint8_t payload_len, 846 | bool crc_on, 847 | bool freq_hop_on, 848 | uint8_t hop_period, 849 | bool iq_inverted, 850 | bool rx_continuous) 851 | { 852 | uint8_t max_payload_len; 853 | (void) freq_hop_on; 854 | (void) hop_period; 855 | 856 | if (rx_continuous) { 857 | _reception_mode = RECEPTION_MODE_CONTINUOUS; 858 | symb_timeout = 0; 859 | } else { 860 | _reception_mode = RECEPTION_MODE_SINGLE; 861 | } 862 | 863 | if (fix_len == true) { 864 | max_payload_len = payload_len; 865 | } else { 866 | max_payload_len = 0xFF; 867 | } 868 | 869 | uint8_t modem_type = (uint8_t) modem; 870 | 871 | switch (modem_type) { 872 | case MODEM_FSK: { 873 | _mod_params.modem_type = MODEM_FSK; 874 | _mod_params.params.gfsk.bit_rate = datarate; 875 | _mod_params.params.gfsk.modulation_shaping = MOD_SHAPING_G_BT_1; 876 | _mod_params.params.gfsk.bandwidth = get_fsk_bw_reg_val(bandwidth); 877 | 878 | _packet_params.modem_type = MODEM_FSK; 879 | _packet_params.params.gfsk.preamble_length = (preamble_len << 3); // convert byte into bit 880 | _packet_params.params.gfsk.preamble_min_detect = 881 | RADIO_PREAMBLE_DETECTOR_08_BITS; 882 | _packet_params.params.gfsk.syncword_length = 3 << 3; // convert byte into bit 883 | _packet_params.params.gfsk.addr_comp = RADIO_ADDRESSCOMP_FILT_OFF; 884 | _packet_params.params.gfsk.header_type = 885 | (fix_len == true) ? 886 | RADIO_PACKET_FIXED_LENGTH : 887 | RADIO_PACKET_VARIABLE_LENGTH; 888 | _packet_params.params.gfsk.payload_length = max_payload_len; 889 | 890 | if (crc_on) { 891 | _packet_params.params.gfsk.crc_length = RADIO_CRC_2_BYTES_CCIT; 892 | } else { 893 | _packet_params.params.gfsk.crc_length = RADIO_CRC_OFF; 894 | } 895 | 896 | _packet_params.params.gfsk.whitening_mode = RADIO_DC_FREEWHITENING; 897 | 898 | set_modem(MODEM_FSK); 899 | 900 | write_to_register(REG_LR_SYNCWORDBASEADDRESS, (uint8_t *) sync_word, 8); 901 | set_whitening_seed(0x01FF); 902 | 903 | _rx_timeout = (uint32_t)(symb_timeout 904 | * ((1.0 / (float) datarate) * 8.0) * 1000); 905 | 906 | break; 907 | } 908 | 909 | case MODEM_LORA: { 910 | _rx_timeout_in_symbols = symb_timeout; 911 | _mod_params.modem_type = MODEM_LORA; 912 | _mod_params.params.lora.spreading_factor = 913 | (lora_spread_factors_t) datarate; 914 | _mod_params.params.lora.bandwidth = (lora_bandwidths_t) lora_bandwidhts[bandwidth]; 915 | _mod_params.params.lora.coding_rate = 916 | (lora_coding_tates_t) coderate; 917 | 918 | if (((bandwidth == 0) && ((datarate == 11) || (datarate == 12))) 919 | || ((bandwidth == 1) && (datarate == 12))) { 920 | _mod_params.params.lora.low_datarate_optimization = 0x01; 921 | } else { 922 | _mod_params.params.lora.low_datarate_optimization = 0x00; 923 | } 924 | 925 | _packet_params.modem_type = MODEM_LORA; 926 | 927 | if ((_mod_params.params.lora.spreading_factor == LORA_SF5) 928 | || (_mod_params.params.lora.spreading_factor == LORA_SF6)) { 929 | if (preamble_len < 12) { 930 | _packet_params.params.lora.preamble_length = 12; 931 | } else { 932 | _packet_params.params.lora.preamble_length = preamble_len; 933 | } 934 | } else { 935 | _packet_params.params.lora.preamble_length = preamble_len; 936 | } 937 | 938 | _packet_params.params.lora.header_type = (lora_pkt_length_t) fix_len; 939 | _packet_params.params.lora.payload_length = max_payload_len; 940 | _packet_params.params.lora.crc_mode = (lora_crc_mode_t) crc_on; 941 | _packet_params.params.lora.invert_IQ = (lora_IQ_mode_t) iq_inverted; 942 | 943 | set_modem(MODEM_LORA); 944 | 945 | if (_reception_mode == RECEPTION_MODE_CONTINUOUS) { 946 | _rx_timeout = 0xFFFFFFFF; 947 | } else { 948 | _rx_timeout = 0x00000000; 949 | } 950 | 951 | break; 952 | } 953 | 954 | default: 955 | break; 956 | } 957 | } 958 | 959 | void SX126X_LoRaRadio::configure_dio_irq(uint16_t irq_mask, uint16_t dio1_mask, 960 | uint16_t dio2_mask, uint16_t dio3_mask) 961 | { 962 | uint8_t buf[8]; 963 | 964 | buf[0] = (uint8_t)((irq_mask >> 8) & 0x00FF); 965 | buf[1] = (uint8_t)(irq_mask & 0x00FF); 966 | buf[2] = (uint8_t)((dio1_mask >> 8) & 0x00FF); 967 | buf[3] = (uint8_t)(dio1_mask & 0x00FF); 968 | buf[4] = (uint8_t)((dio2_mask >> 8) & 0x00FF); 969 | buf[5] = (uint8_t)(dio2_mask & 0x00FF); 970 | buf[6] = (uint8_t)((dio3_mask >> 8) & 0x00FF); 971 | buf[7] = (uint8_t)(dio3_mask & 0x00FF); 972 | 973 | write_opmode_command((uint8_t) RADIO_CFG_DIOIRQ, buf, 8); 974 | } 975 | 976 | void SX126X_LoRaRadio::send(uint8_t *buffer, uint8_t size) 977 | { 978 | set_tx_power(_tx_power); 979 | configure_dio_irq(IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, 980 | IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, 981 | IRQ_RADIO_NONE, 982 | IRQ_RADIO_NONE); 983 | 984 | set_modulation_params(&_mod_params); 985 | set_packet_params(&_packet_params); 986 | 987 | write_fifo(buffer, size); 988 | uint8_t buf[3]; 989 | 990 | // _tx_timeout in ms should be converted to us and then divided by 991 | // 15.625 us. Check data-sheet 13.1.4 SetTX() section. 992 | uint32_t timeout_scalled = ceil((_tx_timeout * 1000) / 15.625); 993 | 994 | buf[0] = (uint8_t)((timeout_scalled >> 16) & 0xFF); 995 | buf[1] = (uint8_t)((timeout_scalled >> 8) & 0xFF); 996 | buf[2] = (uint8_t)(timeout_scalled & 0xFF); 997 | 998 | write_opmode_command(RADIO_SET_TX, buf, 3); 999 | 1000 | _operation_mode = MODE_TX; 1001 | } 1002 | 1003 | 1004 | void SX126X_LoRaRadio::receive(void) 1005 | { 1006 | if (get_modem() == MODEM_LORA) { 1007 | if (_reception_mode != RECEPTION_MODE_CONTINUOUS) { 1008 | // Data-sheet Table 13-11: StopOnPreambParam 1009 | // We will use radio's internal timer to mark no reception. This behaviour 1010 | // is different from SX1272/SX1276 where we are relying on radio to stop 1011 | // at preamble detection. 1012 | // 0x00 means Timer will be stopped on SyncWord(FSK) or Header (LoRa) detection 1013 | // 0x01 means Timer is stopped on preamble detection 1014 | uint8_t stop_at_preamble = 0x01; 1015 | write_opmode_command(RADIO_SET_STOPRXTIMERONPREAMBLE, &stop_at_preamble, 1); 1016 | } 1017 | 1018 | // Data-sheet 13.4.9 SetLoRaSymbNumTimeout 1019 | write_opmode_command(RADIO_SET_LORASYMBTIMEOUT, &_rx_timeout_in_symbols, 1); 1020 | } 1021 | 1022 | if (_reception_mode != RECEPTION_MODE_OTHER) { 1023 | configure_dio_irq(IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR, 1024 | IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR, 1025 | IRQ_RADIO_NONE, 1026 | IRQ_RADIO_NONE); 1027 | set_modulation_params(&_mod_params); 1028 | set_packet_params(&_packet_params); 1029 | } 1030 | 1031 | uint8_t buf[3]; 1032 | 1033 | #if MBED_CONF_SX126X_LORA_DRIVER_BOOST_RX 1034 | write_to_register(REG_RX_GAIN, 0x96); 1035 | #endif 1036 | 1037 | buf[0] = (uint8_t)((_rx_timeout >> 16) & 0xFF); 1038 | buf[1] = (uint8_t)((_rx_timeout >> 8) & 0xFF); 1039 | buf[2] = (uint8_t)(_rx_timeout & 0xFF); 1040 | 1041 | write_opmode_command(RADIO_SET_RX, buf, 3); 1042 | 1043 | _operation_mode = MODE_RX; 1044 | } 1045 | 1046 | // check data-sheet 13.1.14.1 PA optimal settings 1047 | void SX126X_LoRaRadio::set_tx_power(int8_t power) 1048 | { 1049 | uint8_t buf[2]; 1050 | 1051 | if (get_device_variant() == SX1261) { 1052 | if (power >= 14) { 1053 | set_pa_config(0x04, 0x00, 0x01, 0x01); 1054 | power = 14; 1055 | } else if (power < 14) { 1056 | set_pa_config(0x01, 0x00, 0x01, 0x01); 1057 | } 1058 | 1059 | if (power < -3) { 1060 | power = -3; 1061 | } 1062 | write_to_register(REG_OCP, 0x18); // current max is 80 mA for the whole device 1063 | } else { 1064 | // sx1262 or sx1268 1065 | if (power > 22) { 1066 | power = 22; 1067 | } else if (power < -3) { 1068 | power = -3; 1069 | } 1070 | 1071 | if (power <= 14) { 1072 | set_pa_config(0x02, 0x02, 0x00, 0x01); 1073 | } else { 1074 | set_pa_config(0x04, 0x07, 0x00, 0x01); 1075 | } 1076 | 1077 | write_to_register(REG_OCP, 0x38); // current max 160mA for the whole device 1078 | } 1079 | 1080 | buf[0] = power; 1081 | 1082 | if (_crystal_select.is_connected() && _crystal_select == 0) { 1083 | // TCXO 1084 | buf[1] = RADIO_RAMP_200_US; 1085 | } else { 1086 | // XTAL 1087 | buf[1] = RADIO_RAMP_20_US; 1088 | } 1089 | 1090 | write_opmode_command(RADIO_SET_TXPARAMS, buf, 2); 1091 | } 1092 | 1093 | void SX126X_LoRaRadio::set_modulation_params(modulation_params_t *params) 1094 | { 1095 | uint8_t n; 1096 | uint32_t temp = 0; 1097 | uint8_t buf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 1098 | 1099 | // Check if required configuration corresponds to the stored packet type 1100 | // If not, silently update radio packet type 1101 | if (_active_modem != params->modem_type) { 1102 | set_modem(params->modem_type); 1103 | } 1104 | 1105 | switch (params->modem_type) { 1106 | case MODEM_FSK: 1107 | n = 8; 1108 | temp = (uint32_t)(32 * ((float) XTAL_FREQ / (float) params->params.gfsk.bit_rate)); 1109 | buf[0] = (temp >> 16) & 0xFF; 1110 | buf[1] = (temp >> 8) & 0xFF; 1111 | buf[2] = temp & 0xFF; 1112 | buf[3] = params->params.gfsk.modulation_shaping; 1113 | buf[4] = params->params.gfsk.bandwidth; 1114 | temp = (uint32_t)((float) params->params.gfsk.fdev / (float) FREQ_STEP); 1115 | buf[5] = (temp >> 16) & 0xFF; 1116 | buf[6] = (temp >> 8) & 0xFF; 1117 | buf[7] = (temp & 0xFF); 1118 | write_opmode_command(RADIO_SET_MODULATIONPARAMS, buf, n); 1119 | break; 1120 | 1121 | case MODEM_LORA: 1122 | n = 4; 1123 | buf[0] = params->params.lora.spreading_factor; 1124 | buf[1] = params->params.lora.bandwidth; 1125 | buf[2] = params->params.lora.coding_rate; 1126 | buf[3] = params->params.lora.low_datarate_optimization; 1127 | 1128 | write_opmode_command(RADIO_SET_MODULATIONPARAMS, buf, n); 1129 | break; 1130 | 1131 | default: 1132 | return; 1133 | } 1134 | } 1135 | 1136 | void SX126X_LoRaRadio::set_pa_config(uint8_t pa_DC, uint8_t hp_max, 1137 | uint8_t device_type, uint8_t pa_LUT) 1138 | { 1139 | uint8_t buf[4]; 1140 | 1141 | buf[0] = pa_DC; 1142 | buf[1] = hp_max; 1143 | buf[2] = device_type; 1144 | buf[3] = pa_LUT; 1145 | write_opmode_command(RADIO_SET_PACONFIG, buf, 4); 1146 | } 1147 | 1148 | void SX126X_LoRaRadio::set_crc_seed(uint16_t seed) 1149 | { 1150 | if (_active_modem == MODEM_FSK) { 1151 | uint8_t buf[2]; 1152 | buf[0] = (uint8_t)((seed >> 8) & 0xFF); 1153 | buf[1] = (uint8_t)(seed & 0xFF); 1154 | write_to_register(REG_LR_CRCSEEDBASEADDR, buf, 2); 1155 | } 1156 | } 1157 | 1158 | void SX126X_LoRaRadio::set_crc_polynomial(uint16_t polynomial) 1159 | { 1160 | if (_active_modem == MODEM_FSK) { 1161 | uint8_t buf[2]; 1162 | buf[0] = (uint8_t)((polynomial >> 8) & 0xFF); 1163 | buf[1] = (uint8_t)(polynomial & 0xFF); 1164 | write_to_register(REG_LR_CRCPOLYBASEADDR, buf, 2); 1165 | } 1166 | } 1167 | 1168 | void SX126X_LoRaRadio::set_whitening_seed(uint16_t seed) 1169 | { 1170 | if (_active_modem == MODEM_FSK) { 1171 | uint8_t reg_value = read_register(REG_LR_WHITSEEDBASEADDR_MSB) & 0xFE; 1172 | reg_value = ((seed >> 8) & 0x01) | reg_value; 1173 | write_to_register(REG_LR_WHITSEEDBASEADDR_MSB, reg_value); // only 1 bit. 1174 | write_to_register(REG_LR_WHITSEEDBASEADDR_LSB, (uint8_t) seed); 1175 | } 1176 | } 1177 | 1178 | void SX126X_LoRaRadio::set_packet_params(packet_params_t *packet_params) 1179 | { 1180 | uint8_t n; 1181 | uint8_t crc_val = 0; 1182 | uint8_t buf[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 1183 | 1184 | // Check if required configuration corresponds to the stored packet type 1185 | // If not, silently update radio packet type 1186 | if (_active_modem != packet_params->modem_type) { 1187 | set_modem(packet_params->modem_type); 1188 | } 1189 | 1190 | switch (packet_params->modem_type) { 1191 | case MODEM_FSK: 1192 | if (packet_params->params.gfsk.crc_length == RADIO_CRC_2_BYTES_IBM) { 1193 | set_crc_seed(CRC_IBM_SEED); 1194 | set_crc_polynomial(CRC_POLYNOMIAL_IBM); 1195 | crc_val = RADIO_CRC_2_BYTES; 1196 | } else if (packet_params->params.gfsk.crc_length == RADIO_CRC_2_BYTES_CCIT) { 1197 | set_crc_seed(CRC_CCITT_SEED); 1198 | set_crc_polynomial(CRC_POLYNOMIAL_CCITT); 1199 | crc_val = RADIO_CRC_2_BYTES_INV; 1200 | } else { 1201 | crc_val = packet_params->params.gfsk.crc_length; 1202 | } 1203 | n = 9; 1204 | buf[0] = (packet_params->params.gfsk.preamble_length >> 8) & 0xFF; 1205 | buf[1] = packet_params->params.gfsk.preamble_length; 1206 | buf[2] = packet_params->params.gfsk.preamble_min_detect; 1207 | buf[3] = (packet_params->params.gfsk.syncword_length /*<< 3*/); // convert from byte to bit 1208 | buf[4] = packet_params->params.gfsk.addr_comp; 1209 | buf[5] = packet_params->params.gfsk.header_type; 1210 | buf[6] = packet_params->params.gfsk.payload_length; 1211 | buf[7] = crc_val; 1212 | buf[8] = packet_params->params.gfsk.whitening_mode; 1213 | break; 1214 | 1215 | case MODEM_LORA: 1216 | n = 6; 1217 | buf[0] = (packet_params->params.lora.preamble_length >> 8) & 0xFF; 1218 | buf[1] = packet_params->params.lora.preamble_length; 1219 | buf[2] = packet_params->params.lora.header_type; 1220 | buf[3] = packet_params->params.lora.payload_length; 1221 | buf[4] = packet_params->params.lora.crc_mode; 1222 | buf[5] = packet_params->params.lora.invert_IQ; 1223 | break; 1224 | default: 1225 | return; 1226 | } 1227 | write_opmode_command(RADIO_SET_PACKETPARAMS, buf, n); 1228 | } 1229 | 1230 | void SX126X_LoRaRadio::set_cad_params(lora_cad_symbols_t nb_symbols, 1231 | uint8_t det_peak, uint8_t det_min, 1232 | cad_exit_modes_t exit_mode, 1233 | uint32_t timeout) 1234 | { 1235 | uint8_t buf[7]; 1236 | 1237 | buf[0] = (uint8_t) nb_symbols; 1238 | buf[1] = det_peak; 1239 | buf[2] = det_min; 1240 | buf[3] = (uint8_t) exit_mode; 1241 | buf[4] = (uint8_t)((timeout >> 16) & 0xFF); 1242 | buf[5] = (uint8_t)((timeout >> 8) & 0xFF); 1243 | buf[6] = (uint8_t)(timeout & 0xFF); 1244 | write_opmode_command((uint8_t) RADIO_SET_CADPARAMS, buf, 7); 1245 | 1246 | _operation_mode = MODE_CAD; 1247 | } 1248 | 1249 | void SX126X_LoRaRadio::set_buffer_base_addr(uint8_t tx_base_addr, uint8_t rx_base_addr) 1250 | { 1251 | uint8_t buf[2]; 1252 | 1253 | buf[0] = tx_base_addr; 1254 | buf[1] = rx_base_addr; 1255 | write_opmode_command((uint8_t) RADIO_SET_BUFFERBASEADDRESS, buf, 2); 1256 | } 1257 | 1258 | uint8_t SX126X_LoRaRadio::get_status(void) 1259 | { 1260 | if (_operation_mode != MODE_STDBY_RC || _operation_mode != MODE_SLEEP) { 1261 | return 0; 1262 | } 1263 | 1264 | return 0xFF; 1265 | } 1266 | 1267 | int8_t SX126X_LoRaRadio::get_rssi() 1268 | { 1269 | uint8_t buf[1]; 1270 | int8_t rssi = 0; 1271 | 1272 | read_opmode_command((uint8_t) RADIO_GET_RSSIINST, buf, 1); 1273 | rssi = -buf[0] >> 1; 1274 | return rssi; 1275 | } 1276 | 1277 | void SX126X_LoRaRadio::get_rx_buffer_status(uint8_t *payload_len, 1278 | uint8_t *start_ptr) 1279 | { 1280 | uint8_t status[2]; 1281 | 1282 | read_opmode_command((uint8_t) RADIO_GET_RXBUFFERSTATUS, status, 2); 1283 | 1284 | // In case of LORA fixed header, the payloadLength is obtained by reading 1285 | // the register REG_LR_PAYLOADLENGTH 1286 | if ((get_modem() == MODEM_LORA) && 1287 | (read_register(REG_LR_PACKETPARAMS) >> 7 == 1)) { 1288 | *payload_len = read_register(REG_LR_PAYLOADLENGTH); 1289 | } else { 1290 | *payload_len = status[0]; 1291 | } 1292 | 1293 | *start_ptr = status[1]; 1294 | } 1295 | 1296 | void SX126X_LoRaRadio::get_packet_status(packet_status_t *pkt_status) 1297 | { 1298 | uint8_t status[3]; 1299 | 1300 | read_opmode_command((uint8_t) RADIO_GET_PACKETSTATUS, status, 3); 1301 | 1302 | pkt_status->modem_type = (radio_modems_t) get_modem(); 1303 | switch (pkt_status->modem_type) { 1304 | case MODEM_FSK: 1305 | pkt_status->params.gfsk.rx_status = status[0]; 1306 | pkt_status->params.gfsk.rssi_sync = -status[1] >> 1; 1307 | pkt_status->params.gfsk.rssi_avg = -status[2] >> 1; 1308 | pkt_status->params.gfsk.freq_error = 0; 1309 | break; 1310 | 1311 | case MODEM_LORA: 1312 | pkt_status->params.lora.rssi_pkt = -status[0] >> 1; 1313 | // Returns SNR value [dB] rounded to the nearest integer value 1314 | pkt_status->params.lora.snr_pkt = (((int8_t) status[1]) + 2) >> 2; 1315 | pkt_status->params.lora.signal_rssi_pkt = -status[2] >> 1; 1316 | break; 1317 | 1318 | default: 1319 | // In that specific case, we set everything in the pkt_status to zeros 1320 | // and reset the packet type accordingly 1321 | memset(pkt_status, 0, sizeof(packet_status_t)); 1322 | break; 1323 | } 1324 | } 1325 | 1326 | radio_error_t SX126X_LoRaRadio::get_device_errors(void) 1327 | { 1328 | radio_error_t error; 1329 | 1330 | read_opmode_command((uint8_t) RADIO_GET_ERROR, (uint8_t *)&error, 2); 1331 | return error; 1332 | } 1333 | 1334 | void SX126X_LoRaRadio::clear_device_errors(void) 1335 | { 1336 | uint8_t buf[2] = {0x00, 0x00}; 1337 | write_opmode_command((uint8_t) RADIO_CLR_ERROR, buf, 2); 1338 | } 1339 | 1340 | -------------------------------------------------------------------------------- /SX126X/SX126X_LoRaRadio.h: -------------------------------------------------------------------------------- 1 | /** 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2015 Semtech 8 | ___ _____ _ ___ _ _____ ___ ___ ___ ___ 9 | / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 10 | \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 11 | |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 12 | embedded.connectivity.solutions=============== 13 | 14 | Description: LoRaWAN stack layer that controls both MAC and PHY underneath 15 | 16 | License: Revised BSD License, see LICENSE.TXT file include in the project 17 | 18 | Maintainer: Miguel Luis, Gregory Cristian & Gilbert Menth 19 | 20 | Copyright (c) 2019, Arm Limited and affiliates. 21 | 22 | SPDX-License-Identifier: BSD-3-Clause 23 | */ 24 | 25 | #ifndef MBED_LORA_RADIO_DRV_SX126X_LORARADIO_H_ 26 | #define MBED_LORA_RADIO_DRV_SX126X_LORARADIO_H_ 27 | 28 | #include "mbed_critical.h" 29 | #include "PinNames.h" 30 | #include "InterruptIn.h" 31 | #include "DigitalOut.h" 32 | #include "DigitalInOut.h" 33 | #include "DigitalIn.h" 34 | #include "AnalogIn.h" 35 | #include "SPI.h" 36 | #include "platform/PlatformMutex.h" 37 | #ifdef MBED_CONF_RTOS_PRESENT 38 | #include "rtos/Thread.h" 39 | #include "rtos/ThisThread.h" 40 | #endif 41 | #include "sx126x_ds.h" 42 | #include "lorawan/LoRaRadio.h" 43 | 44 | #ifdef MBED_CONF_SX126X_LORA_DRIVER_BUFFER_SIZE 45 | #define MAX_DATA_BUFFER_SIZE_SX126X MBED_CONF_SX126X_LORA_DRIVER_BUFFER_SIZE 46 | #else 47 | #define MAX_DATA_BUFFER_SIZE_SX126X 255 48 | #endif 49 | 50 | class SX126X_LoRaRadio : public LoRaRadio { 51 | 52 | public: 53 | SX126X_LoRaRadio(PinName mosi, 54 | PinName miso, 55 | PinName sclk, 56 | PinName nss, 57 | PinName reset, 58 | PinName dio1, 59 | PinName busy, 60 | PinName freq_select, 61 | PinName device_select, 62 | PinName crystal_select, 63 | PinName ant_switch); 64 | 65 | virtual ~SX126X_LoRaRadio(); 66 | 67 | /** 68 | * Registers radio events with the Mbed LoRaWAN stack and 69 | * undergoes initialization steps if any 70 | * 71 | * @param events Structure containing the driver callback functions 72 | */ 73 | virtual void init_radio(radio_events_t *events); 74 | 75 | /** 76 | * Resets the radio module 77 | */ 78 | virtual void radio_reset(); 79 | 80 | /** 81 | * Put the RF module in sleep mode 82 | */ 83 | virtual void sleep(void); 84 | 85 | /** 86 | * Sets the radio in standby mode 87 | */ 88 | virtual void standby(void); 89 | 90 | /** 91 | * Sets the reception parameters 92 | * 93 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 94 | * @param bandwidth Sets the bandwidth 95 | * FSK : >= 2600 and <= 250000 Hz 96 | * LoRa: [0: 125 kHz, 1: 250 kHz, 97 | * 2: 500 kHz, 3: Reserved] 98 | * @param datarate Sets the Datarate 99 | * FSK : 600..300000 bits/s 100 | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, 101 | * 10: 1024, 11: 2048, 12: 4096 chips] 102 | * @param coderate Sets the coding rate ( LoRa only ) 103 | * FSK : N/A ( set to 0 ) 104 | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] 105 | * @param bandwidth_afc Sets the AFC Bandwidth ( FSK only ) 106 | * FSK : >= 2600 and <= 250000 Hz 107 | * LoRa: N/A ( set to 0 ) 108 | * @param preamble_len Sets the Preamble length ( LoRa only ) 109 | * FSK : N/A ( set to 0 ) 110 | * LoRa: Length in symbols ( the hardware adds 4 more symbols ) 111 | * @param symb_timeout Sets the RxSingle timeout value 112 | * FSK : timeout number of bytes 113 | * LoRa: timeout in symbols 114 | * @param fixLen Fixed length packets [0: variable, 1: fixed] 115 | * @param payload_len Sets payload length when fixed lenght is used 116 | * @param crc_on Enables/Disables the CRC [0: OFF, 1: ON] 117 | * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) 118 | * @param hop_period Number of symbols bewteen each hop (LoRa only) 119 | * @param iq_inverted Inverts IQ signals ( LoRa only ) 120 | * FSK : N/A ( set to 0 ) 121 | * LoRa: [0: not inverted, 1: inverted] 122 | * @param rx_continuous Sets the reception in continuous mode 123 | * [false: single mode, true: continuous mode] 124 | */ 125 | virtual void set_rx_config(radio_modems_t modem, uint32_t bandwidth, 126 | uint32_t datarate, uint8_t coderate, 127 | uint32_t bandwidth_afc, uint16_t preamble_len, 128 | uint16_t symb_timeout, bool fix_len, 129 | uint8_t payload_len, 130 | bool crc_on, bool freq_hop_on, uint8_t hop_period, 131 | bool iq_inverted, bool rx_continuous); 132 | 133 | /** 134 | * Sets the transmission parameters 135 | * 136 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 137 | * @param power Sets the output power [dBm] 138 | * @param fdev Sets the frequency deviation ( FSK only ) 139 | * FSK : [Hz] 140 | * LoRa: 0 141 | * @param bandwidth Sets the bandwidth ( LoRa only ) 142 | * FSK : 0 143 | * LoRa: [0: 125 kHz, 1: 250 kHz, 144 | * 2: 500 kHz, 3: Reserved] 145 | * @param datarate Sets the Datarate 146 | * FSK : 600..300000 bits/s 147 | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, 148 | * 10: 1024, 11: 2048, 12: 4096 chips] 149 | * @param coderate Sets the coding rate ( LoRa only ) 150 | * FSK : N/A ( set to 0 ) 151 | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] 152 | * @param preamble_len Sets the preamble length 153 | * @param fix_len Fixed length packets [0: variable, 1: fixed] 154 | * @param crc_on Enables disables the CRC [0: OFF, 1: ON] 155 | * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) 156 | * @param hop_period Number of symbols bewteen each hop (LoRa only) 157 | * @param iq_inverted Inverts IQ signals ( LoRa only ) 158 | * FSK : N/A ( set to 0 ) 159 | * LoRa: [0: not inverted, 1: inverted] 160 | * @param timeout Transmission timeout [ms] 161 | */ 162 | virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, 163 | uint32_t bandwidth, uint32_t datarate, 164 | uint8_t coderate, uint16_t preamble_len, 165 | bool fix_len, bool crc_on, bool freq_hop_on, 166 | uint8_t hop_period, bool iq_inverted, uint32_t timeout); 167 | 168 | /** 169 | * Sends the buffer of size 170 | * 171 | * Prepares the packet to be sent and sets the radio in transmission 172 | * 173 | * @param buffer Buffer pointer 174 | * @param size Buffer size 175 | */ 176 | virtual void send(uint8_t *buffer, uint8_t size); 177 | 178 | /** 179 | * Sets the radio to receive 180 | * 181 | * All necessary configuration options for reception are set in 182 | * 'set_rx_config(parameters)' API. 183 | */ 184 | virtual void receive(void); 185 | 186 | /** 187 | * Sets the carrier frequency 188 | * 189 | * @param freq Channel RF frequency 190 | */ 191 | virtual void set_channel(uint32_t freq); 192 | 193 | /** 194 | * Generates a 32 bits random value based on the RSSI readings 195 | * 196 | * Remark this function sets the radio in LoRa modem mode and disables 197 | * all interrupts. 198 | * After calling this function either Radio.SetRxConfig or 199 | * Radio.SetTxConfig functions must be called. 200 | * 201 | * @return 32 bits random value 202 | */ 203 | virtual uint32_t random(void); 204 | 205 | /** 206 | * Get radio status 207 | * 208 | * @param status Radio status [RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] 209 | * @return Return current radio status 210 | */ 211 | virtual uint8_t get_status(void); 212 | 213 | /** 214 | * Sets the maximum payload length 215 | * 216 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 217 | * @param max Maximum payload length in bytes 218 | */ 219 | virtual void set_max_payload_length(radio_modems_t modem, uint8_t max); 220 | 221 | /** 222 | * Sets the network to public or private 223 | * 224 | * Updates the sync byte. Applies to LoRa modem only 225 | * 226 | * @param enable if true, it enables a public network 227 | */ 228 | virtual void set_public_network(bool enable); 229 | 230 | /** 231 | * Computes the packet time on air for the given payload 232 | * 233 | * Remark can only be called once SetRxConfig or SetTxConfig have been called 234 | * 235 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 236 | * @param pkt_len Packet payload length 237 | * @return Computed airTime for the given packet payload length 238 | */ 239 | virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len); 240 | 241 | /** 242 | * Perform carrier sensing 243 | * 244 | * Checks for a certain time if the RSSI is above a given threshold. 245 | * This threshold determines if there is already a transmission going on 246 | * in the channel or not. 247 | * 248 | * @param modem Type of the radio modem 249 | * @param freq Carrier frequency 250 | * @param rssi_threshold Threshold value of RSSI 251 | * @param max_carrier_sense_time time to sense the channel 252 | * 253 | * @return true if there is no active transmission 254 | * in the channel, false otherwise 255 | */ 256 | virtual bool perform_carrier_sense(radio_modems_t modem, 257 | uint32_t freq, 258 | int16_t rssi_threshold, 259 | uint32_t max_carrier_sense_time); 260 | 261 | /** 262 | * Sets the radio in CAD mode 263 | * 264 | */ 265 | virtual void start_cad(void); 266 | 267 | /** 268 | * Check if the given RF is in range 269 | * 270 | * @param frequency frequency needed to be checked 271 | */ 272 | virtual bool check_rf_frequency(uint32_t frequency); 273 | 274 | /** Sets the radio in continuous wave transmission mode 275 | * 276 | * @param freq Channel RF frequency 277 | * @param power Sets the output power [dBm] 278 | * @param time Transmission mode timeout [s] 279 | */ 280 | virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time); 281 | 282 | /** 283 | * Acquire exclusive access 284 | */ 285 | virtual void lock(void); 286 | 287 | /** 288 | * Release exclusive access 289 | */ 290 | virtual void unlock(void); 291 | 292 | private: 293 | 294 | // SPI and chip select control 295 | mbed::SPI _spi; 296 | mbed::DigitalOut _chip_select; 297 | 298 | // module rest control 299 | mbed::DigitalInOut _reset_ctl; 300 | 301 | // Interrupt controls 302 | mbed::InterruptIn _dio1_ctl;; 303 | 304 | // module busy control 305 | mbed::DigitalIn _busy; 306 | 307 | // module frequency selection 308 | mbed::AnalogIn _freq_select; 309 | 310 | // module device variant selection 311 | mbed::AnalogIn _dev_select; 312 | 313 | // module TCXO/XTAL control 314 | mbed::DigitalIn _crystal_select; 315 | 316 | // Radio specific controls (TX/RX duplexer switch control) 317 | mbed::DigitalInOut _ant_switch; 318 | 319 | // Structure containing function pointers to the stack callbacks 320 | radio_events_t *_radio_events; 321 | 322 | // Data buffer used for both TX and RX 323 | // Size of this buffer is configurable via Mbed config system 324 | // Default is 255 bytes 325 | uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX126X]; 326 | 327 | #ifdef MBED_CONF_RTOS_PRESENT 328 | // Thread to handle interrupts 329 | rtos::Thread irq_thread; 330 | #endif 331 | 332 | // Access protection 333 | PlatformMutex mutex; 334 | 335 | // helper functions 336 | void wakeup(); 337 | void read_opmode_command(uint8_t cmd, uint8_t *buffer, uint16_t size); 338 | void write_opmode_command(uint8_t cmd, uint8_t *buffer, uint16_t size); 339 | void set_dio2_as_rfswitch_ctrl(uint8_t enable); 340 | void set_dio3_as_tcxo_ctrl(radio_TCXO_ctrl_voltage_t voltage, uint32_t timeout); 341 | uint8_t get_device_variant(void); 342 | void set_device_ready(void); 343 | int8_t get_rssi(); 344 | uint8_t get_fsk_bw_reg_val(uint32_t bandwidth); 345 | void write_to_register(uint16_t addr, uint8_t data); 346 | void write_to_register(uint16_t addr, uint8_t *data, uint8_t size); 347 | uint8_t read_register(uint16_t addr); 348 | void read_register(uint16_t addr, uint8_t *buffer, uint8_t size); 349 | void write_fifo(uint8_t *buffer, uint8_t size); 350 | void read_fifo(uint8_t *buffer, uint8_t size, uint8_t offset); 351 | void rf_irq_task(void); 352 | void set_modem(uint8_t modem); 353 | uint8_t get_modem(); 354 | uint16_t get_irq_status(void); 355 | uint8_t get_frequency_support(void); 356 | 357 | // ISR 358 | void dio1_irq_isr(); 359 | 360 | // Handler called by thread in response to signal 361 | void handle_dio1_irq(); 362 | 363 | void set_modulation_params(modulation_params_t *modulationParams); 364 | void set_packet_params(packet_params_t *packet_params); 365 | void set_cad_params(lora_cad_symbols_t nb_symbols, uint8_t det_peak, 366 | uint8_t det_min, cad_exit_modes_t exit_mode, 367 | uint32_t timeout); 368 | void set_buffer_base_addr(uint8_t tx_base_addr, uint8_t rx_base_addr); 369 | void get_rx_buffer_status(uint8_t *payload_len, uint8_t *rx_buffer_ptr); 370 | void get_packet_status(packet_status_t *pkt_status); 371 | radio_error_t get_device_errors(void); 372 | void clear_device_errors(void); 373 | void clear_irq_status(uint16_t irq); 374 | void set_crc_seed(uint16_t seed); 375 | void set_crc_polynomial(uint16_t polynomial); 376 | void set_whitening_seed(uint16_t seed); 377 | void set_pa_config(uint8_t pa_DC, uint8_t hp_max, uint8_t device_type, 378 | uint8_t pa_LUT); 379 | void set_tx_power(int8_t power); 380 | void calibrate_image(uint32_t freq); 381 | void configure_dio_irq(uint16_t irq_mask, uint16_t dio1_mask, 382 | uint16_t dio2_mask, uint16_t dio3_mask); 383 | void cold_start_wakeup(); 384 | 385 | private: 386 | uint8_t _active_modem; 387 | uint8_t _standby_mode; 388 | uint8_t _operation_mode; 389 | uint8_t _reception_mode; 390 | uint32_t _tx_timeout; 391 | uint32_t _rx_timeout; 392 | uint8_t _rx_timeout_in_symbols; 393 | int8_t _tx_power; 394 | bool _image_calibrated; 395 | bool _force_image_calibration; 396 | bool _network_mode_public; 397 | 398 | // Structure containing all user and network specified settings 399 | // for radio module 400 | modulation_params_t _mod_params; 401 | packet_params_t _packet_params; 402 | }; 403 | 404 | #endif /* MBED_LORA_RADIO_DRV_SX126X_LORARADIO_H_ */ 405 | -------------------------------------------------------------------------------- /SX126X/SleepMode.txt: -------------------------------------------------------------------------------- 1 | Sleep Modes: 2 | 3 | The SX126X series LoRa radios define two different sleep modes, namely: 4 | 5 | i) Sleep mode with Cold Start (default mode in Mbed LoRaWAN stack) 6 | ii) Sleep mode with Warm Start 7 | 8 | 9 | Sleep mode with Warm Start: 10 | This is the default sleep mode for this driver. Radio configurations are retained in this mode. 11 | Typical power consumption in this mode is '600 nA'. 12 | 13 | 14 | Sleep mode with Cold Start: 15 | The driver can be configured to sleep with cold startup. This mode is the lowest power consuming state 16 | for the SX126X series radios. No configurations are retained in this mode, that's why our driver takes 17 | extra measures to keep backups of the configuration in the RAM. Typical power consumption in this mode 18 | is '160 nA'. The radio takes about 3.5 milliseconds to wakeup properly because upon going to sleep all 19 | components gets turned off. The radio thread blocks for that period of time. However, to reduce the impact 20 | of this wakeup time on the time critical operations, the stack shouldn't put the radio to standby rather than 21 | sleep before performing time critical operations. Mbed OS LoRaWAN stack handles this automatically which means 22 | that the user can safely use sleep mode with cold start. -------------------------------------------------------------------------------- /SX126X/mbed_lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SX126X-lora-driver", 3 | "config": { 4 | "spi-frequency": { 5 | "help": "SPI frequency, Default: 16 MHz", 6 | "value": 16000000 7 | }, 8 | "buffer-size": { 9 | "help": "Max. buffer size the radio can handle, Default: 255 B", 10 | "value": 255 11 | }, 12 | "boost-rx": { 13 | "help": "Increases sensitivity at the cost of power ~2mA for around ~3dB in sensitivity 0 = disabled, 1 = enabled", 14 | "value": 0 15 | }, 16 | "regulator-mode": { 17 | "help": "Default: DCDC (low power, high BOM). Alternatively, LDO = 0. Check datasheet section 5.1 for more details", 18 | "value": 1 19 | }, 20 | "sleep-mode": { 21 | "help": "Default: Cold start = 1, Warm start = 0. Check SleepMode.txt", 22 | "value": 1 23 | }, 24 | "standby-mode": { 25 | "help": "Default: STDBY_RC = 0, STDBY_XOSC = 1", 26 | "value": 0 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SX126X/sx126x_ds.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file sx126x.h 3 | * 4 | * \brief SX126x driver implementation 5 | * 6 | * \copyright Revised BSD License, see section \ref LICENSE. 7 | * 8 | * \code 9 | * ______ _ 10 | * / _____) _ | | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 | * _____) ) ____| | | || |_| ____( (___| | | | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 | * (C)2013-2017 Semtech 16 | * 17 | * \endcode 18 | * 19 | * \author Miguel Luis ( Semtech ) 20 | * 21 | * \author Gregory Cristian ( Semtech ) 22 | * 23 | * Copyright (c) 2019, Arm Limited and affiliates. 24 | * 25 | * SPDX-License-Identifier: BSD-3-Clause 26 | */ 27 | 28 | #ifndef MBED_LORA_RADIO_DRV_SX126X_SX126X_DS_H_ 29 | #define MBED_LORA_RADIO_DRV_SX126X_SX126X_DS_H_ 30 | 31 | #include "LoRaRadio.h" 32 | /*! 33 | * \brief Provides the frequency of the chip running on the radio and the frequency step 34 | * 35 | * \remark These defines are used for computing the frequency divider to set the RF frequency 36 | */ 37 | #define XTAL_FREQ 32000000 38 | #define FREQ_DIV 33554432 39 | #define FREQ_STEP 0.95367431640625 // ((double)(XTAL_FREQ / (double)FREQ_DIV)) 40 | #define FREQ_ERR 0.47683715820312 41 | 42 | 43 | /*! 44 | * \brief List of devices supported by this driver 45 | */ 46 | #define SX1261 0 47 | #define SX1262 1 48 | #define SX1268 2 49 | 50 | /*! 51 | * \brief List of matching supported by the sx126x 52 | */ 53 | #define MATCHING_FREQ_915 0 54 | #define MATCHING_FREQ_780 1 55 | #define MATCHING_FREQ_490 2 56 | #define MATCHING_FREQ_434 3 57 | #define MATCHING_FREQ_280 4 58 | #define MATCHING_FREQ_169 5 59 | #define MATCHING_FREQ_868 6 60 | 61 | /*! 62 | * \brief Compensation delay for SetAutoTx/Rx functions in 15.625 microseconds 63 | */ 64 | #define AUTO_RX_TX_OFFSET 2 65 | 66 | /*! 67 | * \brief LFSR initial value to compute IBM type CRC 68 | */ 69 | #define CRC_IBM_SEED 0xFFFF 70 | 71 | /*! 72 | * \brief LFSR initial value to compute CCIT type CRC 73 | */ 74 | #define CRC_CCITT_SEED 0x1D0F 75 | 76 | /*! 77 | * \brief Polynomial used to compute IBM CRC 78 | */ 79 | #define CRC_POLYNOMIAL_IBM 0x8005 80 | 81 | /*! 82 | * \brief Polynomial used to compute CCIT CRC 83 | */ 84 | #define CRC_POLYNOMIAL_CCITT 0x1021 85 | 86 | /*! 87 | * \brief The address of the register holding the first byte defining the CRC seed 88 | * 89 | */ 90 | #define REG_LR_CRCSEEDBASEADDR 0x06BC 91 | 92 | /*! 93 | * \brief The address of the register holding the first byte defining the CRC polynomial 94 | */ 95 | #define REG_LR_CRCPOLYBASEADDR 0x06BE 96 | 97 | /*! 98 | * \brief The address of the register holding the first byte defining the whitening seed 99 | */ 100 | #define REG_LR_WHITSEEDBASEADDR_MSB 0x06B8 101 | #define REG_LR_WHITSEEDBASEADDR_LSB 0x06B9 102 | 103 | /*! 104 | * \brief The address of the register holding the packet configuration 105 | */ 106 | #define REG_LR_PACKETPARAMS 0x0704 107 | 108 | /*! 109 | * \brief The address of the register holding the payload size 110 | */ 111 | #define REG_LR_PAYLOADLENGTH 0x0702 112 | 113 | /*! 114 | * \brief The addresses of the registers holding SyncWords values 115 | */ 116 | #define REG_LR_SYNCWORDBASEADDRESS 0x06C0 117 | 118 | /*! 119 | * \brief The addresses of the register holding LoRa Modem SyncWord value 120 | */ 121 | #define REG_LR_SYNCWORD 0x0740 122 | 123 | /*! 124 | * Syncword for Private LoRa networks 125 | */ 126 | #define LORA_MAC_PRIVATE_SYNCWORD 0x1424 127 | 128 | /*! 129 | * Syncword for Public LoRa networks 130 | */ 131 | #define LORA_MAC_PUBLIC_SYNCWORD 0x3444 132 | 133 | /*! 134 | * The address of the register giving a 4 bytes random number 135 | */ 136 | #define RANDOM_NUMBER_GENERATORBASEADDR 0x0819 137 | 138 | /*! 139 | * The address of the register holding RX Gain value (0x94: power saving, 0x96: rx boosted) 140 | */ 141 | #define REG_RX_GAIN 0x08AC 142 | 143 | /*! 144 | * The address of the register holding frequency error indication 145 | */ 146 | #define REG_FREQUENCY_ERRORBASEADDR 0x076B 147 | 148 | /*! 149 | * Change the value on the device internal trimming capacitor 150 | */ 151 | #define REG_XTA_TRIM 0x0911 152 | 153 | /*! 154 | * Set the current max value in the over current protection 155 | */ 156 | #define REG_OCP 0x08E7 157 | 158 | 159 | /*! 160 | * \brief Represents the Rx internal counters values when GFSK or LoRa packet type is used 161 | */ 162 | typedef struct { 163 | radio_modems_t modem_type; //!< Packet to which the packet status are referring to. 164 | uint16_t packet_received; 165 | uint16_t crc_ok; 166 | uint16_t length_error; 167 | } rx_counter_t; 168 | 169 | /*! 170 | * \brief Represents a calibration configuration 171 | */ 172 | typedef union { 173 | struct { 174 | uint8_t rc64k_enable : 1; //!< Calibrate RC64K clock 175 | uint8_t rc13m_enable : 1; //!< Calibrate RC13M clock 176 | uint8_t pll_enable : 1; //!< Calibrate PLL 177 | uint8_t adc_pulse_enable : 1; //!< Calibrate ADC Pulse 178 | uint8_t adc_bulkN_enable : 1; //!< Calibrate ADC bulkN 179 | uint8_t adc_bulkP_enable : 1; //!< Calibrate ADC bulkP 180 | uint8_t img_enable : 1; 181 | uint8_t pad : 1; 182 | } fields; 183 | 184 | uint8_t value; 185 | 186 | } caliberation_params_t; 187 | 188 | /*! 189 | * \brief Represents the possible radio system error states 190 | */ 191 | typedef union { 192 | struct { 193 | uint8_t rc64k_calib : 1; //!< RC 64kHz oscillator calibration failed 194 | uint8_t rc13m_calib : 1; //!< RC 13MHz oscillator calibration failed 195 | uint8_t pll_calib : 1; //!< PLL calibration failed 196 | uint8_t adc_calib : 1; //!< ADC calibration failed 197 | uint8_t img_calib : 1; //!< Image calibration failed 198 | uint8_t xosc_start : 1; //!< XOSC oscillator failed to start 199 | uint8_t pll_lock : 1; //!< PLL lock failed 200 | uint8_t buck_start : 1; //!< Buck converter failed to start 201 | uint8_t pa_ramp : 1; //!< PA ramp failed 202 | uint8_t reserved : 7; //!< reserved 203 | } fields; 204 | 205 | uint16_t value; 206 | 207 | } radio_error_t; 208 | 209 | /*! 210 | * \brief Represents the operating mode the radio is actually running 211 | */ 212 | typedef enum { 213 | MODE_SLEEP = 0x00, //! The radio is in sleep mode 214 | MODE_DEEP_SLEEP, //! The radio is in deep-sleep mode 215 | MODE_STDBY_RC, //! The radio is in standby mode with RC oscillator 216 | MODE_STDBY_XOSC, //! The radio is in standby mode with XOSC oscillator 217 | MODE_FS, //! The radio is in frequency synthesis mode 218 | MODE_TX, //! The radio is in transmit mode 219 | MODE_RX, //! The radio is in receive mode 220 | MODE_RX_DC, //! The radio is in receive duty cycle mode 221 | MODE_CAD //! The radio is in channel activity detection mode 222 | } radio_operating_mode_t; 223 | 224 | /*! 225 | * \brief Declares the oscillator in use while in standby mode 226 | * 227 | * Using the STDBY_RC standby mode allow to reduce the energy consumption 228 | * STDBY_XOSC should be used for time critical applications 229 | */ 230 | typedef enum { 231 | STDBY_RC = 0x00, 232 | STDBY_XOSC = 0x01, 233 | } radio_standby_mode_t; 234 | 235 | /*! 236 | * \brief Declares the power regulation used to power the device 237 | * 238 | * This command allows the user to specify if DC-DC or LDO is used for power regulation. 239 | * Using only LDO implies that the Rx or Tx current is doubled 240 | */ 241 | typedef enum { 242 | USE_LDO = 0x00, // default 243 | USE_DCDC = 0x01, 244 | } radio_regulator_mode_t; 245 | 246 | /*! 247 | * \brief Represents the ramping time for power amplifier 248 | */ 249 | typedef enum { 250 | RADIO_RAMP_10_US = 0x00, 251 | RADIO_RAMP_20_US = 0x01, 252 | RADIO_RAMP_40_US = 0x02, 253 | RADIO_RAMP_80_US = 0x03, 254 | RADIO_RAMP_200_US = 0x04, 255 | RADIO_RAMP_800_US = 0x05, 256 | RADIO_RAMP_1700_US = 0x06, 257 | RADIO_RAMP_3400_US = 0x07, 258 | } radio_ramp_time_t; 259 | 260 | /*! 261 | * \brief Represents the number of symbols to be used for channel activity detection operation 262 | */ 263 | typedef enum { 264 | LORA_CAD_01_SYMBOL = 0x00, 265 | LORA_CAD_02_SYMBOL = 0x01, 266 | LORA_CAD_04_SYMBOL = 0x02, 267 | LORA_CAD_08_SYMBOL = 0x03, 268 | LORA_CAD_16_SYMBOL = 0x04, 269 | } lora_cad_symbols_t; 270 | 271 | /*! 272 | * \brief Represents the Channel Activity Detection actions after the CAD operation is finished 273 | */ 274 | typedef enum { 275 | LORA_CAD_ONLY = 0x00, 276 | LORA_CAD_RX = 0x01, 277 | LORA_CAD_LBT = 0x10, 278 | } cad_exit_modes_t; 279 | 280 | /*! 281 | * \brief Represents the modulation shaping parameter 282 | */ 283 | typedef enum { 284 | MOD_SHAPING_OFF = 0x00, 285 | MOD_SHAPING_G_BT_03 = 0x08, 286 | MOD_SHAPING_G_BT_05 = 0x09, 287 | MOD_SHAPING_G_BT_07 = 0x0A, 288 | MOD_SHAPING_G_BT_1 = 0x0B, 289 | } radio_mod_shaping_t; 290 | 291 | /*! 292 | * \brief Represents the modulation shaping parameter 293 | */ 294 | typedef enum { 295 | RX_BW_4800 = 0x1F, 296 | RX_BW_5800 = 0x17, 297 | RX_BW_7300 = 0x0F, 298 | RX_BW_9700 = 0x1E, 299 | RX_BW_11700 = 0x16, 300 | RX_BW_14600 = 0x0E, 301 | RX_BW_19500 = 0x1D, 302 | RX_BW_23400 = 0x15, 303 | RX_BW_29300 = 0x0D, 304 | RX_BW_39000 = 0x1C, 305 | RX_BW_46900 = 0x14, 306 | RX_BW_58600 = 0x0C, 307 | RX_BW_78200 = 0x1B, 308 | RX_BW_93800 = 0x13, 309 | RX_BW_117300 = 0x0B, 310 | RX_BW_156200 = 0x1A, 311 | RX_BW_187200 = 0x12, 312 | RX_BW_234300 = 0x0A, 313 | RX_BW_312000 = 0x19, 314 | RX_BW_373600 = 0x11, 315 | RX_BW_467000 = 0x09, 316 | } radio_rx_bandwidth_t; 317 | 318 | /*! 319 | * \brief Represents the possible spreading factor values in LoRa packet types 320 | */ 321 | typedef enum { 322 | LORA_SF5 = 0x05, 323 | LORA_SF6 = 0x06, 324 | LORA_SF7 = 0x07, 325 | LORA_SF8 = 0x08, 326 | LORA_SF9 = 0x09, 327 | LORA_SF10 = 0x0A, 328 | LORA_SF11 = 0x0B, 329 | LORA_SF12 = 0x0C, 330 | } lora_spread_factors_t; 331 | 332 | /*! 333 | * \brief Represents the bandwidth values for LoRa packet type 334 | */ 335 | typedef enum { 336 | LORA_BW_500 = 6, 337 | LORA_BW_250 = 5, 338 | LORA_BW_125 = 4, 339 | LORA_BW_062 = 3, 340 | LORA_BW_041 = 10, 341 | LORA_BW_031 = 2, 342 | LORA_BW_020 = 9, 343 | LORA_BW_015 = 1, 344 | LORA_BW_010 = 8, 345 | LORA_BW_007 = 0, 346 | } lora_bandwidths_t; 347 | 348 | const uint8_t lora_bandwidhts [] = {LORA_BW_125, LORA_BW_250, LORA_BW_500}; 349 | 350 | /*! 351 | * \brief Represents the coding rate values for LoRa packet type 352 | */ 353 | typedef enum { 354 | LORA_CR_4_5 = 0x01, 355 | LORA_CR_4_6 = 0x02, 356 | LORA_CR_4_7 = 0x03, 357 | LORA_CR_4_8 = 0x04, 358 | } lora_coding_tates_t; 359 | 360 | /*! 361 | * \brief Represents the preamble length used to detect the packet on Rx side 362 | */ 363 | typedef enum { 364 | RADIO_PREAMBLE_DETECTOR_OFF = 0x00, //!< Preamble detection length off 365 | RADIO_PREAMBLE_DETECTOR_08_BITS = 0x04, //!< Preamble detection length 8 bits 366 | RADIO_PREAMBLE_DETECTOR_16_BITS = 0x05, //!< Preamble detection length 16 bits 367 | RADIO_PREAMBLE_DETECTOR_24_BITS = 0x06, //!< Preamble detection length 24 bits 368 | RADIO_PREAMBLE_DETECTOR_32_BITS = 0x07, //!< Preamble detection length 32 bit 369 | } radio_preamble_detection_t; 370 | 371 | /*! 372 | * \brief Represents the possible combinations of SyncWord correlators activated 373 | */ 374 | typedef enum { 375 | RADIO_ADDRESSCOMP_FILT_OFF = 0x00, //!< No correlator turned on, i.e. do not search for SyncWord 376 | RADIO_ADDRESSCOMP_FILT_NODE = 0x01, 377 | RADIO_ADDRESSCOMP_FILT_NODE_BROAD = 0x02, 378 | } radio_address_filter_t; 379 | 380 | /*! 381 | * \brief Radio packet length mode 382 | */ 383 | typedef enum { 384 | RADIO_PACKET_VARIABLE_LENGTH = 0x00, //!< The packet is on variable size, header included 385 | RADIO_PACKET_FIXED_LENGTH = 0x01, //!< The packet is known on both sides, no header included in the packet 386 | } radio_pkt_length_t; 387 | 388 | /*! 389 | * \brief Represents the CRC length 390 | */ 391 | typedef enum radio_crc_types_e { 392 | RADIO_CRC_OFF = 0x01, //!< No CRC in use 393 | RADIO_CRC_1_BYTES = 0x00, 394 | RADIO_CRC_2_BYTES = 0x02, 395 | RADIO_CRC_1_BYTES_INV = 0x04, 396 | RADIO_CRC_2_BYTES_INV = 0x06, 397 | RADIO_CRC_2_BYTES_IBM = 0xF1, 398 | RADIO_CRC_2_BYTES_CCIT = 0xF2, 399 | } radio_crc_types_t; 400 | 401 | /*! 402 | * \brief Radio whitening mode activated or deactivated 403 | */ 404 | typedef enum { 405 | RADIO_DC_FREE_OFF = 0x00, 406 | RADIO_DC_FREEWHITENING = 0x01, 407 | } radio_whitening_mode_t; 408 | 409 | /*! 410 | * \brief Holds the lengths mode of a LoRa packet type 411 | */ 412 | typedef enum { 413 | LORA_PACKET_VARIABLE_LENGTH = 0x00, //!< The packet is on variable size, header included 414 | LORA_PACKET_FIXED_LENGTH = 0x01, //!< The packet is known on both sides, no header included in the packet 415 | LORA_PACKET_EXPLICIT = LORA_PACKET_VARIABLE_LENGTH, 416 | LORA_PACKET_IMPLICIT = LORA_PACKET_FIXED_LENGTH, 417 | } lora_pkt_length_t; 418 | 419 | /*! 420 | * \brief Represents the CRC mode for LoRa packet type 421 | */ 422 | typedef enum { 423 | LORA_CRC_ON = 0x01, //!< CRC activated 424 | LORA_CRC_OFF = 0x00, //!< CRC not used 425 | } lora_crc_mode_t; 426 | 427 | /*! 428 | * \brief Represents the IQ mode for LoRa packet type 429 | */ 430 | typedef enum { 431 | LORA_IQ_NORMAL = 0x00, 432 | LORA_IQ_INVERTED = 0x01, 433 | } lora_IQ_mode_t; 434 | 435 | /*! 436 | * \brief Represents the volatge used to control the TCXO on/off from DIO3 437 | */ 438 | typedef enum { 439 | TCXO_CTRL_1_6V = 0x00, 440 | TCXO_CTRL_1_7V = 0x01, 441 | TCXO_CTRL_1_8V = 0x02, 442 | TCXO_CTRL_2_2V = 0x03, 443 | TCXO_CTRL_2_4V = 0x04, 444 | TCXO_CTRL_2_7V = 0x05, 445 | TCXO_CTRL_3_0V = 0x06, 446 | TCXO_CTRL_3_3V = 0x07, 447 | } radio_TCXO_ctrl_voltage_t; 448 | 449 | /*! 450 | * \brief Represents the interruption masks available for the radio 451 | * 452 | * \remark Note that not all these interruptions are available for all packet types 453 | */ 454 | typedef enum { 455 | IRQ_RADIO_NONE = 0x0000, 456 | IRQ_TX_DONE = 0x0001, 457 | IRQ_RX_DONE = 0x0002, 458 | IRQ_PREAMBLE_DETECTED = 0x0004, 459 | IRQ_SYNCWORD_VALID = 0x0008, 460 | IRQ_HEADER_VALID = 0x0010, 461 | IRQ_HEADER_ERROR = 0x0020, 462 | IRQ_CRC_ERROR = 0x0040, 463 | IRQ_CAD_DONE = 0x0080, 464 | IRQ_CAD_ACTIVITY_DETECTED = 0x0100, 465 | IRQ_RX_TX_TIMEOUT = 0x0200, 466 | IRQ_RADIO_ALL = 0xFFFF, 467 | } radio_irq_masks_t; 468 | 469 | typedef enum { 470 | RADIO_GET_STATUS = 0xC0, 471 | RADIO_WRITE_REGISTER = 0x0D, 472 | RADIO_READ_REGISTER = 0x1D, 473 | RADIO_WRITE_BUFFER = 0x0E, 474 | RADIO_READ_BUFFER = 0x1E, 475 | RADIO_SET_SLEEP = 0x84, 476 | RADIO_SET_STANDBY = 0x80, 477 | RADIO_SET_FS = 0xC1, 478 | RADIO_SET_TX = 0x83, 479 | RADIO_SET_RX = 0x82, 480 | RADIO_SET_RXDUTYCYCLE = 0x94, 481 | RADIO_SET_CAD = 0xC5, 482 | RADIO_SET_TXCONTINUOUSWAVE = 0xD1, 483 | RADIO_SET_TXCONTINUOUSPREAMBLE = 0xD2, 484 | RADIO_SET_PACKETTYPE = 0x8A, 485 | RADIO_GET_PACKETTYPE = 0x11, 486 | RADIO_SET_RFFREQUENCY = 0x86, 487 | RADIO_SET_TXPARAMS = 0x8E, 488 | RADIO_SET_PACONFIG = 0x95, 489 | RADIO_SET_CADPARAMS = 0x88, 490 | RADIO_SET_BUFFERBASEADDRESS = 0x8F, 491 | RADIO_SET_MODULATIONPARAMS = 0x8B, 492 | RADIO_SET_PACKETPARAMS = 0x8C, 493 | RADIO_GET_RXBUFFERSTATUS = 0x13, 494 | RADIO_GET_PACKETSTATUS = 0x14, 495 | RADIO_GET_RSSIINST = 0x15, 496 | RADIO_GET_STATS = 0x10, 497 | RADIO_RESET_STATS = 0x00, 498 | RADIO_CFG_DIOIRQ = 0x08, 499 | RADIO_GET_IRQSTATUS = 0x12, 500 | RADIO_CLR_IRQSTATUS = 0x02, 501 | RADIO_CALIBRATE = 0x89, 502 | RADIO_CALIBRATEIMAGE = 0x98, 503 | RADIO_SET_REGULATORMODE = 0x96, 504 | RADIO_GET_ERROR = 0x17, 505 | RADIO_CLR_ERROR = 0x07, 506 | RADIO_SET_TCXOMODE = 0x97, 507 | RADIO_SET_TXFALLBACKMODE = 0x93, 508 | RADIO_SET_RFSWITCHMODE = 0x9D, 509 | RADIO_SET_STOPRXTIMERONPREAMBLE = 0x9F, 510 | RADIO_SET_LORASYMBTIMEOUT = 0xA0, 511 | } opmode_commands_t; 512 | 513 | /*! 514 | * \brief Structure describing the radio status 515 | */ 516 | typedef union { 517 | uint8_t value; 518 | struct { 519 | //bit order is lsb -> msb 520 | uint8_t reserved : 1; //!< Reserved 521 | uint8_t cmd_status : 3; //!< Command status 522 | uint8_t chip_mode : 3; //!< Chip mode 523 | uint8_t cpu_busy : 1; //!< Flag for CPU radio busy 524 | } fields; 525 | } radio_status_t; 526 | 527 | /*! 528 | * \brief Structure describing the error codes for callback functions 529 | */ 530 | typedef enum { 531 | IRQ_HEADER_ERROR_CODE = 0x01, 532 | IRQ_SYNCWORD_ERROR_CODE = 0x02, 533 | IRQ_CRC_ERROR_CODE = 0x04, 534 | } irq_error_t; 535 | 536 | 537 | typedef enum { 538 | IRQ_PBL_DETECT_CODE = 0x01, 539 | IRQ_SYNCWORD_VALID_CODE = 0x02, 540 | IRQ_HEADER_VALID_CODE = 0x04, 541 | } irq_valid_codes_t; 542 | 543 | typedef enum { 544 | IRQ_RX_TIMEOUT = 0x00, 545 | IRQ_TX_TIMEOUT = 0x01, 546 | } irq_timeout_t; 547 | 548 | typedef enum { 549 | RECEPTION_MODE_SINGLE = 0, 550 | RECEPTION_MODE_CONTINUOUS, 551 | RECEPTION_MODE_OTHER 552 | } reception_mode_t; 553 | 554 | /*! 555 | * \brief The type describing the modulation parameters for every packet types 556 | */ 557 | typedef struct { 558 | radio_modems_t modem_type; //!< Packet to which the modulation parameters are referring to. 559 | struct { 560 | struct { 561 | uint32_t bit_rate; 562 | uint32_t fdev; 563 | radio_mod_shaping_t modulation_shaping; 564 | uint8_t bandwidth; 565 | uint32_t operational_frequency; 566 | } gfsk; 567 | 568 | struct { 569 | lora_spread_factors_t spreading_factor; //!< Spreading Factor for the LoRa modulation 570 | lora_bandwidths_t bandwidth; //!< Bandwidth for the LoRa modulation 571 | lora_coding_tates_t coding_rate; //!< Coding rate for the LoRa modulation 572 | uint8_t low_datarate_optimization; //!< Indicates if the modem uses the low datarate optimization 573 | uint32_t operational_frequency; 574 | } lora; 575 | } params; //!< Holds the modulation parameters structure 576 | } modulation_params_t; 577 | 578 | /*! 579 | * \brief The type describing the packet parameters for every packet types 580 | */ 581 | typedef struct packet_params { 582 | radio_modems_t modem_type; //!< Packet to which the packet parameters are referring to. 583 | struct { 584 | /*! 585 | * \brief Holds the GFSK packet parameters 586 | */ 587 | struct { 588 | uint16_t preamble_length; //!< The preamble Tx length for GFSK packet type in bit 589 | radio_preamble_detection_t preamble_min_detect; //!< The preamble Rx length minimal for GFSK packet type 590 | uint8_t syncword_length; //!< The synchronization word length for GFSK packet type 591 | radio_address_filter_t addr_comp; //!< Activated SyncWord correlators 592 | radio_pkt_length_t header_type; //!< If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted 593 | uint8_t payload_length; //!< Size of the payload in the GFSK packet 594 | radio_crc_types_t crc_length; //!< Size of the CRC block in the GFSK packet 595 | radio_whitening_mode_t whitening_mode; 596 | } gfsk; 597 | /*! 598 | * \brief Holds the LoRa packet parameters 599 | */ 600 | struct { 601 | uint16_t preamble_length; //!< The preamble length is the number of LoRa symbols in the preamble 602 | lora_pkt_length_t header_type; //!< If the header is explicit, it will be transmitted in the LoRa packet. If the header is implicit, it will not be transmitted 603 | uint8_t payload_length; //!< Size of the payload in the LoRa packet 604 | lora_crc_mode_t crc_mode; //!< Size of CRC block in LoRa packet 605 | lora_IQ_mode_t invert_IQ; //!< Allows to swap IQ for LoRa packet 606 | } lora; 607 | } params; //!< Holds the packet parameters structure 608 | } packet_params_t; 609 | 610 | /*! 611 | * \brief Represents the packet status for every packet type 612 | */ 613 | typedef struct { 614 | radio_modems_t modem_type; //!< Packet to which the packet status are referring to. 615 | struct { 616 | struct { 617 | uint8_t rx_status; 618 | int8_t rssi_avg; //!< The averaged RSSI 619 | int8_t rssi_sync; //!< The RSSI measured on last packet 620 | uint32_t freq_error; 621 | } gfsk; 622 | struct { 623 | int8_t rssi_pkt; //!< The RSSI of the last packet 624 | int8_t snr_pkt; //!< The SNR of the last packet 625 | int8_t signal_rssi_pkt; 626 | uint32_t freq_error; 627 | } lora; 628 | } params; 629 | } packet_status_t; 630 | 631 | 632 | #endif /* MBED_LORA_RADIO_DRV_SX126X_SX126X_DS_H_ */ 633 | -------------------------------------------------------------------------------- /SX1272/README.md: -------------------------------------------------------------------------------- 1 | # Mbed enabled SX1272 LoRa/FSK radio driver -------------------------------------------------------------------------------- /SX1272/SX1272_LoRaRadio.h: -------------------------------------------------------------------------------- 1 | /** 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | ___ _____ _ ___ _ _____ ___ ___ ___ ___ 9 | / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 10 | \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 11 | |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 12 | embedded.connectivity.solutions=============== 13 | 14 | Description: Radio driver for Semtech SX1272 radio. Implements LoRaRadio class. 15 | 16 | License: Revised BSD License, see LICENSE.TXT file include in the project 17 | 18 | Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 19 | 20 | 21 | Copyright (c) 2017, Arm Limited and affiliates. 22 | 23 | SPDX-License-Identifier: BSD-3-Clause 24 | */ 25 | 26 | #ifndef SX1272_LORARADIO_H_ 27 | #define SX1272_LORARADIO_H_ 28 | 29 | #include "PinNames.h" 30 | #include "InterruptIn.h" 31 | #include "DigitalOut.h" 32 | #include "DigitalInOut.h" 33 | #include "SPI.h" 34 | #include "platform/PlatformMutex.h" 35 | #ifdef MBED_CONF_RTOS_PRESENT 36 | #include "rtos/Thread.h" 37 | #endif 38 | 39 | #include "lorawan/LoRaRadio.h" 40 | 41 | #ifdef MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE 42 | #define MAX_DATA_BUFFER_SIZE_SX172 MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE 43 | #else 44 | #define MAX_DATA_BUFFER_SIZE_SX172 255 45 | #endif 46 | 47 | #if DEVICE_LPTICKER 48 | #include "LowPowerTimeout.h" 49 | #define ALIAS_LORAWAN_TIMER mbed::LowPowerTimeout 50 | #else 51 | #include "Timeout.h" 52 | #define ALIAS_LORAWAN_TIMER mbed::Timeout 53 | #endif 54 | 55 | /** 56 | * Radio driver implementation for Semtech SX1272 plus variants. 57 | * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. 58 | */ 59 | class SX1272_LoRaRadio: public LoRaRadio { 60 | public: 61 | /** 62 | * Use this constructor if pin definitions are provided manually. 63 | * The pins that are marked NC are optional. It is assumed that these 64 | * pins are not connected until/unless configured otherwise. 65 | */ 66 | SX1272_LoRaRadio(PinName mosi, 67 | PinName miso, 68 | PinName sclk, 69 | PinName nss, 70 | PinName reset, 71 | PinName dio0, 72 | PinName dio1, 73 | PinName dio2, 74 | PinName dio3, 75 | PinName dio4, 76 | PinName dio5, 77 | PinName rf_switch_ctl1 = NC, 78 | PinName rf_switch_ctl2 = NC, 79 | PinName txctl = NC, 80 | PinName rxctl = NC, 81 | PinName ant_switch = NC, 82 | PinName pwr_amp_ctl = NC, 83 | PinName tcxo = NC); 84 | 85 | /** 86 | * Destructor 87 | */ 88 | virtual ~SX1272_LoRaRadio(); 89 | 90 | /** 91 | * Registers radio events with the Mbed LoRaWAN stack and 92 | * undergoes initialization steps if any 93 | * 94 | * @param events Structure containing the driver callback functions 95 | */ 96 | virtual void init_radio(radio_events_t *events); 97 | 98 | /** 99 | * Resets the radio module 100 | */ 101 | virtual void radio_reset(); 102 | 103 | /** 104 | * Put the RF module in sleep mode 105 | */ 106 | virtual void sleep(void); 107 | 108 | /** 109 | * Sets the radio in standby mode 110 | */ 111 | virtual void standby(void); 112 | 113 | /** 114 | * Sets the reception parameters 115 | * 116 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 117 | * @param bandwidth Sets the bandwidth 118 | * FSK : >= 2600 and <= 250000 Hz 119 | * LoRa: [0: 125 kHz, 1: 250 kHz, 120 | * 2: 500 kHz, 3: Reserved] 121 | * @param datarate Sets the Datarate 122 | * FSK : 600..300000 bits/s 123 | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, 124 | * 10: 1024, 11: 2048, 12: 4096 chips] 125 | * @param coderate Sets the coding rate ( LoRa only ) 126 | * FSK : N/A ( set to 0 ) 127 | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] 128 | * @param bandwidth_afc Sets the AFC Bandwidth ( FSK only ) 129 | * FSK : >= 2600 and <= 250000 Hz 130 | * LoRa: N/A ( set to 0 ) 131 | * @param preamble_len Sets the Preamble length ( LoRa only ) 132 | * FSK : N/A ( set to 0 ) 133 | * LoRa: Length in symbols ( the hardware adds 4 more symbols ) 134 | * @param symb_timeout Sets the RxSingle timeout value 135 | * FSK : timeout number of bytes 136 | * LoRa: timeout in symbols 137 | * @param fixLen Fixed length packets [0: variable, 1: fixed] 138 | * @param payload_len Sets payload length when fixed lenght is used 139 | * @param crc_on Enables/Disables the CRC [0: OFF, 1: ON] 140 | * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) 141 | * @param hop_period Number of symbols bewteen each hop (LoRa only) 142 | * @param iq_inverted Inverts IQ signals ( LoRa only ) 143 | * FSK : N/A ( set to 0 ) 144 | * LoRa: [0: not inverted, 1: inverted] 145 | * @param rx_continuous Sets the reception in continuous mode 146 | * [false: single mode, true: continuous mode] 147 | */ 148 | virtual void set_rx_config(radio_modems_t modem, uint32_t bandwidth, 149 | uint32_t datarate, uint8_t coderate, 150 | uint32_t bandwidth_afc, uint16_t preamble_len, 151 | uint16_t symb_timeout, bool fix_len, 152 | uint8_t payload_len, 153 | bool crc_on, bool freq_hop_on, uint8_t hop_period, 154 | bool iq_inverted, bool rx_continuous); 155 | 156 | /** 157 | * Sets the transmission parameters 158 | * 159 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 160 | * @param power Sets the output power [dBm] 161 | * @param fdev Sets the frequency deviation ( FSK only ) 162 | * FSK : [Hz] 163 | * LoRa: 0 164 | * @param bandwidth Sets the bandwidth ( LoRa only ) 165 | * FSK : 0 166 | * LoRa: [0: 125 kHz, 1: 250 kHz, 167 | * 2: 500 kHz, 3: Reserved] 168 | * @param datarate Sets the Datarate 169 | * FSK : 600..300000 bits/s 170 | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, 171 | * 10: 1024, 11: 2048, 12: 4096 chips] 172 | * @param coderate Sets the coding rate ( LoRa only ) 173 | * FSK : N/A ( set to 0 ) 174 | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] 175 | * @param preamble_len Sets the preamble length 176 | * @param fix_len Fixed length packets [0: variable, 1: fixed] 177 | * @param crc_on Enables disables the CRC [0: OFF, 1: ON] 178 | * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) 179 | * @param hop_period Number of symbols bewteen each hop (LoRa only) 180 | * @param iq_inverted Inverts IQ signals ( LoRa only ) 181 | * FSK : N/A ( set to 0 ) 182 | * LoRa: [0: not inverted, 1: inverted] 183 | * @param timeout Transmission timeout [ms] 184 | */ 185 | virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, 186 | uint32_t bandwidth, uint32_t datarate, 187 | uint8_t coderate, uint16_t preamble_len, 188 | bool fix_len, bool crc_on, bool freq_hop_on, 189 | uint8_t hop_period, bool iq_inverted, uint32_t timeout); 190 | 191 | /** 192 | * Sends the buffer of size 193 | * 194 | * Prepares the packet to be sent and sets the radio in transmission 195 | * 196 | * @param buffer Buffer pointer 197 | * @param size Buffer size 198 | */ 199 | virtual void send(uint8_t *buffer, uint8_t size); 200 | 201 | /** 202 | * For backwards compatibility 203 | */ 204 | virtual void receive(uint32_t timeout) 205 | { 206 | (void) timeout; 207 | receive(); 208 | } 209 | 210 | /** 211 | * Sets the radio to receive 212 | * 213 | * All necessary configuration options for receptions are set in 214 | * 'set_rx_config(parameters)' API. 215 | */ 216 | virtual void receive(void); 217 | 218 | /** 219 | * Sets the carrier frequency 220 | * 221 | * @param freq Channel RF frequency 222 | */ 223 | virtual void set_channel(uint32_t freq); 224 | 225 | /** 226 | * Generates a 32 bits random value based on the RSSI readings 227 | * 228 | * Remark this function sets the radio in LoRa modem mode and disables 229 | * all interrupts. 230 | * After calling this function either Radio.SetRxConfig or 231 | * Radio.SetTxConfig functions must be called. 232 | * 233 | * @return 32 bits random value 234 | */ 235 | virtual uint32_t random(void); 236 | 237 | /** 238 | * Get radio status 239 | * 240 | * @param status Radio status [RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] 241 | * @return Return current radio status 242 | */ 243 | virtual uint8_t get_status(void); 244 | 245 | /** 246 | * Sets the maximum payload length 247 | * 248 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 249 | * @param max Maximum payload length in bytes 250 | */ 251 | virtual void set_max_payload_length(radio_modems_t modem, uint8_t max); 252 | 253 | /** 254 | * Sets the network to public or private 255 | * 256 | * Updates the sync byte. Applies to LoRa modem only 257 | * 258 | * @param enable if true, it enables a public network 259 | */ 260 | virtual void set_public_network(bool enable); 261 | 262 | /** 263 | * Computes the packet time on air for the given payload 264 | * 265 | * Remark can only be called once SetRxConfig or SetTxConfig have been called 266 | * 267 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 268 | * @param pkt_len Packet payload length 269 | * @return Computed airTime for the given packet payload length 270 | */ 271 | virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len); 272 | 273 | /** 274 | * Perform carrier sensing 275 | * 276 | * Checks for a certain time if the RSSI is above a given threshold. 277 | * This threshold determines if there is already a transmission going on 278 | * in the channel or not. 279 | * 280 | * @param modem Type of the radio modem 281 | * @param freq Carrier frequency 282 | * @param rssi_threshold Threshold value of RSSI 283 | * @param max_carrier_sense_time time to sense the channel 284 | * 285 | * @return true if there is no active transmission 286 | * in the channel, false otherwise 287 | */ 288 | virtual bool perform_carrier_sense(radio_modems_t modem, 289 | uint32_t freq, 290 | int16_t rssi_threshold, 291 | uint32_t max_carrier_sense_time); 292 | 293 | /** 294 | * Sets the radio in CAD mode 295 | * 296 | */ 297 | virtual void start_cad(void); 298 | 299 | /** 300 | * Check if the given RF is in range 301 | * 302 | * @param frequency frequency needed to be checked 303 | */ 304 | virtual bool check_rf_frequency(uint32_t frequency); 305 | 306 | /** Sets the radio in continuous wave transmission mode 307 | * 308 | * @param freq Channel RF frequency 309 | * @param power Sets the output power [dBm] 310 | * @param time Transmission mode timeout [s] 311 | */ 312 | virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time); 313 | 314 | /** 315 | * Acquire exclusive access 316 | */ 317 | virtual void lock(void); 318 | 319 | /** 320 | * Release exclusive access 321 | */ 322 | virtual void unlock(void); 323 | 324 | private: 325 | 326 | // SPI and chip select control 327 | mbed::SPI _spi; 328 | mbed::DigitalOut _chip_select; 329 | 330 | // module rest control 331 | mbed::DigitalInOut _reset_ctl; 332 | 333 | // Interrupt controls 334 | mbed::InterruptIn _dio0_ctl; 335 | mbed::InterruptIn _dio1_ctl; 336 | mbed::InterruptIn _dio2_ctl; 337 | mbed::InterruptIn _dio3_ctl; 338 | mbed::InterruptIn _dio4_ctl; 339 | mbed::InterruptIn _dio5_ctl; 340 | 341 | // Radio specific controls 342 | mbed::DigitalOut _rf_switch_ctl1; 343 | mbed::DigitalOut _rf_switch_ctl2; 344 | mbed::DigitalOut _txctl; 345 | mbed::DigitalOut _rxctl; 346 | mbed::DigitalInOut _ant_switch; 347 | mbed::DigitalOut _pwr_amp_ctl; 348 | mbed::DigitalOut _tcxo; 349 | 350 | // Contains all RF control pin names 351 | // This storage is needed even after assigning the 352 | // pins to corresponding object, as the driver needs to know 353 | // which control pins are connected and which are not. This 354 | // variation is inherent to driver because of target configuration. 355 | rf_ctrls _rf_ctrls; 356 | 357 | // We need these PinNames as not all modules have those connected 358 | PinName _dio4_pin; 359 | PinName _dio5_pin; 360 | 361 | // Structure containing all user and network specified settings 362 | // for radio module 363 | radio_settings_t _rf_settings; 364 | 365 | // Structure containing function pointers to the stack callbacks 366 | radio_events_t *_radio_events; 367 | 368 | // Data buffer used for both TX and RX 369 | // Size of this buffer is configurable via Mbed config system 370 | // Default is 256 bytes 371 | uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX172]; 372 | 373 | // TX timer in ms. This timer is used as a fail safe for TX. 374 | // If the chip fails to transmit, its a fatal error, reflecting 375 | // some catastrophic bus failure etc. We wish to have the control 376 | // back from the driver in such a case. 377 | ALIAS_LORAWAN_TIMER tx_timeout_timer; 378 | 379 | #ifdef MBED_CONF_RTOS_PRESENT 380 | // Thread to handle interrupts 381 | rtos::Thread irq_thread; 382 | #endif 383 | 384 | // Access protection 385 | PlatformMutex mutex; 386 | 387 | uint8_t radio_variant; 388 | 389 | /** 390 | * Flag used to set the RF switch control pins in low power mode when the radio is not active. 391 | */ 392 | bool radio_is_active; 393 | 394 | // helper functions 395 | void setup_registers(); 396 | void default_antenna_switch_ctrls(); 397 | void set_antenna_switch(uint8_t operation_mode); 398 | void setup_spi(); 399 | void gpio_init(); 400 | void gpio_deinit(); 401 | void setup_interrupts(); 402 | void set_modem(uint8_t modem); 403 | void set_operation_mode(uint8_t mode); 404 | void set_low_power_mode(bool status); 405 | void set_sx1272_variant_type(); 406 | uint8_t get_pa_conf_reg(); 407 | void set_rf_tx_power(int8_t power); 408 | int16_t get_rssi(radio_modems_t modem); 409 | uint8_t get_fsk_bw_reg_val(uint32_t bandwidth); 410 | void write_to_register(uint8_t addr, uint8_t data); 411 | void write_to_register(uint8_t addr, uint8_t *data, uint8_t size); 412 | uint8_t read_register(uint8_t addr); 413 | void read_register(uint8_t addr, uint8_t *buffer, uint8_t size); 414 | void write_fifo(uint8_t *buffer, uint8_t size); 415 | void read_fifo(uint8_t *buffer, uint8_t size); 416 | void transmit(uint32_t timeout); 417 | void rf_irq_task(void); 418 | 419 | // ISRs 420 | void dio0_irq_isr(); 421 | void dio1_irq_isr(); 422 | void dio2_irq_isr(); 423 | void dio3_irq_isr(); 424 | void dio4_irq_isr(); 425 | void dio5_irq_isr(); 426 | void timeout_irq_isr(); 427 | 428 | // Handlers called by thread in response to signal 429 | void handle_dio0_irq(); 430 | void handle_dio1_irq(); 431 | void handle_dio2_irq(); 432 | void handle_dio3_irq(); 433 | void handle_dio4_irq(); 434 | void handle_dio5_irq(); 435 | void handle_timeout_irq(); 436 | }; 437 | 438 | #endif /* SX1272_LORARADIO_H_ */ 439 | -------------------------------------------------------------------------------- /SX1272/mbed_lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sx1272-lora-driver", 3 | "config": { 4 | "spi-frequency": { 5 | "help": "SPI frequency, Default: 8 MHz", 6 | "value": 8000000 7 | }, 8 | "buffer-size": { 9 | "help": "Max. buffer size the radio can handle, Default: 255 B", 10 | "value": 255 11 | }, 12 | "radio-variant": { 13 | "help": "Use to set the radio variant if the antenna switch input is not connected.", 14 | "value": "SX1272UNDEFINED" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SX1272/registers/sx1272Regs-Fsk.h: -------------------------------------------------------------------------------- 1 | /** 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C) 2015 Semtech 8 | 9 | Description: SX1272 FSK modem registers and bits definitions 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | 15 | Copyright (c) 2017, Arm Limited and affiliates. 16 | 17 | SPDX-License-Identifier: BSD-3-Clause 18 | */ 19 | #ifndef __SX1272_REGS_FSK_H__ 20 | #define __SX1272_REGS_FSK_H__ 21 | 22 | /*! 23 | * ============================================================================ 24 | * SX1272 Internal registers Address 25 | * ============================================================================ 26 | */ 27 | #define REG_FIFO 0x00 28 | // Common settings 29 | #define REG_OPMODE 0x01 30 | #define REG_BITRATEMSB 0x02 31 | #define REG_BITRATELSB 0x03 32 | #define REG_FDEVMSB 0x04 33 | #define REG_FDEVLSB 0x05 34 | #define REG_FRFMSB 0x06 35 | #define REG_FRFMID 0x07 36 | #define REG_FRFLSB 0x08 37 | // Tx settings 38 | #define REG_PACONFIG 0x09 39 | #define REG_PARAMP 0x0A 40 | #define REG_OCP 0x0B 41 | // Rx settings 42 | #define REG_LNA 0x0C 43 | #define REG_RXCONFIG 0x0D 44 | #define REG_RSSICONFIG 0x0E 45 | #define REG_RSSICOLLISION 0x0F 46 | #define REG_RSSITHRESH 0x10 47 | #define REG_RSSIVALUE 0x11 48 | #define REG_RXBW 0x12 49 | #define REG_AFCBW 0x13 50 | #define REG_OOKPEAK 0x14 51 | #define REG_OOKFIX 0x15 52 | #define REG_OOKAVG 0x16 53 | #define REG_RES17 0x17 54 | #define REG_RES18 0x18 55 | #define REG_RES19 0x19 56 | #define REG_AFCFEI 0x1A 57 | #define REG_AFCMSB 0x1B 58 | #define REG_AFCLSB 0x1C 59 | #define REG_FEIMSB 0x1D 60 | #define REG_FEILSB 0x1E 61 | #define REG_PREAMBLEDETECT 0x1F 62 | #define REG_RXTIMEOUT1 0x20 63 | #define REG_RXTIMEOUT2 0x21 64 | #define REG_RXTIMEOUT3 0x22 65 | #define REG_RXDELAY 0x23 66 | // Oscillator settings 67 | #define REG_OSC 0x24 68 | // Packet handler settings 69 | #define REG_PREAMBLEMSB 0x25 70 | #define REG_PREAMBLELSB 0x26 71 | #define REG_SYNCCONFIG 0x27 72 | #define REG_SYNCVALUE1 0x28 73 | #define REG_SYNCVALUE2 0x29 74 | #define REG_SYNCVALUE3 0x2A 75 | #define REG_SYNCVALUE4 0x2B 76 | #define REG_SYNCVALUE5 0x2C 77 | #define REG_SYNCVALUE6 0x2D 78 | #define REG_SYNCVALUE7 0x2E 79 | #define REG_SYNCVALUE8 0x2F 80 | #define REG_PACKETCONFIG1 0x30 81 | #define REG_PACKETCONFIG2 0x31 82 | #define REG_PAYLOADLENGTH 0x32 83 | #define REG_NODEADRS 0x33 84 | #define REG_BROADCASTADRS 0x34 85 | #define REG_FIFOTHRESH 0x35 86 | // SM settings 87 | #define REG_SEQCONFIG1 0x36 88 | #define REG_SEQCONFIG2 0x37 89 | #define REG_TIMERRESOL 0x38 90 | #define REG_TIMER1COEF 0x39 91 | #define REG_TIMER2COEF 0x3A 92 | // Service settings 93 | #define REG_IMAGECAL 0x3B 94 | #define REG_TEMP 0x3C 95 | #define REG_LOWBAT 0x3D 96 | // Status 97 | #define REG_IRQFLAGS1 0x3E 98 | #define REG_IRQFLAGS2 0x3F 99 | // I/O settings 100 | #define REG_DIOMAPPING1 0x40 101 | #define REG_DIOMAPPING2 0x41 102 | // Version 103 | #define REG_VERSION 0x42 104 | // Additional settings 105 | #define REG_AGCREF 0x43 106 | #define REG_AGCTHRESH1 0x44 107 | #define REG_AGCTHRESH2 0x45 108 | #define REG_AGCTHRESH3 0x46 109 | #define REG_PLLHOP 0x4B 110 | #define REG_TCXO 0x58 111 | #define REG_PADAC 0x5A 112 | #define REG_PLL 0x5C 113 | #define REG_PLLLOWPN 0x5E 114 | #define REG_FORMERTEMP 0x6C 115 | #define REG_BITRATEFRAC 0x70 116 | 117 | /*! 118 | * ============================================================================ 119 | * SX1272 FSK bits control definition 120 | * ============================================================================ 121 | */ 122 | 123 | /*! 124 | * RegFifo 125 | */ 126 | 127 | /*! 128 | * RegOpMode 129 | */ 130 | #define RF_OPMODE_LONGRANGEMODE_MASK 0x7F 131 | #define RF_OPMODE_LONGRANGEMODE_OFF 0x00 132 | #define RF_OPMODE_LONGRANGEMODE_ON 0x80 133 | 134 | #define RF_OPMODE_MODULATIONTYPE_MASK 0x9F 135 | #define RF_OPMODE_MODULATIONTYPE_FSK 0x00 // Default 136 | #define RF_OPMODE_MODULATIONTYPE_OOK 0x20 137 | 138 | #define RF_OPMODE_MODULATIONSHAPING_MASK 0xE7 139 | #define RF_OPMODE_MODULATIONSHAPING_00 0x00 // Default 140 | #define RF_OPMODE_MODULATIONSHAPING_01 0x08 141 | #define RF_OPMODE_MODULATIONSHAPING_10 0x10 142 | #define RF_OPMODE_MODULATIONSHAPING_11 0x18 143 | 144 | #define RF_OPMODE_MASK 0xF8 145 | #define RF_OPMODE_SLEEP 0x00 146 | #define RF_OPMODE_STANDBY 0x01 // Default 147 | #define RF_OPMODE_SYNTHESIZER_TX 0x02 148 | #define RF_OPMODE_TRANSMITTER 0x03 149 | #define RF_OPMODE_SYNTHESIZER_RX 0x04 150 | #define RF_OPMODE_RECEIVER 0x05 151 | 152 | /*! 153 | * RegBitRate (bits/sec) 154 | */ 155 | #define RF_BITRATEMSB_1200_BPS 0x68 156 | #define RF_BITRATELSB_1200_BPS 0x2B 157 | #define RF_BITRATEMSB_2400_BPS 0x34 158 | #define RF_BITRATELSB_2400_BPS 0x15 159 | #define RF_BITRATEMSB_4800_BPS 0x1A // Default 160 | #define RF_BITRATELSB_4800_BPS 0x0B // Default 161 | #define RF_BITRATEMSB_9600_BPS 0x0D 162 | #define RF_BITRATELSB_9600_BPS 0x05 163 | #define RF_BITRATEMSB_15000_BPS 0x08 164 | #define RF_BITRATELSB_15000_BPS 0x55 165 | #define RF_BITRATEMSB_19200_BPS 0x06 166 | #define RF_BITRATELSB_19200_BPS 0x83 167 | #define RF_BITRATEMSB_38400_BPS 0x03 168 | #define RF_BITRATELSB_38400_BPS 0x41 169 | #define RF_BITRATEMSB_76800_BPS 0x01 170 | #define RF_BITRATELSB_76800_BPS 0xA1 171 | #define RF_BITRATEMSB_153600_BPS 0x00 172 | #define RF_BITRATELSB_153600_BPS 0xD0 173 | #define RF_BITRATEMSB_57600_BPS 0x02 174 | #define RF_BITRATELSB_57600_BPS 0x2C 175 | #define RF_BITRATEMSB_115200_BPS 0x01 176 | #define RF_BITRATELSB_115200_BPS 0x16 177 | #define RF_BITRATEMSB_12500_BPS 0x0A 178 | #define RF_BITRATELSB_12500_BPS 0x00 179 | #define RF_BITRATEMSB_25000_BPS 0x05 180 | #define RF_BITRATELSB_25000_BPS 0x00 181 | #define RF_BITRATEMSB_50000_BPS 0x02 182 | #define RF_BITRATELSB_50000_BPS 0x80 183 | #define RF_BITRATEMSB_100000_BPS 0x01 184 | #define RF_BITRATELSB_100000_BPS 0x40 185 | #define RF_BITRATEMSB_150000_BPS 0x00 186 | #define RF_BITRATELSB_150000_BPS 0xD5 187 | #define RF_BITRATEMSB_200000_BPS 0x00 188 | #define RF_BITRATELSB_200000_BPS 0xA0 189 | #define RF_BITRATEMSB_250000_BPS 0x00 190 | #define RF_BITRATELSB_250000_BPS 0x80 191 | #define RF_BITRATEMSB_32768_BPS 0x03 192 | #define RF_BITRATELSB_32768_BPS 0xD1 193 | 194 | /*! 195 | * RegFdev (Hz) 196 | */ 197 | #define RF_FDEVMSB_2000_HZ 0x00 198 | #define RF_FDEVLSB_2000_HZ 0x21 199 | #define RF_FDEVMSB_5000_HZ 0x00 // Default 200 | #define RF_FDEVLSB_5000_HZ 0x52 // Default 201 | #define RF_FDEVMSB_10000_HZ 0x00 202 | #define RF_FDEVLSB_10000_HZ 0xA4 203 | #define RF_FDEVMSB_15000_HZ 0x00 204 | #define RF_FDEVLSB_15000_HZ 0xF6 205 | #define RF_FDEVMSB_20000_HZ 0x01 206 | #define RF_FDEVLSB_20000_HZ 0x48 207 | #define RF_FDEVMSB_25000_HZ 0x01 208 | #define RF_FDEVLSB_25000_HZ 0x9A 209 | #define RF_FDEVMSB_30000_HZ 0x01 210 | #define RF_FDEVLSB_30000_HZ 0xEC 211 | #define RF_FDEVMSB_35000_HZ 0x02 212 | #define RF_FDEVLSB_35000_HZ 0x3D 213 | #define RF_FDEVMSB_40000_HZ 0x02 214 | #define RF_FDEVLSB_40000_HZ 0x8F 215 | #define RF_FDEVMSB_45000_HZ 0x02 216 | #define RF_FDEVLSB_45000_HZ 0xE1 217 | #define RF_FDEVMSB_50000_HZ 0x03 218 | #define RF_FDEVLSB_50000_HZ 0x33 219 | #define RF_FDEVMSB_55000_HZ 0x03 220 | #define RF_FDEVLSB_55000_HZ 0x85 221 | #define RF_FDEVMSB_60000_HZ 0x03 222 | #define RF_FDEVLSB_60000_HZ 0xD7 223 | #define RF_FDEVMSB_65000_HZ 0x04 224 | #define RF_FDEVLSB_65000_HZ 0x29 225 | #define RF_FDEVMSB_70000_HZ 0x04 226 | #define RF_FDEVLSB_70000_HZ 0x7B 227 | #define RF_FDEVMSB_75000_HZ 0x04 228 | #define RF_FDEVLSB_75000_HZ 0xCD 229 | #define RF_FDEVMSB_80000_HZ 0x05 230 | #define RF_FDEVLSB_80000_HZ 0x1F 231 | #define RF_FDEVMSB_85000_HZ 0x05 232 | #define RF_FDEVLSB_85000_HZ 0x71 233 | #define RF_FDEVMSB_90000_HZ 0x05 234 | #define RF_FDEVLSB_90000_HZ 0xC3 235 | #define RF_FDEVMSB_95000_HZ 0x06 236 | #define RF_FDEVLSB_95000_HZ 0x14 237 | #define RF_FDEVMSB_100000_HZ 0x06 238 | #define RF_FDEVLSB_100000_HZ 0x66 239 | #define RF_FDEVMSB_110000_HZ 0x07 240 | #define RF_FDEVLSB_110000_HZ 0x0A 241 | #define RF_FDEVMSB_120000_HZ 0x07 242 | #define RF_FDEVLSB_120000_HZ 0xAE 243 | #define RF_FDEVMSB_130000_HZ 0x08 244 | #define RF_FDEVLSB_130000_HZ 0x52 245 | #define RF_FDEVMSB_140000_HZ 0x08 246 | #define RF_FDEVLSB_140000_HZ 0xF6 247 | #define RF_FDEVMSB_150000_HZ 0x09 248 | #define RF_FDEVLSB_150000_HZ 0x9A 249 | #define RF_FDEVMSB_160000_HZ 0x0A 250 | #define RF_FDEVLSB_160000_HZ 0x3D 251 | #define RF_FDEVMSB_170000_HZ 0x0A 252 | #define RF_FDEVLSB_170000_HZ 0xE1 253 | #define RF_FDEVMSB_180000_HZ 0x0B 254 | #define RF_FDEVLSB_180000_HZ 0x85 255 | #define RF_FDEVMSB_190000_HZ 0x0C 256 | #define RF_FDEVLSB_190000_HZ 0x29 257 | #define RF_FDEVMSB_200000_HZ 0x0C 258 | #define RF_FDEVLSB_200000_HZ 0xCD 259 | 260 | /*! 261 | * RegFrf (MHz) 262 | */ 263 | #define RF_FRFMSB_863_MHZ 0xD7 264 | #define RF_FRFMID_863_MHZ 0xC0 265 | #define RF_FRFLSB_863_MHZ 0x00 266 | #define RF_FRFMSB_864_MHZ 0xD8 267 | #define RF_FRFMID_864_MHZ 0x00 268 | #define RF_FRFLSB_864_MHZ 0x00 269 | #define RF_FRFMSB_865_MHZ 0xD8 270 | #define RF_FRFMID_865_MHZ 0x40 271 | #define RF_FRFLSB_865_MHZ 0x00 272 | #define RF_FRFMSB_866_MHZ 0xD8 273 | #define RF_FRFMID_866_MHZ 0x80 274 | #define RF_FRFLSB_866_MHZ 0x00 275 | #define RF_FRFMSB_867_MHZ 0xD8 276 | #define RF_FRFMID_867_MHZ 0xC0 277 | #define RF_FRFLSB_867_MHZ 0x00 278 | #define RF_FRFMSB_868_MHZ 0xD9 279 | #define RF_FRFMID_868_MHZ 0x00 280 | #define RF_FRFLSB_868_MHZ 0x00 281 | #define RF_FRFMSB_869_MHZ 0xD9 282 | #define RF_FRFMID_869_MHZ 0x40 283 | #define RF_FRFLSB_869_MHZ 0x00 284 | #define RF_FRFMSB_870_MHZ 0xD9 285 | #define RF_FRFMID_870_MHZ 0x80 286 | #define RF_FRFLSB_870_MHZ 0x00 287 | 288 | #define RF_FRFMSB_902_MHZ 0xE1 289 | #define RF_FRFMID_902_MHZ 0x80 290 | #define RF_FRFLSB_902_MHZ 0x00 291 | #define RF_FRFMSB_903_MHZ 0xE1 292 | #define RF_FRFMID_903_MHZ 0xC0 293 | #define RF_FRFLSB_903_MHZ 0x00 294 | #define RF_FRFMSB_904_MHZ 0xE2 295 | #define RF_FRFMID_904_MHZ 0x00 296 | #define RF_FRFLSB_904_MHZ 0x00 297 | #define RF_FRFMSB_905_MHZ 0xE2 298 | #define RF_FRFMID_905_MHZ 0x40 299 | #define RF_FRFLSB_905_MHZ 0x00 300 | #define RF_FRFMSB_906_MHZ 0xE2 301 | #define RF_FRFMID_906_MHZ 0x80 302 | #define RF_FRFLSB_906_MHZ 0x00 303 | #define RF_FRFMSB_907_MHZ 0xE2 304 | #define RF_FRFMID_907_MHZ 0xC0 305 | #define RF_FRFLSB_907_MHZ 0x00 306 | #define RF_FRFMSB_908_MHZ 0xE3 307 | #define RF_FRFMID_908_MHZ 0x00 308 | #define RF_FRFLSB_908_MHZ 0x00 309 | #define RF_FRFMSB_909_MHZ 0xE3 310 | #define RF_FRFMID_909_MHZ 0x40 311 | #define RF_FRFLSB_909_MHZ 0x00 312 | #define RF_FRFMSB_910_MHZ 0xE3 313 | #define RF_FRFMID_910_MHZ 0x80 314 | #define RF_FRFLSB_910_MHZ 0x00 315 | #define RF_FRFMSB_911_MHZ 0xE3 316 | #define RF_FRFMID_911_MHZ 0xC0 317 | #define RF_FRFLSB_911_MHZ 0x00 318 | #define RF_FRFMSB_912_MHZ 0xE4 319 | #define RF_FRFMID_912_MHZ 0x00 320 | #define RF_FRFLSB_912_MHZ 0x00 321 | #define RF_FRFMSB_913_MHZ 0xE4 322 | #define RF_FRFMID_913_MHZ 0x40 323 | #define RF_FRFLSB_913_MHZ 0x00 324 | #define RF_FRFMSB_914_MHZ 0xE4 325 | #define RF_FRFMID_914_MHZ 0x80 326 | #define RF_FRFLSB_914_MHZ 0x00 327 | #define RF_FRFMSB_915_MHZ 0xE4 // Default 328 | #define RF_FRFMID_915_MHZ 0xC0 // Default 329 | #define RF_FRFLSB_915_MHZ 0x00 // Default 330 | #define RF_FRFMSB_916_MHZ 0xE5 331 | #define RF_FRFMID_916_MHZ 0x00 332 | #define RF_FRFLSB_916_MHZ 0x00 333 | #define RF_FRFMSB_917_MHZ 0xE5 334 | #define RF_FRFMID_917_MHZ 0x40 335 | #define RF_FRFLSB_917_MHZ 0x00 336 | #define RF_FRFMSB_918_MHZ 0xE5 337 | #define RF_FRFMID_918_MHZ 0x80 338 | #define RF_FRFLSB_918_MHZ 0x00 339 | #define RF_FRFMSB_919_MHZ 0xE5 340 | #define RF_FRFMID_919_MHZ 0xC0 341 | #define RF_FRFLSB_919_MHZ 0x00 342 | #define RF_FRFMSB_920_MHZ 0xE6 343 | #define RF_FRFMID_920_MHZ 0x00 344 | #define RF_FRFLSB_920_MHZ 0x00 345 | #define RF_FRFMSB_921_MHZ 0xE6 346 | #define RF_FRFMID_921_MHZ 0x40 347 | #define RF_FRFLSB_921_MHZ 0x00 348 | #define RF_FRFMSB_922_MHZ 0xE6 349 | #define RF_FRFMID_922_MHZ 0x80 350 | #define RF_FRFLSB_922_MHZ 0x00 351 | #define RF_FRFMSB_923_MHZ 0xE6 352 | #define RF_FRFMID_923_MHZ 0xC0 353 | #define RF_FRFLSB_923_MHZ 0x00 354 | #define RF_FRFMSB_924_MHZ 0xE7 355 | #define RF_FRFMID_924_MHZ 0x00 356 | #define RF_FRFLSB_924_MHZ 0x00 357 | #define RF_FRFMSB_925_MHZ 0xE7 358 | #define RF_FRFMID_925_MHZ 0x40 359 | #define RF_FRFLSB_925_MHZ 0x00 360 | #define RF_FRFMSB_926_MHZ 0xE7 361 | #define RF_FRFMID_926_MHZ 0x80 362 | #define RF_FRFLSB_926_MHZ 0x00 363 | #define RF_FRFMSB_927_MHZ 0xE7 364 | #define RF_FRFMID_927_MHZ 0xC0 365 | #define RF_FRFLSB_927_MHZ 0x00 366 | #define RF_FRFMSB_928_MHZ 0xE8 367 | #define RF_FRFMID_928_MHZ 0x00 368 | #define RF_FRFLSB_928_MHZ 0x00 369 | 370 | /*! 371 | * RegPaConfig 372 | */ 373 | #define RF_PACONFIG_PASELECT_MASK 0x7F 374 | #define RF_PACONFIG_PASELECT_PABOOST 0x80 375 | #define RF_PACONFIG_PASELECT_RFO 0x00 // Default 376 | 377 | #define RF_PACONFIG_OUTPUTPOWER_MASK 0xF0 378 | 379 | /*! 380 | * RegPaRamp 381 | */ 382 | #define RF_PARAMP_LOWPNTXPLL_MASK 0xEF 383 | #define RF_PARAMP_LOWPNTXPLL_OFF 0x10 // Default 384 | #define RF_PARAMP_LOWPNTXPLL_ON 0x00 385 | 386 | #define RF_PARAMP_MASK 0xF0 387 | #define RF_PARAMP_3400_US 0x00 388 | #define RF_PARAMP_2000_US 0x01 389 | #define RF_PARAMP_1000_US 0x02 390 | #define RF_PARAMP_0500_US 0x03 391 | #define RF_PARAMP_0250_US 0x04 392 | #define RF_PARAMP_0125_US 0x05 393 | #define RF_PARAMP_0100_US 0x06 394 | #define RF_PARAMP_0062_US 0x07 395 | #define RF_PARAMP_0050_US 0x08 396 | #define RF_PARAMP_0040_US 0x09 // Default 397 | #define RF_PARAMP_0031_US 0x0A 398 | #define RF_PARAMP_0025_US 0x0B 399 | #define RF_PARAMP_0020_US 0x0C 400 | #define RF_PARAMP_0015_US 0x0D 401 | #define RF_PARAMP_0012_US 0x0E 402 | #define RF_PARAMP_0010_US 0x0F 403 | 404 | /*! 405 | * RegOcp 406 | */ 407 | #define RF_OCP_MASK 0xDF 408 | #define RF_OCP_ON 0x20 // Default 409 | #define RF_OCP_OFF 0x00 410 | 411 | #define RF_OCP_TRIM_MASK 0xE0 412 | #define RF_OCP_TRIM_045_MA 0x00 413 | #define RF_OCP_TRIM_050_MA 0x01 414 | #define RF_OCP_TRIM_055_MA 0x02 415 | #define RF_OCP_TRIM_060_MA 0x03 416 | #define RF_OCP_TRIM_065_MA 0x04 417 | #define RF_OCP_TRIM_070_MA 0x05 418 | #define RF_OCP_TRIM_075_MA 0x06 419 | #define RF_OCP_TRIM_080_MA 0x07 420 | #define RF_OCP_TRIM_085_MA 0x08 421 | #define RF_OCP_TRIM_090_MA 0x09 422 | #define RF_OCP_TRIM_095_MA 0x0A 423 | #define RF_OCP_TRIM_100_MA 0x0B // Default 424 | #define RF_OCP_TRIM_105_MA 0x0C 425 | #define RF_OCP_TRIM_110_MA 0x0D 426 | #define RF_OCP_TRIM_115_MA 0x0E 427 | #define RF_OCP_TRIM_120_MA 0x0F 428 | #define RF_OCP_TRIM_130_MA 0x10 429 | #define RF_OCP_TRIM_140_MA 0x11 430 | #define RF_OCP_TRIM_150_MA 0x12 431 | #define RF_OCP_TRIM_160_MA 0x13 432 | #define RF_OCP_TRIM_170_MA 0x14 433 | #define RF_OCP_TRIM_180_MA 0x15 434 | #define RF_OCP_TRIM_190_MA 0x16 435 | #define RF_OCP_TRIM_200_MA 0x17 436 | #define RF_OCP_TRIM_210_MA 0x18 437 | #define RF_OCP_TRIM_220_MA 0x19 438 | #define RF_OCP_TRIM_230_MA 0x1A 439 | #define RF_OCP_TRIM_240_MA 0x1B 440 | 441 | /*! 442 | * RegLna 443 | */ 444 | #define RF_LNA_GAIN_MASK 0x1F 445 | #define RF_LNA_GAIN_G1 0x20 // Default 446 | #define RF_LNA_GAIN_G2 0x40 447 | #define RF_LNA_GAIN_G3 0x60 448 | #define RF_LNA_GAIN_G4 0x80 449 | #define RF_LNA_GAIN_G5 0xA0 450 | #define RF_LNA_GAIN_G6 0xC0 451 | 452 | #define RF_LNA_BOOST_MASK 0xFC 453 | #define RF_LNA_BOOST_OFF 0x00 // Default 454 | #define RF_LNA_BOOST_ON 0x03 455 | 456 | /*! 457 | * RegRxConfig 458 | */ 459 | #define RF_RXCONFIG_RESTARTRXONCOLLISION_MASK 0x7F 460 | #define RF_RXCONFIG_RESTARTRXONCOLLISION_ON 0x80 461 | #define RF_RXCONFIG_RESTARTRXONCOLLISION_OFF 0x00 // Default 462 | 463 | #define RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK 0x40 // Write only 464 | 465 | #define RF_RXCONFIG_RESTARTRXWITHPLLLOCK 0x20 // Write only 466 | 467 | #define RF_RXCONFIG_AFCAUTO_MASK 0xEF 468 | #define RF_RXCONFIG_AFCAUTO_ON 0x10 469 | #define RF_RXCONFIG_AFCAUTO_OFF 0x00 // Default 470 | 471 | #define RF_RXCONFIG_AGCAUTO_MASK 0xF7 472 | #define RF_RXCONFIG_AGCAUTO_ON 0x08 // Default 473 | #define RF_RXCONFIG_AGCAUTO_OFF 0x00 474 | 475 | #define RF_RXCONFIG_RXTRIGER_MASK 0xF8 476 | #define RF_RXCONFIG_RXTRIGER_OFF 0x00 477 | #define RF_RXCONFIG_RXTRIGER_RSSI 0x01 478 | #define RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT 0x06 // Default 479 | #define RF_RXCONFIG_RXTRIGER_RSSI_PREAMBLEDETECT 0x07 480 | 481 | /*! 482 | * RegRssiConfig 483 | */ 484 | #define RF_RSSICONFIG_OFFSET_MASK 0x07 485 | #define RF_RSSICONFIG_OFFSET_P_00_DB 0x00 // Default 486 | #define RF_RSSICONFIG_OFFSET_P_01_DB 0x08 487 | #define RF_RSSICONFIG_OFFSET_P_02_DB 0x10 488 | #define RF_RSSICONFIG_OFFSET_P_03_DB 0x18 489 | #define RF_RSSICONFIG_OFFSET_P_04_DB 0x20 490 | #define RF_RSSICONFIG_OFFSET_P_05_DB 0x28 491 | #define RF_RSSICONFIG_OFFSET_P_06_DB 0x30 492 | #define RF_RSSICONFIG_OFFSET_P_07_DB 0x38 493 | #define RF_RSSICONFIG_OFFSET_P_08_DB 0x40 494 | #define RF_RSSICONFIG_OFFSET_P_09_DB 0x48 495 | #define RF_RSSICONFIG_OFFSET_P_10_DB 0x50 496 | #define RF_RSSICONFIG_OFFSET_P_11_DB 0x58 497 | #define RF_RSSICONFIG_OFFSET_P_12_DB 0x60 498 | #define RF_RSSICONFIG_OFFSET_P_13_DB 0x68 499 | #define RF_RSSICONFIG_OFFSET_P_14_DB 0x70 500 | #define RF_RSSICONFIG_OFFSET_P_15_DB 0x78 501 | #define RF_RSSICONFIG_OFFSET_M_16_DB 0x80 502 | #define RF_RSSICONFIG_OFFSET_M_15_DB 0x88 503 | #define RF_RSSICONFIG_OFFSET_M_14_DB 0x90 504 | #define RF_RSSICONFIG_OFFSET_M_13_DB 0x98 505 | #define RF_RSSICONFIG_OFFSET_M_12_DB 0xA0 506 | #define RF_RSSICONFIG_OFFSET_M_11_DB 0xA8 507 | #define RF_RSSICONFIG_OFFSET_M_10_DB 0xB0 508 | #define RF_RSSICONFIG_OFFSET_M_09_DB 0xB8 509 | #define RF_RSSICONFIG_OFFSET_M_08_DB 0xC0 510 | #define RF_RSSICONFIG_OFFSET_M_07_DB 0xC8 511 | #define RF_RSSICONFIG_OFFSET_M_06_DB 0xD0 512 | #define RF_RSSICONFIG_OFFSET_M_05_DB 0xD8 513 | #define RF_RSSICONFIG_OFFSET_M_04_DB 0xE0 514 | #define RF_RSSICONFIG_OFFSET_M_03_DB 0xE8 515 | #define RF_RSSICONFIG_OFFSET_M_02_DB 0xF0 516 | #define RF_RSSICONFIG_OFFSET_M_01_DB 0xF8 517 | 518 | #define RF_RSSICONFIG_SMOOTHING_MASK 0xF8 519 | #define RF_RSSICONFIG_SMOOTHING_2 0x00 520 | #define RF_RSSICONFIG_SMOOTHING_4 0x01 521 | #define RF_RSSICONFIG_SMOOTHING_8 0x02 // Default 522 | #define RF_RSSICONFIG_SMOOTHING_16 0x03 523 | #define RF_RSSICONFIG_SMOOTHING_32 0x04 524 | #define RF_RSSICONFIG_SMOOTHING_64 0x05 525 | #define RF_RSSICONFIG_SMOOTHING_128 0x06 526 | #define RF_RSSICONFIG_SMOOTHING_256 0x07 527 | 528 | /*! 529 | * RegRssiCollision 530 | */ 531 | #define RF_RSSICOLISION_THRESHOLD 0x0A // Default 532 | 533 | /*! 534 | * RegRssiThresh 535 | */ 536 | #define RF_RSSITHRESH_THRESHOLD 0xFF // Default 537 | 538 | /*! 539 | * RegRssiValue (Read Only) 540 | */ 541 | 542 | /*! 543 | * RegRxBw 544 | */ 545 | #define RF_RXBW_MANT_MASK 0xE7 546 | #define RF_RXBW_MANT_16 0x00 547 | #define RF_RXBW_MANT_20 0x08 548 | #define RF_RXBW_MANT_24 0x10 // Default 549 | 550 | #define RF_RXBW_EXP_MASK 0xF8 551 | #define RF_RXBW_EXP_0 0x00 552 | #define RF_RXBW_EXP_1 0x01 553 | #define RF_RXBW_EXP_2 0x02 554 | #define RF_RXBW_EXP_3 0x03 555 | #define RF_RXBW_EXP_4 0x04 556 | #define RF_RXBW_EXP_5 0x05 // Default 557 | #define RF_RXBW_EXP_6 0x06 558 | #define RF_RXBW_EXP_7 0x07 559 | 560 | /*! 561 | * RegAfcBw 562 | */ 563 | #define RF_AFCBW_MANTAFC_MASK 0xE7 564 | #define RF_AFCBW_MANTAFC_16 0x00 565 | #define RF_AFCBW_MANTAFC_20 0x08 // Default 566 | #define RF_AFCBW_MANTAFC_24 0x10 567 | 568 | #define RF_AFCBW_EXPAFC_MASK 0xF8 569 | #define RF_AFCBW_EXPAFC_0 0x00 570 | #define RF_AFCBW_EXPAFC_1 0x01 571 | #define RF_AFCBW_EXPAFC_2 0x02 572 | #define RF_AFCBW_EXPAFC_3 0x03 // Default 573 | #define RF_AFCBW_EXPAFC_4 0x04 574 | #define RF_AFCBW_EXPAFC_5 0x05 575 | #define RF_AFCBW_EXPAFC_6 0x06 576 | #define RF_AFCBW_EXPAFC_7 0x07 577 | 578 | /*! 579 | * RegOokPeak 580 | */ 581 | #define RF_OOKPEAK_BITSYNC_MASK 0xDF // Default 582 | #define RF_OOKPEAK_BITSYNC_ON 0x20 // Default 583 | #define RF_OOKPEAK_BITSYNC_OFF 0x00 584 | 585 | #define RF_OOKPEAK_OOKTHRESHTYPE_MASK 0xE7 586 | #define RF_OOKPEAK_OOKTHRESHTYPE_FIXED 0x00 587 | #define RF_OOKPEAK_OOKTHRESHTYPE_PEAK 0x08 // Default 588 | #define RF_OOKPEAK_OOKTHRESHTYPE_AVERAGE 0x10 589 | 590 | #define RF_OOKPEAK_OOKPEAKTHRESHSTEP_MASK 0xF8 591 | #define RF_OOKPEAK_OOKPEAKTHRESHSTEP_0_5_DB 0x00 // Default 592 | #define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_0_DB 0x01 593 | #define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_5_DB 0x02 594 | #define RF_OOKPEAK_OOKPEAKTHRESHSTEP_2_0_DB 0x03 595 | #define RF_OOKPEAK_OOKPEAKTHRESHSTEP_3_0_DB 0x04 596 | #define RF_OOKPEAK_OOKPEAKTHRESHSTEP_4_0_DB 0x05 597 | #define RF_OOKPEAK_OOKPEAKTHRESHSTEP_5_0_DB 0x06 598 | #define RF_OOKPEAK_OOKPEAKTHRESHSTEP_6_0_DB 0x07 599 | 600 | /*! 601 | * RegOokFix 602 | */ 603 | #define RF_OOKFIX_OOKFIXEDTHRESHOLD 0x0C // Default 604 | 605 | /*! 606 | * RegOokAvg 607 | */ 608 | #define RF_OOKAVG_OOKPEAKTHRESHDEC_MASK 0x1F 609 | #define RF_OOKAVG_OOKPEAKTHRESHDEC_000 0x00 // Default 610 | #define RF_OOKAVG_OOKPEAKTHRESHDEC_001 0x20 611 | #define RF_OOKAVG_OOKPEAKTHRESHDEC_010 0x40 612 | #define RF_OOKAVG_OOKPEAKTHRESHDEC_011 0x60 613 | #define RF_OOKAVG_OOKPEAKTHRESHDEC_100 0x80 614 | #define RF_OOKAVG_OOKPEAKTHRESHDEC_101 0xA0 615 | #define RF_OOKAVG_OOKPEAKTHRESHDEC_110 0xC0 616 | #define RF_OOKAVG_OOKPEAKTHRESHDEC_111 0xE0 617 | 618 | #define RF_OOKAVG_AVERAGEOFFSET_MASK 0xF3 619 | #define RF_OOKAVG_AVERAGEOFFSET_0_DB 0x00 // Default 620 | #define RF_OOKAVG_AVERAGEOFFSET_2_DB 0x04 621 | #define RF_OOKAVG_AVERAGEOFFSET_4_DB 0x08 622 | #define RF_OOKAVG_AVERAGEOFFSET_6_DB 0x0C 623 | 624 | #define RF_OOKAVG_OOKAVERAGETHRESHFILT_MASK 0xFC 625 | #define RF_OOKAVG_OOKAVERAGETHRESHFILT_00 0x00 626 | #define RF_OOKAVG_OOKAVERAGETHRESHFILT_01 0x01 627 | #define RF_OOKAVG_OOKAVERAGETHRESHFILT_10 0x02 // Default 628 | #define RF_OOKAVG_OOKAVERAGETHRESHFILT_11 0x03 629 | 630 | /*! 631 | * RegAfcFei 632 | */ 633 | #define RF_AFCFEI_AGCSTART 0x10 634 | 635 | #define RF_AFCFEI_AFCCLEAR 0x02 636 | 637 | #define RF_AFCFEI_AFCAUTOCLEAR_MASK 0xFE 638 | #define RF_AFCFEI_AFCAUTOCLEAR_ON 0x01 639 | #define RF_AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default 640 | 641 | /*! 642 | * RegAfcMsb (Read Only) 643 | */ 644 | 645 | /*! 646 | * RegAfcLsb (Read Only) 647 | */ 648 | 649 | /*! 650 | * RegFeiMsb (Read Only) 651 | */ 652 | 653 | /*! 654 | * RegFeiLsb (Read Only) 655 | */ 656 | 657 | /*! 658 | * RegPreambleDetect 659 | */ 660 | #define RF_PREAMBLEDETECT_DETECTOR_MASK 0x7F 661 | #define RF_PREAMBLEDETECT_DETECTOR_ON 0x80 // Default 662 | #define RF_PREAMBLEDETECT_DETECTOR_OFF 0x00 663 | 664 | #define RF_PREAMBLEDETECT_DETECTORSIZE_MASK 0x9F 665 | #define RF_PREAMBLEDETECT_DETECTORSIZE_1 0x00 666 | #define RF_PREAMBLEDETECT_DETECTORSIZE_2 0x20 // Default 667 | #define RF_PREAMBLEDETECT_DETECTORSIZE_3 0x40 668 | #define RF_PREAMBLEDETECT_DETECTORSIZE_4 0x60 669 | 670 | #define RF_PREAMBLEDETECT_DETECTORTOL_MASK 0xE0 671 | #define RF_PREAMBLEDETECT_DETECTORTOL_0 0x00 672 | #define RF_PREAMBLEDETECT_DETECTORTOL_1 0x01 673 | #define RF_PREAMBLEDETECT_DETECTORTOL_2 0x02 674 | #define RF_PREAMBLEDETECT_DETECTORTOL_3 0x03 675 | #define RF_PREAMBLEDETECT_DETECTORTOL_4 0x04 676 | #define RF_PREAMBLEDETECT_DETECTORTOL_5 0x05 677 | #define RF_PREAMBLEDETECT_DETECTORTOL_6 0x06 678 | #define RF_PREAMBLEDETECT_DETECTORTOL_7 0x07 679 | #define RF_PREAMBLEDETECT_DETECTORTOL_8 0x08 680 | #define RF_PREAMBLEDETECT_DETECTORTOL_9 0x09 681 | #define RF_PREAMBLEDETECT_DETECTORTOL_10 0x0A // Default 682 | #define RF_PREAMBLEDETECT_DETECTORTOL_11 0x0B 683 | #define RF_PREAMBLEDETECT_DETECTORTOL_12 0x0C 684 | #define RF_PREAMBLEDETECT_DETECTORTOL_13 0x0D 685 | #define RF_PREAMBLEDETECT_DETECTORTOL_14 0x0E 686 | #define RF_PREAMBLEDETECT_DETECTORTOL_15 0x0F 687 | #define RF_PREAMBLEDETECT_DETECTORTOL_16 0x10 688 | #define RF_PREAMBLEDETECT_DETECTORTOL_17 0x11 689 | #define RF_PREAMBLEDETECT_DETECTORTOL_18 0x12 690 | #define RF_PREAMBLEDETECT_DETECTORTOL_19 0x13 691 | #define RF_PREAMBLEDETECT_DETECTORTOL_20 0x14 692 | #define RF_PREAMBLEDETECT_DETECTORTOL_21 0x15 693 | #define RF_PREAMBLEDETECT_DETECTORTOL_22 0x16 694 | #define RF_PREAMBLEDETECT_DETECTORTOL_23 0x17 695 | #define RF_PREAMBLEDETECT_DETECTORTOL_24 0x18 696 | #define RF_PREAMBLEDETECT_DETECTORTOL_25 0x19 697 | #define RF_PREAMBLEDETECT_DETECTORTOL_26 0x1A 698 | #define RF_PREAMBLEDETECT_DETECTORTOL_27 0x1B 699 | #define RF_PREAMBLEDETECT_DETECTORTOL_28 0x1C 700 | #define RF_PREAMBLEDETECT_DETECTORTOL_29 0x1D 701 | #define RF_PREAMBLEDETECT_DETECTORTOL_30 0x1E 702 | #define RF_PREAMBLEDETECT_DETECTORTOL_31 0x1F 703 | 704 | /*! 705 | * RegRxTimeout1 706 | */ 707 | #define RF_RXTIMEOUT1_TIMEOUTRXRSSI 0x00 // Default 708 | 709 | /*! 710 | * RegRxTimeout2 711 | */ 712 | #define RF_RXTIMEOUT2_TIMEOUTRXPREAMBLE 0x00 // Default 713 | 714 | /*! 715 | * RegRxTimeout3 716 | */ 717 | #define RF_RXTIMEOUT3_TIMEOUTSIGNALSYNC 0x00 // Default 718 | 719 | /*! 720 | * RegRxDelay 721 | */ 722 | #define RF_RXDELAY_INTERPACKETRXDELAY 0x00 // Default 723 | 724 | /*! 725 | * RegOsc 726 | */ 727 | #define RF_OSC_RCCALSTART 0x08 728 | 729 | #define RF_OSC_CLKOUT_MASK 0xF8 730 | #define RF_OSC_CLKOUT_32_MHZ 0x00 731 | #define RF_OSC_CLKOUT_16_MHZ 0x01 732 | #define RF_OSC_CLKOUT_8_MHZ 0x02 733 | #define RF_OSC_CLKOUT_4_MHZ 0x03 734 | #define RF_OSC_CLKOUT_2_MHZ 0x04 735 | #define RF_OSC_CLKOUT_1_MHZ 0x05 736 | #define RF_OSC_CLKOUT_RC 0x06 737 | #define RF_OSC_CLKOUT_OFF 0x07 // Default 738 | 739 | /*! 740 | * RegPreambleMsb/RegPreambleLsb 741 | */ 742 | #define RF_PREAMBLEMSB_SIZE 0x00 // Default 743 | #define RF_PREAMBLELSB_SIZE 0x03 // Default 744 | 745 | /*! 746 | * RegSyncConfig 747 | */ 748 | #define RF_SYNCCONFIG_AUTORESTARTRXMODE_MASK 0x3F 749 | #define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON 0x80 // Default 750 | #define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_OFF 0x40 751 | #define RF_SYNCCONFIG_AUTORESTARTRXMODE_OFF 0x00 752 | 753 | 754 | #define RF_SYNCCONFIG_PREAMBLEPOLARITY_MASK 0xDF 755 | #define RF_SYNCCONFIG_PREAMBLEPOLARITY_55 0x20 756 | #define RF_SYNCCONFIG_PREAMBLEPOLARITY_AA 0x00 // Default 757 | 758 | #define RF_SYNCCONFIG_SYNC_MASK 0xEF 759 | #define RF_SYNCCONFIG_SYNC_ON 0x10 // Default 760 | #define RF_SYNCCONFIG_SYNC_OFF 0x00 761 | 762 | #define RF_SYNCCONFIG_FIFOFILLCONDITION_MASK 0xF7 763 | #define RF_SYNCCONFIG_FIFOFILLCONDITION_AUTO 0x00 // Default 764 | #define RF_SYNCCONFIG_FIFOFILLCONDITION_MANUAL 0x08 765 | 766 | #define RF_SYNCCONFIG_SYNCSIZE_MASK 0xF8 767 | #define RF_SYNCCONFIG_SYNCSIZE_1 0x00 768 | #define RF_SYNCCONFIG_SYNCSIZE_2 0x01 769 | #define RF_SYNCCONFIG_SYNCSIZE_3 0x02 770 | #define RF_SYNCCONFIG_SYNCSIZE_4 0x03 // Default 771 | #define RF_SYNCCONFIG_SYNCSIZE_5 0x04 772 | #define RF_SYNCCONFIG_SYNCSIZE_6 0x05 773 | #define RF_SYNCCONFIG_SYNCSIZE_7 0x06 774 | #define RF_SYNCCONFIG_SYNCSIZE_8 0x07 775 | 776 | /*! 777 | * RegSyncValue1-8 778 | */ 779 | #define RF_SYNCVALUE1_SYNCVALUE 0x01 // Default 780 | #define RF_SYNCVALUE2_SYNCVALUE 0x01 // Default 781 | #define RF_SYNCVALUE3_SYNCVALUE 0x01 // Default 782 | #define RF_SYNCVALUE4_SYNCVALUE 0x01 // Default 783 | #define RF_SYNCVALUE5_SYNCVALUE 0x01 // Default 784 | #define RF_SYNCVALUE6_SYNCVALUE 0x01 // Default 785 | #define RF_SYNCVALUE7_SYNCVALUE 0x01 // Default 786 | #define RF_SYNCVALUE8_SYNCVALUE 0x01 // Default 787 | 788 | /*! 789 | * RegPacketConfig1 790 | */ 791 | #define RF_PACKETCONFIG1_PACKETFORMAT_MASK 0x7F 792 | #define RF_PACKETCONFIG1_PACKETFORMAT_FIXED 0x00 793 | #define RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE 0x80 // Default 794 | 795 | #define RF_PACKETCONFIG1_DCFREE_MASK 0x9F 796 | #define RF_PACKETCONFIG1_DCFREE_OFF 0x00 // Default 797 | #define RF_PACKETCONFIG1_DCFREE_MANCHESTER 0x20 798 | #define RF_PACKETCONFIG1_DCFREE_WHITENING 0x40 799 | 800 | #define RF_PACKETCONFIG1_CRC_MASK 0xEF 801 | #define RF_PACKETCONFIG1_CRC_ON 0x10 // Default 802 | #define RF_PACKETCONFIG1_CRC_OFF 0x00 803 | 804 | #define RF_PACKETCONFIG1_CRCAUTOCLEAR_MASK 0xF7 805 | #define RF_PACKETCONFIG1_CRCAUTOCLEAR_ON 0x00 // Default 806 | #define RF_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08 807 | 808 | #define RF_PACKETCONFIG1_ADDRSFILTERING_MASK 0xF9 809 | #define RF_PACKETCONFIG1_ADDRSFILTERING_OFF 0x00 // Default 810 | #define RF_PACKETCONFIG1_ADDRSFILTERING_NODE 0x02 811 | #define RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST 0x04 812 | 813 | #define RF_PACKETCONFIG1_CRCWHITENINGTYPE_MASK 0xFE 814 | #define RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT 0x00 // Default 815 | #define RF_PACKETCONFIG1_CRCWHITENINGTYPE_IBM 0x01 816 | 817 | /*! 818 | * RegPacketConfig2 819 | */ 820 | #define RF_PACKETCONFIG2_DATAMODE_MASK 0xBF 821 | #define RF_PACKETCONFIG2_DATAMODE_CONTINUOUS 0x00 822 | #define RF_PACKETCONFIG2_DATAMODE_PACKET 0x40 // Default 823 | 824 | #define RF_PACKETCONFIG2_IOHOME_MASK 0xDF 825 | #define RF_PACKETCONFIG2_IOHOME_ON 0x20 826 | #define RF_PACKETCONFIG2_IOHOME_OFF 0x00 // Default 827 | 828 | #define RF_PACKETCONFIG2_BEACON_MASK 0xF7 829 | #define RF_PACKETCONFIG2_BEACON_ON 0x08 830 | #define RF_PACKETCONFIG2_BEACON_OFF 0x00 // Default 831 | 832 | #define RF_PACKETCONFIG2_PAYLOADLENGTH_MSB_MASK 0xF8 833 | 834 | /*! 835 | * RegPayloadLength 836 | */ 837 | #define RF_PAYLOADLENGTH_LENGTH 0x40 // Default 838 | 839 | /*! 840 | * RegNodeAdrs 841 | */ 842 | #define RF_NODEADDRESS_ADDRESS 0x00 843 | 844 | /*! 845 | * RegBroadcastAdrs 846 | */ 847 | #define RF_BROADCASTADDRESS_ADDRESS 0x00 848 | 849 | /*! 850 | * RegFifoThresh 851 | */ 852 | #define RF_FIFOTHRESH_TXSTARTCONDITION_MASK 0x7F 853 | #define RF_FIFOTHRESH_TXSTARTCONDITION_FIFOTHRESH 0x00 854 | #define RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY 0x80 // Default 855 | 856 | #define RF_FIFOTHRESH_FIFOTHRESHOLD_MASK 0xC0 857 | #define RF_FIFOTHRESH_FIFOTHRESHOLD_THRESHOLD 0x0F // Default 858 | 859 | /*! 860 | * RegSeqConfig1 861 | */ 862 | #define RF_SEQCONFIG1_SEQUENCER_START 0x80 863 | 864 | #define RF_SEQCONFIG1_SEQUENCER_STOP 0x40 865 | 866 | #define RF_SEQCONFIG1_IDLEMODE_MASK 0xDF 867 | #define RF_SEQCONFIG1_IDLEMODE_SLEEP 0x20 868 | #define RF_SEQCONFIG1_IDLEMODE_STANDBY 0x00 // Default 869 | 870 | #define RF_SEQCONFIG1_FROMSTART_MASK 0xE7 871 | #define RF_SEQCONFIG1_FROMSTART_TOLPS 0x00 // Default 872 | #define RF_SEQCONFIG1_FROMSTART_TORX 0x08 873 | #define RF_SEQCONFIG1_FROMSTART_TOTX 0x10 874 | #define RF_SEQCONFIG1_FROMSTART_TOTX_ONFIFOLEVEL 0x18 875 | 876 | #define RF_SEQCONFIG1_LPS_MASK 0xFB 877 | #define RF_SEQCONFIG1_LPS_SEQUENCER_OFF 0x00 // Default 878 | #define RF_SEQCONFIG1_LPS_IDLE 0x04 879 | 880 | #define RF_SEQCONFIG1_FROMIDLE_MASK 0xFD 881 | #define RF_SEQCONFIG1_FROMIDLE_TOTX 0x00 // Default 882 | #define RF_SEQCONFIG1_FROMIDLE_TORX 0x02 883 | 884 | #define RF_SEQCONFIG1_FROMTX_MASK 0xFE 885 | #define RF_SEQCONFIG1_FROMTX_TOLPS 0x00 // Default 886 | #define RF_SEQCONFIG1_FROMTX_TORX 0x01 887 | 888 | /*! 889 | * RegSeqConfig2 890 | */ 891 | #define RF_SEQCONFIG2_FROMRX_MASK 0x1F 892 | #define RF_SEQCONFIG2_FROMRX_TOUNUSED_000 0x00 // Default 893 | #define RF_SEQCONFIG2_FROMRX_TORXPKT_ONPLDRDY 0x20 894 | #define RF_SEQCONFIG2_FROMRX_TOLPS_ONPLDRDY 0x40 895 | #define RF_SEQCONFIG2_FROMRX_TORXPKT_ONCRCOK 0x60 896 | #define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONRSSI 0x80 897 | #define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONSYNC 0xA0 898 | #define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONPREAMBLE 0xC0 899 | #define RF_SEQCONFIG2_FROMRX_TOUNUSED_111 0xE0 900 | 901 | #define RF_SEQCONFIG2_FROMRXTIMEOUT_MASK 0xE7 902 | #define RF_SEQCONFIG2_FROMRXTIMEOUT_TORXRESTART 0x00 // Default 903 | #define RF_SEQCONFIG2_FROMRXTIMEOUT_TOTX 0x08 904 | #define RF_SEQCONFIG2_FROMRXTIMEOUT_TOLPS 0x10 905 | #define RF_SEQCONFIG2_FROMRXTIMEOUT_TOSEQUENCEROFF 0x18 906 | 907 | #define RF_SEQCONFIG2_FROMRXPKT_MASK 0xF8 908 | #define RF_SEQCONFIG2_FROMRXPKT_TOSEQUENCEROFF 0x00 // Default 909 | #define RF_SEQCONFIG2_FROMRXPKT_TOTX_ONFIFOEMPTY 0x01 910 | #define RF_SEQCONFIG2_FROMRXPKT_TOLPS 0x02 911 | #define RF_SEQCONFIG2_FROMRXPKT_TOSYNTHESIZERRX 0x03 912 | #define RF_SEQCONFIG2_FROMRXPKT_TORX 0x04 913 | 914 | /*! 915 | * RegTimerResol 916 | */ 917 | #define RF_TIMERRESOL_TIMER1RESOL_MASK 0xF3 918 | #define RF_TIMERRESOL_TIMER1RESOL_OFF 0x00 // Default 919 | #define RF_TIMERRESOL_TIMER1RESOL_000064_US 0x04 920 | #define RF_TIMERRESOL_TIMER1RESOL_004100_US 0x08 921 | #define RF_TIMERRESOL_TIMER1RESOL_262000_US 0x0C 922 | 923 | #define RF_TIMERRESOL_TIMER2RESOL_MASK 0xFC 924 | #define RF_TIMERRESOL_TIMER2RESOL_OFF 0x00 // Default 925 | #define RF_TIMERRESOL_TIMER2RESOL_000064_US 0x01 926 | #define RF_TIMERRESOL_TIMER2RESOL_004100_US 0x02 927 | #define RF_TIMERRESOL_TIMER2RESOL_262000_US 0x03 928 | 929 | /*! 930 | * RegTimer1Coef 931 | */ 932 | #define RF_TIMER1COEF_TIMER1COEFFICIENT 0xF5 // Default 933 | 934 | /*! 935 | * RegTimer2Coef 936 | */ 937 | #define RF_TIMER2COEF_TIMER2COEFFICIENT 0x20 // Default 938 | 939 | /*! 940 | * RegImageCal 941 | */ 942 | #define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F 943 | #define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 944 | #define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default 945 | 946 | #define RF_IMAGECAL_IMAGECAL_MASK 0xBF 947 | #define RF_IMAGECAL_IMAGECAL_START 0x40 948 | 949 | #define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 950 | #define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default 951 | 952 | #define RF_IMAGECAL_TEMPCHANGE_HIGHER 0x08 953 | #define RF_IMAGECAL_TEMPCHANGE_LOWER 0x00 954 | 955 | #define RF_IMAGECAL_TEMPTHRESHOLD_MASK 0xF9 956 | #define RF_IMAGECAL_TEMPTHRESHOLD_05 0x00 957 | #define RF_IMAGECAL_TEMPTHRESHOLD_10 0x02 // Default 958 | #define RF_IMAGECAL_TEMPTHRESHOLD_15 0x04 959 | #define RF_IMAGECAL_TEMPTHRESHOLD_20 0x06 960 | 961 | #define RF_IMAGECAL_TEMPMONITOR_MASK 0xFE 962 | #define RF_IMAGECAL_TEMPMONITOR_ON 0x00 // Default 963 | #define RF_IMAGECAL_TEMPMONITOR_OFF 0x01 964 | 965 | /*! 966 | * RegTemp (Read Only) 967 | */ 968 | 969 | /*! 970 | * RegLowBat 971 | */ 972 | #define RF_LOWBAT_MASK 0xF7 973 | #define RF_LOWBAT_ON 0x08 974 | #define RF_LOWBAT_OFF 0x00 // Default 975 | 976 | #define RF_LOWBAT_TRIM_MASK 0xF8 977 | #define RF_LOWBAT_TRIM_1695 0x00 978 | #define RF_LOWBAT_TRIM_1764 0x01 979 | #define RF_LOWBAT_TRIM_1835 0x02 // Default 980 | #define RF_LOWBAT_TRIM_1905 0x03 981 | #define RF_LOWBAT_TRIM_1976 0x04 982 | #define RF_LOWBAT_TRIM_2045 0x05 983 | #define RF_LOWBAT_TRIM_2116 0x06 984 | #define RF_LOWBAT_TRIM_2185 0x07 985 | 986 | /*! 987 | * RegIrqFlags1 988 | */ 989 | #define RF_IRQFLAGS1_MODEREADY 0x80 990 | 991 | #define RF_IRQFLAGS1_RXREADY 0x40 992 | 993 | #define RF_IRQFLAGS1_TXREADY 0x20 994 | 995 | #define RF_IRQFLAGS1_PLLLOCK 0x10 996 | 997 | #define RF_IRQFLAGS1_RSSI 0x08 998 | 999 | #define RF_IRQFLAGS1_TIMEOUT 0x04 1000 | 1001 | #define RF_IRQFLAGS1_PREAMBLEDETECT 0x02 1002 | 1003 | #define RF_IRQFLAGS1_SYNCADDRESSMATCH 0x01 1004 | 1005 | /*! 1006 | * RegIrqFlags2 1007 | */ 1008 | #define RF_IRQFLAGS2_FIFOFULL 0x80 1009 | 1010 | #define RF_IRQFLAGS2_FIFOEMPTY 0x40 1011 | 1012 | #define RF_IRQFLAGS2_FIFOLEVEL 0x20 1013 | 1014 | #define RF_IRQFLAGS2_FIFOOVERRUN 0x10 1015 | 1016 | #define RF_IRQFLAGS2_PACKETSENT 0x08 1017 | 1018 | #define RF_IRQFLAGS2_PAYLOADREADY 0x04 1019 | 1020 | #define RF_IRQFLAGS2_CRCOK 0x02 1021 | 1022 | #define RF_IRQFLAGS2_LOWBAT 0x01 1023 | 1024 | /*! 1025 | * RegDioMapping1 1026 | */ 1027 | #define RF_DIOMAPPING1_DIO0_MASK 0x3F 1028 | #define RF_DIOMAPPING1_DIO0_00 0x00 // Default 1029 | #define RF_DIOMAPPING1_DIO0_01 0x40 1030 | #define RF_DIOMAPPING1_DIO0_10 0x80 1031 | #define RF_DIOMAPPING1_DIO0_11 0xC0 1032 | 1033 | #define RF_DIOMAPPING1_DIO1_MASK 0xCF 1034 | #define RF_DIOMAPPING1_DIO1_00 0x00 // Default 1035 | #define RF_DIOMAPPING1_DIO1_01 0x10 1036 | #define RF_DIOMAPPING1_DIO1_10 0x20 1037 | #define RF_DIOMAPPING1_DIO1_11 0x30 1038 | 1039 | #define RF_DIOMAPPING1_DIO2_MASK 0xF3 1040 | #define RF_DIOMAPPING1_DIO2_00 0x00 // Default 1041 | #define RF_DIOMAPPING1_DIO2_01 0x04 1042 | #define RF_DIOMAPPING1_DIO2_10 0x08 1043 | #define RF_DIOMAPPING1_DIO2_11 0x0C 1044 | 1045 | #define RF_DIOMAPPING1_DIO3_MASK 0xFC 1046 | #define RF_DIOMAPPING1_DIO3_00 0x00 // Default 1047 | #define RF_DIOMAPPING1_DIO3_01 0x01 1048 | #define RF_DIOMAPPING1_DIO3_10 0x02 1049 | #define RF_DIOMAPPING1_DIO3_11 0x03 1050 | 1051 | /*! 1052 | * RegDioMapping2 1053 | */ 1054 | #define RF_DIOMAPPING2_DIO4_MASK 0x3F 1055 | #define RF_DIOMAPPING2_DIO4_00 0x00 // Default 1056 | #define RF_DIOMAPPING2_DIO4_01 0x40 1057 | #define RF_DIOMAPPING2_DIO4_10 0x80 1058 | #define RF_DIOMAPPING2_DIO4_11 0xC0 1059 | 1060 | #define RF_DIOMAPPING2_DIO5_MASK 0xCF 1061 | #define RF_DIOMAPPING2_DIO5_00 0x00 // Default 1062 | #define RF_DIOMAPPING2_DIO5_01 0x10 1063 | #define RF_DIOMAPPING2_DIO5_10 0x20 1064 | #define RF_DIOMAPPING2_DIO5_11 0x30 1065 | 1066 | #define RF_DIOMAPPING2_MAP_MASK 0xFE 1067 | #define RF_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 1068 | #define RF_DIOMAPPING2_MAP_RSSI 0x00 // Default 1069 | 1070 | /*! 1071 | * RegVersion (Read Only) 1072 | */ 1073 | 1074 | /*! 1075 | * RegAgcRef 1076 | */ 1077 | 1078 | /*! 1079 | * RegAgcThresh1 1080 | */ 1081 | 1082 | /*! 1083 | * RegAgcThresh2 1084 | */ 1085 | 1086 | /*! 1087 | * RegAgcThresh3 1088 | */ 1089 | 1090 | /*! 1091 | * RegPllHop 1092 | */ 1093 | #define RF_PLLHOP_FASTHOP_MASK 0x7F 1094 | #define RF_PLLHOP_FASTHOP_ON 0x80 1095 | #define RF_PLLHOP_FASTHOP_OFF 0x00 // Default 1096 | 1097 | /*! 1098 | * RegTcxo 1099 | */ 1100 | #define RF_TCXO_TCXOINPUT_MASK 0xEF 1101 | #define RF_TCXO_TCXOINPUT_ON 0x10 1102 | #define RF_TCXO_TCXOINPUT_OFF 0x00 // Default 1103 | 1104 | /*! 1105 | * RegPaDac 1106 | */ 1107 | #define RF_PADAC_20DBM_MASK 0xF8 1108 | #define RF_PADAC_20DBM_ON 0x07 1109 | #define RF_PADAC_20DBM_OFF 0x04 // Default 1110 | 1111 | /*! 1112 | * RegPll 1113 | */ 1114 | #define RF_PLL_BANDWIDTH_MASK 0x3F 1115 | #define RF_PLL_BANDWIDTH_75 0x00 1116 | #define RF_PLL_BANDWIDTH_150 0x40 1117 | #define RF_PLL_BANDWIDTH_225 0x80 1118 | #define RF_PLL_BANDWIDTH_300 0xC0 // Default 1119 | 1120 | /*! 1121 | * RegPllLowPn 1122 | */ 1123 | #define RF_PLLLOWPN_BANDWIDTH_MASK 0x3F 1124 | #define RF_PLLLOWPN_BANDWIDTH_75 0x00 1125 | #define RF_PLLLOWPN_BANDWIDTH_150 0x40 1126 | #define RF_PLLLOWPN_BANDWIDTH_225 0x80 1127 | #define RF_PLLLOWPN_BANDWIDTH_300 0xC0 // Default 1128 | 1129 | /*! 1130 | * RegFormerTemp 1131 | */ 1132 | 1133 | /*! 1134 | * RegBitrateFrac 1135 | */ 1136 | #define RF_BITRATEFRAC_MASK 0xF0 1137 | 1138 | #endif // __SX1272_REGS_FSK_H__ 1139 | -------------------------------------------------------------------------------- /SX1272/registers/sx1272Regs-LoRa.h: -------------------------------------------------------------------------------- 1 | /** 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C) 2015 Semtech 8 | 9 | Description: SX1272 LoRa modem registers and bits definitions 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | 15 | Copyright (c) 2017, Arm Limited and affiliates. 16 | 17 | SPDX-License-Identifier: BSD-3-Clause 18 | */ 19 | #ifndef __SX1272_REGS_LORA_H__ 20 | #define __SX1272_REGS_LORA_H__ 21 | 22 | /*! 23 | * ============================================================================ 24 | * SX1272 Internal registers Address 25 | * ============================================================================ 26 | */ 27 | #define REG_LR_FIFO 0x00 28 | // Common settings 29 | #define REG_LR_OPMODE 0x01 30 | #define REG_LR_FRFMSB 0x06 31 | #define REG_LR_FRFMID 0x07 32 | #define REG_LR_FRFLSB 0x08 33 | // Tx settings 34 | #define REG_LR_PACONFIG 0x09 35 | #define REG_LR_PARAMP 0x0A 36 | #define REG_LR_OCP 0x0B 37 | // Rx settings 38 | #define REG_LR_LNA 0x0C 39 | // LoRa registers 40 | #define REG_LR_FIFOADDRPTR 0x0D 41 | #define REG_LR_FIFOTXBASEADDR 0x0E 42 | #define REG_LR_FIFORXBASEADDR 0x0F 43 | #define REG_LR_FIFORXCURRENTADDR 0x10 44 | #define REG_LR_IRQFLAGSMASK 0x11 45 | #define REG_LR_IRQFLAGS 0x12 46 | #define REG_LR_RXNBBYTES 0x13 47 | #define REG_LR_RXHEADERCNTVALUEMSB 0x14 48 | #define REG_LR_RXHEADERCNTVALUELSB 0x15 49 | #define REG_LR_RXPACKETCNTVALUEMSB 0x16 50 | #define REG_LR_RXPACKETCNTVALUELSB 0x17 51 | #define REG_LR_MODEMSTAT 0x18 52 | #define REG_LR_PKTSNRVALUE 0x19 53 | #define REG_LR_PKTRSSIVALUE 0x1A 54 | #define REG_LR_RSSIVALUE 0x1B 55 | #define REG_LR_HOPCHANNEL 0x1C 56 | #define REG_LR_MODEMCONFIG1 0x1D 57 | #define REG_LR_MODEMCONFIG2 0x1E 58 | #define REG_LR_SYMBTIMEOUTLSB 0x1F 59 | #define REG_LR_PREAMBLEMSB 0x20 60 | #define REG_LR_PREAMBLELSB 0x21 61 | #define REG_LR_PAYLOADLENGTH 0x22 62 | #define REG_LR_PAYLOADMAXLENGTH 0x23 63 | #define REG_LR_HOPPERIOD 0x24 64 | #define REG_LR_FIFORXBYTEADDR 0x25 65 | #define REG_LR_FEIMSB 0x28 66 | #define REG_LR_FEIMID 0x29 67 | #define REG_LR_FEILSB 0x2A 68 | #define REG_LR_RSSIWIDEBAND 0x2C 69 | #define REG_LR_DETECTOPTIMIZE 0x31 70 | #define REG_LR_INVERTIQ 0x33 71 | #define REG_LR_DETECTIONTHRESHOLD 0x37 72 | #define REG_LR_SYNCWORD 0x39 73 | #define REG_LR_INVERTIQ2 0x3B 74 | 75 | // end of documented register in datasheet 76 | // I/O settings 77 | #define REG_LR_DIOMAPPING1 0x40 78 | #define REG_LR_DIOMAPPING2 0x41 79 | // Version 80 | #define REG_LR_VERSION 0x42 81 | // Additional settings 82 | #define REG_LR_AGCREF 0x43 83 | #define REG_LR_AGCTHRESH1 0x44 84 | #define REG_LR_AGCTHRESH2 0x45 85 | #define REG_LR_AGCTHRESH3 0x46 86 | #define REG_LR_PLLHOP 0x4B 87 | #define REG_LR_TCXO 0x58 88 | #define REG_LR_PADAC 0x5A 89 | #define REG_LR_PLL 0x5C 90 | #define REG_LR_PLLLOWPN 0x5E 91 | #define REG_LR_FORMERTEMP 0x6C 92 | 93 | /*! 94 | * ============================================================================ 95 | * SX1272 LoRa bits control definition 96 | * ============================================================================ 97 | */ 98 | 99 | /*! 100 | * RegFifo 101 | */ 102 | 103 | /*! 104 | * RegOpMode 105 | */ 106 | #define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F 107 | #define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default 108 | #define RFLR_OPMODE_LONGRANGEMODE_ON 0x80 109 | 110 | #define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF 111 | #define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40 112 | #define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default 113 | 114 | #define RFLR_OPMODE_MASK 0xF8 115 | #define RFLR_OPMODE_SLEEP 0x00 116 | #define RFLR_OPMODE_STANDBY 0x01 // Default 117 | #define RFLR_OPMODE_SYNTHESIZER_TX 0x02 118 | #define RFLR_OPMODE_TRANSMITTER 0x03 119 | #define RFLR_OPMODE_SYNTHESIZER_RX 0x04 120 | #define RFLR_OPMODE_RECEIVER 0x05 121 | // LoRa specific modes 122 | #define RFLR_OPMODE_RECEIVER_SINGLE 0x06 123 | #define RFLR_OPMODE_CAD 0x07 124 | 125 | /*! 126 | * RegFrf (MHz) 127 | */ 128 | #define RFLR_FRFMSB_915_MHZ 0xE4 // Default 129 | #define RFLR_FRFMID_915_MHZ 0xC0 // Default 130 | #define RFLR_FRFLSB_915_MHZ 0x00 // Default 131 | 132 | /*! 133 | * RegPaConfig 134 | */ 135 | #define RFLR_PACONFIG_PASELECT_MASK 0x7F 136 | #define RFLR_PACONFIG_PASELECT_PABOOST 0x80 137 | #define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default 138 | 139 | #define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0 140 | 141 | /*! 142 | * RegPaRamp 143 | */ 144 | #define RFLR_PARAMP_LOWPNTXPLL_MASK 0xE0 145 | #define RFLR_PARAMP_LOWPNTXPLL_OFF 0x10 // Default 146 | #define RFLR_PARAMP_LOWPNTXPLL_ON 0x00 147 | 148 | #define RFLR_PARAMP_MASK 0xF0 149 | #define RFLR_PARAMP_3400_US 0x00 150 | #define RFLR_PARAMP_2000_US 0x01 151 | #define RFLR_PARAMP_1000_US 0x02 152 | #define RFLR_PARAMP_0500_US 0x03 153 | #define RFLR_PARAMP_0250_US 0x04 154 | #define RFLR_PARAMP_0125_US 0x05 155 | #define RFLR_PARAMP_0100_US 0x06 156 | #define RFLR_PARAMP_0062_US 0x07 157 | #define RFLR_PARAMP_0050_US 0x08 158 | #define RFLR_PARAMP_0040_US 0x09 // Default 159 | #define RFLR_PARAMP_0031_US 0x0A 160 | #define RFLR_PARAMP_0025_US 0x0B 161 | #define RFLR_PARAMP_0020_US 0x0C 162 | #define RFLR_PARAMP_0015_US 0x0D 163 | #define RFLR_PARAMP_0012_US 0x0E 164 | #define RFLR_PARAMP_0010_US 0x0F 165 | 166 | /*! 167 | * RegOcp 168 | */ 169 | #define RFLR_OCP_MASK 0xDF 170 | #define RFLR_OCP_ON 0x20 // Default 171 | #define RFLR_OCP_OFF 0x00 172 | 173 | #define RFLR_OCP_TRIM_MASK 0xE0 174 | #define RFLR_OCP_TRIM_045_MA 0x00 175 | #define RFLR_OCP_TRIM_050_MA 0x01 176 | #define RFLR_OCP_TRIM_055_MA 0x02 177 | #define RFLR_OCP_TRIM_060_MA 0x03 178 | #define RFLR_OCP_TRIM_065_MA 0x04 179 | #define RFLR_OCP_TRIM_070_MA 0x05 180 | #define RFLR_OCP_TRIM_075_MA 0x06 181 | #define RFLR_OCP_TRIM_080_MA 0x07 182 | #define RFLR_OCP_TRIM_085_MA 0x08 183 | #define RFLR_OCP_TRIM_090_MA 0x09 184 | #define RFLR_OCP_TRIM_095_MA 0x0A 185 | #define RFLR_OCP_TRIM_100_MA 0x0B // Default 186 | #define RFLR_OCP_TRIM_105_MA 0x0C 187 | #define RFLR_OCP_TRIM_110_MA 0x0D 188 | #define RFLR_OCP_TRIM_115_MA 0x0E 189 | #define RFLR_OCP_TRIM_120_MA 0x0F 190 | #define RFLR_OCP_TRIM_130_MA 0x10 191 | #define RFLR_OCP_TRIM_140_MA 0x11 192 | #define RFLR_OCP_TRIM_150_MA 0x12 193 | #define RFLR_OCP_TRIM_160_MA 0x13 194 | #define RFLR_OCP_TRIM_170_MA 0x14 195 | #define RFLR_OCP_TRIM_180_MA 0x15 196 | #define RFLR_OCP_TRIM_190_MA 0x16 197 | #define RFLR_OCP_TRIM_200_MA 0x17 198 | #define RFLR_OCP_TRIM_210_MA 0x18 199 | #define RFLR_OCP_TRIM_220_MA 0x19 200 | #define RFLR_OCP_TRIM_230_MA 0x1A 201 | #define RFLR_OCP_TRIM_240_MA 0x1B 202 | 203 | /*! 204 | * RegLna 205 | */ 206 | #define RFLR_LNA_GAIN_MASK 0x1F 207 | #define RFLR_LNA_GAIN_G1 0x20 // Default 208 | #define RFLR_LNA_GAIN_G2 0x40 209 | #define RFLR_LNA_GAIN_G3 0x60 210 | #define RFLR_LNA_GAIN_G4 0x80 211 | #define RFLR_LNA_GAIN_G5 0xA0 212 | #define RFLR_LNA_GAIN_G6 0xC0 213 | 214 | #define RFLR_LNA_BOOST_MASK 0xFC 215 | #define RFLR_LNA_BOOST_OFF 0x00 // Default 216 | #define RFLR_LNA_BOOST_ON 0x03 217 | 218 | /*! 219 | * RegFifoAddrPtr 220 | */ 221 | #define RFLR_FIFOADDRPTR 0x00 // Default 222 | 223 | /*! 224 | * RegFifoTxBaseAddr 225 | */ 226 | #define RFLR_FIFOTXBASEADDR 0x80 // Default 227 | 228 | /*! 229 | * RegFifoTxBaseAddr 230 | */ 231 | #define RFLR_FIFORXBASEADDR 0x00 // Default 232 | 233 | /*! 234 | * RegFifoRxCurrentAddr (Read Only) 235 | */ 236 | 237 | /*! 238 | * RegIrqFlagsMask 239 | */ 240 | #define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80 241 | #define RFLR_IRQFLAGS_RXDONE_MASK 0x40 242 | #define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20 243 | #define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10 244 | #define RFLR_IRQFLAGS_TXDONE_MASK 0x08 245 | #define RFLR_IRQFLAGS_CADDONE_MASK 0x04 246 | #define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02 247 | #define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01 248 | 249 | /*! 250 | * RegIrqFlags 251 | */ 252 | #define RFLR_IRQFLAGS_RXTIMEOUT 0x80 253 | #define RFLR_IRQFLAGS_RXDONE 0x40 254 | #define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20 255 | #define RFLR_IRQFLAGS_VALIDHEADER 0x10 256 | #define RFLR_IRQFLAGS_TXDONE 0x08 257 | #define RFLR_IRQFLAGS_CADDONE 0x04 258 | #define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02 259 | #define RFLR_IRQFLAGS_CADDETECTED 0x01 260 | 261 | /*! 262 | * RegFifoRxNbBytes (Read Only) 263 | */ 264 | 265 | /*! 266 | * RegRxHeaderCntValueMsb (Read Only) 267 | */ 268 | 269 | /*! 270 | * RegRxHeaderCntValueLsb (Read Only) 271 | */ 272 | 273 | /*! 274 | * RegRxPacketCntValueMsb (Read Only) 275 | */ 276 | 277 | /*! 278 | * RegRxPacketCntValueLsb (Read Only) 279 | */ 280 | 281 | /*! 282 | * RegModemStat (Read Only) 283 | */ 284 | #define RFLR_MODEMSTAT_RX_CR_MASK 0x1F 285 | #define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0 286 | 287 | /*! 288 | * RegPktSnrValue (Read Only) 289 | */ 290 | 291 | /*! 292 | * RegPktRssiValue (Read Only) 293 | */ 294 | 295 | /*! 296 | * RegRssiValue (Read Only) 297 | */ 298 | 299 | /*! 300 | * RegHopChannel (Read Only) 301 | */ 302 | #define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F 303 | #define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80 304 | #define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default 305 | 306 | #define RFLR_HOPCHANNEL_CRCONPAYLOAD_MASK 0xBF 307 | #define RFLR_HOPCHANNEL_CRCONPAYLOAD_ON 0x40 308 | #define RFLR_HOPCHANNEL_CRCONPAYLOAD_OFF 0x00 // Default 309 | 310 | #define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F 311 | 312 | /*! 313 | * RegModemConfig1 314 | */ 315 | #define RFLR_MODEMCONFIG1_BW_MASK 0x3F 316 | #define RFLR_MODEMCONFIG1_BW_125_KHZ 0x00 // Default 317 | #define RFLR_MODEMCONFIG1_BW_250_KHZ 0x40 318 | #define RFLR_MODEMCONFIG1_BW_500_KHZ 0x80 319 | 320 | #define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xC7 321 | #define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x08 322 | #define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x10 // Default 323 | #define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x18 324 | #define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x20 325 | 326 | #define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFB 327 | #define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x04 328 | #define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default 329 | 330 | #define RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK 0xFD 331 | #define RFLR_MODEMCONFIG1_RXPAYLOADCRC_ON 0x02 332 | #define RFLR_MODEMCONFIG1_RXPAYLOADCRC_OFF 0x00 // Default 333 | 334 | #define RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK 0xFE 335 | #define RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_ON 0x01 336 | #define RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_OFF 0x00 // Default 337 | 338 | /*! 339 | * RegModemConfig2 340 | */ 341 | #define RFLR_MODEMCONFIG2_SF_MASK 0x0F 342 | #define RFLR_MODEMCONFIG2_SF_6 0x60 343 | #define RFLR_MODEMCONFIG2_SF_7 0x70 // Default 344 | #define RFLR_MODEMCONFIG2_SF_8 0x80 345 | #define RFLR_MODEMCONFIG2_SF_9 0x90 346 | #define RFLR_MODEMCONFIG2_SF_10 0xA0 347 | #define RFLR_MODEMCONFIG2_SF_11 0xB0 348 | #define RFLR_MODEMCONFIG2_SF_12 0xC0 349 | 350 | #define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7 351 | #define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08 352 | #define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00 353 | 354 | #define RFLR_MODEMCONFIG2_AGCAUTO_MASK 0xFB 355 | #define RFLR_MODEMCONFIG2_AGCAUTO_ON 0x04 // Default 356 | #define RFLR_MODEMCONFIG2_AGCAUTO_OFF 0x00 357 | 358 | #define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC 359 | #define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default 360 | 361 | /*! 362 | * RegSymbTimeoutLsb 363 | */ 364 | #define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default 365 | 366 | /*! 367 | * RegPreambleLengthMsb 368 | */ 369 | #define RFLR_PREAMBLELENGTHMSB 0x00 // Default 370 | 371 | /*! 372 | * RegPreambleLengthLsb 373 | */ 374 | #define RFLR_PREAMBLELENGTHLSB 0x08 // Default 375 | 376 | /*! 377 | * RegPayloadLength 378 | */ 379 | #define RFLR_PAYLOADLENGTH 0x0E // Default 380 | 381 | /*! 382 | * RegPayloadMaxLength 383 | */ 384 | #define RFLR_PAYLOADMAXLENGTH 0xFF // Default 385 | 386 | /*! 387 | * RegHopPeriod 388 | */ 389 | #define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default 390 | 391 | /*! 392 | * RegFifoRxByteAddr (Read Only) 393 | */ 394 | 395 | /*! 396 | * RegFeiMsb (Read Only) 397 | */ 398 | 399 | /*! 400 | * RegFeiMid (Read Only) 401 | */ 402 | 403 | /*! 404 | * RegFeiLsb (Read Only) 405 | */ 406 | 407 | /*! 408 | * RegRssiWideband (Read Only) 409 | */ 410 | 411 | /*! 412 | * RegDetectOptimize 413 | */ 414 | #define RFLR_DETECTIONOPTIMIZE_MASK 0xF8 415 | #define RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 0x03 // Default 416 | #define RFLR_DETECTIONOPTIMIZE_SF6 0x05 417 | 418 | /*! 419 | * RegInvertIQ 420 | */ 421 | #define RFLR_INVERTIQ_RX_MASK 0xBF 422 | #define RFLR_INVERTIQ_RX_OFF 0x00 423 | #define RFLR_INVERTIQ_RX_ON 0x40 424 | #define RFLR_INVERTIQ_TX_MASK 0xFE 425 | #define RFLR_INVERTIQ_TX_OFF 0x01 426 | #define RFLR_INVERTIQ_TX_ON 0x00 427 | 428 | /*! 429 | * RegDetectionThreshold 430 | */ 431 | #define RFLR_DETECTIONTHRESH_SF7_TO_SF12 0x0A // Default 432 | #define RFLR_DETECTIONTHRESH_SF6 0x0C 433 | 434 | /*! 435 | * RegInvertIQ2 436 | */ 437 | #define RFLR_INVERTIQ2_ON 0x19 438 | #define RFLR_INVERTIQ2_OFF 0x1D 439 | 440 | /*! 441 | * RegDioMapping1 442 | */ 443 | #define RFLR_DIOMAPPING1_DIO0_MASK 0x3F 444 | #define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default 445 | #define RFLR_DIOMAPPING1_DIO0_01 0x40 446 | #define RFLR_DIOMAPPING1_DIO0_10 0x80 447 | #define RFLR_DIOMAPPING1_DIO0_11 0xC0 448 | 449 | #define RFLR_DIOMAPPING1_DIO1_MASK 0xCF 450 | #define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default 451 | #define RFLR_DIOMAPPING1_DIO1_01 0x10 452 | #define RFLR_DIOMAPPING1_DIO1_10 0x20 453 | #define RFLR_DIOMAPPING1_DIO1_11 0x30 454 | 455 | #define RFLR_DIOMAPPING1_DIO2_MASK 0xF3 456 | #define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default 457 | #define RFLR_DIOMAPPING1_DIO2_01 0x04 458 | #define RFLR_DIOMAPPING1_DIO2_10 0x08 459 | #define RFLR_DIOMAPPING1_DIO2_11 0x0C 460 | 461 | #define RFLR_DIOMAPPING1_DIO3_MASK 0xFC 462 | #define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default 463 | #define RFLR_DIOMAPPING1_DIO3_01 0x01 464 | #define RFLR_DIOMAPPING1_DIO3_10 0x02 465 | #define RFLR_DIOMAPPING1_DIO3_11 0x03 466 | 467 | /*! 468 | * RegDioMapping2 469 | */ 470 | #define RFLR_DIOMAPPING2_DIO4_MASK 0x3F 471 | #define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default 472 | #define RFLR_DIOMAPPING2_DIO4_01 0x40 473 | #define RFLR_DIOMAPPING2_DIO4_10 0x80 474 | #define RFLR_DIOMAPPING2_DIO4_11 0xC0 475 | 476 | #define RFLR_DIOMAPPING2_DIO5_MASK 0xCF 477 | #define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default 478 | #define RFLR_DIOMAPPING2_DIO5_01 0x10 479 | #define RFLR_DIOMAPPING2_DIO5_10 0x20 480 | #define RFLR_DIOMAPPING2_DIO5_11 0x30 481 | 482 | #define RFLR_DIOMAPPING2_MAP_MASK 0xFE 483 | #define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 484 | #define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default 485 | 486 | /*! 487 | * RegVersion (Read Only) 488 | */ 489 | 490 | /*! 491 | * RegAgcRef 492 | */ 493 | 494 | /*! 495 | * RegAgcThresh1 496 | */ 497 | 498 | /*! 499 | * RegAgcThresh2 500 | */ 501 | 502 | /*! 503 | * RegAgcThresh3 504 | */ 505 | 506 | /*! 507 | * RegPllHop 508 | */ 509 | #define RFLR_PLLHOP_FASTHOP_MASK 0x7F 510 | #define RFLR_PLLHOP_FASTHOP_ON 0x80 511 | #define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default 512 | 513 | /*! 514 | * RegTcxo 515 | */ 516 | #define RFLR_TCXO_TCXOINPUT_MASK 0xEF 517 | #define RFLR_TCXO_TCXOINPUT_ON 0x10 518 | #define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default 519 | 520 | /*! 521 | * RegPaDac 522 | */ 523 | #define RFLR_PADAC_20DBM_MASK 0xF8 524 | #define RFLR_PADAC_20DBM_ON 0x07 525 | #define RFLR_PADAC_20DBM_OFF 0x04 // Default 526 | 527 | /*! 528 | * RegPll 529 | */ 530 | #define RFLR_PLL_BANDWIDTH_MASK 0x3F 531 | #define RFLR_PLL_BANDWIDTH_75 0x00 532 | #define RFLR_PLL_BANDWIDTH_150 0x40 533 | #define RFLR_PLL_BANDWIDTH_225 0x80 534 | #define RFLR_PLL_BANDWIDTH_300 0xC0 // Default 535 | 536 | /*! 537 | * RegPllLowPn 538 | */ 539 | #define RFLR_PLLLOWPN_BANDWIDTH_MASK 0x3F 540 | #define RFLR_PLLLOWPN_BANDWIDTH_75 0x00 541 | #define RFLR_PLLLOWPN_BANDWIDTH_150 0x40 542 | #define RFLR_PLLLOWPN_BANDWIDTH_225 0x80 543 | #define RFLR_PLLLOWPN_BANDWIDTH_300 0xC0 // Default 544 | 545 | /*! 546 | * RegFormerTemp 547 | */ 548 | 549 | #endif // __SX1272_REGS_LORA_H__ 550 | -------------------------------------------------------------------------------- /SX1276/README.md: -------------------------------------------------------------------------------- 1 | # Mbed enabled SX1276 LoRa/FSK radio driver 2 | -------------------------------------------------------------------------------- /SX1276/SX1276_LoRaRadio.h: -------------------------------------------------------------------------------- 1 | /** 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | ___ _____ _ ___ _ _____ ___ ___ ___ ___ 9 | / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 10 | \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 11 | |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 12 | embedded.connectivity.solutions=============== 13 | 14 | Description: LoRaWAN stack layer that controls both MAC and PHY underneath 15 | 16 | License: Revised BSD License, see LICENSE.TXT file include in the project 17 | 18 | Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 19 | 20 | 21 | Copyright (c) 2017, Arm Limited and affiliates. 22 | 23 | SPDX-License-Identifier: BSD-3-Clause 24 | */ 25 | 26 | #ifndef SX1276_LORARADIO_H_ 27 | #define SX1276_LORARADIO_H_ 28 | 29 | #include "PinNames.h" 30 | #include "InterruptIn.h" 31 | #include "DigitalOut.h" 32 | #include "DigitalInOut.h" 33 | #include "SPI.h" 34 | #include "platform/PlatformMutex.h" 35 | #ifdef MBED_CONF_RTOS_PRESENT 36 | #include "rtos/Thread.h" 37 | #endif 38 | 39 | #include "lorawan/LoRaRadio.h" 40 | 41 | #ifdef MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE 42 | #define MAX_DATA_BUFFER_SIZE_SX1276 MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE 43 | #else 44 | #define MAX_DATA_BUFFER_SIZE_SX1276 255 45 | #endif 46 | 47 | #if DEVICE_LPTICKER 48 | #include "LowPowerTimeout.h" 49 | #define ALIAS_LORAWAN_TIMER mbed::LowPowerTimeout 50 | #else 51 | #include "Timeout.h" 52 | #define ALIAS_LORAWAN_TIMER mbed::Timeout 53 | #endif 54 | 55 | /** 56 | * Radio driver implementation for Semtech SX1272 plus variants. 57 | * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. 58 | */ 59 | class SX1276_LoRaRadio: public LoRaRadio { 60 | public: 61 | /** 62 | * Use this constructor if pin definitions are provided manually. 63 | * The pins that are marked NC are optional. It is assumed that these 64 | * pins are not connected until/unless configured otherwise. 65 | * 66 | * Note: Pin ant_switch is equivalent to RxTx pin at 67 | * https://developer.mbed.org/components/SX1276MB1xAS/. 68 | * Reading the state of this pin indicates if the radio module type is 69 | * SX1276MB1LAS(North American frequency band supported) or SX1276MAS 70 | * (European frequency band supported). 71 | * Pin dio4 can be mapped to multiple pins on the board, please refer to 72 | * schematic of your board. For reference look at 73 | * https://developer.mbed.org/components/SX1276MB1xAS/ 74 | * 75 | * Most of the radio module control pins are not being used at the moment as 76 | * the SX1276MB1xAS shield has not connected them. For consistency and future 77 | * use we are leaving the pins in the constructor. For example, if in some 78 | * setting SX1276 radio module gets connected to an external power amplifier 79 | * or radio latch controls are connected. 80 | */ 81 | SX1276_LoRaRadio(PinName mosi, 82 | PinName miso, 83 | PinName sclk, 84 | PinName nss, 85 | PinName reset, 86 | PinName dio0, 87 | PinName dio1, 88 | PinName dio2, 89 | PinName dio3, 90 | PinName dio4, 91 | PinName dio5, 92 | PinName rf_switch_ctl1 = NC, 93 | PinName rf_switch_ctl2 = NC, 94 | PinName txctl = NC, 95 | PinName rxctl = NC, 96 | PinName ant_switch = NC, 97 | PinName pwr_amp_ctl = NC, 98 | PinName tcxo = NC); 99 | 100 | /** 101 | * Destructor 102 | */ 103 | virtual ~SX1276_LoRaRadio(); 104 | 105 | /** 106 | * Registers radio events with the Mbed LoRaWAN stack and 107 | * undergoes initialization steps if any 108 | * 109 | * @param events Structure containing the driver callback functions 110 | */ 111 | virtual void init_radio(radio_events_t *events); 112 | 113 | /** 114 | * Resets the radio module 115 | */ 116 | virtual void radio_reset(); 117 | 118 | /** 119 | * Put the RF module in sleep mode 120 | */ 121 | virtual void sleep(void); 122 | 123 | /** 124 | * Sets the radio in standby mode 125 | */ 126 | virtual void standby(void); 127 | 128 | /** 129 | * Sets the reception parameters 130 | * 131 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 132 | * @param bandwidth Sets the bandwidth 133 | * FSK : >= 2600 and <= 250000 Hz 134 | * LoRa: [0: 125 kHz, 1: 250 kHz, 135 | * 2: 500 kHz, 3: Reserved] 136 | * @param datarate Sets the Datarate 137 | * FSK : 600..300000 bits/s 138 | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, 139 | * 10: 1024, 11: 2048, 12: 4096 chips] 140 | * @param coderate Sets the coding rate ( LoRa only ) 141 | * FSK : N/A ( set to 0 ) 142 | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] 143 | * @param bandwidth_afc Sets the AFC Bandwidth ( FSK only ) 144 | * FSK : >= 2600 and <= 250000 Hz 145 | * LoRa: N/A ( set to 0 ) 146 | * @param preamble_len Sets the Preamble length ( LoRa only ) 147 | * FSK : N/A ( set to 0 ) 148 | * LoRa: Length in symbols ( the hardware adds 4 more symbols ) 149 | * @param symb_timeout Sets the RxSingle timeout value 150 | * FSK : timeout number of bytes 151 | * LoRa: timeout in symbols 152 | * @param fixLen Fixed length packets [0: variable, 1: fixed] 153 | * @param payload_len Sets payload length when fixed lenght is used 154 | * @param crc_on Enables/Disables the CRC [0: OFF, 1: ON] 155 | * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) 156 | * @param hop_period Number of symbols bewteen each hop (LoRa only) 157 | * @param iq_inverted Inverts IQ signals ( LoRa only ) 158 | * FSK : N/A ( set to 0 ) 159 | * LoRa: [0: not inverted, 1: inverted] 160 | * @param rx_continuous Sets the reception in continuous mode 161 | * [false: single mode, true: continuous mode] 162 | */ 163 | virtual void set_rx_config(radio_modems_t modem, uint32_t bandwidth, 164 | uint32_t datarate, uint8_t coderate, 165 | uint32_t bandwidth_afc, uint16_t preamble_len, 166 | uint16_t symb_timeout, bool fix_len, 167 | uint8_t payload_len, 168 | bool crc_on, bool freq_hop_on, uint8_t hop_period, 169 | bool iq_inverted, bool rx_continuous); 170 | 171 | /** 172 | * Sets the transmission parameters 173 | * 174 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 175 | * @param power Sets the output power [dBm] 176 | * @param fdev Sets the frequency deviation ( FSK only ) 177 | * FSK : [Hz] 178 | * LoRa: 0 179 | * @param bandwidth Sets the bandwidth ( LoRa only ) 180 | * FSK : 0 181 | * LoRa: [0: 125 kHz, 1: 250 kHz, 182 | * 2: 500 kHz, 3: Reserved] 183 | * @param datarate Sets the Datarate 184 | * FSK : 600..300000 bits/s 185 | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, 186 | * 10: 1024, 11: 2048, 12: 4096 chips] 187 | * @param coderate Sets the coding rate ( LoRa only ) 188 | * FSK : N/A ( set to 0 ) 189 | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] 190 | * @param preamble_len Sets the preamble length 191 | * @param fix_len Fixed length packets [0: variable, 1: fixed] 192 | * @param crc_on Enables disables the CRC [0: OFF, 1: ON] 193 | * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) 194 | * @param hop_period Number of symbols bewteen each hop (LoRa only) 195 | * @param iq_inverted Inverts IQ signals ( LoRa only ) 196 | * FSK : N/A ( set to 0 ) 197 | * LoRa: [0: not inverted, 1: inverted] 198 | * @param timeout Transmission timeout [ms] 199 | */ 200 | virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, 201 | uint32_t bandwidth, uint32_t datarate, 202 | uint8_t coderate, uint16_t preamble_len, 203 | bool fix_len, bool crc_on, bool freq_hop_on, 204 | uint8_t hop_period, bool iq_inverted, uint32_t timeout); 205 | 206 | /** 207 | * Sends the buffer of size 208 | * 209 | * Prepares the packet to be sent and sets the radio in transmission 210 | * 211 | * @param buffer Buffer pointer 212 | * @param size Buffer size 213 | */ 214 | virtual void send(uint8_t *buffer, uint8_t size); 215 | 216 | /** 217 | * For backwards compatibility 218 | */ 219 | virtual void receive(uint32_t timeout) 220 | { 221 | (void) timeout; 222 | receive(); 223 | } 224 | 225 | /** 226 | * Sets the radio to receive 227 | * 228 | * All necessary configuration options for reception are set in 229 | * 'set_rx_config(parameters)' API. 230 | */ 231 | virtual void receive(void); 232 | 233 | /** 234 | * Sets the carrier frequency 235 | * 236 | * @param freq Channel RF frequency 237 | */ 238 | virtual void set_channel(uint32_t freq); 239 | 240 | /** 241 | * Generates a 32 bits random value based on the RSSI readings 242 | * 243 | * Remark this function sets the radio in LoRa modem mode and disables 244 | * all interrupts. 245 | * After calling this function either Radio.SetRxConfig or 246 | * Radio.SetTxConfig functions must be called. 247 | * 248 | * @return 32 bits random value 249 | */ 250 | virtual uint32_t random(void); 251 | 252 | /** 253 | * Get radio status 254 | * 255 | * @param status Radio status [RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] 256 | * @return Return current radio status 257 | */ 258 | virtual uint8_t get_status(void); 259 | 260 | /** 261 | * Sets the maximum payload length 262 | * 263 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 264 | * @param max Maximum payload length in bytes 265 | */ 266 | virtual void set_max_payload_length(radio_modems_t modem, uint8_t max); 267 | 268 | /** 269 | * Sets the network to public or private 270 | * 271 | * Updates the sync byte. Applies to LoRa modem only 272 | * 273 | * @param enable if true, it enables a public network 274 | */ 275 | virtual void set_public_network(bool enable); 276 | 277 | /** 278 | * Computes the packet time on air for the given payload 279 | * 280 | * Remark can only be called once SetRxConfig or SetTxConfig have been called 281 | * 282 | * @param modem Radio modem to be used [0: FSK, 1: LoRa] 283 | * @param pkt_len Packet payload length 284 | * @return Computed airTime for the given packet payload length 285 | */ 286 | virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len); 287 | 288 | /** 289 | * Perform carrier sensing 290 | * 291 | * Checks for a certain time if the RSSI is above a given threshold. 292 | * This threshold determines if there is already a transmission going on 293 | * in the channel or not. 294 | * 295 | * @param modem Type of the radio modem 296 | * @param freq Carrier frequency 297 | * @param rssi_threshold Threshold value of RSSI 298 | * @param max_carrier_sense_time time to sense the channel 299 | * 300 | * @return true if there is no active transmission 301 | * in the channel, false otherwise 302 | */ 303 | virtual bool perform_carrier_sense(radio_modems_t modem, 304 | uint32_t freq, 305 | int16_t rssi_threshold, 306 | uint32_t max_carrier_sense_time); 307 | 308 | /** 309 | * Sets the radio in CAD mode 310 | * 311 | */ 312 | virtual void start_cad(void); 313 | 314 | /** 315 | * Check if the given RF is in range 316 | * 317 | * @param frequency frequency needed to be checked 318 | */ 319 | virtual bool check_rf_frequency(uint32_t frequency); 320 | 321 | /** Sets the radio in continuous wave transmission mode 322 | * 323 | * @param freq Channel RF frequency 324 | * @param power Sets the output power [dBm] 325 | * @param time Transmission mode timeout [s] 326 | */ 327 | virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time); 328 | 329 | /** 330 | * Acquire exclusive access 331 | */ 332 | virtual void lock(void); 333 | 334 | /** 335 | * Release exclusive access 336 | */ 337 | virtual void unlock(void); 338 | 339 | private: 340 | 341 | // SPI and chip select control 342 | mbed::SPI _spi; 343 | mbed::DigitalOut _chip_select; 344 | 345 | // module rest control 346 | mbed::DigitalInOut _reset_ctl; 347 | 348 | // Interrupt controls 349 | mbed::InterruptIn _dio0_ctl; 350 | mbed::InterruptIn _dio1_ctl; 351 | mbed::InterruptIn _dio2_ctl; 352 | mbed::InterruptIn _dio3_ctl; 353 | mbed::InterruptIn _dio4_ctl; 354 | mbed::InterruptIn _dio5_ctl; 355 | 356 | // Radio specific controls 357 | mbed::DigitalOut _rf_switch_ctl1; 358 | mbed::DigitalOut _rf_switch_ctl2; 359 | mbed::DigitalOut _txctl; 360 | mbed::DigitalOut _rxctl; 361 | mbed::DigitalInOut _ant_switch; 362 | mbed::DigitalOut _pwr_amp_ctl; 363 | mbed::DigitalOut _tcxo; 364 | 365 | // Contains all RF control pin names 366 | // This storage is needed even after assigning the 367 | // pins to corresponding object, as the driver needs to know 368 | // which control pins are connected and which are not. This 369 | // variation is inherent to driver because of target configuration. 370 | rf_ctrls _rf_ctrls; 371 | 372 | // We need these PinNames as not all modules have those connected 373 | PinName _dio4_pin; 374 | PinName _dio5_pin; 375 | 376 | // Structure containing all user and network specified settings 377 | // for radio module 378 | radio_settings_t _rf_settings; 379 | 380 | // Structure containing function pointers to the stack callbacks 381 | radio_events_t *_radio_events; 382 | 383 | // Data buffer used for both TX and RX 384 | // Size of this buffer is configurable via Mbed config system 385 | // Default is 255 bytes 386 | uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX1276]; 387 | 388 | // TX timer in ms. This timer is used as a fail safe for TX. 389 | // If the chip fails to transmit, its a fatal error, reflecting 390 | // some catastrophic bus failure etc. We wish to have the control 391 | // back from the driver in such a case. 392 | ALIAS_LORAWAN_TIMER tx_timeout_timer; 393 | 394 | #ifdef MBED_CONF_RTOS_PRESENT 395 | // Thread to handle interrupts 396 | rtos::Thread irq_thread; 397 | #endif 398 | 399 | // Access protection 400 | PlatformMutex mutex; 401 | 402 | uint8_t radio_variant; 403 | 404 | // helper functions 405 | void setup_registers(); 406 | void default_antenna_switch_ctrls(); 407 | void set_antenna_switch(uint8_t operation_mode); 408 | void setup_spi(); 409 | void gpio_init(); 410 | void gpio_deinit(); 411 | void setup_interrupts(); 412 | void set_operation_mode(uint8_t operation_mode); 413 | void set_low_power_mode(); 414 | void set_sx1276_variant_type(); 415 | uint8_t get_pa_conf_reg(uint32_t channel); 416 | void set_rf_tx_power(int8_t power); 417 | int16_t get_rssi(radio_modems_t modem); 418 | uint8_t get_fsk_bw_reg_val(uint32_t bandwidth); 419 | void write_to_register(uint8_t addr, uint8_t data); 420 | void write_to_register(uint8_t addr, uint8_t *data, uint8_t size); 421 | uint8_t read_register(uint8_t addr); 422 | void read_register(uint8_t addr, uint8_t *buffer, uint8_t size); 423 | void write_fifo(uint8_t *buffer, uint8_t size); 424 | void read_fifo(uint8_t *buffer, uint8_t size); 425 | void transmit(uint32_t timeout); 426 | void rf_irq_task(void); 427 | void set_modem(uint8_t modem); 428 | void rx_chain_calibration(void); 429 | 430 | // ISRs 431 | void dio0_irq_isr(); 432 | void dio1_irq_isr(); 433 | void dio2_irq_isr(); 434 | void dio3_irq_isr(); 435 | void dio4_irq_isr(); 436 | void dio5_irq_isr(); 437 | void timeout_irq_isr(); 438 | 439 | // Handlers called by thread in response to signal 440 | void handle_dio0_irq(); 441 | void handle_dio1_irq(); 442 | void handle_dio2_irq(); 443 | void handle_dio3_irq(); 444 | void handle_dio4_irq(); 445 | void handle_dio5_irq(); 446 | void handle_timeout_irq(); 447 | }; 448 | 449 | #endif // SX1276_LORARADIO_H_ 450 | -------------------------------------------------------------------------------- /SX1276/mbed_lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sx1276-lora-driver", 3 | "config": { 4 | "spi-frequency": { 5 | "help": "SPI frequency, Default: 8 MHz", 6 | "value": 8000000 7 | }, 8 | "buffer-size": { 9 | "help": "Max. buffer size the radio can handle, Default: 255 B", 10 | "value": 255 11 | }, 12 | "radio-variant": { 13 | "help": "Use to set the radio variant if the antenna switch input is not connected.", 14 | "value": "SX1276UNDEFINED" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SX1276/registers/sx1276Regs-LoRa.h: -------------------------------------------------------------------------------- 1 | /** 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C) 2014 Semtech 8 | 9 | Description: SX1276 LoRa modem registers and bits definitions 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | 15 | Copyright (c) 2017, Arm Limited and affiliates. 16 | 17 | SPDX-License-Identifier: BSD-3-Clause 18 | */ 19 | #ifndef __SX1276_REGS_LORA_H__ 20 | #define __SX1276_REGS_LORA_H__ 21 | 22 | /*! 23 | * ============================================================================ 24 | * SX1276 Internal registers Address 25 | * ============================================================================ 26 | */ 27 | #define REG_LR_FIFO 0x00 28 | // Common settings 29 | #define REG_LR_OPMODE 0x01 30 | #define REG_LR_FRFMSB 0x06 31 | #define REG_LR_FRFMID 0x07 32 | #define REG_LR_FRFLSB 0x08 33 | // Tx settings 34 | #define REG_LR_PACONFIG 0x09 35 | #define REG_LR_PARAMP 0x0A 36 | #define REG_LR_OCP 0x0B 37 | // Rx settings 38 | #define REG_LR_LNA 0x0C 39 | // LoRa registers 40 | #define REG_LR_FIFOADDRPTR 0x0D 41 | #define REG_LR_FIFOTXBASEADDR 0x0E 42 | #define REG_LR_FIFORXBASEADDR 0x0F 43 | #define REG_LR_FIFORXCURRENTADDR 0x10 44 | #define REG_LR_IRQFLAGSMASK 0x11 45 | #define REG_LR_IRQFLAGS 0x12 46 | #define REG_LR_RXNBBYTES 0x13 47 | #define REG_LR_RXHEADERCNTVALUEMSB 0x14 48 | #define REG_LR_RXHEADERCNTVALUELSB 0x15 49 | #define REG_LR_RXPACKETCNTVALUEMSB 0x16 50 | #define REG_LR_RXPACKETCNTVALUELSB 0x17 51 | #define REG_LR_MODEMSTAT 0x18 52 | #define REG_LR_PKTSNRVALUE 0x19 53 | #define REG_LR_PKTRSSIVALUE 0x1A 54 | #define REG_LR_RSSIVALUE 0x1B 55 | #define REG_LR_HOPCHANNEL 0x1C 56 | #define REG_LR_MODEMCONFIG1 0x1D 57 | #define REG_LR_MODEMCONFIG2 0x1E 58 | #define REG_LR_SYMBTIMEOUTLSB 0x1F 59 | #define REG_LR_PREAMBLEMSB 0x20 60 | #define REG_LR_PREAMBLELSB 0x21 61 | #define REG_LR_PAYLOADLENGTH 0x22 62 | #define REG_LR_PAYLOADMAXLENGTH 0x23 63 | #define REG_LR_HOPPERIOD 0x24 64 | #define REG_LR_FIFORXBYTEADDR 0x25 65 | #define REG_LR_MODEMCONFIG3 0x26 66 | #define REG_LR_FEIMSB 0x28 67 | #define REG_LR_FEIMID 0x29 68 | #define REG_LR_FEILSB 0x2A 69 | #define REG_LR_RSSIWIDEBAND 0x2C 70 | #define REG_LR_TEST2F 0x2F 71 | #define REG_LR_TEST30 0x30 72 | #define REG_LR_DETECTOPTIMIZE 0x31 73 | #define REG_LR_INVERTIQ 0x33 74 | #define REG_LR_TEST36 0x36 75 | #define REG_LR_DETECTIONTHRESHOLD 0x37 76 | #define REG_LR_SYNCWORD 0x39 77 | #define REG_LR_TEST3A 0x3A 78 | #define REG_LR_INVERTIQ2 0x3B 79 | 80 | // end of documented register in datasheet 81 | // I/O settings 82 | #define REG_LR_DIOMAPPING1 0x40 83 | #define REG_LR_DIOMAPPING2 0x41 84 | // Version 85 | #define REG_LR_VERSION 0x42 86 | // Additional settings 87 | #define REG_LR_PLLHOP 0x44 88 | #define REG_LR_TCXO 0x4B 89 | #define REG_LR_PADAC 0x4D 90 | #define REG_LR_FORMERTEMP 0x5B 91 | #define REG_LR_BITRATEFRAC 0x5D 92 | #define REG_LR_AGCREF 0x61 93 | #define REG_LR_AGCTHRESH1 0x62 94 | #define REG_LR_AGCTHRESH2 0x63 95 | #define REG_LR_AGCTHRESH3 0x64 96 | #define REG_LR_PLL 0x70 97 | 98 | /*! 99 | * ============================================================================ 100 | * SX1276 LoRa bits control definition 101 | * ============================================================================ 102 | */ 103 | 104 | /*! 105 | * RegFifo 106 | */ 107 | 108 | /*! 109 | * RegOpMode 110 | */ 111 | #define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F 112 | #define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default 113 | #define RFLR_OPMODE_LONGRANGEMODE_ON 0x80 114 | 115 | #define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF 116 | #define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40 117 | #define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default 118 | 119 | #define RFLR_OPMODE_FREQMODE_ACCESS_MASK 0xF7 120 | #define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default 121 | #define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00 122 | 123 | #define RFLR_OPMODE_MASK 0xF8 124 | #define RFLR_OPMODE_SLEEP 0x00 125 | #define RFLR_OPMODE_STANDBY 0x01 // Default 126 | #define RFLR_OPMODE_SYNTHESIZER_TX 0x02 127 | #define RFLR_OPMODE_TRANSMITTER 0x03 128 | #define RFLR_OPMODE_SYNTHESIZER_RX 0x04 129 | #define RFLR_OPMODE_RECEIVER 0x05 130 | // LoRa specific modes 131 | #define RFLR_OPMODE_RECEIVER_SINGLE 0x06 132 | #define RFLR_OPMODE_CAD 0x07 133 | 134 | /*! 135 | * RegFrf (MHz) 136 | */ 137 | #define RFLR_FRFMSB_434_MHZ 0x6C // Default 138 | #define RFLR_FRFMID_434_MHZ 0x80 // Default 139 | #define RFLR_FRFLSB_434_MHZ 0x00 // Default 140 | 141 | /*! 142 | * RegPaConfig 143 | */ 144 | #define RFLR_PACONFIG_PASELECT_MASK 0x7F 145 | #define RFLR_PACONFIG_PASELECT_PABOOST 0x80 146 | #define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default 147 | 148 | #define RFLR_PACONFIG_MAX_POWER_MASK 0x8F 149 | 150 | #define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0 151 | 152 | /*! 153 | * RegPaRamp 154 | */ 155 | #define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF 156 | #define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10 157 | #define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default 158 | 159 | #define RFLR_PARAMP_MASK 0xF0 160 | #define RFLR_PARAMP_3400_US 0x00 161 | #define RFLR_PARAMP_2000_US 0x01 162 | #define RFLR_PARAMP_1000_US 0x02 163 | #define RFLR_PARAMP_0500_US 0x03 164 | #define RFLR_PARAMP_0250_US 0x04 165 | #define RFLR_PARAMP_0125_US 0x05 166 | #define RFLR_PARAMP_0100_US 0x06 167 | #define RFLR_PARAMP_0062_US 0x07 168 | #define RFLR_PARAMP_0050_US 0x08 169 | #define RFLR_PARAMP_0040_US 0x09 // Default 170 | #define RFLR_PARAMP_0031_US 0x0A 171 | #define RFLR_PARAMP_0025_US 0x0B 172 | #define RFLR_PARAMP_0020_US 0x0C 173 | #define RFLR_PARAMP_0015_US 0x0D 174 | #define RFLR_PARAMP_0012_US 0x0E 175 | #define RFLR_PARAMP_0010_US 0x0F 176 | 177 | /*! 178 | * RegOcp 179 | */ 180 | #define RFLR_OCP_MASK 0xDF 181 | #define RFLR_OCP_ON 0x20 // Default 182 | #define RFLR_OCP_OFF 0x00 183 | 184 | #define RFLR_OCP_TRIM_MASK 0xE0 185 | #define RFLR_OCP_TRIM_045_MA 0x00 186 | #define RFLR_OCP_TRIM_050_MA 0x01 187 | #define RFLR_OCP_TRIM_055_MA 0x02 188 | #define RFLR_OCP_TRIM_060_MA 0x03 189 | #define RFLR_OCP_TRIM_065_MA 0x04 190 | #define RFLR_OCP_TRIM_070_MA 0x05 191 | #define RFLR_OCP_TRIM_075_MA 0x06 192 | #define RFLR_OCP_TRIM_080_MA 0x07 193 | #define RFLR_OCP_TRIM_085_MA 0x08 194 | #define RFLR_OCP_TRIM_090_MA 0x09 195 | #define RFLR_OCP_TRIM_095_MA 0x0A 196 | #define RFLR_OCP_TRIM_100_MA 0x0B // Default 197 | #define RFLR_OCP_TRIM_105_MA 0x0C 198 | #define RFLR_OCP_TRIM_110_MA 0x0D 199 | #define RFLR_OCP_TRIM_115_MA 0x0E 200 | #define RFLR_OCP_TRIM_120_MA 0x0F 201 | #define RFLR_OCP_TRIM_130_MA 0x10 202 | #define RFLR_OCP_TRIM_140_MA 0x11 203 | #define RFLR_OCP_TRIM_150_MA 0x12 204 | #define RFLR_OCP_TRIM_160_MA 0x13 205 | #define RFLR_OCP_TRIM_170_MA 0x14 206 | #define RFLR_OCP_TRIM_180_MA 0x15 207 | #define RFLR_OCP_TRIM_190_MA 0x16 208 | #define RFLR_OCP_TRIM_200_MA 0x17 209 | #define RFLR_OCP_TRIM_210_MA 0x18 210 | #define RFLR_OCP_TRIM_220_MA 0x19 211 | #define RFLR_OCP_TRIM_230_MA 0x1A 212 | #define RFLR_OCP_TRIM_240_MA 0x1B 213 | 214 | /*! 215 | * RegLna 216 | */ 217 | #define RFLR_LNA_GAIN_MASK 0x1F 218 | #define RFLR_LNA_GAIN_G1 0x20 // Default 219 | #define RFLR_LNA_GAIN_G2 0x40 220 | #define RFLR_LNA_GAIN_G3 0x60 221 | #define RFLR_LNA_GAIN_G4 0x80 222 | #define RFLR_LNA_GAIN_G5 0xA0 223 | #define RFLR_LNA_GAIN_G6 0xC0 224 | 225 | #define RFLR_LNA_BOOST_LF_MASK 0xE7 226 | #define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default 227 | 228 | #define RFLR_LNA_BOOST_HF_MASK 0xFC 229 | #define RFLR_LNA_BOOST_HF_OFF 0x00 // Default 230 | #define RFLR_LNA_BOOST_HF_ON 0x03 231 | 232 | /*! 233 | * RegFifoAddrPtr 234 | */ 235 | #define RFLR_FIFOADDRPTR 0x00 // Default 236 | 237 | /*! 238 | * RegFifoTxBaseAddr 239 | */ 240 | #define RFLR_FIFOTXBASEADDR 0x80 // Default 241 | 242 | /*! 243 | * RegFifoTxBaseAddr 244 | */ 245 | #define RFLR_FIFORXBASEADDR 0x00 // Default 246 | 247 | /*! 248 | * RegFifoRxCurrentAddr (Read Only) 249 | */ 250 | 251 | /*! 252 | * RegIrqFlagsMask 253 | */ 254 | #define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80 255 | #define RFLR_IRQFLAGS_RXDONE_MASK 0x40 256 | #define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20 257 | #define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10 258 | #define RFLR_IRQFLAGS_TXDONE_MASK 0x08 259 | #define RFLR_IRQFLAGS_CADDONE_MASK 0x04 260 | #define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02 261 | #define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01 262 | 263 | /*! 264 | * RegIrqFlags 265 | */ 266 | #define RFLR_IRQFLAGS_RXTIMEOUT 0x80 267 | #define RFLR_IRQFLAGS_RXDONE 0x40 268 | #define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20 269 | #define RFLR_IRQFLAGS_VALIDHEADER 0x10 270 | #define RFLR_IRQFLAGS_TXDONE 0x08 271 | #define RFLR_IRQFLAGS_CADDONE 0x04 272 | #define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02 273 | #define RFLR_IRQFLAGS_CADDETECTED 0x01 274 | 275 | /*! 276 | * RegFifoRxNbBytes (Read Only) 277 | */ 278 | 279 | /*! 280 | * RegRxHeaderCntValueMsb (Read Only) 281 | */ 282 | 283 | /*! 284 | * RegRxHeaderCntValueLsb (Read Only) 285 | */ 286 | 287 | /*! 288 | * RegRxPacketCntValueMsb (Read Only) 289 | */ 290 | 291 | /*! 292 | * RegRxPacketCntValueLsb (Read Only) 293 | */ 294 | 295 | /*! 296 | * RegModemStat (Read Only) 297 | */ 298 | #define RFLR_MODEMSTAT_RX_CR_MASK 0x1F 299 | #define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0 300 | 301 | /*! 302 | * RegPktSnrValue (Read Only) 303 | */ 304 | 305 | /*! 306 | * RegPktRssiValue (Read Only) 307 | */ 308 | 309 | /*! 310 | * RegRssiValue (Read Only) 311 | */ 312 | 313 | /*! 314 | * RegHopChannel (Read Only) 315 | */ 316 | #define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F 317 | #define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80 318 | #define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default 319 | 320 | #define RFLR_HOPCHANNEL_CRCONPAYLOAD_MASK 0xBF 321 | #define RFLR_HOPCHANNEL_CRCONPAYLOAD_ON 0x40 322 | #define RFLR_HOPCHANNEL_CRCONPAYLOAD_OFF 0x00 // Default 323 | 324 | #define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F 325 | 326 | /*! 327 | * RegModemConfig1 328 | */ 329 | #define RFLR_MODEMCONFIG1_BW_MASK 0x0F 330 | #define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00 331 | #define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10 332 | #define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20 333 | #define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30 334 | #define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40 335 | #define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50 336 | #define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60 337 | #define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default 338 | #define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80 339 | #define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90 340 | 341 | #define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1 342 | #define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02 343 | #define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default 344 | #define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06 345 | #define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08 346 | 347 | #define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE 348 | #define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01 349 | #define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default 350 | 351 | /*! 352 | * RegModemConfig2 353 | */ 354 | #define RFLR_MODEMCONFIG2_SF_MASK 0x0F 355 | #define RFLR_MODEMCONFIG2_SF_6 0x60 356 | #define RFLR_MODEMCONFIG2_SF_7 0x70 // Default 357 | #define RFLR_MODEMCONFIG2_SF_8 0x80 358 | #define RFLR_MODEMCONFIG2_SF_9 0x90 359 | #define RFLR_MODEMCONFIG2_SF_10 0xA0 360 | #define RFLR_MODEMCONFIG2_SF_11 0xB0 361 | #define RFLR_MODEMCONFIG2_SF_12 0xC0 362 | 363 | #define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7 364 | #define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08 365 | #define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00 366 | 367 | #define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK 0xFB 368 | #define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04 369 | #define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default 370 | 371 | #define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC 372 | #define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default 373 | 374 | /*! 375 | * RegSymbTimeoutLsb 376 | */ 377 | #define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default 378 | 379 | /*! 380 | * RegPreambleLengthMsb 381 | */ 382 | #define RFLR_PREAMBLELENGTHMSB 0x00 // Default 383 | 384 | /*! 385 | * RegPreambleLengthLsb 386 | */ 387 | #define RFLR_PREAMBLELENGTHLSB 0x08 // Default 388 | 389 | /*! 390 | * RegPayloadLength 391 | */ 392 | #define RFLR_PAYLOADLENGTH 0x0E // Default 393 | 394 | /*! 395 | * RegPayloadMaxLength 396 | */ 397 | #define RFLR_PAYLOADMAXLENGTH 0xFF // Default 398 | 399 | /*! 400 | * RegHopPeriod 401 | */ 402 | #define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default 403 | 404 | /*! 405 | * RegFifoRxByteAddr (Read Only) 406 | */ 407 | 408 | /*! 409 | * RegModemConfig3 410 | */ 411 | #define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK 0xF7 412 | #define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON 0x08 413 | #define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF 0x00 // Default 414 | 415 | #define RFLR_MODEMCONFIG3_AGCAUTO_MASK 0xFB 416 | #define RFLR_MODEMCONFIG3_AGCAUTO_ON 0x04 // Default 417 | #define RFLR_MODEMCONFIG3_AGCAUTO_OFF 0x00 418 | 419 | /*! 420 | * RegFeiMsb (Read Only) 421 | */ 422 | 423 | /*! 424 | * RegFeiMid (Read Only) 425 | */ 426 | 427 | /*! 428 | * RegFeiLsb (Read Only) 429 | */ 430 | 431 | /*! 432 | * RegRssiWideband (Read Only) 433 | */ 434 | 435 | /*! 436 | * RegDetectOptimize 437 | */ 438 | #define RFLR_DETECTIONOPTIMIZE_MASK 0xF8 439 | #define RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 0x03 // Default 440 | #define RFLR_DETECTIONOPTIMIZE_SF6 0x05 441 | 442 | /*! 443 | * RegInvertIQ 444 | */ 445 | #define RFLR_INVERTIQ_RX_MASK 0xBF 446 | #define RFLR_INVERTIQ_RX_OFF 0x00 447 | #define RFLR_INVERTIQ_RX_ON 0x40 448 | #define RFLR_INVERTIQ_TX_MASK 0xFE 449 | #define RFLR_INVERTIQ_TX_OFF 0x01 450 | #define RFLR_INVERTIQ_TX_ON 0x00 451 | 452 | /*! 453 | * RegDetectionThreshold 454 | */ 455 | #define RFLR_DETECTIONTHRESH_SF7_TO_SF12 0x0A // Default 456 | #define RFLR_DETECTIONTHRESH_SF6 0x0C 457 | 458 | /*! 459 | * RegInvertIQ2 460 | */ 461 | #define RFLR_INVERTIQ2_ON 0x19 462 | #define RFLR_INVERTIQ2_OFF 0x1D 463 | 464 | /*! 465 | * RegDioMapping1 466 | */ 467 | #define RFLR_DIOMAPPING1_DIO0_MASK 0x3F 468 | #define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default 469 | #define RFLR_DIOMAPPING1_DIO0_01 0x40 470 | #define RFLR_DIOMAPPING1_DIO0_10 0x80 471 | #define RFLR_DIOMAPPING1_DIO0_11 0xC0 472 | 473 | #define RFLR_DIOMAPPING1_DIO1_MASK 0xCF 474 | #define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default 475 | #define RFLR_DIOMAPPING1_DIO1_01 0x10 476 | #define RFLR_DIOMAPPING1_DIO1_10 0x20 477 | #define RFLR_DIOMAPPING1_DIO1_11 0x30 478 | 479 | #define RFLR_DIOMAPPING1_DIO2_MASK 0xF3 480 | #define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default 481 | #define RFLR_DIOMAPPING1_DIO2_01 0x04 482 | #define RFLR_DIOMAPPING1_DIO2_10 0x08 483 | #define RFLR_DIOMAPPING1_DIO2_11 0x0C 484 | 485 | #define RFLR_DIOMAPPING1_DIO3_MASK 0xFC 486 | #define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default 487 | #define RFLR_DIOMAPPING1_DIO3_01 0x01 488 | #define RFLR_DIOMAPPING1_DIO3_10 0x02 489 | #define RFLR_DIOMAPPING1_DIO3_11 0x03 490 | 491 | /*! 492 | * RegDioMapping2 493 | */ 494 | #define RFLR_DIOMAPPING2_DIO4_MASK 0x3F 495 | #define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default 496 | #define RFLR_DIOMAPPING2_DIO4_01 0x40 497 | #define RFLR_DIOMAPPING2_DIO4_10 0x80 498 | #define RFLR_DIOMAPPING2_DIO4_11 0xC0 499 | 500 | #define RFLR_DIOMAPPING2_DIO5_MASK 0xCF 501 | #define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default 502 | #define RFLR_DIOMAPPING2_DIO5_01 0x10 503 | #define RFLR_DIOMAPPING2_DIO5_10 0x20 504 | #define RFLR_DIOMAPPING2_DIO5_11 0x30 505 | 506 | #define RFLR_DIOMAPPING2_MAP_MASK 0xFE 507 | #define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 508 | #define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default 509 | 510 | /*! 511 | * RegVersion (Read Only) 512 | */ 513 | 514 | /*! 515 | * RegPllHop 516 | */ 517 | #define RFLR_PLLHOP_FASTHOP_MASK 0x7F 518 | #define RFLR_PLLHOP_FASTHOP_ON 0x80 519 | #define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default 520 | 521 | /*! 522 | * RegTcxo 523 | */ 524 | #define RFLR_TCXO_TCXOINPUT_MASK 0xEF 525 | #define RFLR_TCXO_TCXOINPUT_ON 0x10 526 | #define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default 527 | 528 | /*! 529 | * RegPaDac 530 | */ 531 | #define RFLR_PADAC_20DBM_MASK 0xF8 532 | #define RFLR_PADAC_20DBM_ON 0x07 533 | #define RFLR_PADAC_20DBM_OFF 0x04 // Default 534 | 535 | /*! 536 | * RegFormerTemp 537 | */ 538 | 539 | /*! 540 | * RegBitrateFrac 541 | */ 542 | #define RF_BITRATEFRAC_MASK 0xF0 543 | 544 | /*! 545 | * RegAgcRef 546 | */ 547 | 548 | /*! 549 | * RegAgcThresh1 550 | */ 551 | 552 | /*! 553 | * RegAgcThresh2 554 | */ 555 | 556 | /*! 557 | * RegAgcThresh3 558 | */ 559 | 560 | /*! 561 | * RegPll 562 | */ 563 | #define RF_PLL_BANDWIDTH_MASK 0x3F 564 | #define RF_PLL_BANDWIDTH_75 0x00 565 | #define RF_PLL_BANDWIDTH_150 0x40 566 | #define RF_PLL_BANDWIDTH_225 0x80 567 | #define RF_PLL_BANDWIDTH_300 0xC0 // Default 568 | 569 | #endif // __SX1276_REGS_LORA_H__ 570 | --------------------------------------------------------------------------------