Level measurement using range finder and lora technology

Dependencies:   Cayenne-LPP SDBlockDevice

Committer:
wamae
Date:
Wed Jun 26 10:35:50 2019 +0000
Revision:
0:f930f0440fd5
better copy

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wamae 0:f930f0440fd5 1 /**
wamae 0:f930f0440fd5 2 / _____) _ | |
wamae 0:f930f0440fd5 3 ( (____ _____ ____ _| |_ _____ ____| |__
wamae 0:f930f0440fd5 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
wamae 0:f930f0440fd5 5 _____) ) ____| | | || |_| ____( (___| | | |
wamae 0:f930f0440fd5 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
wamae 0:f930f0440fd5 7 (C)2013 Semtech
wamae 0:f930f0440fd5 8 ___ _____ _ ___ _ _____ ___ ___ ___ ___
wamae 0:f930f0440fd5 9 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
wamae 0:f930f0440fd5 10 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
wamae 0:f930f0440fd5 11 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
wamae 0:f930f0440fd5 12 embedded.connectivity.solutions===============
wamae 0:f930f0440fd5 13
wamae 0:f930f0440fd5 14 Description: LoRaWAN stack layer that controls both MAC and PHY underneath
wamae 0:f930f0440fd5 15
wamae 0:f930f0440fd5 16 License: Revised BSD License, see LICENSE.TXT file include in the project
wamae 0:f930f0440fd5 17
wamae 0:f930f0440fd5 18 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
wamae 0:f930f0440fd5 19
wamae 0:f930f0440fd5 20 Copyright (c) 2017, Arm Limited and affiliates.
wamae 0:f930f0440fd5 21
wamae 0:f930f0440fd5 22 SPDX-License-Identifier: BSD-3-Clause
wamae 0:f930f0440fd5 23 */
wamae 0:f930f0440fd5 24
wamae 0:f930f0440fd5 25 #include <stdio.h>
wamae 0:f930f0440fd5 26 #include <math.h> //rint
wamae 0:f930f0440fd5 27 #include <string.h>
wamae 0:f930f0440fd5 28 #include "mbed.h"
wamae 0:f930f0440fd5 29 #include "SX1276_LoRaRadio.h"
wamae 0:f930f0440fd5 30 #include "sx1276Regs-Fsk.h"
wamae 0:f930f0440fd5 31 #include "sx1276Regs-LoRa.h"
wamae 0:f930f0440fd5 32
wamae 0:f930f0440fd5 33 #ifdef DEVICE_SPI
wamae 0:f930f0440fd5 34
wamae 0:f930f0440fd5 35 /*!
wamae 0:f930f0440fd5 36 * Sync word for Private LoRa networks
wamae 0:f930f0440fd5 37 */
wamae 0:f930f0440fd5 38 #define LORA_MAC_PRIVATE_SYNCWORD 0x12
wamae 0:f930f0440fd5 39
wamae 0:f930f0440fd5 40 /*!
wamae 0:f930f0440fd5 41 * Sync word for Public LoRa networks
wamae 0:f930f0440fd5 42 */
wamae 0:f930f0440fd5 43 #define LORA_MAC_PUBLIC_SYNCWORD 0x34
wamae 0:f930f0440fd5 44
wamae 0:f930f0440fd5 45 /*!
wamae 0:f930f0440fd5 46 * SX1276 definitions
wamae 0:f930f0440fd5 47 */
wamae 0:f930f0440fd5 48 #define XTAL_FREQ 32000000
wamae 0:f930f0440fd5 49 #define FREQ_STEP 61.03515625
wamae 0:f930f0440fd5 50
wamae 0:f930f0440fd5 51 /*!
wamae 0:f930f0440fd5 52 * Constant values need to compute the RSSI value
wamae 0:f930f0440fd5 53 */
wamae 0:f930f0440fd5 54 #define RSSI_OFFSET_LF -164.0
wamae 0:f930f0440fd5 55 #define RSSI_OFFSET_HF -157.0
wamae 0:f930f0440fd5 56 #define RF_MID_BAND_THRESH 525000000
wamae 0:f930f0440fd5 57
wamae 0:f930f0440fd5 58
wamae 0:f930f0440fd5 59 /*!
wamae 0:f930f0440fd5 60 * FSK bandwidth definition
wamae 0:f930f0440fd5 61 */
wamae 0:f930f0440fd5 62 typedef struct
wamae 0:f930f0440fd5 63 {
wamae 0:f930f0440fd5 64 uint32_t bandwidth;
wamae 0:f930f0440fd5 65 uint8_t register_value;
wamae 0:f930f0440fd5 66 } fsk_bw_t;
wamae 0:f930f0440fd5 67
wamae 0:f930f0440fd5 68 /*!
wamae 0:f930f0440fd5 69 * Radio registers definition
wamae 0:f930f0440fd5 70 */
wamae 0:f930f0440fd5 71 typedef struct
wamae 0:f930f0440fd5 72 {
wamae 0:f930f0440fd5 73 uint8_t modem;
wamae 0:f930f0440fd5 74 uint8_t addr;
wamae 0:f930f0440fd5 75 uint8_t value;
wamae 0:f930f0440fd5 76 } radio_registers_t;
wamae 0:f930f0440fd5 77
wamae 0:f930f0440fd5 78 #define RADIO_INIT_REGISTERS_VALUE \
wamae 0:f930f0440fd5 79 { \
wamae 0:f930f0440fd5 80 { MODEM_FSK , REG_LNA , 0x23 },\
wamae 0:f930f0440fd5 81 { MODEM_FSK , REG_RXCONFIG , 0x1E },\
wamae 0:f930f0440fd5 82 { MODEM_FSK , REG_RSSICONFIG , 0xD2 },\
wamae 0:f930f0440fd5 83 { MODEM_FSK , REG_AFCFEI , 0x01 },\
wamae 0:f930f0440fd5 84 { MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },\
wamae 0:f930f0440fd5 85 { MODEM_FSK , REG_OSC , 0x07 },\
wamae 0:f930f0440fd5 86 { MODEM_FSK , REG_SYNCCONFIG , 0x12 },\
wamae 0:f930f0440fd5 87 { MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },\
wamae 0:f930f0440fd5 88 { MODEM_FSK , REG_SYNCVALUE2 , 0x94 },\
wamae 0:f930f0440fd5 89 { MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },\
wamae 0:f930f0440fd5 90 { MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },\
wamae 0:f930f0440fd5 91 { MODEM_FSK , REG_FIFOTHRESH , 0x8F },\
wamae 0:f930f0440fd5 92 { MODEM_FSK , REG_IMAGECAL , 0x02 },\
wamae 0:f930f0440fd5 93 { MODEM_FSK , REG_DIOMAPPING1 , 0x00 },\
wamae 0:f930f0440fd5 94 { MODEM_FSK , REG_DIOMAPPING2 , 0x30 },\
wamae 0:f930f0440fd5 95 { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\
wamae 0:f930f0440fd5 96 }
wamae 0:f930f0440fd5 97
wamae 0:f930f0440fd5 98 static const fsk_bw_t fsk_bandwidths[] =
wamae 0:f930f0440fd5 99 {
wamae 0:f930f0440fd5 100 { 2600 , 0x17 },
wamae 0:f930f0440fd5 101 { 3100 , 0x0F },
wamae 0:f930f0440fd5 102 { 3900 , 0x07 },
wamae 0:f930f0440fd5 103 { 5200 , 0x16 },
wamae 0:f930f0440fd5 104 { 6300 , 0x0E },
wamae 0:f930f0440fd5 105 { 7800 , 0x06 },
wamae 0:f930f0440fd5 106 { 10400 , 0x15 },
wamae 0:f930f0440fd5 107 { 12500 , 0x0D },
wamae 0:f930f0440fd5 108 { 15600 , 0x05 },
wamae 0:f930f0440fd5 109 { 20800 , 0x14 },
wamae 0:f930f0440fd5 110 { 25000 , 0x0C },
wamae 0:f930f0440fd5 111 { 31300 , 0x04 },
wamae 0:f930f0440fd5 112 { 41700 , 0x13 },
wamae 0:f930f0440fd5 113 { 50000 , 0x0B },
wamae 0:f930f0440fd5 114 { 62500 , 0x03 },
wamae 0:f930f0440fd5 115 { 83333 , 0x12 },
wamae 0:f930f0440fd5 116 { 100000, 0x0A },
wamae 0:f930f0440fd5 117 { 125000, 0x02 },
wamae 0:f930f0440fd5 118 { 166700, 0x11 },
wamae 0:f930f0440fd5 119 { 200000, 0x09 },
wamae 0:f930f0440fd5 120 { 250000, 0x01 },
wamae 0:f930f0440fd5 121 { 300000, 0x00 }, // Invalid bandwidth
wamae 0:f930f0440fd5 122 };
wamae 0:f930f0440fd5 123
wamae 0:f930f0440fd5 124 /**
wamae 0:f930f0440fd5 125 * SPI read/write masks
wamae 0:f930f0440fd5 126 */
wamae 0:f930f0440fd5 127 #define SPI_WRITE_CMD 0x80
wamae 0:f930f0440fd5 128 #define SPI_READ_CMD 0x7F
wamae 0:f930f0440fd5 129
wamae 0:f930f0440fd5 130 /**
wamae 0:f930f0440fd5 131 * Signals
wamae 0:f930f0440fd5 132 */
wamae 0:f930f0440fd5 133 #define SIG_DIO0 0x01
wamae 0:f930f0440fd5 134 #define SIG_DIO1 0x02
wamae 0:f930f0440fd5 135 #define SIG_DIO2 0x04
wamae 0:f930f0440fd5 136 #define SIG_DIO3 0x08
wamae 0:f930f0440fd5 137 #define SIG_DIO4 0x10
wamae 0:f930f0440fd5 138 #define SIG_DIO5 0x20
wamae 0:f930f0440fd5 139 #define SIG_TIMOUT 0x40
wamae 0:f930f0440fd5 140
wamae 0:f930f0440fd5 141 /**
wamae 0:f930f0440fd5 142 * Radio hardware registers initialization
wamae 0:f930f0440fd5 143 */
wamae 0:f930f0440fd5 144 static const radio_registers_t radio_reg_init[] = RADIO_INIT_REGISTERS_VALUE;
wamae 0:f930f0440fd5 145
wamae 0:f930f0440fd5 146 enum RadioVariant {
wamae 0:f930f0440fd5 147 SX1276UNDEFINED = 0,
wamae 0:f930f0440fd5 148 SX1276MB1LAS,
wamae 0:f930f0440fd5 149 SX1276MB1MAS
wamae 0:f930f0440fd5 150 };
wamae 0:f930f0440fd5 151
wamae 0:f930f0440fd5 152 #ifdef MBED_SX1276_LORA_RADIO_SPI_FREQUENCY
wamae 0:f930f0440fd5 153 #define SPI_FREQUENCY MBED_SX1276_LORA_RADIO_SPI_FREQUENCY
wamae 0:f930f0440fd5 154 #else
wamae 0:f930f0440fd5 155 #define SPI_FREQUENCY 8000000
wamae 0:f930f0440fd5 156 #endif
wamae 0:f930f0440fd5 157
wamae 0:f930f0440fd5 158 /**
wamae 0:f930f0440fd5 159 * Constructor
wamae 0:f930f0440fd5 160 */
wamae 0:f930f0440fd5 161 SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi,
wamae 0:f930f0440fd5 162 PinName spi_miso,
wamae 0:f930f0440fd5 163 PinName spi_sclk,
wamae 0:f930f0440fd5 164 PinName nss,
wamae 0:f930f0440fd5 165 PinName reset,
wamae 0:f930f0440fd5 166 PinName dio0,
wamae 0:f930f0440fd5 167 PinName dio1,
wamae 0:f930f0440fd5 168 PinName dio2,
wamae 0:f930f0440fd5 169 PinName dio3,
wamae 0:f930f0440fd5 170 PinName dio4,
wamae 0:f930f0440fd5 171 PinName dio5,
wamae 0:f930f0440fd5 172 PinName rf_switch_ctl1,
wamae 0:f930f0440fd5 173 PinName rf_switch_ctl2,
wamae 0:f930f0440fd5 174 PinName txctl,
wamae 0:f930f0440fd5 175 PinName rxctl,
wamae 0:f930f0440fd5 176 PinName antswitch,
wamae 0:f930f0440fd5 177 PinName pwr_amp_ctl,
wamae 0:f930f0440fd5 178 PinName tcxo)
wamae 0:f930f0440fd5 179 : _spi(spi_mosi, spi_miso, spi_sclk),
wamae 0:f930f0440fd5 180 _chip_select(nss, 1),
wamae 0:f930f0440fd5 181 _reset_ctl(reset),
wamae 0:f930f0440fd5 182 _dio0_ctl(dio0), _dio1_ctl(dio1), _dio2_ctl(dio2), _dio3_ctl(dio3), _dio4_ctl(dio4), _dio5_ctl(dio5),
wamae 0:f930f0440fd5 183 _rf_switch_ctl1(rf_switch_ctl1, 0), _rf_switch_ctl2(rf_switch_ctl2, 0),
wamae 0:f930f0440fd5 184 _txctl(txctl, 0), _rxctl(rxctl, 0),
wamae 0:f930f0440fd5 185 _ant_switch(antswitch, PIN_INPUT, PullUp, 0),
wamae 0:f930f0440fd5 186 _pwr_amp_ctl(pwr_amp_ctl),
wamae 0:f930f0440fd5 187 _tcxo(tcxo)
wamae 0:f930f0440fd5 188
wamae 0:f930f0440fd5 189 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 190 , irq_thread(osPriorityRealtime, 1024)
wamae 0:f930f0440fd5 191 #endif
wamae 0:f930f0440fd5 192 {
wamae 0:f930f0440fd5 193 _rf_ctrls.ant_switch = antswitch;
wamae 0:f930f0440fd5 194 _rf_ctrls.pwr_amp_ctl = pwr_amp_ctl;
wamae 0:f930f0440fd5 195 _rf_ctrls.rf_switch_ctl1 = rf_switch_ctl1;
wamae 0:f930f0440fd5 196 _rf_ctrls.rf_switch_ctl2 = rf_switch_ctl2;
wamae 0:f930f0440fd5 197 _rf_ctrls.rxctl = rxctl;
wamae 0:f930f0440fd5 198 _rf_ctrls.txctl = txctl;
wamae 0:f930f0440fd5 199 _rf_ctrls.tcxo = tcxo;
wamae 0:f930f0440fd5 200
wamae 0:f930f0440fd5 201 _dio4_pin = dio4;
wamae 0:f930f0440fd5 202 _dio5_pin = dio5;
wamae 0:f930f0440fd5 203
wamae 0:f930f0440fd5 204 _radio_events = NULL;
wamae 0:f930f0440fd5 205
wamae 0:f930f0440fd5 206 if (tcxo != NC) {
wamae 0:f930f0440fd5 207 _tcxo = 1;
wamae 0:f930f0440fd5 208 }
wamae 0:f930f0440fd5 209
wamae 0:f930f0440fd5 210 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 211 irq_thread.start(mbed::callback(this, &SX1276_LoRaRadio::rf_irq_task));
wamae 0:f930f0440fd5 212 #endif
wamae 0:f930f0440fd5 213 }
wamae 0:f930f0440fd5 214
wamae 0:f930f0440fd5 215 /**
wamae 0:f930f0440fd5 216 * Destructor
wamae 0:f930f0440fd5 217 */
wamae 0:f930f0440fd5 218 SX1276_LoRaRadio::~SX1276_LoRaRadio()
wamae 0:f930f0440fd5 219 {
wamae 0:f930f0440fd5 220
wamae 0:f930f0440fd5 221 }
wamae 0:f930f0440fd5 222
wamae 0:f930f0440fd5 223 /*****************************************************************************
wamae 0:f930f0440fd5 224 * Public APIs *
wamae 0:f930f0440fd5 225 ****************************************************************************/
wamae 0:f930f0440fd5 226 /**
wamae 0:f930f0440fd5 227 * Acquire lock
wamae 0:f930f0440fd5 228 */
wamae 0:f930f0440fd5 229 void SX1276_LoRaRadio::lock(void)
wamae 0:f930f0440fd5 230 {
wamae 0:f930f0440fd5 231 mutex.lock();
wamae 0:f930f0440fd5 232 }
wamae 0:f930f0440fd5 233
wamae 0:f930f0440fd5 234 /**
wamae 0:f930f0440fd5 235 * Release lock
wamae 0:f930f0440fd5 236 */
wamae 0:f930f0440fd5 237 void SX1276_LoRaRadio::unlock(void)
wamae 0:f930f0440fd5 238 {
wamae 0:f930f0440fd5 239 mutex.unlock();
wamae 0:f930f0440fd5 240 }
wamae 0:f930f0440fd5 241
wamae 0:f930f0440fd5 242 /**
wamae 0:f930f0440fd5 243 * Initializes radio module
wamae 0:f930f0440fd5 244 */
wamae 0:f930f0440fd5 245 void SX1276_LoRaRadio::init_radio(radio_events_t *events)
wamae 0:f930f0440fd5 246 {
wamae 0:f930f0440fd5 247 _radio_events = events;
wamae 0:f930f0440fd5 248
wamae 0:f930f0440fd5 249 // Reset the radio transceiver
wamae 0:f930f0440fd5 250 radio_reset();
wamae 0:f930f0440fd5 251
wamae 0:f930f0440fd5 252 // Setup radio variant type
wamae 0:f930f0440fd5 253 set_sx1276_variant_type();
wamae 0:f930f0440fd5 254
wamae 0:f930f0440fd5 255 // setup SPI frequency
wamae 0:f930f0440fd5 256 // default is 8MHz although, configurable through
wamae 0:f930f0440fd5 257 // SPI_FREQUENCY macro
wamae 0:f930f0440fd5 258 setup_spi();
wamae 0:f930f0440fd5 259
wamae 0:f930f0440fd5 260 // Calibrate radio receiver chain
wamae 0:f930f0440fd5 261 rx_chain_calibration();
wamae 0:f930f0440fd5 262
wamae 0:f930f0440fd5 263 // set radio mode to sleep
wamae 0:f930f0440fd5 264 set_operation_mode(RF_OPMODE_SLEEP);
wamae 0:f930f0440fd5 265
wamae 0:f930f0440fd5 266 // Setup radio registers to defaults
wamae 0:f930f0440fd5 267 setup_registers();
wamae 0:f930f0440fd5 268
wamae 0:f930f0440fd5 269 // set modem type - defaults to FSK here
wamae 0:f930f0440fd5 270 set_modem(MODEM_FSK);
wamae 0:f930f0440fd5 271
wamae 0:f930f0440fd5 272 // set state to be idle
wamae 0:f930f0440fd5 273 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 274
wamae 0:f930f0440fd5 275 // Setup interrupts on DIO pins
wamae 0:f930f0440fd5 276 setup_interrupts();
wamae 0:f930f0440fd5 277 }
wamae 0:f930f0440fd5 278
wamae 0:f930f0440fd5 279 /**
wamae 0:f930f0440fd5 280 * Can be used by application/stack or the driver itself
wamae 0:f930f0440fd5 281 */
wamae 0:f930f0440fd5 282 void SX1276_LoRaRadio::radio_reset()
wamae 0:f930f0440fd5 283 {
wamae 0:f930f0440fd5 284 _reset_ctl.output();
wamae 0:f930f0440fd5 285 _reset_ctl = 0;
wamae 0:f930f0440fd5 286 wait_ms(2);
wamae 0:f930f0440fd5 287 _reset_ctl.input();
wamae 0:f930f0440fd5 288 wait_ms(6);
wamae 0:f930f0440fd5 289 }
wamae 0:f930f0440fd5 290
wamae 0:f930f0440fd5 291 /**
wamae 0:f930f0440fd5 292 * TODO: The purpose of this API is unclear.
wamae 0:f930f0440fd5 293 * Need to start an internal discussion.
wamae 0:f930f0440fd5 294 */
wamae 0:f930f0440fd5 295 bool SX1276_LoRaRadio::check_rf_frequency(uint32_t frequency)
wamae 0:f930f0440fd5 296 {
wamae 0:f930f0440fd5 297 // Implement check. Currently all frequencies are supported ? What band ?
wamae 0:f930f0440fd5 298 return true;
wamae 0:f930f0440fd5 299 }
wamae 0:f930f0440fd5 300
wamae 0:f930f0440fd5 301 /**
wamae 0:f930f0440fd5 302 * Returns current status of the radio state machine
wamae 0:f930f0440fd5 303 */
wamae 0:f930f0440fd5 304 uint8_t SX1276_LoRaRadio::get_status(void)
wamae 0:f930f0440fd5 305 {
wamae 0:f930f0440fd5 306 return _rf_settings.state;
wamae 0:f930f0440fd5 307 }
wamae 0:f930f0440fd5 308
wamae 0:f930f0440fd5 309 /**
wamae 0:f930f0440fd5 310 * Sets up carrier frequency
wamae 0:f930f0440fd5 311 */
wamae 0:f930f0440fd5 312 void SX1276_LoRaRadio::set_channel(uint32_t freq)
wamae 0:f930f0440fd5 313 {
wamae 0:f930f0440fd5 314 _rf_settings.channel = freq;
wamae 0:f930f0440fd5 315 freq = (uint32_t) ((double) freq / (double) FREQ_STEP);
wamae 0:f930f0440fd5 316 write_to_register(REG_FRFMSB, (uint8_t) ((freq >> 16) & 0xFF));
wamae 0:f930f0440fd5 317 write_to_register(REG_FRFMID, (uint8_t) ((freq >> 8) & 0xFF));
wamae 0:f930f0440fd5 318 write_to_register(REG_FRFLSB, (uint8_t) (freq & 0xFF));
wamae 0:f930f0440fd5 319 }
wamae 0:f930f0440fd5 320
wamae 0:f930f0440fd5 321 /**
wamae 0:f930f0440fd5 322 * Generates 32 bit random number based upon RSSI monitoring
wamae 0:f930f0440fd5 323 * Used for various calculation by the stack for example dev nonce
wamae 0:f930f0440fd5 324 *
wamae 0:f930f0440fd5 325 * When this API is used modem is set in LoRa mode and all interrupts are
wamae 0:f930f0440fd5 326 * masked. If the user had been using FSK mode, it should be noted that a
wamae 0:f930f0440fd5 327 * change of mode is required again because the registers have changed.
wamae 0:f930f0440fd5 328 * In addition to that RX and TX configuration APIs should be called again in
wamae 0:f930f0440fd5 329 * order to have correct desires setup.
wamae 0:f930f0440fd5 330 */
wamae 0:f930f0440fd5 331 uint32_t SX1276_LoRaRadio::random( void )
wamae 0:f930f0440fd5 332 {
wamae 0:f930f0440fd5 333 uint8_t i;
wamae 0:f930f0440fd5 334 uint32_t rnd = 0;
wamae 0:f930f0440fd5 335
wamae 0:f930f0440fd5 336 /*
wamae 0:f930f0440fd5 337 * Radio setup for random number generation
wamae 0:f930f0440fd5 338 */
wamae 0:f930f0440fd5 339 set_modem( MODEM_LORA );
wamae 0:f930f0440fd5 340
wamae 0:f930f0440fd5 341 // Disable LoRa modem interrupts
wamae 0:f930f0440fd5 342 write_to_register( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
wamae 0:f930f0440fd5 343 RFLR_IRQFLAGS_RXDONE |
wamae 0:f930f0440fd5 344 RFLR_IRQFLAGS_PAYLOADCRCERROR |
wamae 0:f930f0440fd5 345 RFLR_IRQFLAGS_VALIDHEADER |
wamae 0:f930f0440fd5 346 RFLR_IRQFLAGS_TXDONE |
wamae 0:f930f0440fd5 347 RFLR_IRQFLAGS_CADDONE |
wamae 0:f930f0440fd5 348 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
wamae 0:f930f0440fd5 349 RFLR_IRQFLAGS_CADDETECTED );
wamae 0:f930f0440fd5 350
wamae 0:f930f0440fd5 351 // Set radio in continuous reception
wamae 0:f930f0440fd5 352 set_operation_mode(RF_OPMODE_RECEIVER);
wamae 0:f930f0440fd5 353
wamae 0:f930f0440fd5 354 for (i = 0; i < 32; i++) {
wamae 0:f930f0440fd5 355 wait_ms(1);
wamae 0:f930f0440fd5 356 // Unfiltered RSSI value reading. Only takes the LSB value
wamae 0:f930f0440fd5 357 rnd |= ((uint32_t) read_register( REG_LR_RSSIWIDEBAND) & 0x01) << i;
wamae 0:f930f0440fd5 358 }
wamae 0:f930f0440fd5 359
wamae 0:f930f0440fd5 360 sleep();
wamae 0:f930f0440fd5 361
wamae 0:f930f0440fd5 362 return rnd;
wamae 0:f930f0440fd5 363 }
wamae 0:f930f0440fd5 364
wamae 0:f930f0440fd5 365 /**
wamae 0:f930f0440fd5 366 * Sets up receiver related configurations
wamae 0:f930f0440fd5 367 *
wamae 0:f930f0440fd5 368 * Must be called before setting the radio in rx mode
wamae 0:f930f0440fd5 369 */
wamae 0:f930f0440fd5 370 void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth,
wamae 0:f930f0440fd5 371 uint32_t datarate, uint8_t coderate,
wamae 0:f930f0440fd5 372 uint32_t bandwidth_afc,
wamae 0:f930f0440fd5 373 uint16_t preamble_len,
wamae 0:f930f0440fd5 374 uint16_t symb_timeout, bool fix_len,
wamae 0:f930f0440fd5 375 uint8_t payload_len, bool crc_on,
wamae 0:f930f0440fd5 376 bool freq_hop_on, uint8_t hop_period,
wamae 0:f930f0440fd5 377 bool iq_inverted, bool rx_continuous)
wamae 0:f930f0440fd5 378 {
wamae 0:f930f0440fd5 379 set_modem(modem);
wamae 0:f930f0440fd5 380
wamae 0:f930f0440fd5 381 switch (modem) {
wamae 0:f930f0440fd5 382 case MODEM_FSK:
wamae 0:f930f0440fd5 383 _rf_settings.fsk.bandwidth = bandwidth;
wamae 0:f930f0440fd5 384 _rf_settings.fsk.datarate = datarate;
wamae 0:f930f0440fd5 385 _rf_settings.fsk.bandwidth_afc = bandwidth_afc;
wamae 0:f930f0440fd5 386 _rf_settings.fsk.fix_len = fix_len;
wamae 0:f930f0440fd5 387 _rf_settings.fsk.payload_len = payload_len;
wamae 0:f930f0440fd5 388 _rf_settings.fsk.crc_on = crc_on;
wamae 0:f930f0440fd5 389 _rf_settings.fsk.iq_inverted = iq_inverted;
wamae 0:f930f0440fd5 390 _rf_settings.fsk.rx_continuous = rx_continuous;
wamae 0:f930f0440fd5 391 _rf_settings.fsk.preamble_len = preamble_len;
wamae 0:f930f0440fd5 392 _rf_settings.fsk.rx_single_timeout = symb_timeout
wamae 0:f930f0440fd5 393 * ((1.0 / (double) datarate) * 8.0) * 1e3;
wamae 0:f930f0440fd5 394
wamae 0:f930f0440fd5 395 datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate);
wamae 0:f930f0440fd5 396 write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8));
wamae 0:f930f0440fd5 397 write_to_register(REG_BITRATELSB, (uint8_t) (datarate & 0xFF));
wamae 0:f930f0440fd5 398
wamae 0:f930f0440fd5 399 write_to_register(REG_RXBW, get_fsk_bw_reg_val(bandwidth));
wamae 0:f930f0440fd5 400 write_to_register(REG_AFCBW, get_fsk_bw_reg_val(bandwidth_afc));
wamae 0:f930f0440fd5 401
wamae 0:f930f0440fd5 402 write_to_register(REG_PREAMBLEMSB,
wamae 0:f930f0440fd5 403 (uint8_t) ((preamble_len >> 8) & 0xFF));
wamae 0:f930f0440fd5 404 write_to_register(REG_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF));
wamae 0:f930f0440fd5 405
wamae 0:f930f0440fd5 406 if (fix_len == 1) {
wamae 0:f930f0440fd5 407 write_to_register(REG_PAYLOADLENGTH, payload_len);
wamae 0:f930f0440fd5 408 } else {
wamae 0:f930f0440fd5 409 write_to_register(REG_PAYLOADLENGTH, 0xFF); // Set payload length to the maximum
wamae 0:f930f0440fd5 410 }
wamae 0:f930f0440fd5 411
wamae 0:f930f0440fd5 412 write_to_register(
wamae 0:f930f0440fd5 413 REG_PACKETCONFIG1,
wamae 0:f930f0440fd5 414 (read_register(REG_PACKETCONFIG1)
wamae 0:f930f0440fd5 415 & RF_PACKETCONFIG1_CRC_MASK
wamae 0:f930f0440fd5 416 & RF_PACKETCONFIG1_PACKETFORMAT_MASK)
wamae 0:f930f0440fd5 417 | ((fix_len == 1) ?
wamae 0:f930f0440fd5 418 RF_PACKETCONFIG1_PACKETFORMAT_FIXED :
wamae 0:f930f0440fd5 419 RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE)
wamae 0:f930f0440fd5 420 | (crc_on << 4));
wamae 0:f930f0440fd5 421
wamae 0:f930f0440fd5 422 // TODO why packet mode 2 ?
wamae 0:f930f0440fd5 423 write_to_register(REG_PACKETCONFIG2, (read_register(REG_PACKETCONFIG2)
wamae 0:f930f0440fd5 424 | RF_PACKETCONFIG2_DATAMODE_PACKET));
wamae 0:f930f0440fd5 425
wamae 0:f930f0440fd5 426 break;
wamae 0:f930f0440fd5 427
wamae 0:f930f0440fd5 428 case MODEM_LORA:
wamae 0:f930f0440fd5 429
wamae 0:f930f0440fd5 430 if (bandwidth > 2) {
wamae 0:f930f0440fd5 431 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
wamae 0:f930f0440fd5 432 while (1)
wamae 0:f930f0440fd5 433 ;
wamae 0:f930f0440fd5 434 // TODO Return a proper error from here
wamae 0:f930f0440fd5 435 }
wamae 0:f930f0440fd5 436
wamae 0:f930f0440fd5 437 // stupid hack. TODO think something better
wamae 0:f930f0440fd5 438 bandwidth+=7;
wamae 0:f930f0440fd5 439
wamae 0:f930f0440fd5 440 _rf_settings.lora.bandwidth = bandwidth;
wamae 0:f930f0440fd5 441 _rf_settings.lora.datarate = datarate;
wamae 0:f930f0440fd5 442 _rf_settings.lora.coderate = coderate;
wamae 0:f930f0440fd5 443 _rf_settings.lora.preamble_len = preamble_len;
wamae 0:f930f0440fd5 444 _rf_settings.lora.fix_len = fix_len;
wamae 0:f930f0440fd5 445 _rf_settings.lora.payload_len = payload_len;
wamae 0:f930f0440fd5 446 _rf_settings.lora.crc_on = crc_on;
wamae 0:f930f0440fd5 447 _rf_settings.lora.freq_hop_on = freq_hop_on;
wamae 0:f930f0440fd5 448 _rf_settings.lora.hop_period = hop_period;
wamae 0:f930f0440fd5 449 _rf_settings.lora.iq_inverted = iq_inverted;
wamae 0:f930f0440fd5 450 _rf_settings.lora.rx_continuous = rx_continuous;
wamae 0:f930f0440fd5 451
wamae 0:f930f0440fd5 452 if (datarate > 12) {
wamae 0:f930f0440fd5 453 datarate = 12;
wamae 0:f930f0440fd5 454 } else if (datarate < 6) {
wamae 0:f930f0440fd5 455 datarate = 6;
wamae 0:f930f0440fd5 456 }
wamae 0:f930f0440fd5 457
wamae 0:f930f0440fd5 458 if (((bandwidth == 7) && ((datarate == 11) || (datarate == 12)))
wamae 0:f930f0440fd5 459 || ((bandwidth == 8) && (datarate == 12))) {
wamae 0:f930f0440fd5 460 _rf_settings.lora.low_datarate_optimize = 0x01;
wamae 0:f930f0440fd5 461 } else {
wamae 0:f930f0440fd5 462 _rf_settings.lora.low_datarate_optimize = 0x00;
wamae 0:f930f0440fd5 463 }
wamae 0:f930f0440fd5 464
wamae 0:f930f0440fd5 465 write_to_register(REG_LR_MODEMCONFIG1, (read_register( REG_LR_MODEMCONFIG1)
wamae 0:f930f0440fd5 466 & RFLR_MODEMCONFIG1_BW_MASK
wamae 0:f930f0440fd5 467 & RFLR_MODEMCONFIG1_CODINGRATE_MASK
wamae 0:f930f0440fd5 468 & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK)
wamae 0:f930f0440fd5 469 | (bandwidth << 4)
wamae 0:f930f0440fd5 470 | (coderate << 1) | fix_len);
wamae 0:f930f0440fd5 471
wamae 0:f930f0440fd5 472 write_to_register(REG_LR_MODEMCONFIG2, (read_register( REG_LR_MODEMCONFIG2)
wamae 0:f930f0440fd5 473 & RFLR_MODEMCONFIG2_SF_MASK
wamae 0:f930f0440fd5 474 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK
wamae 0:f930f0440fd5 475 & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK)
wamae 0:f930f0440fd5 476 | (datarate << 4)
wamae 0:f930f0440fd5 477 | (crc_on << 2)
wamae 0:f930f0440fd5 478 | ((symb_timeout >> 8)
wamae 0:f930f0440fd5 479 & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK));
wamae 0:f930f0440fd5 480
wamae 0:f930f0440fd5 481 write_to_register(REG_LR_MODEMCONFIG3, (read_register( REG_LR_MODEMCONFIG3)
wamae 0:f930f0440fd5 482 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK)
wamae 0:f930f0440fd5 483 | (_rf_settings.lora.low_datarate_optimize << 3));
wamae 0:f930f0440fd5 484
wamae 0:f930f0440fd5 485 write_to_register(REG_LR_SYMBTIMEOUTLSB, (uint8_t) (symb_timeout & 0xFF));
wamae 0:f930f0440fd5 486
wamae 0:f930f0440fd5 487 write_to_register(REG_LR_PREAMBLEMSB, (uint8_t) ((preamble_len >> 8) & 0xFF));
wamae 0:f930f0440fd5 488 write_to_register(REG_LR_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF));
wamae 0:f930f0440fd5 489
wamae 0:f930f0440fd5 490 if (fix_len == 1) {
wamae 0:f930f0440fd5 491 write_to_register(REG_LR_PAYLOADLENGTH, payload_len);
wamae 0:f930f0440fd5 492 }
wamae 0:f930f0440fd5 493
wamae 0:f930f0440fd5 494 if (_rf_settings.lora.freq_hop_on == true) {
wamae 0:f930f0440fd5 495 write_to_register(REG_LR_PLLHOP, (read_register( REG_LR_PLLHOP)
wamae 0:f930f0440fd5 496 & RFLR_PLLHOP_FASTHOP_MASK)
wamae 0:f930f0440fd5 497 | RFLR_PLLHOP_FASTHOP_ON);
wamae 0:f930f0440fd5 498 write_to_register(REG_LR_HOPPERIOD,_rf_settings.lora.hop_period);
wamae 0:f930f0440fd5 499 }
wamae 0:f930f0440fd5 500
wamae 0:f930f0440fd5 501 if ((bandwidth == 9) && (_rf_settings.channel > RF_MID_BAND_THRESH)) {
wamae 0:f930f0440fd5 502 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
wamae 0:f930f0440fd5 503 write_to_register(REG_LR_TEST36, 0x02);
wamae 0:f930f0440fd5 504 write_to_register(REG_LR_TEST3A, 0x64);
wamae 0:f930f0440fd5 505 } else if (bandwidth == 9) {
wamae 0:f930f0440fd5 506 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
wamae 0:f930f0440fd5 507 write_to_register(REG_LR_TEST36, 0x02);
wamae 0:f930f0440fd5 508 write_to_register(REG_LR_TEST3A, 0x7F);
wamae 0:f930f0440fd5 509 } else {
wamae 0:f930f0440fd5 510 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
wamae 0:f930f0440fd5 511 write_to_register(REG_LR_TEST36, 0x03);
wamae 0:f930f0440fd5 512 }
wamae 0:f930f0440fd5 513
wamae 0:f930f0440fd5 514 if (datarate == 6) {
wamae 0:f930f0440fd5 515 write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE)
wamae 0:f930f0440fd5 516 & RFLR_DETECTIONOPTIMIZE_MASK)
wamae 0:f930f0440fd5 517 | RFLR_DETECTIONOPTIMIZE_SF6);
wamae 0:f930f0440fd5 518 write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF6);
wamae 0:f930f0440fd5 519 } else {
wamae 0:f930f0440fd5 520 write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE)
wamae 0:f930f0440fd5 521 & RFLR_DETECTIONOPTIMIZE_MASK)
wamae 0:f930f0440fd5 522 | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12);
wamae 0:f930f0440fd5 523 write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12);
wamae 0:f930f0440fd5 524 }
wamae 0:f930f0440fd5 525 break;
wamae 0:f930f0440fd5 526
wamae 0:f930f0440fd5 527 default:
wamae 0:f930f0440fd5 528 break;
wamae 0:f930f0440fd5 529 }
wamae 0:f930f0440fd5 530 }
wamae 0:f930f0440fd5 531
wamae 0:f930f0440fd5 532 /**
wamae 0:f930f0440fd5 533 * Sets up transmitter related configuration
wamae 0:f930f0440fd5 534 *
wamae 0:f930f0440fd5 535 * Must be called before putting the radio module in Tx mode or trying
wamae 0:f930f0440fd5 536 * to send
wamae 0:f930f0440fd5 537 */
wamae 0:f930f0440fd5 538 void SX1276_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power,
wamae 0:f930f0440fd5 539 uint32_t fdev, uint32_t bandwidth,
wamae 0:f930f0440fd5 540 uint32_t datarate, uint8_t coderate,
wamae 0:f930f0440fd5 541 uint16_t preamble_len, bool fix_len,
wamae 0:f930f0440fd5 542 bool crc_on, bool freq_hop_on,
wamae 0:f930f0440fd5 543 uint8_t hop_period, bool iq_inverted,
wamae 0:f930f0440fd5 544 uint32_t timeout)
wamae 0:f930f0440fd5 545 {
wamae 0:f930f0440fd5 546 set_modem(modem);
wamae 0:f930f0440fd5 547 set_rf_tx_power(power);
wamae 0:f930f0440fd5 548
wamae 0:f930f0440fd5 549 switch (modem) {
wamae 0:f930f0440fd5 550 case MODEM_FSK:
wamae 0:f930f0440fd5 551 _rf_settings.fsk.power = power;
wamae 0:f930f0440fd5 552 _rf_settings.fsk.f_dev = fdev;
wamae 0:f930f0440fd5 553 _rf_settings.fsk.bandwidth = bandwidth;
wamae 0:f930f0440fd5 554 _rf_settings.fsk.datarate = datarate;
wamae 0:f930f0440fd5 555 _rf_settings.fsk.preamble_len = preamble_len;
wamae 0:f930f0440fd5 556 _rf_settings.fsk.fix_len = fix_len;
wamae 0:f930f0440fd5 557 _rf_settings.fsk.crc_on = crc_on;
wamae 0:f930f0440fd5 558 _rf_settings.fsk.iq_inverted = iq_inverted;
wamae 0:f930f0440fd5 559 _rf_settings.fsk.tx_timeout = timeout;
wamae 0:f930f0440fd5 560
wamae 0:f930f0440fd5 561 fdev = (uint16_t) ((double) fdev / (double) FREQ_STEP);
wamae 0:f930f0440fd5 562 write_to_register( REG_FDEVMSB, (uint8_t) (fdev >> 8));
wamae 0:f930f0440fd5 563 write_to_register( REG_FDEVLSB, (uint8_t) (fdev & 0xFF));
wamae 0:f930f0440fd5 564
wamae 0:f930f0440fd5 565 datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate);
wamae 0:f930f0440fd5 566 write_to_register( REG_BITRATEMSB, (uint8_t) (datarate >> 8));
wamae 0:f930f0440fd5 567 write_to_register( REG_BITRATELSB, (uint8_t) (datarate & 0xFF));
wamae 0:f930f0440fd5 568
wamae 0:f930f0440fd5 569 write_to_register( REG_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF);
wamae 0:f930f0440fd5 570 write_to_register( REG_PREAMBLELSB, preamble_len & 0xFF);
wamae 0:f930f0440fd5 571
wamae 0:f930f0440fd5 572 write_to_register(REG_PACKETCONFIG1,
wamae 0:f930f0440fd5 573 (read_register( REG_PACKETCONFIG1) &
wamae 0:f930f0440fd5 574 RF_PACKETCONFIG1_CRC_MASK &
wamae 0:f930f0440fd5 575 RF_PACKETCONFIG1_PACKETFORMAT_MASK)
wamae 0:f930f0440fd5 576 | ((fix_len == 1) ?
wamae 0:f930f0440fd5 577 RF_PACKETCONFIG1_PACKETFORMAT_FIXED :
wamae 0:f930f0440fd5 578 RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE)
wamae 0:f930f0440fd5 579 | (crc_on << 4));
wamae 0:f930f0440fd5 580 write_to_register(REG_PACKETCONFIG2,
wamae 0:f930f0440fd5 581 (read_register( REG_PACKETCONFIG2)
wamae 0:f930f0440fd5 582 | RF_PACKETCONFIG2_DATAMODE_PACKET));
wamae 0:f930f0440fd5 583
wamae 0:f930f0440fd5 584 break;
wamae 0:f930f0440fd5 585
wamae 0:f930f0440fd5 586 case MODEM_LORA:
wamae 0:f930f0440fd5 587 _rf_settings.lora.power = power;
wamae 0:f930f0440fd5 588 if (bandwidth > 2) {
wamae 0:f930f0440fd5 589 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
wamae 0:f930f0440fd5 590 while (1)
wamae 0:f930f0440fd5 591 ;
wamae 0:f930f0440fd5 592 }
wamae 0:f930f0440fd5 593 bandwidth += 7;
wamae 0:f930f0440fd5 594 _rf_settings.lora.bandwidth = bandwidth;
wamae 0:f930f0440fd5 595 _rf_settings.lora.datarate = datarate;
wamae 0:f930f0440fd5 596 _rf_settings.lora.coderate = coderate;
wamae 0:f930f0440fd5 597 _rf_settings.lora.preamble_len = preamble_len;
wamae 0:f930f0440fd5 598 _rf_settings.lora.fix_len = fix_len;
wamae 0:f930f0440fd5 599 _rf_settings.lora.freq_hop_on = freq_hop_on;
wamae 0:f930f0440fd5 600 _rf_settings.lora.hop_period = hop_period;
wamae 0:f930f0440fd5 601 _rf_settings.lora.crc_on = crc_on;
wamae 0:f930f0440fd5 602 _rf_settings.lora.iq_inverted = iq_inverted;
wamae 0:f930f0440fd5 603 _rf_settings.lora.tx_timeout = timeout;
wamae 0:f930f0440fd5 604
wamae 0:f930f0440fd5 605 if (datarate > 12) {
wamae 0:f930f0440fd5 606 datarate = 12;
wamae 0:f930f0440fd5 607 } else if (datarate < 6) {
wamae 0:f930f0440fd5 608 datarate = 6;
wamae 0:f930f0440fd5 609 }
wamae 0:f930f0440fd5 610 if (((bandwidth == 7) && ((datarate == 11) || (datarate == 12)))
wamae 0:f930f0440fd5 611 || ((bandwidth == 8) && (datarate == 12))) {
wamae 0:f930f0440fd5 612 _rf_settings.lora.low_datarate_optimize = 0x01;
wamae 0:f930f0440fd5 613 } else {
wamae 0:f930f0440fd5 614 _rf_settings.lora.low_datarate_optimize = 0x00;
wamae 0:f930f0440fd5 615 }
wamae 0:f930f0440fd5 616
wamae 0:f930f0440fd5 617 if (_rf_settings.lora.freq_hop_on == true) {
wamae 0:f930f0440fd5 618 write_to_register(REG_LR_PLLHOP, (read_register(REG_LR_PLLHOP)
wamae 0:f930f0440fd5 619 & RFLR_PLLHOP_FASTHOP_MASK)
wamae 0:f930f0440fd5 620 | RFLR_PLLHOP_FASTHOP_ON);
wamae 0:f930f0440fd5 621 write_to_register( REG_LR_HOPPERIOD, _rf_settings.lora.hop_period);
wamae 0:f930f0440fd5 622 }
wamae 0:f930f0440fd5 623
wamae 0:f930f0440fd5 624 write_to_register(REG_LR_MODEMCONFIG1, (read_register( REG_LR_MODEMCONFIG1)
wamae 0:f930f0440fd5 625 & RFLR_MODEMCONFIG1_BW_MASK
wamae 0:f930f0440fd5 626 & RFLR_MODEMCONFIG1_CODINGRATE_MASK
wamae 0:f930f0440fd5 627 & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK) | (bandwidth << 4)
wamae 0:f930f0440fd5 628 | (coderate << 1) | fix_len);
wamae 0:f930f0440fd5 629
wamae 0:f930f0440fd5 630 write_to_register(REG_LR_MODEMCONFIG2, (read_register( REG_LR_MODEMCONFIG2)
wamae 0:f930f0440fd5 631 & RFLR_MODEMCONFIG2_SF_MASK
wamae 0:f930f0440fd5 632 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK)
wamae 0:f930f0440fd5 633 | (datarate << 4)
wamae 0:f930f0440fd5 634 | (crc_on << 2));
wamae 0:f930f0440fd5 635
wamae 0:f930f0440fd5 636 write_to_register(REG_LR_MODEMCONFIG3, (read_register(REG_LR_MODEMCONFIG3)
wamae 0:f930f0440fd5 637 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK)
wamae 0:f930f0440fd5 638 | (_rf_settings.lora.low_datarate_optimize << 3));
wamae 0:f930f0440fd5 639
wamae 0:f930f0440fd5 640 write_to_register(REG_LR_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF);
wamae 0:f930f0440fd5 641 write_to_register(REG_LR_PREAMBLELSB, preamble_len & 0xFF);
wamae 0:f930f0440fd5 642
wamae 0:f930f0440fd5 643 if (datarate == 6) {
wamae 0:f930f0440fd5 644 write_to_register(REG_LR_DETECTOPTIMIZE, (read_register( REG_LR_DETECTOPTIMIZE)
wamae 0:f930f0440fd5 645 & RFLR_DETECTIONOPTIMIZE_MASK) | RFLR_DETECTIONOPTIMIZE_SF6);
wamae 0:f930f0440fd5 646 write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF6);
wamae 0:f930f0440fd5 647 } else {
wamae 0:f930f0440fd5 648 write_to_register(REG_LR_DETECTOPTIMIZE, (read_register( REG_LR_DETECTOPTIMIZE)
wamae 0:f930f0440fd5 649 & RFLR_DETECTIONOPTIMIZE_MASK) | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12);
wamae 0:f930f0440fd5 650 write_to_register( REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12);
wamae 0:f930f0440fd5 651 }
wamae 0:f930f0440fd5 652
wamae 0:f930f0440fd5 653 break;
wamae 0:f930f0440fd5 654 }
wamae 0:f930f0440fd5 655 }
wamae 0:f930f0440fd5 656
wamae 0:f930f0440fd5 657 /**
wamae 0:f930f0440fd5 658 * Calculates time on Air i.e., dwell time for a single packet
wamae 0:f930f0440fd5 659 *
wamae 0:f930f0440fd5 660 * Crucial for the stack in order to calculate dwell time so as to control
wamae 0:f930f0440fd5 661 * duty cycling.
wamae 0:f930f0440fd5 662 */
wamae 0:f930f0440fd5 663 uint32_t SX1276_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len)
wamae 0:f930f0440fd5 664 {
wamae 0:f930f0440fd5 665 uint32_t airTime = 0;
wamae 0:f930f0440fd5 666
wamae 0:f930f0440fd5 667 switch (modem) {
wamae 0:f930f0440fd5 668 case MODEM_FSK:
wamae 0:f930f0440fd5 669 airTime =
wamae 0:f930f0440fd5 670 rint((8 * (_rf_settings.fsk.preamble_len
wamae 0:f930f0440fd5 671 + ((read_register( REG_SYNCCONFIG)
wamae 0:f930f0440fd5 672 & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1)
wamae 0:f930f0440fd5 673 + ((_rf_settings.fsk.fix_len == 0x01) ?
wamae 0:f930f0440fd5 674 0.0 : 1.0)
wamae 0:f930f0440fd5 675 + (((read_register( REG_PACKETCONFIG1)
wamae 0:f930f0440fd5 676 & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK)
wamae 0:f930f0440fd5 677 != 0x00) ? 1.0 : 0) + pkt_len
wamae 0:f930f0440fd5 678 + ((_rf_settings.fsk.crc_on == 0x01) ?
wamae 0:f930f0440fd5 679 2.0 : 0))
wamae 0:f930f0440fd5 680 / _rf_settings.fsk.datarate) * 1e3);
wamae 0:f930f0440fd5 681
wamae 0:f930f0440fd5 682 break;
wamae 0:f930f0440fd5 683 case MODEM_LORA:
wamae 0:f930f0440fd5 684 double bw = 0.0;
wamae 0:f930f0440fd5 685 // REMARK: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
wamae 0:f930f0440fd5 686 switch (_rf_settings.lora.bandwidth) {
wamae 0:f930f0440fd5 687 //case 0: // 7.8 kHz
wamae 0:f930f0440fd5 688 // bw = 78e2;
wamae 0:f930f0440fd5 689 // break;
wamae 0:f930f0440fd5 690 //case 1: // 10.4 kHz
wamae 0:f930f0440fd5 691 // bw = 104e2;
wamae 0:f930f0440fd5 692 // break;
wamae 0:f930f0440fd5 693 //case 2: // 15.6 kHz
wamae 0:f930f0440fd5 694 // bw = 156e2;
wamae 0:f930f0440fd5 695 // break;
wamae 0:f930f0440fd5 696 //case 3: // 20.8 kHz
wamae 0:f930f0440fd5 697 // bw = 208e2;
wamae 0:f930f0440fd5 698 // break;
wamae 0:f930f0440fd5 699 //case 4: // 31.2 kHz
wamae 0:f930f0440fd5 700 // bw = 312e2;
wamae 0:f930f0440fd5 701 // break;
wamae 0:f930f0440fd5 702 //case 5: // 41.4 kHz
wamae 0:f930f0440fd5 703 // bw = 414e2;
wamae 0:f930f0440fd5 704 // break;
wamae 0:f930f0440fd5 705 //case 6: // 62.5 kHz
wamae 0:f930f0440fd5 706 // bw = 625e2;
wamae 0:f930f0440fd5 707 // break;
wamae 0:f930f0440fd5 708 case 7: // 125 kHz
wamae 0:f930f0440fd5 709 bw = 125e3;
wamae 0:f930f0440fd5 710 break;
wamae 0:f930f0440fd5 711 case 8: // 250 kHz
wamae 0:f930f0440fd5 712 bw = 250e3;
wamae 0:f930f0440fd5 713 break;
wamae 0:f930f0440fd5 714 case 9: // 500 kHz
wamae 0:f930f0440fd5 715 bw = 500e3;
wamae 0:f930f0440fd5 716 break;
wamae 0:f930f0440fd5 717 }
wamae 0:f930f0440fd5 718
wamae 0:f930f0440fd5 719 // Symbol rate : time for one symbol (secs)
wamae 0:f930f0440fd5 720 double rs = bw / (1 << _rf_settings.lora.datarate);
wamae 0:f930f0440fd5 721 double ts = 1 / rs;
wamae 0:f930f0440fd5 722 // time of preamble
wamae 0:f930f0440fd5 723 double tPreamble = (_rf_settings.lora.preamble_len + 4.25) * ts;
wamae 0:f930f0440fd5 724 // Symbol length of payload and time
wamae 0:f930f0440fd5 725 double tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28
wamae 0:f930f0440fd5 726 + 16 * _rf_settings.lora.crc_on
wamae 0:f930f0440fd5 727 - (_rf_settings.lora.fix_len ? 20 : 0))
wamae 0:f930f0440fd5 728 / (double) (4
wamae 0:f930f0440fd5 729 * (_rf_settings.lora.datarate
wamae 0:f930f0440fd5 730 - ((_rf_settings.lora.low_datarate_optimize > 0)
wamae 0:f930f0440fd5 731 ? 2 : 0))))
wamae 0:f930f0440fd5 732 * (_rf_settings.lora.coderate + 4);
wamae 0:f930f0440fd5 733 double nPayload = 8 + ((tmp > 0) ? tmp : 0);
wamae 0:f930f0440fd5 734 double tPayload = nPayload * ts;
wamae 0:f930f0440fd5 735 // Time on air
wamae 0:f930f0440fd5 736 double tOnAir = tPreamble + tPayload;
wamae 0:f930f0440fd5 737 // return ms secs
wamae 0:f930f0440fd5 738 airTime = floor(tOnAir * 1e3 + 0.999);
wamae 0:f930f0440fd5 739
wamae 0:f930f0440fd5 740 break;
wamae 0:f930f0440fd5 741 }
wamae 0:f930f0440fd5 742
wamae 0:f930f0440fd5 743 return airTime;
wamae 0:f930f0440fd5 744 }
wamae 0:f930f0440fd5 745
wamae 0:f930f0440fd5 746 /**
wamae 0:f930f0440fd5 747 * Prepares and sends the radio packet out in the air
wamae 0:f930f0440fd5 748 */
wamae 0:f930f0440fd5 749 void SX1276_LoRaRadio::send(uint8_t *buffer, uint8_t size)
wamae 0:f930f0440fd5 750 {
wamae 0:f930f0440fd5 751 uint32_t tx_timeout = 0;
wamae 0:f930f0440fd5 752
wamae 0:f930f0440fd5 753 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 754 case MODEM_FSK:
wamae 0:f930f0440fd5 755 _rf_settings.fsk_packet_handler.nb_bytes = 0;
wamae 0:f930f0440fd5 756 _rf_settings.fsk_packet_handler.size = size;
wamae 0:f930f0440fd5 757
wamae 0:f930f0440fd5 758 if (_rf_settings.fsk.fix_len == false) {
wamae 0:f930f0440fd5 759 write_fifo((uint8_t*) &size, 1);
wamae 0:f930f0440fd5 760 } else {
wamae 0:f930f0440fd5 761 write_to_register(REG_PAYLOADLENGTH, size);
wamae 0:f930f0440fd5 762 }
wamae 0:f930f0440fd5 763
wamae 0:f930f0440fd5 764 if ((size > 0) && (size <= 64)) {
wamae 0:f930f0440fd5 765 _rf_settings.fsk_packet_handler.chunk_size = size;
wamae 0:f930f0440fd5 766 } else {
wamae 0:f930f0440fd5 767 memcpy(_data_buffer, buffer, size);
wamae 0:f930f0440fd5 768 _rf_settings.fsk_packet_handler.chunk_size = 32;
wamae 0:f930f0440fd5 769 }
wamae 0:f930f0440fd5 770
wamae 0:f930f0440fd5 771 // Write payload buffer
wamae 0:f930f0440fd5 772 write_fifo(buffer, _rf_settings.fsk_packet_handler.chunk_size);
wamae 0:f930f0440fd5 773 _rf_settings.fsk_packet_handler.nb_bytes +=
wamae 0:f930f0440fd5 774 _rf_settings.fsk_packet_handler.chunk_size;
wamae 0:f930f0440fd5 775 tx_timeout = _rf_settings.fsk.tx_timeout;
wamae 0:f930f0440fd5 776
wamae 0:f930f0440fd5 777 break;
wamae 0:f930f0440fd5 778
wamae 0:f930f0440fd5 779 case MODEM_LORA:
wamae 0:f930f0440fd5 780 if (_rf_settings.lora.iq_inverted == true) {
wamae 0:f930f0440fd5 781 write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ)
wamae 0:f930f0440fd5 782 & RFLR_INVERTIQ_TX_MASK
wamae 0:f930f0440fd5 783 & RFLR_INVERTIQ_RX_MASK)
wamae 0:f930f0440fd5 784 | RFLR_INVERTIQ_RX_OFF
wamae 0:f930f0440fd5 785 | RFLR_INVERTIQ_TX_ON));
wamae 0:f930f0440fd5 786 write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON);
wamae 0:f930f0440fd5 787 } else {
wamae 0:f930f0440fd5 788 write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ)
wamae 0:f930f0440fd5 789 & RFLR_INVERTIQ_TX_MASK
wamae 0:f930f0440fd5 790 & RFLR_INVERTIQ_RX_MASK)
wamae 0:f930f0440fd5 791 | RFLR_INVERTIQ_RX_OFF
wamae 0:f930f0440fd5 792 | RFLR_INVERTIQ_TX_OFF));
wamae 0:f930f0440fd5 793 write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF);
wamae 0:f930f0440fd5 794 }
wamae 0:f930f0440fd5 795
wamae 0:f930f0440fd5 796 _rf_settings.lora_packet_handler.size = size;
wamae 0:f930f0440fd5 797
wamae 0:f930f0440fd5 798 // Initializes the payload size
wamae 0:f930f0440fd5 799 write_to_register(REG_LR_PAYLOADLENGTH, size);
wamae 0:f930f0440fd5 800
wamae 0:f930f0440fd5 801 // Full buffer used for Tx
wamae 0:f930f0440fd5 802 write_to_register(REG_LR_FIFOTXBASEADDR, 0);
wamae 0:f930f0440fd5 803 write_to_register(REG_LR_FIFOADDRPTR, 0);
wamae 0:f930f0440fd5 804
wamae 0:f930f0440fd5 805 // FIFO operations can not take place in Sleep mode
wamae 0:f930f0440fd5 806 if ((read_register( REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) {
wamae 0:f930f0440fd5 807 standby();
wamae 0:f930f0440fd5 808 wait_ms(1);
wamae 0:f930f0440fd5 809 }
wamae 0:f930f0440fd5 810 // write_to_register payload buffer
wamae 0:f930f0440fd5 811 write_fifo(buffer, size);
wamae 0:f930f0440fd5 812 tx_timeout = _rf_settings.lora.tx_timeout;
wamae 0:f930f0440fd5 813
wamae 0:f930f0440fd5 814 break;
wamae 0:f930f0440fd5 815 }
wamae 0:f930f0440fd5 816
wamae 0:f930f0440fd5 817 transmit(tx_timeout);
wamae 0:f930f0440fd5 818 }
wamae 0:f930f0440fd5 819
wamae 0:f930f0440fd5 820 /**
wamae 0:f930f0440fd5 821 * sets the radio module to sleep
wamae 0:f930f0440fd5 822 */
wamae 0:f930f0440fd5 823
wamae 0:f930f0440fd5 824 void SX1276_LoRaRadio::sleep()
wamae 0:f930f0440fd5 825 {
wamae 0:f930f0440fd5 826 // stop timers
wamae 0:f930f0440fd5 827 tx_timeout_timer.detach();
wamae 0:f930f0440fd5 828 rx_timeout_timer.detach();
wamae 0:f930f0440fd5 829
wamae 0:f930f0440fd5 830 // put module in sleep mode
wamae 0:f930f0440fd5 831 set_operation_mode(RF_OPMODE_SLEEP);
wamae 0:f930f0440fd5 832 }
wamae 0:f930f0440fd5 833
wamae 0:f930f0440fd5 834 /**
wamae 0:f930f0440fd5 835 * Put radio in Standby mode
wamae 0:f930f0440fd5 836 */
wamae 0:f930f0440fd5 837 void SX1276_LoRaRadio::standby( void )
wamae 0:f930f0440fd5 838 {
wamae 0:f930f0440fd5 839 tx_timeout_timer.detach();
wamae 0:f930f0440fd5 840 rx_timeout_timer.detach();
wamae 0:f930f0440fd5 841
wamae 0:f930f0440fd5 842 set_operation_mode(RF_OPMODE_STANDBY);
wamae 0:f930f0440fd5 843 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 844 }
wamae 0:f930f0440fd5 845
wamae 0:f930f0440fd5 846 /**
wamae 0:f930f0440fd5 847 * Sets the radio module in receive mode
wamae 0:f930f0440fd5 848 *
wamae 0:f930f0440fd5 849 * A DIO4 interrupt let's the state machine know that a preamble is detected
wamae 0:f930f0440fd5 850 * and finally a DIO0 interrupt let's the state machine know that a packet is
wamae 0:f930f0440fd5 851 * ready to be read from the FIFO
wamae 0:f930f0440fd5 852 */
wamae 0:f930f0440fd5 853 void SX1276_LoRaRadio::receive(uint32_t timeout)
wamae 0:f930f0440fd5 854 {
wamae 0:f930f0440fd5 855 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 856 case MODEM_FSK:
wamae 0:f930f0440fd5 857 if (timeout == 0 && _rf_settings.fsk.rx_continuous == false) {
wamae 0:f930f0440fd5 858 // user messed up probably timeout was 0 but mode was not
wamae 0:f930f0440fd5 859 // continuous, force it to be continuous
wamae 0:f930f0440fd5 860 _rf_settings.fsk.rx_continuous = true;
wamae 0:f930f0440fd5 861 }
wamae 0:f930f0440fd5 862
wamae 0:f930f0440fd5 863 // DIO0=PayloadReady
wamae 0:f930f0440fd5 864 // DIO1=FifoLevel
wamae 0:f930f0440fd5 865 // DIO2=SyncAddr
wamae 0:f930f0440fd5 866 // DIO3=FifoEmpty
wamae 0:f930f0440fd5 867 // DIO4=Preamble
wamae 0:f930f0440fd5 868 // DIO5=ModeReady
wamae 0:f930f0440fd5 869 write_to_register(REG_DIOMAPPING1, (read_register( REG_DIOMAPPING1)
wamae 0:f930f0440fd5 870 & RF_DIOMAPPING1_DIO0_MASK
wamae 0:f930f0440fd5 871 & RF_DIOMAPPING1_DIO1_MASK
wamae 0:f930f0440fd5 872 & RF_DIOMAPPING1_DIO2_MASK)
wamae 0:f930f0440fd5 873 | RF_DIOMAPPING1_DIO0_00
wamae 0:f930f0440fd5 874 | RF_DIOMAPPING1_DIO1_00
wamae 0:f930f0440fd5 875 | RF_DIOMAPPING1_DIO2_11);
wamae 0:f930f0440fd5 876
wamae 0:f930f0440fd5 877 write_to_register(REG_DIOMAPPING2, (read_register( REG_DIOMAPPING2)
wamae 0:f930f0440fd5 878 & RF_DIOMAPPING2_DIO4_MASK
wamae 0:f930f0440fd5 879 & RF_DIOMAPPING2_MAP_MASK)
wamae 0:f930f0440fd5 880 | RF_DIOMAPPING2_DIO4_11
wamae 0:f930f0440fd5 881 | RF_DIOMAPPING2_MAP_PREAMBLEDETECT);
wamae 0:f930f0440fd5 882
wamae 0:f930f0440fd5 883 _rf_settings.fsk_packet_handler.fifo_thresh =
wamae 0:f930f0440fd5 884 read_register(REG_FIFOTHRESH) & 0x3F;
wamae 0:f930f0440fd5 885
wamae 0:f930f0440fd5 886 write_to_register(REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON
wamae 0:f930f0440fd5 887 | RF_RXCONFIG_AGCAUTO_ON
wamae 0:f930f0440fd5 888 | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT);
wamae 0:f930f0440fd5 889
wamae 0:f930f0440fd5 890 _rf_settings.fsk_packet_handler.preamble_detected = 0;
wamae 0:f930f0440fd5 891 _rf_settings.fsk_packet_handler.sync_word_detected = 0;
wamae 0:f930f0440fd5 892 _rf_settings.fsk_packet_handler.nb_bytes = 0;
wamae 0:f930f0440fd5 893 _rf_settings.fsk_packet_handler.size = 0;
wamae 0:f930f0440fd5 894
wamae 0:f930f0440fd5 895 break;
wamae 0:f930f0440fd5 896
wamae 0:f930f0440fd5 897 case MODEM_LORA:
wamae 0:f930f0440fd5 898 if (timeout == 0 && _rf_settings.lora.rx_continuous == false) {
wamae 0:f930f0440fd5 899 // user messed up probably timeout was 0 but mode was not
wamae 0:f930f0440fd5 900 // continuous, force it to be continuous
wamae 0:f930f0440fd5 901 _rf_settings.lora.rx_continuous = true;
wamae 0:f930f0440fd5 902 }
wamae 0:f930f0440fd5 903 if (_rf_settings.lora.iq_inverted == true) {
wamae 0:f930f0440fd5 904 write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ)
wamae 0:f930f0440fd5 905 & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK)
wamae 0:f930f0440fd5 906 | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF));
wamae 0:f930f0440fd5 907 write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON);
wamae 0:f930f0440fd5 908 } else {
wamae 0:f930f0440fd5 909 write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ)
wamae 0:f930f0440fd5 910 & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK)
wamae 0:f930f0440fd5 911 | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF));
wamae 0:f930f0440fd5 912 write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF);
wamae 0:f930f0440fd5 913 }
wamae 0:f930f0440fd5 914
wamae 0:f930f0440fd5 915 // ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal
wamae 0:f930f0440fd5 916 if (_rf_settings.lora.bandwidth < 9) {
wamae 0:f930f0440fd5 917 write_to_register(REG_LR_DETECTOPTIMIZE,
wamae 0:f930f0440fd5 918 read_register(REG_LR_DETECTOPTIMIZE) & 0x7F);
wamae 0:f930f0440fd5 919 write_to_register(REG_LR_TEST30, 0x00);
wamae 0:f930f0440fd5 920 switch (_rf_settings.lora.bandwidth) {
wamae 0:f930f0440fd5 921 case 0: // 7.8 kHz
wamae 0:f930f0440fd5 922 write_to_register( REG_LR_TEST2F, 0x48);
wamae 0:f930f0440fd5 923 set_channel(_rf_settings.channel + 7.81e3);
wamae 0:f930f0440fd5 924 break;
wamae 0:f930f0440fd5 925 case 1: // 10.4 kHz
wamae 0:f930f0440fd5 926 write_to_register( REG_LR_TEST2F, 0x44);
wamae 0:f930f0440fd5 927 set_channel(_rf_settings.channel + 10.42e3);
wamae 0:f930f0440fd5 928 break;
wamae 0:f930f0440fd5 929 case 2: // 15.6 kHz
wamae 0:f930f0440fd5 930 write_to_register( REG_LR_TEST2F, 0x44);
wamae 0:f930f0440fd5 931 set_channel(_rf_settings.channel + 15.62e3);
wamae 0:f930f0440fd5 932 break;
wamae 0:f930f0440fd5 933 case 3: // 20.8 kHz
wamae 0:f930f0440fd5 934 write_to_register( REG_LR_TEST2F, 0x44);
wamae 0:f930f0440fd5 935 set_channel(_rf_settings.channel + 20.83e3);
wamae 0:f930f0440fd5 936 break;
wamae 0:f930f0440fd5 937 case 4: // 31.2 kHz
wamae 0:f930f0440fd5 938 write_to_register( REG_LR_TEST2F, 0x44);
wamae 0:f930f0440fd5 939 set_channel(_rf_settings.channel + 31.25e3);
wamae 0:f930f0440fd5 940 break;
wamae 0:f930f0440fd5 941 case 5: // 41.4 kHz
wamae 0:f930f0440fd5 942 write_to_register( REG_LR_TEST2F, 0x44);
wamae 0:f930f0440fd5 943 set_channel(_rf_settings.channel + 41.67e3);
wamae 0:f930f0440fd5 944 break;
wamae 0:f930f0440fd5 945 case 6: // 62.5 kHz
wamae 0:f930f0440fd5 946 write_to_register( REG_LR_TEST2F, 0x40);
wamae 0:f930f0440fd5 947 break;
wamae 0:f930f0440fd5 948 case 7: // 125 kHz
wamae 0:f930f0440fd5 949 write_to_register( REG_LR_TEST2F, 0x40);
wamae 0:f930f0440fd5 950 break;
wamae 0:f930f0440fd5 951 case 8: // 250 kHz
wamae 0:f930f0440fd5 952 write_to_register( REG_LR_TEST2F, 0x40);
wamae 0:f930f0440fd5 953 break;
wamae 0:f930f0440fd5 954 }
wamae 0:f930f0440fd5 955 } else {
wamae 0:f930f0440fd5 956 write_to_register( REG_LR_DETECTOPTIMIZE,
wamae 0:f930f0440fd5 957 read_register( REG_LR_DETECTOPTIMIZE) | 0x80);
wamae 0:f930f0440fd5 958 }
wamae 0:f930f0440fd5 959
wamae 0:f930f0440fd5 960 if (_rf_settings.lora.freq_hop_on == true) {
wamae 0:f930f0440fd5 961 write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_VALIDHEADER
wamae 0:f930f0440fd5 962 | RFLR_IRQFLAGS_TXDONE
wamae 0:f930f0440fd5 963 | RFLR_IRQFLAGS_CADDONE
wamae 0:f930f0440fd5 964 | RFLR_IRQFLAGS_CADDETECTED);
wamae 0:f930f0440fd5 965
wamae 0:f930f0440fd5 966 // DIO0=RxDone, DIO2=FhssChangeChannel
wamae 0:f930f0440fd5 967 write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1)
wamae 0:f930f0440fd5 968 & RFLR_DIOMAPPING1_DIO0_MASK
wamae 0:f930f0440fd5 969 & RFLR_DIOMAPPING1_DIO2_MASK)
wamae 0:f930f0440fd5 970 | RFLR_DIOMAPPING1_DIO0_00
wamae 0:f930f0440fd5 971 | RFLR_DIOMAPPING1_DIO2_00);
wamae 0:f930f0440fd5 972 } else {
wamae 0:f930f0440fd5 973 write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_VALIDHEADER
wamae 0:f930f0440fd5 974 | RFLR_IRQFLAGS_TXDONE
wamae 0:f930f0440fd5 975 | RFLR_IRQFLAGS_CADDONE
wamae 0:f930f0440fd5 976 | RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL
wamae 0:f930f0440fd5 977 | RFLR_IRQFLAGS_CADDETECTED);
wamae 0:f930f0440fd5 978
wamae 0:f930f0440fd5 979 // DIO0=RxDone
wamae 0:f930f0440fd5 980 write_to_register(REG_DIOMAPPING1, (read_register( REG_DIOMAPPING1)
wamae 0:f930f0440fd5 981 & RFLR_DIOMAPPING1_DIO0_MASK)
wamae 0:f930f0440fd5 982 | RFLR_DIOMAPPING1_DIO0_00);
wamae 0:f930f0440fd5 983 }
wamae 0:f930f0440fd5 984 write_to_register(REG_LR_FIFORXBASEADDR, 0);
wamae 0:f930f0440fd5 985 write_to_register(REG_LR_FIFOADDRPTR, 0);
wamae 0:f930f0440fd5 986
wamae 0:f930f0440fd5 987 break;
wamae 0:f930f0440fd5 988 }
wamae 0:f930f0440fd5 989
wamae 0:f930f0440fd5 990 memset(_data_buffer, 0, (size_t) MAX_DATA_BUFFER_SIZE_SX1276);
wamae 0:f930f0440fd5 991
wamae 0:f930f0440fd5 992 _rf_settings.state = RF_RX_RUNNING;
wamae 0:f930f0440fd5 993
wamae 0:f930f0440fd5 994 if (timeout != 0) {
wamae 0:f930f0440fd5 995 rx_timeout_timer.attach_us(
wamae 0:f930f0440fd5 996 callback(this, &SX1276_LoRaRadio::timeout_irq_isr),
wamae 0:f930f0440fd5 997 timeout * 1e3);
wamae 0:f930f0440fd5 998 }
wamae 0:f930f0440fd5 999
wamae 0:f930f0440fd5 1000 if (_rf_settings.modem == MODEM_FSK) {
wamae 0:f930f0440fd5 1001 set_operation_mode(RF_OPMODE_RECEIVER);
wamae 0:f930f0440fd5 1002
wamae 0:f930f0440fd5 1003 if (_rf_settings.fsk.rx_continuous == false) {
wamae 0:f930f0440fd5 1004 rx_timeout_sync_word.attach_us(
wamae 0:f930f0440fd5 1005 callback(this, &SX1276_LoRaRadio::timeout_irq_isr),
wamae 0:f930f0440fd5 1006 _rf_settings.fsk.rx_single_timeout * 1e3);
wamae 0:f930f0440fd5 1007 }
wamae 0:f930f0440fd5 1008
wamae 0:f930f0440fd5 1009 return;
wamae 0:f930f0440fd5 1010 }
wamae 0:f930f0440fd5 1011
wamae 0:f930f0440fd5 1012 // If mode is LoRa set mode
wamae 0:f930f0440fd5 1013 if (_rf_settings.lora.rx_continuous == true) {
wamae 0:f930f0440fd5 1014 set_operation_mode(RFLR_OPMODE_RECEIVER);
wamae 0:f930f0440fd5 1015 } else {
wamae 0:f930f0440fd5 1016 set_operation_mode(RFLR_OPMODE_RECEIVER_SINGLE);
wamae 0:f930f0440fd5 1017 }
wamae 0:f930f0440fd5 1018 }
wamae 0:f930f0440fd5 1019
wamae 0:f930f0440fd5 1020
wamae 0:f930f0440fd5 1021 /**
wamae 0:f930f0440fd5 1022 * Perform carrier sensing
wamae 0:f930f0440fd5 1023 *
wamae 0:f930f0440fd5 1024 * Checks for a certain time if the RSSI is above a given threshold.
wamae 0:f930f0440fd5 1025 * This threshold determines if there is already a transmission going on
wamae 0:f930f0440fd5 1026 * in the channel or not.
wamae 0:f930f0440fd5 1027 *
wamae 0:f930f0440fd5 1028 */
wamae 0:f930f0440fd5 1029 bool SX1276_LoRaRadio::perform_carrier_sense(radio_modems_t modem,
wamae 0:f930f0440fd5 1030 uint32_t freq,
wamae 0:f930f0440fd5 1031 int16_t rssi_threshold,
wamae 0:f930f0440fd5 1032 uint32_t max_carrier_sense_time)
wamae 0:f930f0440fd5 1033 {
wamae 0:f930f0440fd5 1034 bool status = true;
wamae 0:f930f0440fd5 1035 int16_t rssi = 0;
wamae 0:f930f0440fd5 1036
wamae 0:f930f0440fd5 1037 set_modem(modem);
wamae 0:f930f0440fd5 1038 set_channel(freq);
wamae 0:f930f0440fd5 1039 set_operation_mode(RF_OPMODE_RECEIVER);
wamae 0:f930f0440fd5 1040
wamae 0:f930f0440fd5 1041 // hold on a bit, radio turn-around time
wamae 0:f930f0440fd5 1042 wait_ms(1);
wamae 0:f930f0440fd5 1043
wamae 0:f930f0440fd5 1044 Timer elapsed_time;
wamae 0:f930f0440fd5 1045 elapsed_time.start();
wamae 0:f930f0440fd5 1046
wamae 0:f930f0440fd5 1047 // Perform carrier sense for maxCarrierSenseTime
wamae 0:f930f0440fd5 1048 while (elapsed_time.read_ms() < (int)max_carrier_sense_time) {
wamae 0:f930f0440fd5 1049 rssi = get_rssi(modem);
wamae 0:f930f0440fd5 1050
wamae 0:f930f0440fd5 1051 if (rssi > rssi_threshold) {
wamae 0:f930f0440fd5 1052 status = false;
wamae 0:f930f0440fd5 1053 break;
wamae 0:f930f0440fd5 1054 }
wamae 0:f930f0440fd5 1055 }
wamae 0:f930f0440fd5 1056
wamae 0:f930f0440fd5 1057 sleep();
wamae 0:f930f0440fd5 1058 return status;
wamae 0:f930f0440fd5 1059 }
wamae 0:f930f0440fd5 1060
wamae 0:f930f0440fd5 1061 /**
wamae 0:f930f0440fd5 1062 * TODO: Making sure if this API is valid only for LoRa modulation ?
wamae 0:f930f0440fd5 1063 *
wamae 0:f930f0440fd5 1064 * Indicates if the node is part of a private or public network
wamae 0:f930f0440fd5 1065 */
wamae 0:f930f0440fd5 1066 void SX1276_LoRaRadio::set_public_network(bool enable)
wamae 0:f930f0440fd5 1067 {
wamae 0:f930f0440fd5 1068 set_modem(MODEM_LORA);
wamae 0:f930f0440fd5 1069
wamae 0:f930f0440fd5 1070 _rf_settings.lora.public_network = enable;
wamae 0:f930f0440fd5 1071 if (enable == true) {
wamae 0:f930f0440fd5 1072 // Change lora modem SyncWord
wamae 0:f930f0440fd5 1073 write_to_register(REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD);
wamae 0:f930f0440fd5 1074 } else {
wamae 0:f930f0440fd5 1075 // Change lora modem SyncWord
wamae 0:f930f0440fd5 1076 write_to_register(REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD);
wamae 0:f930f0440fd5 1077 }
wamae 0:f930f0440fd5 1078
wamae 0:f930f0440fd5 1079 }
wamae 0:f930f0440fd5 1080
wamae 0:f930f0440fd5 1081 /**
wamae 0:f930f0440fd5 1082 * Puts a limit on the size of payload the module can handle
wamae 0:f930f0440fd5 1083 * By default it is MAX, i.e., 256 bytes
wamae 0:f930f0440fd5 1084 */
wamae 0:f930f0440fd5 1085 void SX1276_LoRaRadio::set_max_payload_length(radio_modems_t modem, uint8_t max)
wamae 0:f930f0440fd5 1086 {
wamae 0:f930f0440fd5 1087 set_modem(modem);
wamae 0:f930f0440fd5 1088
wamae 0:f930f0440fd5 1089 switch (modem) {
wamae 0:f930f0440fd5 1090 case MODEM_FSK:
wamae 0:f930f0440fd5 1091 if (_rf_settings.fsk.fix_len == false) {
wamae 0:f930f0440fd5 1092 write_to_register(REG_PAYLOADLENGTH, max);
wamae 0:f930f0440fd5 1093 }
wamae 0:f930f0440fd5 1094 break;
wamae 0:f930f0440fd5 1095 case MODEM_LORA:
wamae 0:f930f0440fd5 1096 write_to_register(REG_LR_PAYLOADMAXLENGTH, max);
wamae 0:f930f0440fd5 1097 break;
wamae 0:f930f0440fd5 1098 }
wamae 0:f930f0440fd5 1099 }
wamae 0:f930f0440fd5 1100
wamae 0:f930f0440fd5 1101 /**
wamae 0:f930f0440fd5 1102 * Channel Activity detection (can be done only in LoRa mode)
wamae 0:f930f0440fd5 1103 *
wamae 0:f930f0440fd5 1104 * If any activity on the channel is detected, an interrupt is asserted on
wamae 0:f930f0440fd5 1105 * DIO3. A callback will be generated to the stack/application upon the
wamae 0:f930f0440fd5 1106 * assertion of DIO3.
wamae 0:f930f0440fd5 1107 */
wamae 0:f930f0440fd5 1108 void SX1276_LoRaRadio::start_cad()
wamae 0:f930f0440fd5 1109 {
wamae 0:f930f0440fd5 1110 uint8_t reg_val;
wamae 0:f930f0440fd5 1111
wamae 0:f930f0440fd5 1112 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 1113 case MODEM_FSK:
wamae 0:f930f0440fd5 1114 break;
wamae 0:f930f0440fd5 1115 case MODEM_LORA:
wamae 0:f930f0440fd5 1116 write_to_register(REG_LR_IRQFLAGSMASK,
wamae 0:f930f0440fd5 1117 RFLR_IRQFLAGS_RXTIMEOUT |
wamae 0:f930f0440fd5 1118 RFLR_IRQFLAGS_RXDONE |
wamae 0:f930f0440fd5 1119 RFLR_IRQFLAGS_PAYLOADCRCERROR |
wamae 0:f930f0440fd5 1120 RFLR_IRQFLAGS_VALIDHEADER |
wamae 0:f930f0440fd5 1121 RFLR_IRQFLAGS_TXDONE |
wamae 0:f930f0440fd5 1122 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL);
wamae 0:f930f0440fd5 1123
wamae 0:f930f0440fd5 1124 // DIO3=CADDone
wamae 0:f930f0440fd5 1125 reg_val = read_register(REG_DIOMAPPING1);
wamae 0:f930f0440fd5 1126 write_to_register(REG_DIOMAPPING1, (reg_val &
wamae 0:f930f0440fd5 1127 RFLR_DIOMAPPING1_DIO3_MASK) |
wamae 0:f930f0440fd5 1128 RFLR_DIOMAPPING1_DIO3_00);
wamae 0:f930f0440fd5 1129
wamae 0:f930f0440fd5 1130 set_operation_mode(RFLR_OPMODE_CAD);
wamae 0:f930f0440fd5 1131
wamae 0:f930f0440fd5 1132 _rf_settings.state = RF_CAD;
wamae 0:f930f0440fd5 1133
wamae 0:f930f0440fd5 1134 break;
wamae 0:f930f0440fd5 1135 default:
wamae 0:f930f0440fd5 1136 break;
wamae 0:f930f0440fd5 1137 }
wamae 0:f930f0440fd5 1138 }
wamae 0:f930f0440fd5 1139
wamae 0:f930f0440fd5 1140 /**
wamae 0:f930f0440fd5 1141 * Set transmission in continuous wave mode
wamae 0:f930f0440fd5 1142 */
wamae 0:f930f0440fd5 1143 void SX1276_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power,
wamae 0:f930f0440fd5 1144 uint16_t time)
wamae 0:f930f0440fd5 1145 {
wamae 0:f930f0440fd5 1146 uint8_t reg_val;
wamae 0:f930f0440fd5 1147
wamae 0:f930f0440fd5 1148 set_channel(freq);
wamae 0:f930f0440fd5 1149 set_tx_config(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, time);
wamae 0:f930f0440fd5 1150 reg_val = read_register(REG_PACKETCONFIG2);
wamae 0:f930f0440fd5 1151
wamae 0:f930f0440fd5 1152 write_to_register( REG_PACKETCONFIG2, (reg_val & RF_PACKETCONFIG2_DATAMODE_MASK ) );
wamae 0:f930f0440fd5 1153 // Disable radio interrupts
wamae 0:f930f0440fd5 1154 write_to_register( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 );
wamae 0:f930f0440fd5 1155 write_to_register( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 );
wamae 0:f930f0440fd5 1156
wamae 0:f930f0440fd5 1157 _rf_settings.state = RF_TX_RUNNING;
wamae 0:f930f0440fd5 1158 tx_timeout_timer.attach_us(callback(this, &SX1276_LoRaRadio::timeout_irq_isr), time*1e3);
wamae 0:f930f0440fd5 1159 set_operation_mode(RF_OPMODE_TRANSMITTER);
wamae 0:f930f0440fd5 1160 }
wamae 0:f930f0440fd5 1161
wamae 0:f930f0440fd5 1162 /*****************************************************************************
wamae 0:f930f0440fd5 1163 * Private APIs *
wamae 0:f930f0440fd5 1164 ****************************************************************************/
wamae 0:f930f0440fd5 1165 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 1166 /**
wamae 0:f930f0440fd5 1167 * Thread task handling IRQs
wamae 0:f930f0440fd5 1168 */
wamae 0:f930f0440fd5 1169 void SX1276_LoRaRadio::rf_irq_task(void)
wamae 0:f930f0440fd5 1170 {
wamae 0:f930f0440fd5 1171 for (;;) {
wamae 0:f930f0440fd5 1172 osEvent event = irq_thread.signal_wait(0, osWaitForever);
wamae 0:f930f0440fd5 1173 if (event.status != osEventSignal) {
wamae 0:f930f0440fd5 1174 continue;
wamae 0:f930f0440fd5 1175 }
wamae 0:f930f0440fd5 1176
wamae 0:f930f0440fd5 1177 lock();
wamae 0:f930f0440fd5 1178 if (event.value.signals & SIG_DIO0) {
wamae 0:f930f0440fd5 1179 handle_dio0_irq();
wamae 0:f930f0440fd5 1180 }
wamae 0:f930f0440fd5 1181 if (event.value.signals & SIG_DIO1) {
wamae 0:f930f0440fd5 1182 handle_dio1_irq();
wamae 0:f930f0440fd5 1183 }
wamae 0:f930f0440fd5 1184 if (event.value.signals & SIG_DIO2) {
wamae 0:f930f0440fd5 1185 handle_dio2_irq();
wamae 0:f930f0440fd5 1186 }
wamae 0:f930f0440fd5 1187 if (event.value.signals & SIG_DIO3) {
wamae 0:f930f0440fd5 1188 handle_dio3_irq();
wamae 0:f930f0440fd5 1189 }
wamae 0:f930f0440fd5 1190 if (event.value.signals & SIG_DIO4) {
wamae 0:f930f0440fd5 1191 handle_dio4_irq();
wamae 0:f930f0440fd5 1192 }
wamae 0:f930f0440fd5 1193 if (event.value.signals & SIG_DIO5) {
wamae 0:f930f0440fd5 1194 handle_dio5_irq();
wamae 0:f930f0440fd5 1195 }
wamae 0:f930f0440fd5 1196 if (event.value.signals & SIG_TIMOUT) {
wamae 0:f930f0440fd5 1197 handle_timeout_irq();
wamae 0:f930f0440fd5 1198 }
wamae 0:f930f0440fd5 1199 unlock();
wamae 0:f930f0440fd5 1200 }
wamae 0:f930f0440fd5 1201 }
wamae 0:f930f0440fd5 1202 #endif
wamae 0:f930f0440fd5 1203
wamae 0:f930f0440fd5 1204 /**
wamae 0:f930f0440fd5 1205 * Writes a single byte to a given register
wamae 0:f930f0440fd5 1206 */
wamae 0:f930f0440fd5 1207 void SX1276_LoRaRadio::write_to_register(uint8_t addr, uint8_t data)
wamae 0:f930f0440fd5 1208 {
wamae 0:f930f0440fd5 1209 write_to_register(addr, &data, 1);
wamae 0:f930f0440fd5 1210 }
wamae 0:f930f0440fd5 1211
wamae 0:f930f0440fd5 1212 /**
wamae 0:f930f0440fd5 1213 * Writes multiple bytes to a given register
wamae 0:f930f0440fd5 1214 */
wamae 0:f930f0440fd5 1215 void SX1276_LoRaRadio::write_to_register(uint8_t addr, uint8_t *data, uint8_t size)
wamae 0:f930f0440fd5 1216 {
wamae 0:f930f0440fd5 1217 // set chip-select low
wamae 0:f930f0440fd5 1218 _chip_select = 0;
wamae 0:f930f0440fd5 1219
wamae 0:f930f0440fd5 1220 // set write command
wamae 0:f930f0440fd5 1221 _spi.write(addr | SPI_WRITE_CMD);
wamae 0:f930f0440fd5 1222
wamae 0:f930f0440fd5 1223 // write data
wamae 0:f930f0440fd5 1224 for (uint8_t i = 0; i < size; i++) {
wamae 0:f930f0440fd5 1225 _spi.write(data[i]);
wamae 0:f930f0440fd5 1226 }
wamae 0:f930f0440fd5 1227
wamae 0:f930f0440fd5 1228 // set chip-select high
wamae 0:f930f0440fd5 1229 _chip_select = 1;
wamae 0:f930f0440fd5 1230 }
wamae 0:f930f0440fd5 1231
wamae 0:f930f0440fd5 1232 /**
wamae 0:f930f0440fd5 1233 * Reads the value of a single register
wamae 0:f930f0440fd5 1234 */
wamae 0:f930f0440fd5 1235 uint8_t SX1276_LoRaRadio::read_register(uint8_t addr)
wamae 0:f930f0440fd5 1236 {
wamae 0:f930f0440fd5 1237 uint8_t data;
wamae 0:f930f0440fd5 1238 read_register(addr, &data, 1);
wamae 0:f930f0440fd5 1239 return data;
wamae 0:f930f0440fd5 1240 }
wamae 0:f930f0440fd5 1241
wamae 0:f930f0440fd5 1242 /**
wamae 0:f930f0440fd5 1243 * Reads multiple values from a given register
wamae 0:f930f0440fd5 1244 */
wamae 0:f930f0440fd5 1245 void SX1276_LoRaRadio::read_register(uint8_t addr, uint8_t *buffer, uint8_t size)
wamae 0:f930f0440fd5 1246 {
wamae 0:f930f0440fd5 1247 // set chip-select low
wamae 0:f930f0440fd5 1248 _chip_select = 0;
wamae 0:f930f0440fd5 1249
wamae 0:f930f0440fd5 1250 // set read command
wamae 0:f930f0440fd5 1251 _spi.write(addr & SPI_READ_CMD);
wamae 0:f930f0440fd5 1252
wamae 0:f930f0440fd5 1253 // read buffers
wamae 0:f930f0440fd5 1254 for (uint8_t i = 0; i < size; i++) {
wamae 0:f930f0440fd5 1255 buffer[i] = _spi.write(0);
wamae 0:f930f0440fd5 1256 }
wamae 0:f930f0440fd5 1257
wamae 0:f930f0440fd5 1258 // set chip-select high
wamae 0:f930f0440fd5 1259 _chip_select = 1;
wamae 0:f930f0440fd5 1260 }
wamae 0:f930f0440fd5 1261
wamae 0:f930f0440fd5 1262 /**
wamae 0:f930f0440fd5 1263 * Writes to FIIO provided by the chip
wamae 0:f930f0440fd5 1264 */
wamae 0:f930f0440fd5 1265 void SX1276_LoRaRadio::write_fifo(uint8_t *buffer, uint8_t size)
wamae 0:f930f0440fd5 1266 {
wamae 0:f930f0440fd5 1267 write_to_register(0, buffer, size);
wamae 0:f930f0440fd5 1268 }
wamae 0:f930f0440fd5 1269
wamae 0:f930f0440fd5 1270 /**
wamae 0:f930f0440fd5 1271 * Reads from the FIFO provided by the chip
wamae 0:f930f0440fd5 1272 */
wamae 0:f930f0440fd5 1273 void SX1276_LoRaRadio::read_fifo(uint8_t *buffer, uint8_t size)
wamae 0:f930f0440fd5 1274 {
wamae 0:f930f0440fd5 1275 read_register(0, buffer, size);
wamae 0:f930f0440fd5 1276 }
wamae 0:f930f0440fd5 1277
wamae 0:f930f0440fd5 1278 /**
wamae 0:f930f0440fd5 1279 * Sets up operation mode
wamae 0:f930f0440fd5 1280 */
wamae 0:f930f0440fd5 1281 void SX1276_LoRaRadio::set_operation_mode(uint8_t mode)
wamae 0:f930f0440fd5 1282 {
wamae 0:f930f0440fd5 1283 if (mode == RF_OPMODE_SLEEP) {
wamae 0:f930f0440fd5 1284 set_low_power_mode();
wamae 0:f930f0440fd5 1285 } else {
wamae 0:f930f0440fd5 1286 set_low_power_mode();
wamae 0:f930f0440fd5 1287 set_antenna_switch(mode);
wamae 0:f930f0440fd5 1288 }
wamae 0:f930f0440fd5 1289
wamae 0:f930f0440fd5 1290 write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RF_OPMODE_MASK) | mode);
wamae 0:f930f0440fd5 1291 }
wamae 0:f930f0440fd5 1292
wamae 0:f930f0440fd5 1293 /**
wamae 0:f930f0440fd5 1294 * Sets the modem type to use
wamae 0:f930f0440fd5 1295 *
wamae 0:f930f0440fd5 1296 * At initialization FSK is chosen. Later stack or application
wamae 0:f930f0440fd5 1297 * can choose to change.
wamae 0:f930f0440fd5 1298 */
wamae 0:f930f0440fd5 1299 void SX1276_LoRaRadio::set_modem(uint8_t modem )
wamae 0:f930f0440fd5 1300 {
wamae 0:f930f0440fd5 1301 if ((read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON) != 0 ) {
wamae 0:f930f0440fd5 1302 _rf_settings.modem = MODEM_LORA;
wamae 0:f930f0440fd5 1303 } else {
wamae 0:f930f0440fd5 1304 _rf_settings.modem = MODEM_FSK;
wamae 0:f930f0440fd5 1305 }
wamae 0:f930f0440fd5 1306
wamae 0:f930f0440fd5 1307 if(_rf_settings.modem == modem ) {
wamae 0:f930f0440fd5 1308 // if the modem is already set
wamae 0:f930f0440fd5 1309 return;
wamae 0:f930f0440fd5 1310 }
wamae 0:f930f0440fd5 1311
wamae 0:f930f0440fd5 1312 _rf_settings.modem = modem;
wamae 0:f930f0440fd5 1313
wamae 0:f930f0440fd5 1314 switch(_rf_settings.modem)
wamae 0:f930f0440fd5 1315 {
wamae 0:f930f0440fd5 1316 default:
wamae 0:f930f0440fd5 1317 case MODEM_FSK:
wamae 0:f930f0440fd5 1318 // before changing modem mode, put the module to sleep
wamae 0:f930f0440fd5 1319 sleep();
wamae 0:f930f0440fd5 1320 write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK)
wamae 0:f930f0440fd5 1321 | RFLR_OPMODE_LONGRANGEMODE_OFF);
wamae 0:f930f0440fd5 1322
wamae 0:f930f0440fd5 1323 // Datasheet Tables 28, 29 DIO mapping
wamae 0:f930f0440fd5 1324 write_to_register(REG_DIOMAPPING1, 0x00); // sets DIO0-DI03 in default mode
wamae 0:f930f0440fd5 1325 write_to_register(REG_DIOMAPPING2, 0x30); // bits 4-5 are turned on i.e.,
wamae 0:f930f0440fd5 1326 // DIO5 and DIO4=ModeReady
wamae 0:f930f0440fd5 1327 break;
wamae 0:f930f0440fd5 1328 case MODEM_LORA:
wamae 0:f930f0440fd5 1329 sleep();
wamae 0:f930f0440fd5 1330 write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK)
wamae 0:f930f0440fd5 1331 | RFLR_OPMODE_LONGRANGEMODE_ON);
wamae 0:f930f0440fd5 1332
wamae 0:f930f0440fd5 1333 // Datasheet Tables 17 DIO mapping for LoRa
wamae 0:f930f0440fd5 1334 // set to defaults
wamae 0:f930f0440fd5 1335 write_to_register(REG_DIOMAPPING1, 0x00); // DIO0 - DIO3 defaults
wamae 0:f930f0440fd5 1336 write_to_register(REG_DIOMAPPING2, 0x00); // DIO4 - DIO5 defaults
wamae 0:f930f0440fd5 1337
wamae 0:f930f0440fd5 1338 break;
wamae 0:f930f0440fd5 1339 }
wamae 0:f930f0440fd5 1340 }
wamae 0:f930f0440fd5 1341
wamae 0:f930f0440fd5 1342 /**
wamae 0:f930f0440fd5 1343 * Set the radio module variant
wamae 0:f930f0440fd5 1344 */
wamae 0:f930f0440fd5 1345 void SX1276_LoRaRadio::set_sx1276_variant_type()
wamae 0:f930f0440fd5 1346 {
wamae 0:f930f0440fd5 1347 if (_rf_ctrls.ant_switch != NC) {
wamae 0:f930f0440fd5 1348 _ant_switch.input();
wamae 0:f930f0440fd5 1349 wait_ms(1);
wamae 0:f930f0440fd5 1350 if (_ant_switch == 1) {
wamae 0:f930f0440fd5 1351 radio_variant = SX1276MB1LAS;
wamae 0:f930f0440fd5 1352 } else {
wamae 0:f930f0440fd5 1353 radio_variant = SX1276MB1MAS;
wamae 0:f930f0440fd5 1354 }
wamae 0:f930f0440fd5 1355 _ant_switch.output();
wamae 0:f930f0440fd5 1356 wait_ms(1);
wamae 0:f930f0440fd5 1357 } else {
wamae 0:f930f0440fd5 1358 radio_variant = SX1276UNDEFINED;
wamae 0:f930f0440fd5 1359 }
wamae 0:f930f0440fd5 1360 }
wamae 0:f930f0440fd5 1361
wamae 0:f930f0440fd5 1362 /**
wamae 0:f930f0440fd5 1363 * Sets up frequency for SPI module
wamae 0:f930f0440fd5 1364 * Reference DataSheet: 4.3 SPI Interface
wamae 0:f930f0440fd5 1365 */
wamae 0:f930f0440fd5 1366 void SX1276_LoRaRadio::setup_spi()
wamae 0:f930f0440fd5 1367 {
wamae 0:f930f0440fd5 1368 // SPI bus frequency
wamae 0:f930f0440fd5 1369 uint32_t spi_freq = SPI_FREQUENCY;
wamae 0:f930f0440fd5 1370
wamae 0:f930f0440fd5 1371 // Hold chip-select high
wamae 0:f930f0440fd5 1372 _chip_select = 1;
wamae 0:f930f0440fd5 1373 _spi.format(8, 0);
wamae 0:f930f0440fd5 1374
wamae 0:f930f0440fd5 1375 #if defined (TARGET_KL25Z)
wamae 0:f930f0440fd5 1376 //bus-clock frequency is halved -> double the SPI frequency to compensate
wamae 0:f930f0440fd5 1377 _spi.frequency(spi_freq * 2);
wamae 0:f930f0440fd5 1378 #else
wamae 0:f930f0440fd5 1379 // otherwise use default SPI frequency which is 8 MHz
wamae 0:f930f0440fd5 1380 _spi.frequency(spi_freq);
wamae 0:f930f0440fd5 1381 #endif
wamae 0:f930f0440fd5 1382 // 100 us wait to settle down
wamae 0:f930f0440fd5 1383 wait(0.1);
wamae 0:f930f0440fd5 1384 }
wamae 0:f930f0440fd5 1385
wamae 0:f930f0440fd5 1386 /**
wamae 0:f930f0440fd5 1387 * Sets the radio registers to defaults
wamae 0:f930f0440fd5 1388 */
wamae 0:f930f0440fd5 1389 void SX1276_LoRaRadio::setup_registers()
wamae 0:f930f0440fd5 1390 {
wamae 0:f930f0440fd5 1391 for (unsigned int i = 0; i < sizeof(radio_reg_init) / sizeof(radio_registers_t); i++) {
wamae 0:f930f0440fd5 1392 set_modem(radio_reg_init[i].modem);
wamae 0:f930f0440fd5 1393 write_to_register(radio_reg_init[i].addr, radio_reg_init[i].value);
wamae 0:f930f0440fd5 1394 }
wamae 0:f930f0440fd5 1395 }
wamae 0:f930f0440fd5 1396
wamae 0:f930f0440fd5 1397 /**
wamae 0:f930f0440fd5 1398 * Performs the Rx chain calibration for LF and HF bands
wamae 0:f930f0440fd5 1399 *
wamae 0:f930f0440fd5 1400 * Must be called just after the reset so all registers are at their
wamae 0:f930f0440fd5 1401 * default values.
wamae 0:f930f0440fd5 1402 */
wamae 0:f930f0440fd5 1403 void SX1276_LoRaRadio::rx_chain_calibration(void)
wamae 0:f930f0440fd5 1404 {
wamae 0:f930f0440fd5 1405 uint8_t regPaConfigInitVal;
wamae 0:f930f0440fd5 1406 uint32_t initialFreq;
wamae 0:f930f0440fd5 1407
wamae 0:f930f0440fd5 1408 // Save context
wamae 0:f930f0440fd5 1409 regPaConfigInitVal = read_register( REG_PACONFIG );
wamae 0:f930f0440fd5 1410 initialFreq = ( double )( ( ( uint32_t )this->read_register( REG_FRFMSB ) << 16 ) |
wamae 0:f930f0440fd5 1411 ( ( uint32_t )this->read_register( REG_FRFMID ) << 8 ) |
wamae 0:f930f0440fd5 1412 ( ( uint32_t )this->read_register( REG_FRFLSB ) ) ) * ( double )FREQ_STEP;
wamae 0:f930f0440fd5 1413
wamae 0:f930f0440fd5 1414 // Cut the PA just in case, RFO output, power = -1 dBm
wamae 0:f930f0440fd5 1415 write_to_register( REG_PACONFIG, 0x00 );
wamae 0:f930f0440fd5 1416
wamae 0:f930f0440fd5 1417 // Launch Rx chain calibration for LF band
wamae 0:f930f0440fd5 1418 write_to_register (REG_IMAGECAL, (read_register(REG_IMAGECAL)
wamae 0:f930f0440fd5 1419 & RF_IMAGECAL_IMAGECAL_MASK)
wamae 0:f930f0440fd5 1420 | RF_IMAGECAL_IMAGECAL_START);
wamae 0:f930f0440fd5 1421 while((read_register(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING )
wamae 0:f930f0440fd5 1422 == RF_IMAGECAL_IMAGECAL_RUNNING )
wamae 0:f930f0440fd5 1423 {
wamae 0:f930f0440fd5 1424 }
wamae 0:f930f0440fd5 1425
wamae 0:f930f0440fd5 1426 // Sets a Frequency in HF band
wamae 0:f930f0440fd5 1427 set_channel(868000000);
wamae 0:f930f0440fd5 1428
wamae 0:f930f0440fd5 1429 // Launch Rx chain calibration for HF band
wamae 0:f930f0440fd5 1430 write_to_register (REG_IMAGECAL, (read_register(REG_IMAGECAL)
wamae 0:f930f0440fd5 1431 & RF_IMAGECAL_IMAGECAL_MASK )
wamae 0:f930f0440fd5 1432 | RF_IMAGECAL_IMAGECAL_START );
wamae 0:f930f0440fd5 1433 while((read_register(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING )
wamae 0:f930f0440fd5 1434 == RF_IMAGECAL_IMAGECAL_RUNNING )
wamae 0:f930f0440fd5 1435 {
wamae 0:f930f0440fd5 1436 // do nothing, just wait while rf image frequency calibration is done
wamae 0:f930f0440fd5 1437 }
wamae 0:f930f0440fd5 1438
wamae 0:f930f0440fd5 1439 // Restore context
wamae 0:f930f0440fd5 1440 write_to_register( REG_PACONFIG, regPaConfigInitVal );
wamae 0:f930f0440fd5 1441 set_channel(initialFreq);
wamae 0:f930f0440fd5 1442 }
wamae 0:f930f0440fd5 1443
wamae 0:f930f0440fd5 1444 /**
wamae 0:f930f0440fd5 1445 * Gets FSK bandwidth values
wamae 0:f930f0440fd5 1446 *
wamae 0:f930f0440fd5 1447 * Gives either normal bandwidths or bandwidths for
wamae 0:f930f0440fd5 1448 * AFC (auto frequency correction)
wamae 0:f930f0440fd5 1449 */
wamae 0:f930f0440fd5 1450 uint8_t SX1276_LoRaRadio::get_fsk_bw_reg_val(uint32_t bandwidth)
wamae 0:f930f0440fd5 1451 {
wamae 0:f930f0440fd5 1452 uint8_t i;
wamae 0:f930f0440fd5 1453
wamae 0:f930f0440fd5 1454 for (i = 0; i < (sizeof(fsk_bandwidths) / sizeof(fsk_bw_t)) - 1; i++) {
wamae 0:f930f0440fd5 1455 if ((bandwidth >= fsk_bandwidths[i].bandwidth)
wamae 0:f930f0440fd5 1456 && (bandwidth < fsk_bandwidths[i + 1].bandwidth)) {
wamae 0:f930f0440fd5 1457 return fsk_bandwidths[i].register_value;
wamae 0:f930f0440fd5 1458 }
wamae 0:f930f0440fd5 1459 }
wamae 0:f930f0440fd5 1460 // ERROR: Value not found
wamae 0:f930f0440fd5 1461 // This should never happen
wamae 0:f930f0440fd5 1462 while (1);
wamae 0:f930f0440fd5 1463 }
wamae 0:f930f0440fd5 1464
wamae 0:f930f0440fd5 1465 uint8_t SX1276_LoRaRadio::get_pa_conf_reg(uint32_t channel)
wamae 0:f930f0440fd5 1466 {
wamae 0:f930f0440fd5 1467 if (radio_variant == SX1276UNDEFINED) {
wamae 0:f930f0440fd5 1468 return RF_PACONFIG_PASELECT_PABOOST;
wamae 0:f930f0440fd5 1469 } else if (channel > RF_MID_BAND_THRESH) {
wamae 0:f930f0440fd5 1470 if (radio_variant == SX1276MB1LAS) {
wamae 0:f930f0440fd5 1471 return RF_PACONFIG_PASELECT_PABOOST;
wamae 0:f930f0440fd5 1472 } else {
wamae 0:f930f0440fd5 1473 return RF_PACONFIG_PASELECT_RFO;
wamae 0:f930f0440fd5 1474 }
wamae 0:f930f0440fd5 1475 } else {
wamae 0:f930f0440fd5 1476 return RF_PACONFIG_PASELECT_RFO;
wamae 0:f930f0440fd5 1477 }
wamae 0:f930f0440fd5 1478 }
wamae 0:f930f0440fd5 1479
wamae 0:f930f0440fd5 1480 /**
wamae 0:f930f0440fd5 1481 * Sets the transmit power for the module
wamae 0:f930f0440fd5 1482 */
wamae 0:f930f0440fd5 1483 void SX1276_LoRaRadio::set_rf_tx_power(int8_t power)
wamae 0:f930f0440fd5 1484 {
wamae 0:f930f0440fd5 1485
wamae 0:f930f0440fd5 1486 uint8_t paConfig = 0;
wamae 0:f930f0440fd5 1487 uint8_t paDac = 0;
wamae 0:f930f0440fd5 1488
wamae 0:f930f0440fd5 1489 paConfig = read_register(REG_PACONFIG);
wamae 0:f930f0440fd5 1490 paDac = read_register(REG_PADAC);
wamae 0:f930f0440fd5 1491
wamae 0:f930f0440fd5 1492 paConfig = (paConfig & RF_PACONFIG_PASELECT_MASK) | get_pa_conf_reg(_rf_settings.channel);
wamae 0:f930f0440fd5 1493 paConfig = (paConfig & RF_PACONFIG_MAX_POWER_MASK) | 0x70;
wamae 0:f930f0440fd5 1494
wamae 0:f930f0440fd5 1495 if ((paConfig & RF_PACONFIG_PASELECT_PABOOST) == RF_PACONFIG_PASELECT_PABOOST) {
wamae 0:f930f0440fd5 1496 if (power > 17) {
wamae 0:f930f0440fd5 1497 paDac = (paDac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_ON;
wamae 0:f930f0440fd5 1498 } else {
wamae 0:f930f0440fd5 1499 paDac = (paDac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_OFF;
wamae 0:f930f0440fd5 1500 }
wamae 0:f930f0440fd5 1501 if ((paDac & RF_PADAC_20DBM_ON) == RF_PADAC_20DBM_ON) {
wamae 0:f930f0440fd5 1502 if (power < 5) {
wamae 0:f930f0440fd5 1503 power = 5;
wamae 0:f930f0440fd5 1504 }
wamae 0:f930f0440fd5 1505 if (power > 20) {
wamae 0:f930f0440fd5 1506 power = 20;
wamae 0:f930f0440fd5 1507 }
wamae 0:f930f0440fd5 1508 paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK)
wamae 0:f930f0440fd5 1509 | (uint8_t) ((uint16_t) (power - 5) & 0x0F);
wamae 0:f930f0440fd5 1510 } else {
wamae 0:f930f0440fd5 1511 if (power < 2) {
wamae 0:f930f0440fd5 1512 power = 2;
wamae 0:f930f0440fd5 1513 }
wamae 0:f930f0440fd5 1514 if (power > 17) {
wamae 0:f930f0440fd5 1515 power = 17;
wamae 0:f930f0440fd5 1516 }
wamae 0:f930f0440fd5 1517 paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK)
wamae 0:f930f0440fd5 1518 | (uint8_t) ((uint16_t) (power - 2) & 0x0F);
wamae 0:f930f0440fd5 1519 }
wamae 0:f930f0440fd5 1520 } else {
wamae 0:f930f0440fd5 1521 if (power < -1) {
wamae 0:f930f0440fd5 1522 power = -1;
wamae 0:f930f0440fd5 1523 }
wamae 0:f930f0440fd5 1524 if (power > 14) {
wamae 0:f930f0440fd5 1525 power = 14;
wamae 0:f930f0440fd5 1526 }
wamae 0:f930f0440fd5 1527 paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK)
wamae 0:f930f0440fd5 1528 | (uint8_t) ((uint16_t) (power + 1) & 0x0F);
wamae 0:f930f0440fd5 1529 }
wamae 0:f930f0440fd5 1530 write_to_register( REG_PACONFIG, paConfig);
wamae 0:f930f0440fd5 1531 write_to_register( REG_PADAC, paDac);
wamae 0:f930f0440fd5 1532 }
wamae 0:f930f0440fd5 1533
wamae 0:f930f0440fd5 1534 /**
wamae 0:f930f0440fd5 1535 * Actual TX - Transmit routine
wamae 0:f930f0440fd5 1536 *
wamae 0:f930f0440fd5 1537 * A DIO0 interrupt let the state machine know that a a packet is
wamae 0:f930f0440fd5 1538 * successfully sent, otherwise a TxTimeout is invoked.
wamae 0:f930f0440fd5 1539 * TxTimeout should never happen in normal circumstances as the radio should
wamae 0:f930f0440fd5 1540 * be able to send a packet out in the air no matter what.
wamae 0:f930f0440fd5 1541 */
wamae 0:f930f0440fd5 1542 void SX1276_LoRaRadio::transmit(uint32_t timeout)
wamae 0:f930f0440fd5 1543 {
wamae 0:f930f0440fd5 1544 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 1545
wamae 0:f930f0440fd5 1546 case MODEM_FSK:
wamae 0:f930f0440fd5 1547 // DIO0=PacketSent
wamae 0:f930f0440fd5 1548 // DIO1=FifoEmpty
wamae 0:f930f0440fd5 1549 // DIO2=FifoFull
wamae 0:f930f0440fd5 1550 // DIO3=FifoEmpty
wamae 0:f930f0440fd5 1551 // DIO4=LowBat
wamae 0:f930f0440fd5 1552 // DIO5=ModeReady
wamae 0:f930f0440fd5 1553 write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) &
wamae 0:f930f0440fd5 1554 RF_DIOMAPPING1_DIO0_MASK &
wamae 0:f930f0440fd5 1555 RF_DIOMAPPING1_DIO1_MASK &
wamae 0:f930f0440fd5 1556 RF_DIOMAPPING1_DIO2_MASK) |
wamae 0:f930f0440fd5 1557 RF_DIOMAPPING1_DIO1_01);
wamae 0:f930f0440fd5 1558
wamae 0:f930f0440fd5 1559 write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) &
wamae 0:f930f0440fd5 1560 RF_DIOMAPPING2_DIO4_MASK &
wamae 0:f930f0440fd5 1561 RF_DIOMAPPING2_MAP_MASK));
wamae 0:f930f0440fd5 1562 _rf_settings.fsk_packet_handler.fifo_thresh =
wamae 0:f930f0440fd5 1563 read_register(REG_FIFOTHRESH) & 0x3F;
wamae 0:f930f0440fd5 1564
wamae 0:f930f0440fd5 1565 break;
wamae 0:f930f0440fd5 1566
wamae 0:f930f0440fd5 1567 case MODEM_LORA:
wamae 0:f930f0440fd5 1568
wamae 0:f930f0440fd5 1569 if (_rf_settings.lora.freq_hop_on == true) {
wamae 0:f930f0440fd5 1570 write_to_register(REG_LR_IRQFLAGSMASK,
wamae 0:f930f0440fd5 1571 RFLR_IRQFLAGS_RXTIMEOUT |
wamae 0:f930f0440fd5 1572 RFLR_IRQFLAGS_RXDONE |
wamae 0:f930f0440fd5 1573 RFLR_IRQFLAGS_PAYLOADCRCERROR |
wamae 0:f930f0440fd5 1574 RFLR_IRQFLAGS_VALIDHEADER |
wamae 0:f930f0440fd5 1575 RFLR_IRQFLAGS_CADDONE |
wamae 0:f930f0440fd5 1576 RFLR_IRQFLAGS_CADDETECTED);
wamae 0:f930f0440fd5 1577
wamae 0:f930f0440fd5 1578 // DIO0=tx_done, DIO2=fhss_change_channel
wamae 0:f930f0440fd5 1579
wamae 0:f930f0440fd5 1580 write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) &
wamae 0:f930f0440fd5 1581 RFLR_DIOMAPPING1_DIO0_MASK &
wamae 0:f930f0440fd5 1582 RFLR_DIOMAPPING1_DIO2_MASK) |
wamae 0:f930f0440fd5 1583 RFLR_DIOMAPPING1_DIO0_01 |
wamae 0:f930f0440fd5 1584 RFLR_DIOMAPPING1_DIO2_00);
wamae 0:f930f0440fd5 1585 } else {
wamae 0:f930f0440fd5 1586 write_to_register(REG_LR_IRQFLAGSMASK,
wamae 0:f930f0440fd5 1587 RFLR_IRQFLAGS_RXTIMEOUT |
wamae 0:f930f0440fd5 1588 RFLR_IRQFLAGS_RXDONE |
wamae 0:f930f0440fd5 1589 RFLR_IRQFLAGS_PAYLOADCRCERROR |
wamae 0:f930f0440fd5 1590 RFLR_IRQFLAGS_VALIDHEADER |
wamae 0:f930f0440fd5 1591 RFLR_IRQFLAGS_CADDONE |
wamae 0:f930f0440fd5 1592 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
wamae 0:f930f0440fd5 1593 RFLR_IRQFLAGS_CADDETECTED);
wamae 0:f930f0440fd5 1594
wamae 0:f930f0440fd5 1595 // DIO0=tx_done
wamae 0:f930f0440fd5 1596 write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) &
wamae 0:f930f0440fd5 1597 RFLR_DIOMAPPING1_DIO0_MASK) |
wamae 0:f930f0440fd5 1598 RFLR_DIOMAPPING1_DIO0_01);
wamae 0:f930f0440fd5 1599 }
wamae 0:f930f0440fd5 1600
wamae 0:f930f0440fd5 1601 break;
wamae 0:f930f0440fd5 1602 }
wamae 0:f930f0440fd5 1603
wamae 0:f930f0440fd5 1604 _rf_settings.state = RF_TX_RUNNING;
wamae 0:f930f0440fd5 1605 tx_timeout_timer.attach_us(callback(this,
wamae 0:f930f0440fd5 1606 &SX1276_LoRaRadio::timeout_irq_isr), timeout*1e3);
wamae 0:f930f0440fd5 1607 set_operation_mode(RF_OPMODE_TRANSMITTER);
wamae 0:f930f0440fd5 1608 }
wamae 0:f930f0440fd5 1609
wamae 0:f930f0440fd5 1610 /**
wamae 0:f930f0440fd5 1611 * Get RSSI from the module
wamae 0:f930f0440fd5 1612 */
wamae 0:f930f0440fd5 1613 int16_t SX1276_LoRaRadio::get_rssi(radio_modems_t modem)
wamae 0:f930f0440fd5 1614 {
wamae 0:f930f0440fd5 1615 int16_t rssi = 0;
wamae 0:f930f0440fd5 1616
wamae 0:f930f0440fd5 1617 switch (modem) {
wamae 0:f930f0440fd5 1618 case MODEM_FSK:
wamae 0:f930f0440fd5 1619 rssi = -(read_register(REG_RSSIVALUE) >> 1);
wamae 0:f930f0440fd5 1620 break;
wamae 0:f930f0440fd5 1621 case MODEM_LORA:
wamae 0:f930f0440fd5 1622 if (_rf_settings.channel > RF_MID_BAND_THRESH) {
wamae 0:f930f0440fd5 1623 rssi = RSSI_OFFSET_HF + read_register(REG_LR_RSSIVALUE);
wamae 0:f930f0440fd5 1624 } else {
wamae 0:f930f0440fd5 1625 rssi = RSSI_OFFSET_LF + read_register(REG_LR_RSSIVALUE);
wamae 0:f930f0440fd5 1626 }
wamae 0:f930f0440fd5 1627 break;
wamae 0:f930f0440fd5 1628 default:
wamae 0:f930f0440fd5 1629 rssi = -1;
wamae 0:f930f0440fd5 1630 break;
wamae 0:f930f0440fd5 1631 }
wamae 0:f930f0440fd5 1632 return rssi;
wamae 0:f930f0440fd5 1633 }
wamae 0:f930f0440fd5 1634
wamae 0:f930f0440fd5 1635 /**
wamae 0:f930f0440fd5 1636 * Sets the module in low power mode by disconnecting
wamae 0:f930f0440fd5 1637 * TX and RX submodules, turning off power amplifier etc.
wamae 0:f930f0440fd5 1638 */
wamae 0:f930f0440fd5 1639 void SX1276_LoRaRadio::set_low_power_mode()
wamae 0:f930f0440fd5 1640 {
wamae 0:f930f0440fd5 1641
wamae 0:f930f0440fd5 1642 if (_rf_ctrls.rf_switch_ctl1 != NC) {
wamae 0:f930f0440fd5 1643 _rf_switch_ctl1 = 0;
wamae 0:f930f0440fd5 1644 }
wamae 0:f930f0440fd5 1645
wamae 0:f930f0440fd5 1646 if (_rf_ctrls.rf_switch_ctl2 != NC) {
wamae 0:f930f0440fd5 1647 _rf_switch_ctl2 = 0;
wamae 0:f930f0440fd5 1648 }
wamae 0:f930f0440fd5 1649
wamae 0:f930f0440fd5 1650 if (_rf_ctrls.pwr_amp_ctl != NC) {
wamae 0:f930f0440fd5 1651 _pwr_amp_ctl = 0;
wamae 0:f930f0440fd5 1652 }
wamae 0:f930f0440fd5 1653
wamae 0:f930f0440fd5 1654 if (_rf_ctrls.txctl != NC) {
wamae 0:f930f0440fd5 1655 _txctl = 0;
wamae 0:f930f0440fd5 1656 }
wamae 0:f930f0440fd5 1657
wamae 0:f930f0440fd5 1658 if (_rf_ctrls.txctl != NC) {
wamae 0:f930f0440fd5 1659 _rxctl = 0;
wamae 0:f930f0440fd5 1660 }
wamae 0:f930f0440fd5 1661
wamae 0:f930f0440fd5 1662 if (_rf_ctrls.ant_switch != NC) {
wamae 0:f930f0440fd5 1663 _ant_switch = 0;
wamae 0:f930f0440fd5 1664 }
wamae 0:f930f0440fd5 1665 }
wamae 0:f930f0440fd5 1666
wamae 0:f930f0440fd5 1667 /**
wamae 0:f930f0440fd5 1668 * Attaches ISRs to interrupt pins
wamae 0:f930f0440fd5 1669 */
wamae 0:f930f0440fd5 1670 void SX1276_LoRaRadio::setup_interrupts()
wamae 0:f930f0440fd5 1671 {
wamae 0:f930f0440fd5 1672 _dio0_ctl.rise(callback(this, &SX1276_LoRaRadio::dio0_irq_isr));
wamae 0:f930f0440fd5 1673 _dio1_ctl.rise(callback(this, &SX1276_LoRaRadio::dio1_irq_isr));
wamae 0:f930f0440fd5 1674 _dio2_ctl.rise(callback(this, &SX1276_LoRaRadio::dio2_irq_isr));
wamae 0:f930f0440fd5 1675 _dio3_ctl.rise(callback(this, &SX1276_LoRaRadio::dio3_irq_isr));
wamae 0:f930f0440fd5 1676 if (_dio4_pin != NC) {
wamae 0:f930f0440fd5 1677 _dio4_ctl.rise(callback(this, &SX1276_LoRaRadio::dio4_irq_isr));
wamae 0:f930f0440fd5 1678 }
wamae 0:f930f0440fd5 1679 if (_dio5_pin != NC) {
wamae 0:f930f0440fd5 1680 _dio5_ctl.rise(callback(this, &SX1276_LoRaRadio::dio5_irq_isr));
wamae 0:f930f0440fd5 1681 }
wamae 0:f930f0440fd5 1682 }
wamae 0:f930f0440fd5 1683
wamae 0:f930f0440fd5 1684 /**
wamae 0:f930f0440fd5 1685 * Sets up radio latch position according to the
wamae 0:f930f0440fd5 1686 * radio mode
wamae 0:f930f0440fd5 1687 */
wamae 0:f930f0440fd5 1688 void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode)
wamae 0:f930f0440fd5 1689 {
wamae 0:f930f0440fd5 1690 // here we got to do ifdef for changing controls
wamae 0:f930f0440fd5 1691 // as some pins might be NC
wamae 0:f930f0440fd5 1692 switch (mode) {
wamae 0:f930f0440fd5 1693 case RFLR_OPMODE_TRANSMITTER:
wamae 0:f930f0440fd5 1694 if (_rf_ctrls.rf_switch_ctl1 != NC
wamae 0:f930f0440fd5 1695 && _rf_ctrls.rf_switch_ctl2 != NC) {
wamae 0:f930f0440fd5 1696 // module is in transmit mode and RF latch switches
wamae 0:f930f0440fd5 1697 // are connected. Check if power amplifier boost is
wamae 0:f930f0440fd5 1698 // setup or not
wamae 0:f930f0440fd5 1699 if ((read_register(REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST)
wamae 0:f930f0440fd5 1700 == RF_PACONFIG_PASELECT_PABOOST) {
wamae 0:f930f0440fd5 1701 _rf_switch_ctl1 = 1;
wamae 0:f930f0440fd5 1702 _rf_switch_ctl2 = 0;
wamae 0:f930f0440fd5 1703 } else {
wamae 0:f930f0440fd5 1704 // power amplifier not selected
wamae 0:f930f0440fd5 1705 _rf_switch_ctl1 = 0;
wamae 0:f930f0440fd5 1706 _rf_switch_ctl2 = 1;
wamae 0:f930f0440fd5 1707 }
wamae 0:f930f0440fd5 1708 }
wamae 0:f930f0440fd5 1709 if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) {
wamae 0:f930f0440fd5 1710 // module is in transmit mode and tx/rx submodule control
wamae 0:f930f0440fd5 1711 // pins are connected
wamae 0:f930f0440fd5 1712 if (_rf_ctrls.pwr_amp_ctl != NC) {
wamae 0:f930f0440fd5 1713 if (read_register(REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST) {
wamae 0:f930f0440fd5 1714 _pwr_amp_ctl = 1;
wamae 0:f930f0440fd5 1715 _txctl = 0;
wamae 0:f930f0440fd5 1716 } else {
wamae 0:f930f0440fd5 1717 _pwr_amp_ctl = 0;
wamae 0:f930f0440fd5 1718 _txctl = 1;
wamae 0:f930f0440fd5 1719 }
wamae 0:f930f0440fd5 1720 } else {
wamae 0:f930f0440fd5 1721 _txctl = 1;
wamae 0:f930f0440fd5 1722 }
wamae 0:f930f0440fd5 1723 _rxctl = 0;
wamae 0:f930f0440fd5 1724 }
wamae 0:f930f0440fd5 1725 if (_rf_ctrls.ant_switch != NC){
wamae 0:f930f0440fd5 1726 _ant_switch = 1;
wamae 0:f930f0440fd5 1727 }
wamae 0:f930f0440fd5 1728 break;
wamae 0:f930f0440fd5 1729 case RFLR_OPMODE_RECEIVER:
wamae 0:f930f0440fd5 1730 case RFLR_OPMODE_RECEIVER_SINGLE:
wamae 0:f930f0440fd5 1731 case RFLR_OPMODE_CAD:
wamae 0:f930f0440fd5 1732 if (_rf_ctrls.rf_switch_ctl1 != NC
wamae 0:f930f0440fd5 1733 && _rf_ctrls.rf_switch_ctl2 != NC) {
wamae 0:f930f0440fd5 1734 // radio is in reception or CAD mode and RF latch switches
wamae 0:f930f0440fd5 1735 // are connected
wamae 0:f930f0440fd5 1736 _rf_switch_ctl1 = 1;
wamae 0:f930f0440fd5 1737 _rf_switch_ctl2 = 1;
wamae 0:f930f0440fd5 1738 }
wamae 0:f930f0440fd5 1739 if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) {
wamae 0:f930f0440fd5 1740 _txctl = 0;
wamae 0:f930f0440fd5 1741 _rxctl = 1;
wamae 0:f930f0440fd5 1742 }
wamae 0:f930f0440fd5 1743 if (_rf_ctrls.ant_switch != NC) {
wamae 0:f930f0440fd5 1744 _ant_switch = 0;
wamae 0:f930f0440fd5 1745 }
wamae 0:f930f0440fd5 1746 if (_rf_ctrls.pwr_amp_ctl != NC) {
wamae 0:f930f0440fd5 1747 _pwr_amp_ctl = 0;
wamae 0:f930f0440fd5 1748 }
wamae 0:f930f0440fd5 1749 break;
wamae 0:f930f0440fd5 1750 default:
wamae 0:f930f0440fd5 1751 // Enforce default case when any connected control pin is kept low.
wamae 0:f930f0440fd5 1752 if (_rf_ctrls.rf_switch_ctl1 != NC
wamae 0:f930f0440fd5 1753 && _rf_ctrls.rf_switch_ctl2 != NC) {
wamae 0:f930f0440fd5 1754 // radio is in reception or CAD mode and RF latch switches
wamae 0:f930f0440fd5 1755 // are connected
wamae 0:f930f0440fd5 1756 _rf_switch_ctl1 = 0;
wamae 0:f930f0440fd5 1757 _rf_switch_ctl2 = 0;
wamae 0:f930f0440fd5 1758 }
wamae 0:f930f0440fd5 1759 if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) {
wamae 0:f930f0440fd5 1760 _txctl = 0;
wamae 0:f930f0440fd5 1761 _rxctl = 0;
wamae 0:f930f0440fd5 1762 }
wamae 0:f930f0440fd5 1763 if (_rf_ctrls.ant_switch != NC) {
wamae 0:f930f0440fd5 1764 _ant_switch = 0;
wamae 0:f930f0440fd5 1765 }
wamae 0:f930f0440fd5 1766 if (_rf_ctrls.pwr_amp_ctl != NC) {
wamae 0:f930f0440fd5 1767 _pwr_amp_ctl = 0;
wamae 0:f930f0440fd5 1768 }
wamae 0:f930f0440fd5 1769 break;
wamae 0:f930f0440fd5 1770 }
wamae 0:f930f0440fd5 1771 }
wamae 0:f930f0440fd5 1772
wamae 0:f930f0440fd5 1773 /*****************************************************************************
wamae 0:f930f0440fd5 1774 * Interrupt service routines (ISRs) - set signals to the irq_thread *
wamae 0:f930f0440fd5 1775 ****************************************************************************/
wamae 0:f930f0440fd5 1776 void SX1276_LoRaRadio::dio0_irq_isr()
wamae 0:f930f0440fd5 1777 {
wamae 0:f930f0440fd5 1778 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 1779 irq_thread.signal_set(SIG_DIO0);
wamae 0:f930f0440fd5 1780 #else
wamae 0:f930f0440fd5 1781 handle_dio0_irq();
wamae 0:f930f0440fd5 1782 #endif
wamae 0:f930f0440fd5 1783 }
wamae 0:f930f0440fd5 1784
wamae 0:f930f0440fd5 1785 void SX1276_LoRaRadio::dio1_irq_isr()
wamae 0:f930f0440fd5 1786 {
wamae 0:f930f0440fd5 1787 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 1788 irq_thread.signal_set(SIG_DIO1);
wamae 0:f930f0440fd5 1789 #else
wamae 0:f930f0440fd5 1790 handle_dio1_irq();
wamae 0:f930f0440fd5 1791 #endif
wamae 0:f930f0440fd5 1792 }
wamae 0:f930f0440fd5 1793
wamae 0:f930f0440fd5 1794 void SX1276_LoRaRadio::dio2_irq_isr()
wamae 0:f930f0440fd5 1795 {
wamae 0:f930f0440fd5 1796 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 1797 irq_thread.signal_set(SIG_DIO2);
wamae 0:f930f0440fd5 1798 #else
wamae 0:f930f0440fd5 1799 handle_dio2_irq();
wamae 0:f930f0440fd5 1800 #endif
wamae 0:f930f0440fd5 1801 }
wamae 0:f930f0440fd5 1802
wamae 0:f930f0440fd5 1803 void SX1276_LoRaRadio::dio3_irq_isr()
wamae 0:f930f0440fd5 1804 {
wamae 0:f930f0440fd5 1805 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 1806 irq_thread.signal_set(SIG_DIO3);
wamae 0:f930f0440fd5 1807 #else
wamae 0:f930f0440fd5 1808 handle_dio3_irq();
wamae 0:f930f0440fd5 1809 #endif
wamae 0:f930f0440fd5 1810 }
wamae 0:f930f0440fd5 1811
wamae 0:f930f0440fd5 1812 void SX1276_LoRaRadio::dio4_irq_isr()
wamae 0:f930f0440fd5 1813 {
wamae 0:f930f0440fd5 1814 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 1815 irq_thread.signal_set(SIG_DIO4);
wamae 0:f930f0440fd5 1816 #else
wamae 0:f930f0440fd5 1817 handle_dio4_irq();
wamae 0:f930f0440fd5 1818 #endif
wamae 0:f930f0440fd5 1819 }
wamae 0:f930f0440fd5 1820
wamae 0:f930f0440fd5 1821 void SX1276_LoRaRadio::dio5_irq_isr()
wamae 0:f930f0440fd5 1822 {
wamae 0:f930f0440fd5 1823 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 1824 irq_thread.signal_set(SIG_DIO5);
wamae 0:f930f0440fd5 1825 #else
wamae 0:f930f0440fd5 1826 handle_dio5_irq();
wamae 0:f930f0440fd5 1827 #endif
wamae 0:f930f0440fd5 1828 }
wamae 0:f930f0440fd5 1829
wamae 0:f930f0440fd5 1830 // This is not a hardware interrupt
wamae 0:f930f0440fd5 1831 // we invoke it ourselves based upon
wamae 0:f930f0440fd5 1832 // our timers
wamae 0:f930f0440fd5 1833 void SX1276_LoRaRadio::timeout_irq_isr()
wamae 0:f930f0440fd5 1834 {
wamae 0:f930f0440fd5 1835 #ifdef MBED_CONF_RTOS_PRESENT
wamae 0:f930f0440fd5 1836 irq_thread.signal_set(SIG_TIMOUT);
wamae 0:f930f0440fd5 1837 #else
wamae 0:f930f0440fd5 1838 handle_timeout_irq();
wamae 0:f930f0440fd5 1839 #endif
wamae 0:f930f0440fd5 1840 }
wamae 0:f930f0440fd5 1841
wamae 0:f930f0440fd5 1842 /******************************************************************************
wamae 0:f930f0440fd5 1843 * Interrupt Handlers *
wamae 0:f930f0440fd5 1844 *****************************************************************************/
wamae 0:f930f0440fd5 1845
wamae 0:f930f0440fd5 1846 void SX1276_LoRaRadio::handle_dio0_irq()
wamae 0:f930f0440fd5 1847 {
wamae 0:f930f0440fd5 1848 volatile uint8_t irqFlags = 0;
wamae 0:f930f0440fd5 1849
wamae 0:f930f0440fd5 1850 switch (_rf_settings.state) {
wamae 0:f930f0440fd5 1851 case RF_RX_RUNNING:
wamae 0:f930f0440fd5 1852 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 1853 case MODEM_FSK:
wamae 0:f930f0440fd5 1854 if (_rf_settings.fsk.crc_on == true) {
wamae 0:f930f0440fd5 1855 irqFlags = read_register(REG_IRQFLAGS2);
wamae 0:f930f0440fd5 1856 if ((irqFlags & RF_IRQFLAGS2_CRCOK)
wamae 0:f930f0440fd5 1857 != RF_IRQFLAGS2_CRCOK) {
wamae 0:f930f0440fd5 1858 // Clear Irqs
wamae 0:f930f0440fd5 1859 write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
wamae 0:f930f0440fd5 1860 RF_IRQFLAGS1_PREAMBLEDETECT |
wamae 0:f930f0440fd5 1861 RF_IRQFLAGS1_SYNCADDRESSMATCH);
wamae 0:f930f0440fd5 1862 write_to_register(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN);
wamae 0:f930f0440fd5 1863
wamae 0:f930f0440fd5 1864
wamae 0:f930f0440fd5 1865 if (_rf_settings.fsk.rx_continuous == false) {
wamae 0:f930f0440fd5 1866 rx_timeout_sync_word.detach();
wamae 0:f930f0440fd5 1867 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 1868 } else {
wamae 0:f930f0440fd5 1869 // Continuous mode restart Rx chain
wamae 0:f930f0440fd5 1870 write_to_register(REG_RXCONFIG,
wamae 0:f930f0440fd5 1871 read_register(REG_RXCONFIG) |
wamae 0:f930f0440fd5 1872 RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
wamae 0:f930f0440fd5 1873 }
wamae 0:f930f0440fd5 1874
wamae 0:f930f0440fd5 1875 rx_timeout_timer.detach();
wamae 0:f930f0440fd5 1876
wamae 0:f930f0440fd5 1877 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 1878 && (_radio_events->rx_error)) {
wamae 0:f930f0440fd5 1879 _radio_events->rx_error();
wamae 0:f930f0440fd5 1880 }
wamae 0:f930f0440fd5 1881 _rf_settings.fsk_packet_handler.preamble_detected = 0;
wamae 0:f930f0440fd5 1882 _rf_settings.fsk_packet_handler.sync_word_detected = 0;
wamae 0:f930f0440fd5 1883 _rf_settings.fsk_packet_handler.nb_bytes = 0;
wamae 0:f930f0440fd5 1884 _rf_settings.fsk_packet_handler.size = 0;
wamae 0:f930f0440fd5 1885 // break from here, a CRC error happened, RX_ERROR
wamae 0:f930f0440fd5 1886 // was notified. No need to go any further
wamae 0:f930f0440fd5 1887 break;
wamae 0:f930f0440fd5 1888 }
wamae 0:f930f0440fd5 1889 }
wamae 0:f930f0440fd5 1890
wamae 0:f930f0440fd5 1891 // Read received packet size
wamae 0:f930f0440fd5 1892 if ((_rf_settings.fsk_packet_handler.size == 0)
wamae 0:f930f0440fd5 1893 && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) {
wamae 0:f930f0440fd5 1894 if (_rf_settings.fsk.fix_len == false) {
wamae 0:f930f0440fd5 1895 read_fifo((uint8_t*) &_rf_settings.fsk_packet_handler.size, 1);
wamae 0:f930f0440fd5 1896 } else {
wamae 0:f930f0440fd5 1897 _rf_settings.fsk_packet_handler.size = read_register(REG_PAYLOADLENGTH);
wamae 0:f930f0440fd5 1898 }
wamae 0:f930f0440fd5 1899 read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes,
wamae 0:f930f0440fd5 1900 _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes);
wamae 0:f930f0440fd5 1901 _rf_settings.fsk_packet_handler.nb_bytes +=
wamae 0:f930f0440fd5 1902 (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes);
wamae 0:f930f0440fd5 1903 } else {
wamae 0:f930f0440fd5 1904 read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes,
wamae 0:f930f0440fd5 1905 _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes);
wamae 0:f930f0440fd5 1906 _rf_settings.fsk_packet_handler.nb_bytes +=
wamae 0:f930f0440fd5 1907 (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes);
wamae 0:f930f0440fd5 1908 }
wamae 0:f930f0440fd5 1909
wamae 0:f930f0440fd5 1910 if (_rf_settings.fsk.rx_continuous == false) {
wamae 0:f930f0440fd5 1911 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 1912 rx_timeout_sync_word.detach();
wamae 0:f930f0440fd5 1913 } else {
wamae 0:f930f0440fd5 1914 // Continuous mode restart Rx chain
wamae 0:f930f0440fd5 1915 write_to_register(REG_RXCONFIG, read_register(REG_RXCONFIG)
wamae 0:f930f0440fd5 1916 | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
wamae 0:f930f0440fd5 1917 }
wamae 0:f930f0440fd5 1918
wamae 0:f930f0440fd5 1919 rx_timeout_timer.detach();
wamae 0:f930f0440fd5 1920
wamae 0:f930f0440fd5 1921 if ((_radio_events != NULL) && (_radio_events->rx_done)) {
wamae 0:f930f0440fd5 1922 _radio_events->rx_done(
wamae 0:f930f0440fd5 1923 _data_buffer,
wamae 0:f930f0440fd5 1924 _rf_settings.fsk_packet_handler.size,
wamae 0:f930f0440fd5 1925 _rf_settings.fsk_packet_handler.rssi_value, 0);
wamae 0:f930f0440fd5 1926 }
wamae 0:f930f0440fd5 1927 _rf_settings.fsk_packet_handler.preamble_detected = 0;
wamae 0:f930f0440fd5 1928 _rf_settings.fsk_packet_handler.sync_word_detected = 0;
wamae 0:f930f0440fd5 1929 _rf_settings.fsk_packet_handler.nb_bytes = 0;
wamae 0:f930f0440fd5 1930 _rf_settings.fsk_packet_handler.size = 0;
wamae 0:f930f0440fd5 1931 break;
wamae 0:f930f0440fd5 1932
wamae 0:f930f0440fd5 1933 case MODEM_LORA: {
wamae 0:f930f0440fd5 1934 int8_t snr = 0;
wamae 0:f930f0440fd5 1935
wamae 0:f930f0440fd5 1936 // Clear Irq
wamae 0:f930f0440fd5 1937 write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE);
wamae 0:f930f0440fd5 1938
wamae 0:f930f0440fd5 1939 irqFlags = read_register(REG_LR_IRQFLAGS);
wamae 0:f930f0440fd5 1940 if ((irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK)
wamae 0:f930f0440fd5 1941 == RFLR_IRQFLAGS_PAYLOADCRCERROR) {
wamae 0:f930f0440fd5 1942 // Clear Irq
wamae 0:f930f0440fd5 1943 write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR);
wamae 0:f930f0440fd5 1944
wamae 0:f930f0440fd5 1945 if (_rf_settings.lora.rx_continuous == false) {
wamae 0:f930f0440fd5 1946 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 1947 }
wamae 0:f930f0440fd5 1948 rx_timeout_timer.detach();
wamae 0:f930f0440fd5 1949
wamae 0:f930f0440fd5 1950 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 1951 && (_radio_events->rx_error)) {
wamae 0:f930f0440fd5 1952 _radio_events->rx_error();
wamae 0:f930f0440fd5 1953 }
wamae 0:f930f0440fd5 1954 break;
wamae 0:f930f0440fd5 1955 }
wamae 0:f930f0440fd5 1956
wamae 0:f930f0440fd5 1957 _rf_settings.lora_packet_handler.snr_value = read_register(
wamae 0:f930f0440fd5 1958 REG_LR_PKTSNRVALUE);
wamae 0:f930f0440fd5 1959 if (_rf_settings.lora_packet_handler.snr_value & 0x80) // The SNR sign bit is 1
wamae 0:f930f0440fd5 1960 {
wamae 0:f930f0440fd5 1961 // Invert and divide by 4
wamae 0:f930f0440fd5 1962 snr = ((~_rf_settings.lora_packet_handler.snr_value + 1)
wamae 0:f930f0440fd5 1963 & 0xFF) >> 2;
wamae 0:f930f0440fd5 1964 snr = -snr;
wamae 0:f930f0440fd5 1965 } else {
wamae 0:f930f0440fd5 1966 // Divide by 4
wamae 0:f930f0440fd5 1967 snr =
wamae 0:f930f0440fd5 1968 (_rf_settings.lora_packet_handler.snr_value
wamae 0:f930f0440fd5 1969 & 0xFF) >> 2;
wamae 0:f930f0440fd5 1970 }
wamae 0:f930f0440fd5 1971
wamae 0:f930f0440fd5 1972 int16_t rssi = read_register( REG_LR_PKTRSSIVALUE);
wamae 0:f930f0440fd5 1973 if (snr < 0) {
wamae 0:f930f0440fd5 1974 if (_rf_settings.channel > RF_MID_BAND_THRESH) {
wamae 0:f930f0440fd5 1975 _rf_settings.lora_packet_handler.rssi_value =
wamae 0:f930f0440fd5 1976 RSSI_OFFSET_HF + rssi + (rssi >> 4) + snr;
wamae 0:f930f0440fd5 1977 } else {
wamae 0:f930f0440fd5 1978 _rf_settings.lora_packet_handler.rssi_value =
wamae 0:f930f0440fd5 1979 RSSI_OFFSET_LF + rssi + (rssi >> 4) + snr;
wamae 0:f930f0440fd5 1980 }
wamae 0:f930f0440fd5 1981 } else {
wamae 0:f930f0440fd5 1982 if (_rf_settings.channel > RF_MID_BAND_THRESH) {
wamae 0:f930f0440fd5 1983 _rf_settings.lora_packet_handler.rssi_value =
wamae 0:f930f0440fd5 1984 RSSI_OFFSET_HF + rssi + (rssi >> 4);
wamae 0:f930f0440fd5 1985 } else {
wamae 0:f930f0440fd5 1986 _rf_settings.lora_packet_handler.rssi_value =
wamae 0:f930f0440fd5 1987 RSSI_OFFSET_LF + rssi + (rssi >> 4);
wamae 0:f930f0440fd5 1988 }
wamae 0:f930f0440fd5 1989 }
wamae 0:f930f0440fd5 1990
wamae 0:f930f0440fd5 1991 _rf_settings.lora_packet_handler.size = read_register(REG_LR_RXNBBYTES);
wamae 0:f930f0440fd5 1992 read_fifo(_data_buffer, _rf_settings.lora_packet_handler.size);
wamae 0:f930f0440fd5 1993
wamae 0:f930f0440fd5 1994 if (_rf_settings.lora.rx_continuous == false) {
wamae 0:f930f0440fd5 1995 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 1996 }
wamae 0:f930f0440fd5 1997 rx_timeout_timer.detach();
wamae 0:f930f0440fd5 1998
wamae 0:f930f0440fd5 1999 if ((_radio_events != NULL) && (_radio_events->rx_done)) {
wamae 0:f930f0440fd5 2000 _radio_events->rx_done(_data_buffer,
wamae 0:f930f0440fd5 2001 _rf_settings.lora_packet_handler.size,
wamae 0:f930f0440fd5 2002 _rf_settings.lora_packet_handler.rssi_value,
wamae 0:f930f0440fd5 2003 _rf_settings.lora_packet_handler.snr_value);
wamae 0:f930f0440fd5 2004 }
wamae 0:f930f0440fd5 2005 }
wamae 0:f930f0440fd5 2006 break;
wamae 0:f930f0440fd5 2007 default:
wamae 0:f930f0440fd5 2008 break;
wamae 0:f930f0440fd5 2009 }
wamae 0:f930f0440fd5 2010 break;
wamae 0:f930f0440fd5 2011 case RF_TX_RUNNING:
wamae 0:f930f0440fd5 2012 tx_timeout_timer.detach();
wamae 0:f930f0440fd5 2013 // TxDone interrupt
wamae 0:f930f0440fd5 2014 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 2015 case MODEM_LORA:
wamae 0:f930f0440fd5 2016 // Clear Irq
wamae 0:f930f0440fd5 2017 write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE);
wamae 0:f930f0440fd5 2018 // Intentional fall through
wamae 0:f930f0440fd5 2019 case MODEM_FSK:
wamae 0:f930f0440fd5 2020 default:
wamae 0:f930f0440fd5 2021 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 2022 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 2023 && (_radio_events->tx_done)) {
wamae 0:f930f0440fd5 2024 _radio_events->tx_done();
wamae 0:f930f0440fd5 2025 }
wamae 0:f930f0440fd5 2026 break;
wamae 0:f930f0440fd5 2027 }
wamae 0:f930f0440fd5 2028 break;
wamae 0:f930f0440fd5 2029 default:
wamae 0:f930f0440fd5 2030 break;
wamae 0:f930f0440fd5 2031 }
wamae 0:f930f0440fd5 2032 }
wamae 0:f930f0440fd5 2033
wamae 0:f930f0440fd5 2034 void SX1276_LoRaRadio::handle_dio1_irq()
wamae 0:f930f0440fd5 2035 {
wamae 0:f930f0440fd5 2036 switch (_rf_settings.state) {
wamae 0:f930f0440fd5 2037 case RF_RX_RUNNING:
wamae 0:f930f0440fd5 2038 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 2039 case MODEM_FSK:
wamae 0:f930f0440fd5 2040 // FifoLevel interrupt
wamae 0:f930f0440fd5 2041 // Read received packet size
wamae 0:f930f0440fd5 2042 if ((_rf_settings.fsk_packet_handler.size == 0)
wamae 0:f930f0440fd5 2043 && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) {
wamae 0:f930f0440fd5 2044 if (_rf_settings.fsk.fix_len == false) {
wamae 0:f930f0440fd5 2045 read_fifo((uint8_t*) &_rf_settings.fsk_packet_handler.size, 1);
wamae 0:f930f0440fd5 2046 } else {
wamae 0:f930f0440fd5 2047 _rf_settings.fsk_packet_handler.size =
wamae 0:f930f0440fd5 2048 read_register(REG_PAYLOADLENGTH);
wamae 0:f930f0440fd5 2049 }
wamae 0:f930f0440fd5 2050 }
wamae 0:f930f0440fd5 2051
wamae 0:f930f0440fd5 2052 if ((_rf_settings.fsk_packet_handler.size
wamae 0:f930f0440fd5 2053 - _rf_settings.fsk_packet_handler.nb_bytes)
wamae 0:f930f0440fd5 2054 > _rf_settings.fsk_packet_handler.fifo_thresh) {
wamae 0:f930f0440fd5 2055 read_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes),
wamae 0:f930f0440fd5 2056 _rf_settings.fsk_packet_handler.fifo_thresh);
wamae 0:f930f0440fd5 2057 _rf_settings.fsk_packet_handler.nb_bytes +=
wamae 0:f930f0440fd5 2058 _rf_settings.fsk_packet_handler.fifo_thresh;
wamae 0:f930f0440fd5 2059 } else {
wamae 0:f930f0440fd5 2060 read_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes),
wamae 0:f930f0440fd5 2061 _rf_settings.fsk_packet_handler.size
wamae 0:f930f0440fd5 2062 - _rf_settings.fsk_packet_handler.nb_bytes);
wamae 0:f930f0440fd5 2063 _rf_settings.fsk_packet_handler.nb_bytes +=
wamae 0:f930f0440fd5 2064 (_rf_settings.fsk_packet_handler.size
wamae 0:f930f0440fd5 2065 - _rf_settings.fsk_packet_handler.nb_bytes);
wamae 0:f930f0440fd5 2066 }
wamae 0:f930f0440fd5 2067
wamae 0:f930f0440fd5 2068 break;
wamae 0:f930f0440fd5 2069
wamae 0:f930f0440fd5 2070 case MODEM_LORA:
wamae 0:f930f0440fd5 2071 // Sync time out
wamae 0:f930f0440fd5 2072 rx_timeout_timer.detach();
wamae 0:f930f0440fd5 2073 // Clear Irq
wamae 0:f930f0440fd5 2074 write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT);
wamae 0:f930f0440fd5 2075 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 2076 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 2077 && (_radio_events->rx_timeout)) {
wamae 0:f930f0440fd5 2078 _radio_events->rx_timeout();
wamae 0:f930f0440fd5 2079 }
wamae 0:f930f0440fd5 2080 break;
wamae 0:f930f0440fd5 2081 default:
wamae 0:f930f0440fd5 2082 break;
wamae 0:f930f0440fd5 2083 }
wamae 0:f930f0440fd5 2084
wamae 0:f930f0440fd5 2085 break;
wamae 0:f930f0440fd5 2086
wamae 0:f930f0440fd5 2087 case RF_TX_RUNNING:
wamae 0:f930f0440fd5 2088 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 2089 case MODEM_FSK:
wamae 0:f930f0440fd5 2090 // FifoLevel interrupt
wamae 0:f930f0440fd5 2091 if ((_rf_settings.fsk_packet_handler.size
wamae 0:f930f0440fd5 2092 - _rf_settings.fsk_packet_handler.nb_bytes)
wamae 0:f930f0440fd5 2093 > _rf_settings.fsk_packet_handler.chunk_size) {
wamae 0:f930f0440fd5 2094 write_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes),
wamae 0:f930f0440fd5 2095 _rf_settings.fsk_packet_handler.chunk_size);
wamae 0:f930f0440fd5 2096 _rf_settings.fsk_packet_handler.nb_bytes +=
wamae 0:f930f0440fd5 2097 _rf_settings.fsk_packet_handler.chunk_size;
wamae 0:f930f0440fd5 2098 } else {
wamae 0:f930f0440fd5 2099 // Write the last chunk of data
wamae 0:f930f0440fd5 2100 write_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes,
wamae 0:f930f0440fd5 2101 _rf_settings.fsk_packet_handler.size
wamae 0:f930f0440fd5 2102 - _rf_settings.fsk_packet_handler.nb_bytes);
wamae 0:f930f0440fd5 2103 _rf_settings.fsk_packet_handler.nb_bytes +=
wamae 0:f930f0440fd5 2104 _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes;
wamae 0:f930f0440fd5 2105 }
wamae 0:f930f0440fd5 2106
wamae 0:f930f0440fd5 2107 break;
wamae 0:f930f0440fd5 2108
wamae 0:f930f0440fd5 2109 case MODEM_LORA:
wamae 0:f930f0440fd5 2110 break;
wamae 0:f930f0440fd5 2111 default:
wamae 0:f930f0440fd5 2112 break;
wamae 0:f930f0440fd5 2113 }
wamae 0:f930f0440fd5 2114 break;
wamae 0:f930f0440fd5 2115 default:
wamae 0:f930f0440fd5 2116 break;
wamae 0:f930f0440fd5 2117 }
wamae 0:f930f0440fd5 2118 }
wamae 0:f930f0440fd5 2119
wamae 0:f930f0440fd5 2120 void SX1276_LoRaRadio::handle_dio2_irq(void)
wamae 0:f930f0440fd5 2121 {
wamae 0:f930f0440fd5 2122 switch (_rf_settings.state) {
wamae 0:f930f0440fd5 2123 case RF_RX_RUNNING:
wamae 0:f930f0440fd5 2124 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 2125 case MODEM_FSK:
wamae 0:f930f0440fd5 2126 // DIO4 must have been asserted to set preamble_detected to true
wamae 0:f930f0440fd5 2127 if ((_rf_settings.fsk_packet_handler.preamble_detected == 1)
wamae 0:f930f0440fd5 2128 && (_rf_settings.fsk_packet_handler.sync_word_detected == 0)) {
wamae 0:f930f0440fd5 2129 if (_rf_settings.fsk.rx_continuous == false) {
wamae 0:f930f0440fd5 2130 rx_timeout_sync_word.detach();
wamae 0:f930f0440fd5 2131 }
wamae 0:f930f0440fd5 2132
wamae 0:f930f0440fd5 2133 _rf_settings.fsk_packet_handler.sync_word_detected = 1;
wamae 0:f930f0440fd5 2134
wamae 0:f930f0440fd5 2135 _rf_settings.fsk_packet_handler.rssi_value =
wamae 0:f930f0440fd5 2136 -(read_register(REG_RSSIVALUE) >> 1);
wamae 0:f930f0440fd5 2137
wamae 0:f930f0440fd5 2138 _rf_settings.fsk_packet_handler.afc_value =
wamae 0:f930f0440fd5 2139 (int32_t) (double) (((uint16_t) read_register(
wamae 0:f930f0440fd5 2140 REG_AFCMSB) << 8)
wamae 0:f930f0440fd5 2141 | (uint16_t) read_register( REG_AFCLSB))
wamae 0:f930f0440fd5 2142 * (double) FREQ_STEP;
wamae 0:f930f0440fd5 2143 _rf_settings.fsk_packet_handler.rx_gain =
wamae 0:f930f0440fd5 2144 (read_register( REG_LNA) >> 5) & 0x07;
wamae 0:f930f0440fd5 2145 }
wamae 0:f930f0440fd5 2146
wamae 0:f930f0440fd5 2147 break;
wamae 0:f930f0440fd5 2148
wamae 0:f930f0440fd5 2149 case MODEM_LORA:
wamae 0:f930f0440fd5 2150 if (_rf_settings.lora.freq_hop_on == true) {
wamae 0:f930f0440fd5 2151 // Clear Irq
wamae 0:f930f0440fd5 2152 write_to_register(REG_LR_IRQFLAGS,
wamae 0:f930f0440fd5 2153 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL);
wamae 0:f930f0440fd5 2154
wamae 0:f930f0440fd5 2155 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 2156 && (_radio_events->fhss_change_channel)) {
wamae 0:f930f0440fd5 2157 _radio_events->fhss_change_channel(
wamae 0:f930f0440fd5 2158 (read_register(REG_LR_HOPCHANNEL)
wamae 0:f930f0440fd5 2159 & RFLR_HOPCHANNEL_CHANNEL_MASK));
wamae 0:f930f0440fd5 2160 }
wamae 0:f930f0440fd5 2161 }
wamae 0:f930f0440fd5 2162
wamae 0:f930f0440fd5 2163 break;
wamae 0:f930f0440fd5 2164
wamae 0:f930f0440fd5 2165 default:
wamae 0:f930f0440fd5 2166 break;
wamae 0:f930f0440fd5 2167 }
wamae 0:f930f0440fd5 2168
wamae 0:f930f0440fd5 2169 break;
wamae 0:f930f0440fd5 2170
wamae 0:f930f0440fd5 2171 case RF_TX_RUNNING:
wamae 0:f930f0440fd5 2172 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 2173 case MODEM_FSK:
wamae 0:f930f0440fd5 2174 break;
wamae 0:f930f0440fd5 2175 case MODEM_LORA:
wamae 0:f930f0440fd5 2176 if (_rf_settings.lora.freq_hop_on == true) {
wamae 0:f930f0440fd5 2177 // Clear Irq
wamae 0:f930f0440fd5 2178 write_to_register(REG_LR_IRQFLAGS,
wamae 0:f930f0440fd5 2179 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL);
wamae 0:f930f0440fd5 2180
wamae 0:f930f0440fd5 2181 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 2182 && (_radio_events->fhss_change_channel)) {
wamae 0:f930f0440fd5 2183 _radio_events->fhss_change_channel(
wamae 0:f930f0440fd5 2184 (read_register(REG_LR_HOPCHANNEL)
wamae 0:f930f0440fd5 2185 & RFLR_HOPCHANNEL_CHANNEL_MASK));
wamae 0:f930f0440fd5 2186 }
wamae 0:f930f0440fd5 2187 }
wamae 0:f930f0440fd5 2188 break;
wamae 0:f930f0440fd5 2189 default:
wamae 0:f930f0440fd5 2190 break;
wamae 0:f930f0440fd5 2191 }
wamae 0:f930f0440fd5 2192 break;
wamae 0:f930f0440fd5 2193 default:
wamae 0:f930f0440fd5 2194 break;
wamae 0:f930f0440fd5 2195 }
wamae 0:f930f0440fd5 2196 }
wamae 0:f930f0440fd5 2197
wamae 0:f930f0440fd5 2198 void SX1276_LoRaRadio::handle_dio3_irq(void)
wamae 0:f930f0440fd5 2199 {
wamae 0:f930f0440fd5 2200 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 2201 case MODEM_FSK:
wamae 0:f930f0440fd5 2202 break;
wamae 0:f930f0440fd5 2203 case MODEM_LORA:
wamae 0:f930f0440fd5 2204 if ((read_register(REG_LR_IRQFLAGS) & RFLR_IRQFLAGS_CADDETECTED)
wamae 0:f930f0440fd5 2205 == RFLR_IRQFLAGS_CADDETECTED) {
wamae 0:f930f0440fd5 2206 // Clear Irq
wamae 0:f930f0440fd5 2207 write_to_register(REG_LR_IRQFLAGS,
wamae 0:f930f0440fd5 2208 RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE);
wamae 0:f930f0440fd5 2209 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 2210 && (_radio_events->cad_done)) {
wamae 0:f930f0440fd5 2211 _radio_events->cad_done(true);
wamae 0:f930f0440fd5 2212 }
wamae 0:f930f0440fd5 2213 } else {
wamae 0:f930f0440fd5 2214 // Clear Irq
wamae 0:f930f0440fd5 2215 write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE);
wamae 0:f930f0440fd5 2216 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 2217 && (_radio_events->cad_done)) {
wamae 0:f930f0440fd5 2218 _radio_events->cad_done(false);
wamae 0:f930f0440fd5 2219 }
wamae 0:f930f0440fd5 2220 }
wamae 0:f930f0440fd5 2221 break;
wamae 0:f930f0440fd5 2222 default:
wamae 0:f930f0440fd5 2223 break;
wamae 0:f930f0440fd5 2224 }
wamae 0:f930f0440fd5 2225 }
wamae 0:f930f0440fd5 2226
wamae 0:f930f0440fd5 2227 void SX1276_LoRaRadio::handle_dio4_irq(void)
wamae 0:f930f0440fd5 2228 {
wamae 0:f930f0440fd5 2229 // is asserted when a preamble is detected (FSK modem only)
wamae 0:f930f0440fd5 2230 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 2231 case MODEM_FSK: {
wamae 0:f930f0440fd5 2232 if (_rf_settings.fsk_packet_handler.preamble_detected == 0) {
wamae 0:f930f0440fd5 2233 _rf_settings.fsk_packet_handler.preamble_detected = 1;
wamae 0:f930f0440fd5 2234 }
wamae 0:f930f0440fd5 2235 }
wamae 0:f930f0440fd5 2236 break;
wamae 0:f930f0440fd5 2237 case MODEM_LORA:
wamae 0:f930f0440fd5 2238 break;
wamae 0:f930f0440fd5 2239 default:
wamae 0:f930f0440fd5 2240 break;
wamae 0:f930f0440fd5 2241 }
wamae 0:f930f0440fd5 2242 }
wamae 0:f930f0440fd5 2243
wamae 0:f930f0440fd5 2244 void SX1276_LoRaRadio::handle_dio5_irq()
wamae 0:f930f0440fd5 2245 {
wamae 0:f930f0440fd5 2246 switch (_rf_settings.modem) {
wamae 0:f930f0440fd5 2247 case MODEM_FSK:
wamae 0:f930f0440fd5 2248 break;
wamae 0:f930f0440fd5 2249 case MODEM_LORA:
wamae 0:f930f0440fd5 2250 break;
wamae 0:f930f0440fd5 2251 default:
wamae 0:f930f0440fd5 2252 break;
wamae 0:f930f0440fd5 2253 }
wamae 0:f930f0440fd5 2254 }
wamae 0:f930f0440fd5 2255
wamae 0:f930f0440fd5 2256
wamae 0:f930f0440fd5 2257 void SX1276_LoRaRadio::handle_timeout_irq()
wamae 0:f930f0440fd5 2258 {
wamae 0:f930f0440fd5 2259 switch (_rf_settings.state) {
wamae 0:f930f0440fd5 2260 case RF_RX_RUNNING:
wamae 0:f930f0440fd5 2261 if (_rf_settings.modem == MODEM_FSK) {
wamae 0:f930f0440fd5 2262 _rf_settings.fsk_packet_handler.preamble_detected = 0;
wamae 0:f930f0440fd5 2263 _rf_settings.fsk_packet_handler.sync_word_detected = 0;
wamae 0:f930f0440fd5 2264 _rf_settings.fsk_packet_handler.nb_bytes = 0;
wamae 0:f930f0440fd5 2265 _rf_settings.fsk_packet_handler.size = 0;
wamae 0:f930f0440fd5 2266
wamae 0:f930f0440fd5 2267 // Clear Irqs
wamae 0:f930f0440fd5 2268 write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
wamae 0:f930f0440fd5 2269 RF_IRQFLAGS1_PREAMBLEDETECT |
wamae 0:f930f0440fd5 2270 RF_IRQFLAGS1_SYNCADDRESSMATCH);
wamae 0:f930f0440fd5 2271 write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN);
wamae 0:f930f0440fd5 2272
wamae 0:f930f0440fd5 2273 if (_rf_settings.fsk.rx_continuous == true) {
wamae 0:f930f0440fd5 2274 // Continuous mode restart Rx chain
wamae 0:f930f0440fd5 2275 write_to_register( REG_RXCONFIG,
wamae 0:f930f0440fd5 2276 read_register(REG_RXCONFIG) |
wamae 0:f930f0440fd5 2277 RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
wamae 0:f930f0440fd5 2278 } else {
wamae 0:f930f0440fd5 2279 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 2280 rx_timeout_sync_word.attach_us(
wamae 0:f930f0440fd5 2281 callback(this, &SX1276_LoRaRadio::timeout_irq_isr),
wamae 0:f930f0440fd5 2282 _rf_settings.fsk.rx_single_timeout * 1e3);
wamae 0:f930f0440fd5 2283 }
wamae 0:f930f0440fd5 2284 }
wamae 0:f930f0440fd5 2285
wamae 0:f930f0440fd5 2286 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 2287 && (_radio_events->rx_timeout)) {
wamae 0:f930f0440fd5 2288 _radio_events->rx_timeout();
wamae 0:f930f0440fd5 2289 }
wamae 0:f930f0440fd5 2290
wamae 0:f930f0440fd5 2291 break;
wamae 0:f930f0440fd5 2292
wamae 0:f930f0440fd5 2293 case RF_TX_RUNNING:
wamae 0:f930f0440fd5 2294 // Tx timeout shouldn't happen.
wamae 0:f930f0440fd5 2295 // But it has been observed that when it happens it is a result of a
wamae 0:f930f0440fd5 2296 // corrupted SPI transfer
wamae 0:f930f0440fd5 2297 // The workaround is to put the radio in a known state.
wamae 0:f930f0440fd5 2298 // Thus, we re-initialize it.
wamae 0:f930f0440fd5 2299
wamae 0:f930f0440fd5 2300 // Reset the radio
wamae 0:f930f0440fd5 2301 radio_reset();
wamae 0:f930f0440fd5 2302
wamae 0:f930f0440fd5 2303 // Initialize radio default values
wamae 0:f930f0440fd5 2304 set_operation_mode(RF_OPMODE_SLEEP);
wamae 0:f930f0440fd5 2305
wamae 0:f930f0440fd5 2306 setup_registers();
wamae 0:f930f0440fd5 2307
wamae 0:f930f0440fd5 2308 set_modem(MODEM_FSK);
wamae 0:f930f0440fd5 2309
wamae 0:f930f0440fd5 2310 // Restore previous network type setting.
wamae 0:f930f0440fd5 2311 set_public_network(_rf_settings.lora.public_network);
wamae 0:f930f0440fd5 2312
wamae 0:f930f0440fd5 2313 _rf_settings.state = RF_IDLE;
wamae 0:f930f0440fd5 2314 if ((_radio_events != NULL)
wamae 0:f930f0440fd5 2315 && (_radio_events->tx_timeout)) {
wamae 0:f930f0440fd5 2316 _radio_events->tx_timeout();
wamae 0:f930f0440fd5 2317 }
wamae 0:f930f0440fd5 2318 break;
wamae 0:f930f0440fd5 2319 default:
wamae 0:f930f0440fd5 2320 break;
wamae 0:f930f0440fd5 2321 }
wamae 0:f930f0440fd5 2322 }
wamae 0:f930f0440fd5 2323 // EOF
wamae 0:f930f0440fd5 2324
wamae 0:f930f0440fd5 2325 #endif //DEVICE_SPI
wamae 0:f930f0440fd5 2326