testing hex for lorawan communication

Committer:
brunnobbco
Date:
Thu Nov 12 21:35:41 2020 +0000
Revision:
1:3bdd6f917bf5
Parent:
0:561d07a737bc
Child:
2:6c5853c2fd72
Moved Frequency Hop irq and Cad irq to polling timers.

Who changed what in which revision?

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