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