Level measurement using range finder and lora technology

Dependencies:   Cayenne-LPP SDBlockDevice

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

Who changed what in which revision?

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