How to measure water in a reservoir

Dependencies:   Cayenne-MQTT-mbed Cayenne-LPP

Committer:
wamae
Date:
Fri Mar 08 11:34:56 2019 +0000
Revision:
0:7bfeb237e600
working code

Who changed what in which revision?

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