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