testing hex for lorawan communication

Committer:
afzalsamira
Date:
Fri Dec 04 18:33:07 2020 +0000
Revision:
3:9e7d20163e7a
Parent:
2:6c5853c2fd72
testing hex;

Who changed what in which revision?

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