Driver for SX1272 connected to Pulga devices using only DIO0 pins and polling (error states and timeout).

Dependents:   pulga-mbed-lorawan-gps mbed-lorawan-pulga mbed-lorawan-pulga-testing-channel mbed-lorawan-pulga-serial_rx ... more

Committer:
brunnobbco
Date:
Thu Nov 12 19:26:24 2020 +0000
Revision:
0:561d07a737bc
Child:
1:3bdd6f917bf5
SX1272 driver using only DIO0 and polling.

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