From 0d536766be0912bb176cbbae426e07d862c5cf9f Mon Sep 17 00:00:00 2001 From: Antti Kauppila Date: Thu, 30 Nov 2017 16:35:28 +0200 Subject: [PATCH 01/42] Initial commit --- LICENCE-BSD-3-Clause | 25 + LICENSE | 25 + README.md | 1 + SX1272/README.md | 1 + SX1272/SX1272_LoRaRadio.cpp | 2137 +++++++++++++++++++++++++ SX1272/SX1272_LoRaRadio.h | 402 +++++ SX1272/mbed_lib.json | 13 + SX1272/registers/sx1272Regs-Fsk.h | 1138 ++++++++++++++ SX1272/registers/sx1272Regs-LoRa.h | 549 +++++++ SX1276/README.md | 1 + SX1276/SX1276_LoRaRadio.cpp | 2308 ++++++++++++++++++++++++++++ SX1276/SX1276_LoRaRadio.h | 424 +++++ SX1276/mbed_lib.json | 13 + SX1276/registers/sx1276Regs-Fsk.h | 1138 ++++++++++++++ SX1276/registers/sx1276Regs-LoRa.h | 569 +++++++ 15 files changed, 8744 insertions(+) create mode 100644 LICENCE-BSD-3-Clause create mode 100644 LICENSE create mode 100644 README.md create mode 100644 SX1272/README.md create mode 100644 SX1272/SX1272_LoRaRadio.cpp create mode 100644 SX1272/SX1272_LoRaRadio.h create mode 100644 SX1272/mbed_lib.json create mode 100644 SX1272/registers/sx1272Regs-Fsk.h create mode 100644 SX1272/registers/sx1272Regs-LoRa.h create mode 100644 SX1276/README.md create mode 100644 SX1276/SX1276_LoRaRadio.cpp create mode 100644 SX1276/SX1276_LoRaRadio.h create mode 100644 SX1276/mbed_lib.json create mode 100644 SX1276/registers/sx1276Regs-Fsk.h create mode 100644 SX1276/registers/sx1276Regs-LoRa.h diff --git a/LICENCE-BSD-3-Clause b/LICENCE-BSD-3-Clause new file mode 100644 index 0000000000..23f888dd89 --- /dev/null +++ b/LICENCE-BSD-3-Clause @@ -0,0 +1,25 @@ +Copyright 2017 Arm Limited and affiliates. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..6d7f3191ab --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +--- Revised BSD License --- +Copyright (c) 2013, SEMTECH S.A. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Semtech corporation nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..988b94f741 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Mbed enabled Semtech LoRa/FSK radio drivers. diff --git a/SX1272/README.md b/SX1272/README.md new file mode 100644 index 0000000000..5cf59950c9 --- /dev/null +++ b/SX1272/README.md @@ -0,0 +1 @@ +# Mbed enabled SX1272 LoRa/FSK radio driver \ No newline at end of file diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp new file mode 100644 index 0000000000..698428e9bb --- /dev/null +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -0,0 +1,2137 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: Radio driver for Semtech SX1272 LoRa radio chip. Implements LoRaRadio class. + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#include +#include //rint +#include +#include "mbed.h" +#include "SX1272_LoRaRadio.h" +#include "sx1272Regs-Fsk.h" +#include "sx1272Regs-LoRa.h" + +#if defined(FEATURE_COMMON_PAL) +#include "mbed_trace.h" +#define TRACE_GROUP "LRAD" +#else +#define tr_debug(...) (void(0)) //dummies if feature common pal is not added +#define tr_info(...) (void(0)) //dummies if feature common pal is not added +#define tr_error(...) (void(0)) //dummies if feature common pal is not added +#endif //defined(FEATURE_COMMON_PAL) + +#ifdef MBED_SX1272_LORA_RADIO_SPI_FREQUENCY +#define SPI_FREQUENCY MBED_SX1272_LORA_RADIO_SPI_FREQUENCY +#else +#define SPI_FREQUENCY 8000000 +#endif + +// Sync word for Private LoRa networks +#define LORA_MAC_PRIVATE_SYNCWORD 0x12 +// Sync word for Public LoRa networks +#define LORA_MAC_PUBLIC_SYNCWORD 0x34 + +// SX1272 definitions +#define XTAL_FREQ 32000000 +#define FREQ_STEP 61.03515625 + +enum RadioVariant { + SX1272MB2XAS = 0, + SX1272MB1DCS +}; + +/*! + * FSK bandwidth definition + */ +typedef struct +{ + uint32_t bandwidth; + uint8_t register_value; +} fsk_bw_t; + +/*! + * Radio registers definition + */ +typedef struct +{ + modem_type modem; + uint8_t addr; + uint8_t value; +} radio_registers_t; + +/*! + * Constant values need to compute the RSSI value + */ +#define RSSI_OFFSET -139 + +#define RADIO_INIT_REGISTERS_VALUE \ +{ \ + { MODEM_FSK , REG_LNA , 0x23 },\ + { MODEM_FSK , REG_RXCONFIG , 0x1E },\ + { MODEM_FSK , REG_RSSICONFIG , 0xD2 },\ + { MODEM_FSK , REG_AFCFEI , 0x01 },\ + { MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },\ + { MODEM_FSK , REG_OSC , 0x07 },\ + { MODEM_FSK , REG_SYNCCONFIG , 0x12 },\ + { MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },\ + { MODEM_FSK , REG_SYNCVALUE2 , 0x94 },\ + { MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },\ + { MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },\ + { MODEM_FSK , REG_FIFOTHRESH , 0x8F },\ + { MODEM_FSK , REG_IMAGECAL , 0x02 },\ + { MODEM_FSK , REG_DIOMAPPING1 , 0x00 },\ + { MODEM_FSK , REG_DIOMAPPING2 , 0x30 },\ + { MODEM_LORA, REG_LR_DETECTOPTIMIZE , 0x43 },\ + { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\ +} + +const fsk_bw_t fsk_bandwidths[] = +{ + { 2600 , 0x17 }, + { 3100 , 0x0F }, + { 3900 , 0x07 }, + { 5200 , 0x16 }, + { 6300 , 0x0E }, + { 7800 , 0x06 }, + { 10400 , 0x15 }, + { 12500 , 0x0D }, + { 15600 , 0x05 }, + { 20800 , 0x14 }, + { 25000 , 0x0C }, + { 31300 , 0x04 }, + { 41700 , 0x13 }, + { 50000 , 0x0B }, + { 62500 , 0x03 }, + { 83333 , 0x12 }, + { 100000, 0x0A }, + { 125000, 0x02 }, + { 166700, 0x11 }, + { 200000, 0x09 }, + { 250000, 0x01 }, + { 300000, 0x00 }, // Invalid bandwidth +}; + +/** + * SPI read/write masks + */ +#define SPI_WRITE_CMD 0x80 +#define SPI_READ_CMD 0x7F + +/** + * Signals + */ +#define SIG_DIO0 0x01 +#define SIG_DIO1 0x02 +#define SIG_DIO2 0x04 +#define SIG_DIO3 0x08 +#define SIG_DIO4 0x10 +#define SIG_DIO5 0x20 +#define SIG_TIMOUT 0x40 + +/** + * Radio hardware registers initialization + */ +static const radio_registers_t radio_reg_init[] = RADIO_INIT_REGISTERS_VALUE; + +static uint8_t radio_variant; + +/** + * Flag used to set the RF switch control pins in low power mode when the radio is not active. + */ +static bool RadioIsActive = false; + +/** + * Constructor + */ +SX1272_LoRaRadio::SX1272_LoRaRadio(PinName spi_mosi, PinName spi_miso, + PinName spi_sclk, PinName nss, PinName reset, PinName dio0, PinName dio1, + PinName dio2, PinName dio3, PinName dio4, PinName dio5, PinName rf_switch_ctl1, + PinName rf_switch_ctl2, + PinName txctl, PinName rxctl, PinName antswitch, PinName pwr_amp_ctl) + : _spi(spi_mosi, spi_miso, spi_sclk), + _chip_select(nss, 1), _reset_ctl(reset), + _dio0_ctl(dio0), _dio1_ctl(dio1), _dio2_ctl(dio2), _dio3_ctl(dio3), + _dio4_ctl(dio4), _dio5_ctl(dio5), _rf_switch_ctl1(rf_switch_ctl1, 0), + _rf_switch_ctl2(rf_switch_ctl2, 0),_txctl(txctl, 0), _rxctl(rxctl, 0), + _ant_switch(antswitch, PIN_INPUT, PullUp, 0), _pwr_amp_ctl(pwr_amp_ctl) +#ifdef MBED_CONF_RTOS_PRESENT + , irq_thread(osPriorityRealtime, 1024) +#endif +{ + _rf_ctrls.ant_switch = antswitch; + _rf_ctrls.pwr_amp_ctl = pwr_amp_ctl; + _rf_ctrls.rf_switch_ctl1 = rf_switch_ctl1; + _rf_ctrls.rf_switch_ctl2 = rf_switch_ctl2; + _rf_ctrls.rxctl = rxctl; + _rf_ctrls.txctl = txctl; + + _radio_events = NULL; + +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.start(mbed::callback(this, &SX1272_LoRaRadio::rf_irq_task)); +#endif +} + +/** + * Destructor + */ +SX1272_LoRaRadio::~SX1272_LoRaRadio() +{ + +} + +/***************************************************************************** + * Public APIs * + ****************************************************************************/ + +/** + * Acquire lock + */ +void SX1272_LoRaRadio::lock(void) +{ + mutex.lock(); +} + +/** + * Release lock + */ +void SX1272_LoRaRadio::unlock(void) +{ + mutex.unlock(); +} + +/** + * Initializes radio module + */ +void SX1272_LoRaRadio::init_radio(radio_events_t *events) +{ + _radio_events = events; + + // Reset the radio transceiver + radio_reset(); + + // Setup radio variant type + set_sx1272_variant_type(); + + // setup SPI frequency + // default is 8MHz although, configurable through + // SPI_FREQUENCY macro + setup_spi(); + + // set radio mode to sleep + set_operation_mode(RF_OPMODE_SLEEP); + + // Setup radio registers to defaults + setup_registers(); + + // set modem type - defaults to FSK here + set_modem(MODEM_FSK); + + // set state to be idle + _rf_settings.state = RF_IDLE; + + // Setup interrupts on DIO pins + setup_interrupts(); +} + +/** + * TODO: The purpose of this API is unclear. + * Need to start an internal discussion. + */ +bool SX1272_LoRaRadio::check_rf_frequency(uint32_t frequency) +{ + // Implement check. Currently all frequencies are supported ? What band ? + return true; +} + +/** + * Sets up carrier frequency + */ +void SX1272_LoRaRadio::set_channel(uint32_t freq) +{ + _rf_settings.channel = freq; + freq = (uint32_t) ((double) freq / (double) FREQ_STEP); + write_to_register(REG_FRFMSB, (uint8_t) ((freq >> 16) & 0xFF)); + write_to_register(REG_FRFMID, (uint8_t) ((freq >> 8) & 0xFF)); + write_to_register(REG_FRFLSB, (uint8_t) (freq & 0xFF)); +} + +/** + * Returns current status of the radio state machine + */ +uint8_t SX1272_LoRaRadio::get_status(void) +{ + return _rf_settings.state; +} + +/** + * sets the radio module to sleep + */ + +void SX1272_LoRaRadio::sleep() +{ + // stop timers + tx_timeout_timer.detach(); + rx_timeout_timer.detach(); + + // put module in sleep mode + set_operation_mode(RF_OPMODE_SLEEP); +} + +/** + * Sets up operation mode + */ +void SX1272_LoRaRadio::set_operation_mode(uint8_t mode) +{ + if (mode == RF_OPMODE_SLEEP) { + set_low_power_mode(true); + } else { + set_low_power_mode(false); + set_antenna_switch(mode); + } + + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RF_OPMODE_MASK) | mode); +} + +/** + * Sets the modem type to use + * + * At initialization FSK is chosen. Later stack or application + * can choose to change. + */ +void SX1272_LoRaRadio::set_modem(uint8_t modem ) +{ + if ((read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON) != 0 ) { + _rf_settings.modem = MODEM_LORA; + } else { + _rf_settings.modem = MODEM_FSK; + } + + if(_rf_settings.modem == modem ) { + // if the modem is already set + return; + } + + _rf_settings.modem = modem; + + switch(_rf_settings.modem) + { + default: + case MODEM_FSK: + // before changing modem mode, put the module to sleep + sleep(); + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) + | RFLR_OPMODE_LONGRANGEMODE_OFF); + + // Datasheet Tables 28, 29 DIO mapping + write_to_register(REG_DIOMAPPING1, 0x00); // sets DIO0-DI03 in default mode + write_to_register(REG_DIOMAPPING2, 0x30); // bits 4-5 are turned on i.e., + // DIO5 and DIO4=ModeReady + break; + case MODEM_LORA: + sleep(); + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) + | RFLR_OPMODE_LONGRANGEMODE_ON); + + // Datasheet Tables 17 DIO mapping for LoRa + // set to defaults + write_to_register(REG_DIOMAPPING1, 0x00); // DIO0 - DIO3 defaults + write_to_register(REG_DIOMAPPING2, 0x00); // DIO4 - DIO5 defaults + + break; + } +} + +/** + * Can be used by application/stack or the driver itself + * Ref: Datasheet 7.2.2 Manual Reset + */ +void SX1272_LoRaRadio::radio_reset() +{ + _reset_ctl.output(); + _reset_ctl = 0; + wait_ms(2); + _reset_ctl.input(); + wait_ms(6); +} + +/** + * Sets up receiver related configurations + * + * Must be called before setting the radio in rx mode + */ +void SX1272_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidth_afc, uint16_t preamble_len, + uint16_t symb_timeout, bool fix_len, + uint8_t payload_len, + bool crc_on, bool freq_hop_on, uint8_t hop_period, + bool iq_inverted, bool rx_continuous) +{ + set_modem(modem); + + switch (modem) { + case MODEM_FSK: + _rf_settings.fsk.bandwidth = bandwidth; + _rf_settings.fsk.datarate = datarate; + _rf_settings.fsk.bandwidth_afc = bandwidth_afc; + _rf_settings.fsk.fix_len = fix_len; + _rf_settings.fsk.payload_len = payload_len; + _rf_settings.fsk.crc_on = crc_on; + _rf_settings.fsk.iq_inverted = iq_inverted; + _rf_settings.fsk.rx_continuous = rx_continuous; + _rf_settings.fsk.preamble_len = preamble_len; + _rf_settings.fsk.rx_single_timeout = + symb_timeout * ((1.0 / (double) datarate) * 8.0) * 1e3; + + datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); + write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8)); + write_to_register(REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); + + write_to_register(REG_RXBW, get_fsk_bw_reg_val(bandwidth)); + write_to_register(REG_AFCBW, get_fsk_bw_reg_val(bandwidth_afc)); + + write_to_register(REG_PREAMBLEMSB, (uint8_t) ((preamble_len >> 8) & 0xFF)); + write_to_register(REG_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF)); + + if (fix_len == 1) { + write_to_register(REG_PAYLOADLENGTH, payload_len); + } else { + write_to_register(REG_PAYLOADLENGTH, 0xFF); // Set payload length to the maximum + } + + write_to_register(REG_PACKETCONFIG1, (read_register(REG_PACKETCONFIG1) & RF_PACKETCONFIG1_CRC_MASK + & RF_PACKETCONFIG1_PACKETFORMAT_MASK) + | ((fix_len == 1) ? + RF_PACKETCONFIG1_PACKETFORMAT_FIXED : + RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) + | (crc_on << 4)); + + // TODO why packet mode 2 ? + write_to_register(REG_PACKETCONFIG2, (read_register(REG_PACKETCONFIG2) | RF_PACKETCONFIG2_DATAMODE_PACKET)); + + break; + + case MODEM_LORA: + _rf_settings.lora.bandwidth = bandwidth; + _rf_settings.lora.datarate = datarate; + _rf_settings.lora.coderate = coderate; + _rf_settings.lora.preamble_len = preamble_len; + _rf_settings.lora.fix_len = fix_len; + _rf_settings.lora.payload_len = payload_len; + _rf_settings.lora.crc_on = crc_on; + _rf_settings.lora.freq_hop_on = freq_hop_on; + _rf_settings.lora.hop_period = hop_period; + _rf_settings.lora.iq_inverted = iq_inverted; + _rf_settings.lora.rx_continuous = rx_continuous; + + if (datarate > 12) { + datarate = 12; + } else if (datarate < 6) { + datarate = 6; + } + + if (((bandwidth == 0) && ((datarate == 11) || (datarate == 12))) + || ((bandwidth == 1) && (datarate == 12))) { + _rf_settings.lora.low_datarate_optimize = 0x01; + } else { + _rf_settings.lora.low_datarate_optimize = 0x00; + } + + write_to_register(REG_LR_MODEMCONFIG1, (read_register(REG_LR_MODEMCONFIG1) & RFLR_MODEMCONFIG1_BW_MASK + & RFLR_MODEMCONFIG1_CODINGRATE_MASK + & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK + & RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK & RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK) + | (bandwidth << 6) + | (coderate << 3) | (fix_len << 2) | (crc_on << 1) + | _rf_settings.lora.low_datarate_optimize); + + write_to_register(REG_LR_MODEMCONFIG2, (read_register(REG_LR_MODEMCONFIG2) & RFLR_MODEMCONFIG2_SF_MASK + & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK) + | (datarate << 4) + | ((symb_timeout >> 8) + & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK)); + + write_to_register(REG_LR_SYMBTIMEOUTLSB, (uint8_t) (symb_timeout & 0xFF)); + + write_to_register(REG_LR_PREAMBLEMSB, (uint8_t) ((preamble_len >> 8) & 0xFF)); + write_to_register(REG_LR_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF)); + + if (fix_len == 1) { + write_to_register(REG_LR_PAYLOADLENGTH, payload_len); + } + + if (_rf_settings.lora.freq_hop_on == true) { + write_to_register( REG_LR_PLLHOP, (read_register(REG_LR_PLLHOP) & RFLR_PLLHOP_FASTHOP_MASK) + | RFLR_PLLHOP_FASTHOP_ON); + write_to_register( REG_LR_HOPPERIOD, _rf_settings.lora.hop_period); + } + + if (datarate == 6) { + write_to_register( REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) & RFLR_DETECTIONOPTIMIZE_MASK) + | RFLR_DETECTIONOPTIMIZE_SF6); + write_to_register( REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF6); + } else { + write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) & RFLR_DETECTIONOPTIMIZE_MASK) + | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); + write_to_register( REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12); + } + + break; + + default: + break; + } +} + +/** + * Sets up transmitter related configuration + * + * Must be called before putting the radio module in Tx mode or trying + * to send + */ +void SX1272_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power, + uint32_t fdev, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint16_t preamble_len, bool fix_len, + bool crc_on, bool freq_hop_on, + uint8_t hop_period, bool iq_inverted, + uint32_t timeout) +{ + set_modem(modem); + set_rf_tx_power(power); + + switch (modem) { + case MODEM_FSK: + _rf_settings.fsk.power = power; + _rf_settings.fsk.f_dev = fdev; + _rf_settings.fsk.bandwidth = bandwidth; + _rf_settings.fsk.datarate = datarate; + _rf_settings.fsk.preamble_len = preamble_len; + _rf_settings.fsk.fix_len = fix_len; + _rf_settings.fsk.crc_on = crc_on; + _rf_settings.fsk.iq_inverted = iq_inverted; + _rf_settings.fsk.tx_timeout = timeout; + + fdev = (uint16_t) ((double) fdev / (double) FREQ_STEP); + write_to_register( REG_FDEVMSB, (uint8_t) (fdev >> 8)); + write_to_register( REG_FDEVLSB, (uint8_t) (fdev & 0xFF)); + + datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); + write_to_register( REG_BITRATEMSB, (uint8_t) (datarate >> 8)); + write_to_register( REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); + + write_to_register( REG_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); + write_to_register( REG_PREAMBLELSB, preamble_len & 0xFF); + + + write_to_register(REG_PACKETCONFIG1, (read_register(REG_PACKETCONFIG1) + & RF_PACKETCONFIG1_CRC_MASK + & RF_PACKETCONFIG1_PACKETFORMAT_MASK) + | ((fix_len == 1) ? + RF_PACKETCONFIG1_PACKETFORMAT_FIXED : + RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) + | (crc_on << 4)); + + //cfg_mode = read_register(REG_PACKETCONFIG2); + write_to_register(REG_PACKETCONFIG2, read_register(REG_PACKETCONFIG2) + | RF_PACKETCONFIG2_DATAMODE_PACKET); + + break; + + case MODEM_LORA: + _rf_settings.lora.power = power; + _rf_settings.lora.bandwidth = bandwidth; + _rf_settings.lora.datarate = datarate; + _rf_settings.lora.coderate = coderate; + _rf_settings.lora.preamble_len = preamble_len; + _rf_settings.lora.fix_len = fix_len; + _rf_settings.lora.freq_hop_on = freq_hop_on; + _rf_settings.lora.hop_period = hop_period; + _rf_settings.lora.crc_on = crc_on; + _rf_settings.lora.iq_inverted = iq_inverted; + _rf_settings.lora.tx_timeout = timeout; + + if (datarate > 12) { + datarate = 12; + } else if (datarate < 6) { + datarate = 6; + } + if (((bandwidth == 0) && ((datarate == 11) || (datarate == 12))) + || ((bandwidth == 1) && (datarate == 12))) { + _rf_settings.lora.low_datarate_optimize = 0x01; + } else { + _rf_settings.lora.low_datarate_optimize = 0x00; + } + + if (_rf_settings.lora.freq_hop_on == true) { + write_to_register(REG_LR_PLLHOP, (read_register(REG_LR_PLLHOP) + & RFLR_PLLHOP_FASTHOP_MASK) + | RFLR_PLLHOP_FASTHOP_ON); + write_to_register(REG_LR_HOPPERIOD, _rf_settings.lora.hop_period); + } + + write_to_register(REG_LR_MODEMCONFIG1, (read_register(REG_LR_MODEMCONFIG1) & + RFLR_MODEMCONFIG1_BW_MASK & + RFLR_MODEMCONFIG1_CODINGRATE_MASK & + RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK & + RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK & + RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK) + | (bandwidth << 6) | (coderate << 3) + | (fix_len << 2) | (crc_on << 1) + | _rf_settings.lora.low_datarate_optimize); + + write_to_register(REG_LR_MODEMCONFIG2, + (read_register(REG_LR_MODEMCONFIG2) & + RFLR_MODEMCONFIG2_SF_MASK) | (datarate << 4)); + + write_to_register( REG_LR_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); + write_to_register( REG_LR_PREAMBLELSB, preamble_len & 0xFF); + + if (datarate == 6) { + write_to_register(REG_LR_DETECTOPTIMIZE, + (read_register(REG_LR_DETECTOPTIMIZE) & + RFLR_DETECTIONOPTIMIZE_MASK) | + RFLR_DETECTIONOPTIMIZE_SF6); + write_to_register( REG_LR_DETECTIONTHRESHOLD, + RFLR_DETECTIONTHRESH_SF6); + } else { + write_to_register(REG_LR_DETECTOPTIMIZE, + (read_register(REG_LR_DETECTOPTIMIZE) & + RFLR_DETECTIONOPTIMIZE_MASK) | + RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); + write_to_register(REG_LR_DETECTIONTHRESHOLD, + RFLR_DETECTIONTHRESH_SF7_TO_SF12); + } + + break; + } +} + +/** + * Calculates time on Air i.e., dwell time for a single packet + * + * Crucial for the stack in order to calculate dwell time so as to control + * duty cycling. + */ +uint32_t SX1272_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) +{ + uint32_t airtime = 0; + + switch (modem) { + case MODEM_FSK: { + airtime = rint((8 * (_rf_settings.fsk.preamble_len + + ((read_register( REG_SYNCCONFIG) + & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1) + + ((_rf_settings.fsk.fix_len == 0x01) ? + 0.0 : 1.0) + + (((read_register( REG_PACKETCONFIG1) + & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK) + != 0x00) ? 1.0 : 0) + pkt_len + + ((_rf_settings.fsk.crc_on == 0x01) ? + 2.0 : 0)) + / _rf_settings.fsk.datarate) * 1e3); + } + break; + case MODEM_LORA: { + double bw = 0.0; + switch (_rf_settings.lora.bandwidth) { + case 0: // 125 kHz + bw = 125e3; + break; + case 1: // 250 kHz + bw = 250e3; + break; + case 2: // 500 kHz + bw = 500e3; + break; + } + + // Symbol rate : time for one symbol (secs) + double rs = bw / (1 << _rf_settings.lora.datarate); + double ts = 1 / rs; + // time of preamble + double preamble_time = (_rf_settings.lora.preamble_len + 4.25) * ts; + // Symbol length of payload and time + double tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28 + + 16 * _rf_settings.lora.crc_on - + (_rf_settings.lora.fix_len ? 20 : 0)) + / (double) (4 * (_rf_settings.lora.datarate - + ((_rf_settings.lora.low_datarate_optimize + > 0) ? 2 : 0)))) * + (_rf_settings.lora.coderate + 4); + double n_payload = 8 + ((tmp > 0) ? tmp : 0); + double t_payload = n_payload * ts; + // Time on air + double t_onair = preamble_time + t_payload; + // return ms secs + airtime = floor(t_onair * 1e3 + 0.999); + } + break; + } + return airtime; +} + +/** + * Prepares and sends the radio packet out in the air + */ +void SX1272_LoRaRadio::send(uint8_t *buffer, uint8_t size) +{ + uint32_t tx_timeout = 0; + + switch (_rf_settings.modem) { + case MODEM_FSK: + + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = size; + + // FIFO operations can not take place in Sleep mode + if ((read_register(REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) { + standby(); + wait_ms(1); + } + + if (_rf_settings.fsk.fix_len == false) { + write_fifo((uint8_t *) &size, 1); + } else { + write_to_register(REG_PAYLOADLENGTH, size); + } + + if ((size > 0) && (size <= 64)) { + _rf_settings.fsk_packet_handler.chunk_size = size; + } else { + memcpy(_data_buffer, buffer, size); + _rf_settings.fsk_packet_handler.chunk_size = 32; + } + + // write payload buffer + write_fifo(buffer, _rf_settings.fsk_packet_handler.chunk_size); + _rf_settings.fsk_packet_handler.nb_bytes += + _rf_settings.fsk_packet_handler.chunk_size; + tx_timeout = _rf_settings.fsk.tx_timeout; + + break; + case MODEM_LORA: + if (_rf_settings.lora.iq_inverted == true) { + write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) & + RFLR_INVERTIQ_TX_MASK & + RFLR_INVERTIQ_RX_MASK) | + RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON)); + write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); + } else { + write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) & + RFLR_INVERTIQ_TX_MASK & + RFLR_INVERTIQ_RX_MASK) | + RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF)); + write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); + } + + _rf_settings.lora_packet_handler.size = size; + + // Initializes the payload size + write_to_register(REG_LR_PAYLOADLENGTH, size); + + // Full buffer used for Tx + write_to_register(REG_LR_FIFOTXBASEADDR, 0); + write_to_register(REG_LR_FIFOADDRPTR, 0); + + // FIFO operations can not take place in Sleep mode + if ((read_register(REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) { + standby(); + wait_ms(1); + } + // write payload buffer + write_fifo(buffer, size); + tx_timeout = _rf_settings.lora.tx_timeout; + + break; + } + + // transmit + transmit(tx_timeout); +} + +/** + * Actual TX - Transmit routine + * + * A DIO0 interrupt let the state machine know that a a packet is + * successfully sent, otherwise a TxTimeout is invoked. + * TxTimeout should never happen in normal circumstances as the radio should + * be able to send a packet out in the air no matter what. + */ +void SX1272_LoRaRadio::transmit(uint32_t timeout) +{ + switch (_rf_settings.modem) { + + case MODEM_FSK: + // DIO0=PacketSent + // DIO1=FifoEmpty + // DIO2=FifoFull + // DIO3=FifoEmpty + // DIO4=LowBat + // DIO5=ModeReady + write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) & + RF_DIOMAPPING1_DIO0_MASK & + RF_DIOMAPPING1_DIO1_MASK & + RF_DIOMAPPING1_DIO2_MASK) | + RF_DIOMAPPING1_DIO1_01); + + write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) & + RF_DIOMAPPING2_DIO4_MASK & + RF_DIOMAPPING2_MAP_MASK)); + _rf_settings.fsk_packet_handler.fifo_thresh = + read_register(REG_FIFOTHRESH) & 0x3F; + + break; + + case MODEM_LORA: + + if (_rf_settings.lora.freq_hop_on == true) { + write_to_register(REG_LR_IRQFLAGSMASK, + RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_CADDETECTED); + + // DIO0=tx_done, DIO2=fhss_change_channel + + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & + RFLR_DIOMAPPING1_DIO0_MASK & + RFLR_DIOMAPPING1_DIO2_MASK) | + RFLR_DIOMAPPING1_DIO0_01 | + RFLR_DIOMAPPING1_DIO2_00); + } else { + write_to_register(REG_LR_IRQFLAGSMASK, + RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED); + + // DIO0=tx_done + write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) & + RFLR_DIOMAPPING1_DIO0_MASK) | + RFLR_DIOMAPPING1_DIO0_01); + } + + break; + } + + _rf_settings.state = RF_TX_RUNNING; + tx_timeout_timer.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr), timeout*1e3); + set_operation_mode(RF_OPMODE_TRANSMITTER); +} + +/** + * Sets the radio module in receive mode + * + * A DIO4 interrupt let's the state machine know that a preamble is detected + * and finally a DIO0 interrupt let's the state machine know that a packet is + * ready to be read from the FIFO + */ +void SX1272_LoRaRadio::receive(uint32_t timeout) +{ + switch (_rf_settings.modem) { + case MODEM_FSK: + if (timeout == 0 && _rf_settings.fsk.rx_continuous == false) { + // user messed up probably timeout was 0 but mode was not + // continuous, force it to be continuous + _rf_settings.fsk.rx_continuous = true; + } + + // DIO0=PayloadReady + // DIO1=FifoLevel + // DIO2=SyncAddr + // DIO3=FifoEmpty + // DIO4=Preamble + // DIO5=ModeReady + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & + RF_DIOMAPPING1_DIO0_MASK & + RF_DIOMAPPING1_DIO1_MASK & + RF_DIOMAPPING1_DIO2_MASK) | + RF_DIOMAPPING1_DIO0_00 | + RF_DIOMAPPING1_DIO1_00 | + RF_DIOMAPPING1_DIO2_11); + + write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) & + RF_DIOMAPPING2_DIO4_MASK & + RF_DIOMAPPING2_MAP_MASK) | + RF_DIOMAPPING2_DIO4_11 | + RF_DIOMAPPING2_MAP_PREAMBLEDETECT); + + _rf_settings.fsk_packet_handler.fifo_thresh = + read_register(REG_FIFOTHRESH) & 0x3F; + + write_to_register(REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | + RF_RXCONFIG_AGCAUTO_ON | + RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT); + + _rf_settings.fsk_packet_handler.preamble_detected = false; + _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; + + break; + + case MODEM_LORA: + if (timeout == 0 && _rf_settings.lora.rx_continuous == false) { + // user messed up probably timeout was 0 but mode was not + // continuous, force it to be continuous + _rf_settings.lora.rx_continuous = true; + } + + if (_rf_settings.lora.iq_inverted == true) { + write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) & + RFLR_INVERTIQ_TX_MASK & + RFLR_INVERTIQ_RX_MASK) | + RFLR_INVERTIQ_RX_ON | + RFLR_INVERTIQ_TX_OFF)); + write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); + } else { + write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) & + RFLR_INVERTIQ_TX_MASK & + RFLR_INVERTIQ_RX_MASK) | + RFLR_INVERTIQ_RX_OFF | + RFLR_INVERTIQ_TX_OFF)); + write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); + } + + if (_rf_settings.lora.freq_hop_on == true) { + write_to_register(REG_LR_IRQFLAGSMASK, + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_CADDETECTED); + + // DIO0=rx_done, DIO2=fhss_change_channel + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & + RFLR_DIOMAPPING1_DIO0_MASK & + RFLR_DIOMAPPING1_DIO2_MASK) | + RFLR_DIOMAPPING1_DIO0_00 | + RFLR_DIOMAPPING1_DIO2_00); + } else { + write_to_register(REG_LR_IRQFLAGSMASK, + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED); + + // DIO0=rx_done + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & + RFLR_DIOMAPPING1_DIO0_MASK) | + RFLR_DIOMAPPING1_DIO0_00); + } + + write_to_register(REG_LR_FIFORXBASEADDR, 0); + write_to_register(REG_LR_FIFOADDRPTR, 0); + + break; + } + + memset(_data_buffer, 0, (size_t) MAX_DATA_BUFFER_SIZE); + + _rf_settings.state = RF_RX_RUNNING; + + if (timeout != 0) { + rx_timeout_timer.attach_us(callback(this, + &SX1272_LoRaRadio::timeout_irq_isr), + timeout*1e3); + } + + if (_rf_settings.modem == MODEM_FSK) { + set_operation_mode(RF_OPMODE_RECEIVER); + + if (_rf_settings.fsk.rx_continuous == false) { + rx_timeout_sync_word.attach_us(callback(this, + &SX1272_LoRaRadio::timeout_irq_isr), + _rf_settings.fsk.rx_single_timeout * 1e3); + } + + return; + } + + // If mode is LoRa set mode + if (_rf_settings.lora.rx_continuous == true) { + set_operation_mode(RFLR_OPMODE_RECEIVER); + } else { + set_operation_mode(RFLR_OPMODE_RECEIVER_SINGLE); + } +} + +/** + * Puts a limit on the size of payload the module can handle + * By default it is MAX, i.e., 256 bytes + */ +void SX1272_LoRaRadio::set_max_payload_length(radio_modems_t modem, uint8_t max) +{ + set_modem(modem); + + switch (modem) { + case MODEM_FSK: + if (_rf_settings.fsk.fix_len == false) { + write_to_register(REG_PAYLOADLENGTH, max); + } + break; + case MODEM_LORA: + write_to_register(REG_LR_PAYLOADMAXLENGTH, max); + break; + } +} + +/** + * TODO: Making sure if this API is valid only for LoRa modulation ? + * + * Indicates if the node is part of a private or public network + */ +void SX1272_LoRaRadio::set_public_network(bool enable) +{ + set_modem(MODEM_LORA); + + _rf_settings.lora.public_network = enable; + if (enable == true) { + // Change lora modem SyncWord + write_to_register(REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD); + } else { + // Change lora modem SyncWord + write_to_register(REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD); + } + +} + +/** + * Perform carrier sensing + * + * Checks for a certain time if the RSSI is above a given threshold. + * This threshold determines if there is already a transmission going on + * in the channel or not. + * + */ +bool SX1272_LoRaRadio::perform_carrier_sense(radio_modems_t modem, + uint32_t freq, + int16_t rssi_threshold, + uint32_t max_carrier_sense_time) +{ + bool status = true; + int16_t rssi = 0; + + set_modem(modem); + set_channel(freq); + set_operation_mode(RF_OPMODE_RECEIVER); + + // hold on a bit, radio turn-around time + wait_ms(1); + + Timer elapsed_time; + elapsed_time.start(); + + // Perform carrier sense for maxCarrierSenseTime + while (elapsed_time.read_ms() < max_carrier_sense_time) { + rssi = get_rssi(modem); + + if (rssi > rssi_threshold) { + status = false; + break; + } + } + + sleep(); + return status; +} + +/** + * Channel Activity detection (can be done only in LoRa mode) + * + * If any activity on the channel is detected, an interrupt is asserted on + * DIO3. A callback will be generated to the stack/application upon the + * assertion of DIO3. + */ +void SX1272_LoRaRadio::start_cad() +{ + uint8_t reg_val; + + switch (_rf_settings.modem) { + case MODEM_FSK: + break; + case MODEM_LORA: + write_to_register(REG_LR_IRQFLAGSMASK, + RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL); + + // DIO3=CADDone + reg_val = read_register(REG_DIOMAPPING1); + write_to_register(REG_DIOMAPPING1, (reg_val & + RFLR_DIOMAPPING1_DIO3_MASK) | + RFLR_DIOMAPPING1_DIO3_00); + + set_operation_mode(RFLR_OPMODE_CAD); + + _rf_settings.state = RF_CAD; + + break; + default: + break; + } +} + +/** + * Set transmission in continuous wave mode + */ +void SX1272_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, + uint16_t time) +{ + uint8_t reg_val; + + set_channel(freq); + set_tx_config(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, time); + reg_val = read_register(REG_PACKETCONFIG2); + + write_to_register( REG_PACKETCONFIG2, (reg_val & RF_PACKETCONFIG2_DATAMODE_MASK ) ); + // Disable radio interrupts + write_to_register( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 ); + write_to_register( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 ); + + _rf_settings.state = RF_TX_RUNNING; + tx_timeout_timer.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr), time*1e3); + set_operation_mode(RF_OPMODE_TRANSMITTER); +} + +/** + * Put radio in Standby mode + */ +void SX1272_LoRaRadio::standby( void ) +{ + tx_timeout_timer.detach(); + rx_timeout_timer.detach(); + + set_operation_mode(RF_OPMODE_STANDBY); + _rf_settings.state = RF_IDLE; +} + +/** + * Generates 32 bit random number based upon RSSI monitoring + * Used for various calculation by the stack for example dev nonce + * + * When this API is used modem is set in LoRa mode and all interrupts are + * masked. If the user had been using FSK mode, it should be noted that a + * change of mode is required again because the registers have changed. + * In addition to that RX and TX configuration APIs should be called again in + * order to have correct desires setup. + */ +uint32_t SX1272_LoRaRadio::random() +{ + uint8_t i; + uint32_t rnd = 0; + + // Set LoRa modem ON + set_modem(MODEM_LORA); + + // Disable LoRa modem interrupts, i.e., mask all interrupts + write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | RFLR_IRQFLAGS_RXDONE + | RFLR_IRQFLAGS_PAYLOADCRCERROR | RFLR_IRQFLAGS_VALIDHEADER + | RFLR_IRQFLAGS_TXDONE | RFLR_IRQFLAGS_CADDONE + | RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | RFLR_IRQFLAGS_CADDETECTED); + + // Set radio in continuous reception + set_operation_mode(RF_OPMODE_RECEIVER); + + for (i = 0; i < 32; i++) { + wait_ms(1); + // Unfiltered RSSI value reading. Only takes the LSB value + rnd |= ((uint32_t) read_register(REG_LR_RSSIWIDEBAND) & 0x01) << i; + } + + sleep(); + + return rnd; +} + + +/***************************************************************************** + * Private APIs * + ****************************************************************************/ +#ifdef MBED_CONF_RTOS_PRESENT +/** + * Thread task handling IRQs + */ +void SX1272_LoRaRadio::rf_irq_task(void) +{ + for (;;) { + osEvent event = irq_thread.signal_wait(0, osWaitForever); + if (event.status != osEventSignal) { + continue; + } + + lock(); + if (event.value.signals & SIG_DIO0) { + handle_dio0_irq(); + } + if (event.value.signals & SIG_DIO1) { + handle_dio1_irq(); + } + if (event.value.signals & SIG_DIO2) { + handle_dio2_irq(); + } + if (event.value.signals & SIG_DIO3) { + handle_dio3_irq(); + } + if (event.value.signals & SIG_DIO4) { + handle_dio4_irq(); + } + if (event.value.signals & SIG_DIO5) { + handle_dio5_irq(); + } + if (event.value.signals & SIG_TIMOUT) { + handle_timeout_irq(); + } + unlock(); + } +} +#endif + +/** + * Writes a single byte to a given register + */ +void SX1272_LoRaRadio::write_to_register(uint8_t addr, uint8_t data) +{ + write_to_register(addr, &data, 1); +} + +/** + * Writes multiple bytes to a given register + */ +void SX1272_LoRaRadio::write_to_register(uint8_t addr, uint8_t *data, uint8_t size) +{ + // set chip-select low + _chip_select = 0; + + // set write command + _spi.write(addr | SPI_WRITE_CMD); + + // write data + for (uint8_t i = 0; i < size; i++) { + _spi.write(data[i]); + } + + // set chip-select high + _chip_select = 1; +} + +/** + * Reads the value of a single register + */ +uint8_t SX1272_LoRaRadio::read_register(uint8_t addr) +{ + uint8_t data; + read_register(addr, &data, 1); + return data; +} + +/** + * Reads multiple values from a given register + */ +void SX1272_LoRaRadio::read_register(uint8_t addr, uint8_t *buffer, uint8_t size) +{ + // set chip-select low + _chip_select = 0; + + // set read command + _spi.write(addr & SPI_READ_CMD); + + // read buffers + for (uint8_t i = 0; i < size; i++) { + buffer[i] = _spi.write(0); + } + + // set chip-select high + _chip_select = 1; +} + +/** + * Writes to FIIO provided by the chip + */ +void SX1272_LoRaRadio::write_fifo(uint8_t *buffer, uint8_t size) +{ + write_to_register(0, buffer, size); +} + +/** + * Reads from the FIFO provided by the chip + */ +void SX1272_LoRaRadio::read_fifo(uint8_t *buffer, uint8_t size) +{ + read_register(0, buffer, size); +} + +/** + * Gets FSK bandwidth values + * + * Gives either normal bandwidths or bandwidths for + * AFC (auto frequency correction) + */ +uint8_t SX1272_LoRaRadio::get_fsk_bw_reg_val(uint32_t bandwidth) +{ + uint8_t i; + + for (i = 0; i < (sizeof(fsk_bandwidths) / sizeof(fsk_bw_t)) - 1; i++) { + if ((bandwidth >= fsk_bandwidths[i].bandwidth) + && (bandwidth < fsk_bandwidths[i + 1].bandwidth)) { + return fsk_bandwidths[i].register_value; + } + } + // ERROR: Value not found + // This should never happen + while (1); +} + +/** + * Sets the radio modules to default position (off) + * + * Historically they were being called as Antenna switches, so we kept the name. + * In essence these are control latches over duplexer which either let + * TX submodule or RX submodule circuitry enabled at a time. + */ +void SX1272_LoRaRadio::default_antenna_switch_ctrls() +{ + if (_rf_ctrls.pwr_amp_ctl != NC) { + _pwr_amp_ctl = 0; + } + + if (_rf_ctrls.rf_switch_ctl1 != NC && _rf_ctrls.rf_switch_ctl2 != NC) { + _rf_switch_ctl1 = 0; + _rf_switch_ctl2 = 0; + } + + if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) + _txctl = 0; + _rxctl = 0; +} + +/** + * Gets the power amplifier configuration register + */ +uint8_t SX1272_LoRaRadio::get_pa_conf_reg() +{ + +#if defined(TARGET_MTS_MDOT_F411RE) + return RF_PACONFIG_PASELECT_PABOOST; +#endif + if (radio_variant == SX1272MB1DCS) { + return RF_PACONFIG_PASELECT_PABOOST; + } + + return RF_PACONFIG_PASELECT_RFO; +} + +/** + * Get RSSI from the module + */ +int16_t SX1272_LoRaRadio::get_rssi(radio_modems_t modem) +{ + int16_t rssi = 0; + + switch( modem ) + { + case MODEM_FSK: + rssi = -(read_register(REG_RSSIVALUE) >> 1 ); + break; + case MODEM_LORA: + rssi = RSSI_OFFSET + read_register(REG_LR_RSSIVALUE); + break; + default: + rssi = -1; + break; + } + return rssi; +} + +/** + * Sets the transmit power for the module + */ +#if defined ( TARGET_MOTE_L152RC ) +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}; +static const uint8_t RFO_table[11] = {1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 9}; +#endif + +void SX1272_LoRaRadio::set_rf_tx_power(int8_t power) +{ + uint8_t pa_config = 0; + uint8_t pa_dac = 0; + + pa_config = read_register(REG_PACONFIG); + pa_dac = read_register(REG_PADAC); + +#if defined ( TARGET_MOTE_L152RC ) + if(power > 19) { + pa_config = (pa_config & RF_PACONFIG_PASELECT_MASK) | RF_PACONFIG_PASELECT_RFO; + pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) | RFO_table[power - 20]; + } + else + { + pa_config = (pa_config & RF_PACONFIG_PASELECT_MASK) | RF_PACONFIG_PASELECT_PABOOST; + pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) | pa_boost_table[power]; + } +#else + pa_config = (pa_config & RF_PACONFIG_PASELECT_MASK) | get_pa_conf_reg(); + + if ((pa_config & RF_PACONFIG_PASELECT_PABOOST) + == RF_PACONFIG_PASELECT_PABOOST) { + if (power > 17) { + pa_dac = (pa_dac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_ON; + } else { + pa_dac = (pa_dac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_OFF; + } + if ((pa_dac & RF_PADAC_20DBM_ON) == RF_PADAC_20DBM_ON) { + if (power < 5) { + power = 5; + } + if (power > 20) { + power = 20; + } + pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) + | (uint8_t) ((uint16_t) (power - 5) & 0x0F); + } else { + if (power < 2) { + power = 2; + } + if (power > 17) { + power = 17; + } + pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) + | (uint8_t) ((uint16_t) (power - 2) & 0x0F); + } + } else { + if (power < -1) { + power = -1; + } + if (power > 14) { + power = 14; + } + pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) + | (uint8_t) ((uint16_t) (power + 1) & 0x0F); + } +#endif + write_to_register(REG_PACONFIG, pa_config); + write_to_register(REG_PADAC, pa_dac); +} + +/** + * Sets the radio registers to defaults + */ +void SX1272_LoRaRadio::setup_registers() +{ + for (unsigned int i = 0; i < sizeof(radio_reg_init) / sizeof(radio_registers_t); i++) { + set_modem(radio_reg_init[i].modem); + write_to_register(radio_reg_init[i].addr, radio_reg_init[i].value); + } +} + +/** + * Set the radio module variant + */ +void SX1272_LoRaRadio::set_sx1272_variant_type() +{ + _ant_switch.input(); + wait_ms(1); + if (_ant_switch == 1) { + radio_variant = SX1272MB1DCS; + } else { + radio_variant = SX1272MB2XAS; + } + _ant_switch.output(); + wait_ms(1); +} + +/** + * Sets up radio latch position according to the + * radio mode + */ +void SX1272_LoRaRadio::set_antenna_switch(uint8_t mode) +{ + // here we got to do ifdef for changing controls + // as some pins might be NC + switch (mode) { + case RFLR_OPMODE_TRANSMITTER: + if (_rf_ctrls.rf_switch_ctl1 != NC + && _rf_ctrls.rf_switch_ctl2 != NC) { + // module is in transmit mode and RF latch switches + // are connected. Check if power amplifier boost is + // setup or not + if ((read_register(REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST) + == RF_PACONFIG_PASELECT_PABOOST) { + _rf_switch_ctl1 = 1; + _rf_switch_ctl2 = 0; + } else { + // power amplifier not selected + _rf_switch_ctl1 = 0; + _rf_switch_ctl2 = 1; + } + } else if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) { + // module is in transmit mode and tx/rx submodule control + // pins are connected + _txctl = 1; + _rxctl = 0; + } else if (_rf_ctrls.ant_switch != NC){ + MBED_ASSERT(_rf_ctrls.ant_switch == NC); + _ant_switch = 1; + } else { + // Either None of the control pins are connected or wrong + // combination of controls pins. Break the system right here. + MBED_ASSERT(false); + } + break; + case RFLR_OPMODE_RECEIVER: + case RFLR_OPMODE_RECEIVER_SINGLE: + case RFLR_OPMODE_CAD: + if (_rf_ctrls.rf_switch_ctl1 != NC + && _rf_ctrls.rf_switch_ctl2 != NC) { + // radio is in reception or CAD mode and RF latch switches + // are connected + _rf_switch_ctl1 = 1; + _rf_switch_ctl2 = 1; + } else if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) { + _txctl = 0; + _rxctl = 1; + } else if (_rf_ctrls.ant_switch != NC) { + _ant_switch = 0; + } else { + // Either None of the control pins are connected or wrong + // combination of controls pins. Break the system right here. + MBED_ASSERT(false); + } + break; + default: + // Enforce default case when any connected control pin is kept low. + if (_rf_ctrls.rf_switch_ctl1 != NC + && _rf_ctrls.rf_switch_ctl2 != NC) { + // radio is in reception or CAD mode and RF latch switches + // are connected + _rf_switch_ctl1 = 0; + _rf_switch_ctl2 = 0; + } else if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) { + _txctl = 0; + _rxctl = 0; + } else if (_rf_ctrls.ant_switch != NC) { + _ant_switch = 0; + } else { + // Either None of the control pins are connected or wrong + // combination of controls pins. Break the system right here. + MBED_ASSERT(false); + } + break; + } +} + +/** + * Sets up frequency for SPI module + * Reference DataSheet: 4.3 SPI Interface + */ +void SX1272_LoRaRadio::setup_spi() +{ + // SPI bus frequency + uint32_t spi_freq = SPI_FREQUENCY; + + // Hold chip-select high + _chip_select = 1; + _spi.format(8, 0); + +#if defined (TARGET_KL25Z) + //bus-clock frequency is halved -> double the SPI frequency to compensate + _spi.frequency(spi_freq * 2); +#else + // otherwise use default SPI frequency which is 8 MHz + _spi.frequency(spi_freq); +#endif + // 100 us wait to settle down + wait(0.1); +} + +/** + * Attaches ISRs to interrupt pins + */ +void SX1272_LoRaRadio::setup_interrupts() +{ + _dio0_ctl.rise(callback(this, &SX1272_LoRaRadio::dio0_irq_isr)); + _dio1_ctl.rise(callback(this, &SX1272_LoRaRadio::dio1_irq_isr)); + _dio2_ctl.rise(callback(this, &SX1272_LoRaRadio::dio2_irq_isr)); + _dio3_ctl.rise(callback(this, &SX1272_LoRaRadio::dio3_irq_isr)); + _dio4_ctl.rise(callback(this, &SX1272_LoRaRadio::dio4_irq_isr)); + _dio5_ctl.rise(callback(this, &SX1272_LoRaRadio::dio5_irq_isr)); +} + +/** + * Sets the module in low power mode by disconnecting + * TX and RX submodules, turning off power amplifier etc. + */ +void SX1272_LoRaRadio::set_low_power_mode(bool status) +{ + + if( RadioIsActive != status ) + { + RadioIsActive = status; + + if( status == false ) + { + // Its safe to not check for pin connections here as the write() + // would do nothing if pin is not connected + _rf_switch_ctl1 = 0; + _rf_switch_ctl2 = 0; + _pwr_amp_ctl = 0; + _txctl = 0; + _rxctl = 0; + } + else + { + default_antenna_switch_ctrls( ); + } + } +} + +/***************************************************************************** + * Interrupt service routines (ISRs) - set signals to the irq_thread * + ****************************************************************************/ +void SX1272_LoRaRadio::dio0_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO0); +#else + handle_dio0_irq(); +#endif +} + +void SX1272_LoRaRadio::dio1_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO1); +#else + handle_dio1_irq(); +#endif +} + +void SX1272_LoRaRadio::dio2_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO2); +#else + handle_dio2_irq(); +#endif +} + +void SX1272_LoRaRadio::dio3_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO3); +#else + handle_dio3_irq(); +#endif +} + +void SX1272_LoRaRadio::dio4_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO4); +#else + handle_dio4_irq(); +#endif +} + +void SX1272_LoRaRadio::dio5_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO5); +#else + handle_dio5_irq(); +#endif +} + +// This is not a hardware interrupt +// we invoke it ourselves based upon +// our timers +void SX1272_LoRaRadio::timeout_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_TIMOUT); +#else + handle_timeout_irq(); +#endif +} + +/****************************************************************************** + * Interrupt Handlers * + *****************************************************************************/ + +void SX1272_LoRaRadio::handle_dio0_irq() +{ + volatile uint8_t irqFlags = 0; + + switch (_rf_settings.state) { + case RF_RX_RUNNING: + switch (_rf_settings.modem) { + case MODEM_FSK: + if (_rf_settings.fsk.crc_on == true) { + irqFlags = read_register(REG_IRQFLAGS2); + if ((irqFlags & RF_IRQFLAGS2_CRCOK) + != RF_IRQFLAGS2_CRCOK) { + // Clear Irqs + write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | + RF_IRQFLAGS1_PREAMBLEDETECT | + RF_IRQFLAGS1_SYNCADDRESSMATCH); + write_to_register(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); + + + if (_rf_settings.fsk.rx_continuous == false) { + rx_timeout_sync_word.detach(); + _rf_settings.state = RF_IDLE; + } else { + // Continuous mode restart Rx chain + write_to_register(REG_RXCONFIG, + read_register(REG_RXCONFIG) | + RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + } + + rx_timeout_timer.detach(); + + if ((_radio_events != NULL) + && (_radio_events->rx_error != NULL)) { + _radio_events->rx_error(); + } + _rf_settings.fsk_packet_handler.preamble_detected = false; + _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; + // break from here, a CRC error happened, RX_ERROR + // was notified. No need to go any further + break; + } + } + + // Read received packet size + if ((_rf_settings.fsk_packet_handler.size == 0) + && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) { + if (_rf_settings.fsk.fix_len == false) { + read_fifo((uint8_t*) &_rf_settings.fsk_packet_handler.size, 1); + } else { + _rf_settings.fsk_packet_handler.size = read_register(REG_PAYLOADLENGTH); + } + read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.nb_bytes += + (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + } else { + read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.nb_bytes += + (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + } + + if (_rf_settings.fsk.rx_continuous == false) { + _rf_settings.state = RF_IDLE; + rx_timeout_sync_word.detach(); + } else { + // Continuous mode restart Rx chain + write_to_register(REG_RXCONFIG, read_register(REG_RXCONFIG) + | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + } + + rx_timeout_timer.detach(); + + if ((_radio_events != NULL) && (_radio_events->rx_done != NULL)) { + _radio_events->rx_done( + _data_buffer, + _rf_settings.fsk_packet_handler.size, + _rf_settings.fsk_packet_handler.rssi_value, 0); + } + _rf_settings.fsk_packet_handler.preamble_detected = false; + _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; + break; + case MODEM_LORA: { + int8_t snr = 0; + + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE); + + irqFlags = read_register(REG_LR_IRQFLAGS); + if ((irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK) + == RFLR_IRQFLAGS_PAYLOADCRCERROR) { + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, + RFLR_IRQFLAGS_PAYLOADCRCERROR); + + if (_rf_settings.lora.rx_continuous == false) { + _rf_settings.state = RF_IDLE; + } + rx_timeout_timer.detach(); + + if ((_radio_events != NULL) + && (_radio_events->rx_error != NULL)) { + _radio_events->rx_error(); + } + break; + } + + _rf_settings.lora_packet_handler.snr_value = read_register(REG_LR_PKTSNRVALUE); + if (_rf_settings.lora_packet_handler.snr_value & 0x80) // The SNR sign bit is 1 + { + // Invert and divide by 4 + snr = ((~_rf_settings.lora_packet_handler.snr_value + 1) & 0xFF) >> 2; + snr = -snr; + } else { + // Divide by 4 + snr =(_rf_settings.lora_packet_handler.snr_value & 0xFF) >> 2; + } + + int16_t rssi = read_register(REG_LR_PKTRSSIVALUE); + if (snr < 0) { + _rf_settings.lora_packet_handler.rssi_value = + RSSI_OFFSET + rssi + (rssi >> 4) + snr; + } else { + _rf_settings.lora_packet_handler.rssi_value = + RSSI_OFFSET + rssi + (rssi >> 4); + } + + _rf_settings.lora_packet_handler.size = read_register(REG_LR_RXNBBYTES); + read_fifo(_data_buffer, _rf_settings.lora_packet_handler.size); + + if (_rf_settings.lora.rx_continuous == false) { + _rf_settings.state = RF_IDLE; + } + rx_timeout_timer.detach(); + + if ((_radio_events != NULL) + && (_radio_events->rx_done != NULL)) { + _radio_events->rx_done( + _data_buffer, + _rf_settings.lora_packet_handler.size, + _rf_settings.lora_packet_handler.rssi_value, + _rf_settings.lora_packet_handler.snr_value); + } + } + break; + default: + break; + } + break; + case RF_TX_RUNNING: + tx_timeout_timer.detach(); + // TxDone interrupt + switch (_rf_settings.modem) { + case MODEM_LORA: + // Clear Irq + write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE); + // Intentional fall through + case MODEM_FSK: + default: + _rf_settings.state = RF_IDLE; + if ((_radio_events != NULL) + && (_radio_events->tx_done != NULL)) { + _radio_events->tx_done(); + } + break; + } + break; + default: + break; + } +} + +void SX1272_LoRaRadio::handle_dio1_irq() +{ + + switch(_rf_settings.state ) + { + case RF_RX_RUNNING: + switch(_rf_settings.modem ) { + case MODEM_FSK: + // FifoLevel interrupt + // Read received packet size + if( ( _rf_settings.fsk_packet_handler.size == 0 ) && ( _rf_settings.fsk_packet_handler.nb_bytes == 0 ) ) + { + if( _rf_settings.fsk.fix_len == false ) + { + read_fifo( ( uint8_t* )&_rf_settings.fsk_packet_handler.size, 1 ); + } + else + { + _rf_settings.fsk_packet_handler.size = read_register(REG_PAYLOADLENGTH); + } + } + + if( ( _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ) > _rf_settings.fsk_packet_handler.fifo_thresh ) + { + read_fifo( ( _data_buffer + _rf_settings.fsk_packet_handler.nb_bytes ), _rf_settings.fsk_packet_handler.fifo_thresh ); + _rf_settings.fsk_packet_handler.nb_bytes += _rf_settings.fsk_packet_handler.fifo_thresh; + } + else + { + read_fifo( ( _data_buffer + _rf_settings.fsk_packet_handler.nb_bytes ), _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ); + _rf_settings.fsk_packet_handler.nb_bytes += ( _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ); + } + break; + case MODEM_LORA: + // Sync time out + rx_timeout_timer.detach( ); + _rf_settings.state = RF_IDLE; + if ((_radio_events != NULL) && (_radio_events->rx_timeout != NULL)) { + _radio_events->rx_timeout(); + } + break; + default: + break; + } + break; + case RF_TX_RUNNING: + switch( _rf_settings.modem ) + { + case MODEM_FSK: + // FifoLevel interrupt + if( ( _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ) > _rf_settings.fsk_packet_handler.chunk_size ) + { + write_fifo(( _data_buffer + _rf_settings.fsk_packet_handler.nb_bytes ), _rf_settings.fsk_packet_handler.chunk_size ); + _rf_settings.fsk_packet_handler.nb_bytes += _rf_settings.fsk_packet_handler.chunk_size; + } + else + { + // Write the last chunk of data + write_fifo( _data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ); + _rf_settings.fsk_packet_handler.nb_bytes += _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes; + } + break; + case MODEM_LORA: + break; + default: + break; + } + break; + default: + break; + } +} + +void SX1272_LoRaRadio::handle_dio2_irq(void) +{ + switch(_rf_settings.state ) + { + case RF_RX_RUNNING: + switch( _rf_settings.modem ) + { + case MODEM_FSK: + + // DIO4 must have been asserted to set preamble_detected to true + if( ( _rf_settings.fsk_packet_handler.preamble_detected == true ) && ( _rf_settings.fsk_packet_handler.sync_word_detected == false ) ) + { + if (_rf_settings.fsk.rx_continuous == false) { + rx_timeout_sync_word.detach( ); + } + + _rf_settings.fsk_packet_handler.sync_word_detected = true; + + _rf_settings.fsk_packet_handler.rssi_value = -( read_register( REG_RSSIVALUE ) >> 1 ); + + _rf_settings.fsk_packet_handler.afc_value = ( int32_t )( double )( ( ( uint16_t )read_register( REG_AFCMSB ) << 8 ) | + ( uint16_t )read_register( REG_AFCLSB ) ) * + ( double )FREQ_STEP; + _rf_settings.fsk_packet_handler.rx_gain = ( read_register( REG_LNA ) >> 5 ) & 0x07; + } + break; + case MODEM_LORA: + if( _rf_settings.lora.freq_hop_on == true ) + { + // Clear Irq + write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); + + if( ( _radio_events != NULL ) && (_radio_events->fhss_change_channel != NULL ) ) + { + _radio_events->fhss_change_channel((read_register( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK )); + } + } + break; + default: + break; + } + break; + case RF_TX_RUNNING: + switch( _rf_settings.modem ) + { + case MODEM_FSK: + break; + case MODEM_LORA: + if( _rf_settings.lora.freq_hop_on == true ) + { + // Clear Irq + write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); + + if( (_radio_events != NULL ) && ( _radio_events->fhss_change_channel != NULL ) ) + { + _radio_events->fhss_change_channel((read_register( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK )); + } + } + break; + default: + break; + } + break; + default: + break; + } +} + +void SX1272_LoRaRadio::handle_dio3_irq( void ) +{ + switch( _rf_settings.modem ) + { + case MODEM_FSK: + break; + case MODEM_LORA: + if( ( read_register( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED ) + { + // Clear Irq + write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE ); + if( ( _radio_events != NULL ) && ( _radio_events->cad_done != NULL ) ) + { + _radio_events->cad_done( true ); + } + } + else + { + // Clear Irq + write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE ); + if( ( _radio_events != NULL ) && ( _radio_events->cad_done != NULL ) ) + { + _radio_events->cad_done( false ); + } + } + break; + default: + break; + } +} + +void SX1272_LoRaRadio::handle_dio4_irq(void) +{ + // is asserted when a preamble is detected (FSK modem only) + switch (_rf_settings.modem) { + case MODEM_FSK: { + if (_rf_settings.fsk_packet_handler.preamble_detected + == false) { + _rf_settings.fsk_packet_handler.preamble_detected = true; + } + } + break; + case MODEM_LORA: + break; + default: + break; + } +} + +void SX1272_LoRaRadio::handle_dio5_irq() +{ + switch( _rf_settings.modem ) + { + case MODEM_FSK: + break; + case MODEM_LORA: + break; + default: + break; + } +} + + +void SX1272_LoRaRadio::handle_timeout_irq() +{ + switch(_rf_settings.state ) + { + case RF_RX_RUNNING: + if( _rf_settings.modem == MODEM_FSK ) { + _rf_settings.fsk_packet_handler.preamble_detected = false; + _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; + + // Clear Irqs + write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | + RF_IRQFLAGS1_PREAMBLEDETECT | + RF_IRQFLAGS1_SYNCADDRESSMATCH); + write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); + + if( _rf_settings.fsk.rx_continuous == true ) + { + // Continuous mode restart Rx chain + write_to_register( REG_RXCONFIG, read_register(REG_RXCONFIG) | + RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + } + else + { + _rf_settings.state = RF_IDLE; + rx_timeout_sync_word.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr), + _rf_settings.fsk.rx_single_timeout * 1e3); + } + } + + if((_radio_events != NULL) && (_radio_events->rx_timeout != NULL)) { + _radio_events->rx_timeout(); + } + + break; + + case RF_TX_RUNNING: + // Tx timeout shouldn't happen. + // But it has been observed that when it happens it is a result of a + // corrupted SPI transfer + // The workaround is to put the radio in a known state. + // Thus, we re-initialize it. + + // Reset the radio + radio_reset( ); + + // Initialize radio default values + set_operation_mode( RF_OPMODE_SLEEP ); + + setup_registers(); + + set_modem(MODEM_FSK); + + // Restore previous network type setting. + set_public_network(_rf_settings.lora.public_network); + + _rf_settings.state = RF_IDLE; + if( ( _radio_events != NULL ) && ( _radio_events->tx_timeout != NULL ) ) + { + _radio_events->tx_timeout( ); + } + break; + default: + break; + } +} diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h new file mode 100644 index 0000000000..c99d237207 --- /dev/null +++ b/SX1272/SX1272_LoRaRadio.h @@ -0,0 +1,402 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: Radio driver for Semtech SX1272 radio. Implements LoRaRadio class. + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef SX1272_LORARADIO_H_ +#define SX1272_LORARADIO_H_ + +#include "netsocket/LoRaRadio.h" + +#ifdef MBED_SX1272_LORARADIO_BUFFER_SIZE +#define MAX_DATA_BUFFER_SIZE MBED_SX1272_LORARADIO_BUFFER_SIZE +#else +#define MAX_DATA_BUFFER_SIZE 256 +#endif + +typedef struct { + PinName rf_switch_ctl1; + PinName rf_switch_ctl2; + PinName txctl; + PinName rxctl; + PinName ant_switch; + PinName pwr_amp_ctl; +} rf_ctrls; + +/** + * Radio driver implementation for Semtech SX1272 plus variants. + * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. + */ +class SX1272_LoRaRadio: public LoRaRadio { +public: + /** + * Use this constructor if pin definitions are provided manually. + * The pins that are marked NC are optional. It is assumed that these + * pins are not connected until/unless configured otherwise. + */ + SX1272_LoRaRadio(PinName mosi, PinName miso, PinName sclk, PinName nss, + PinName reset, PinName dio0, PinName dio1, PinName dio2, + PinName dio3, PinName dio4, PinName dio5, + PinName rf_switch_ctl1=NC, + PinName rf_switch_ctl2=NC, PinName txctl = NC, + PinName rxctl = NC, PinName ant_switch = NC, + PinName pwr_amp_ctl = NC); + + /** + * Destructor + */ + virtual ~SX1272_LoRaRadio(); + + /** + * Registers radio events with the Mbed LoRaWAN stack and + * undergoes initialization steps if any + * + * @param events Structure containing the driver callback functions + */ + virtual void init_radio(radio_events_t *events); + + /** + * Resets the radio module + */ + virtual void radio_reset(); + + /** + * Put the RF module in sleep mode + */ + virtual void sleep(void); + + /** + * Sets the radio in standby mode + */ + virtual void standby(void); + + /** + * Sets the reception parameters + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param bandwidth Sets the bandwidth + * FSK : >= 2600 and <= 250000 Hz + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * @param datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * @param coderate Sets the coding rate ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * @param bandwidth_afc Sets the AFC Bandwidth ( FSK only ) + * FSK : >= 2600 and <= 250000 Hz + * LoRa: N/A ( set to 0 ) + * @param preamble_len Sets the Preamble length ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: Length in symbols ( the hardware adds 4 more symbols ) + * @param symb_timeout Sets the RxSingle timeout value + * FSK : timeout number of bytes + * LoRa: timeout in symbols + * @param fixLen Fixed length packets [0: variable, 1: fixed] + * @param payload_len Sets payload length when fixed lenght is used + * @param crc_on Enables/Disables the CRC [0: OFF, 1: ON] + * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) + * @param hop_period Number of symbols bewteen each hop (LoRa only) + * @param iq_inverted Inverts IQ signals ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * @param rx_continuous Sets the reception in continuous mode + * [false: single mode, true: continuous mode] + */ + virtual void set_rx_config (radio_modems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidth_afc, uint16_t preamble_len, + uint16_t symb_timeout, bool fix_len, + uint8_t payload_len, + bool crc_on, bool freq_hop_on, uint8_t hop_period, + bool iq_inverted, bool rx_continuous); + + /** + * Sets the transmission parameters + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param power Sets the output power [dBm] + * @param fdev Sets the frequency deviation ( FSK only ) + * FSK : [Hz] + * LoRa: 0 + * @param bandwidth Sets the bandwidth ( LoRa only ) + * FSK : 0 + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * @param datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * @param coderate Sets the coding rate ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * @param preamble_len Sets the preamble length + * @param fix_len Fixed length packets [0: variable, 1: fixed] + * @param crc_on Enables disables the CRC [0: OFF, 1: ON] + * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) + * @param hop_period Number of symbols bewteen each hop (LoRa only) + * @param iq_inverted Inverts IQ signals ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * @param timeout Transmission timeout [us] + */ + virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preamble_len, + bool fix_len, bool crc_on, bool freq_hop_on, + uint8_t hop_period, bool iq_inverted, uint32_t timeout); + + /** + * Sends the buffer of size + * + * Prepares the packet to be sent and sets the radio in transmission + * + * @param buffer Buffer pointer + * @param size Buffer size + */ + virtual void send(uint8_t *buffer, uint8_t size); + + /** + * Sets the radio in reception mode for the given time + * + * It should be noted that if the timeout is set to 0, it essentially + * puts the receiver in continuous mode and hence from thereon it should + * be treated as if in continuous mode. However, an appropriate way of + * setting the receiver in continuous mode is by using set_rx_config() + * API. + * + * @param timeout Reception timeout [ms] + * + */ + virtual void receive(uint32_t timeout); + + /** + * Sets the carrier frequency + * + * @param freq Channel RF frequency + */ + virtual void set_channel(uint32_t freq); + + /** + * Generates a 32 bits random value based on the RSSI readings + * + * Remark this function sets the radio in LoRa modem mode and disables + * all interrupts. + * After calling this function either Radio.SetRxConfig or + * Radio.SetTxConfig functions must be called. + * + * @return 32 bits random value + */ + virtual uint32_t random(void); + + /** + * Get radio status + * + * @param status Radio status [RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] + * @return Return current radio status + */ + virtual uint8_t get_status(void); + + /** + * Sets the maximum payload length + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param max Maximum payload length in bytes + */ + virtual void set_max_payload_length(radio_modems_t modem, uint8_t max); + + /** + * Sets the network to public or private + * + * Updates the sync byte. Applies to LoRa modem only + * + * @param enable if true, it enables a public network + */ + virtual void set_public_network(bool enable); + + /** + * Computes the packet time on air for the given payload + * + * Remark can only be called once SetRxConfig or SetTxConfig have been called + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param pkt_len Packet payload length + * @return Computed airTime for the given packet payload length + */ + virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len); + + /** + * Perform carrier sensing + * + * Checks for a certain time if the RSSI is above a given threshold. + * This threshold determines if there is already a transmission going on + * in the channel or not. + * + * @param modem Type of the radio modem + * @param freq Carrier frequency + * @param rssi_threshold Threshold value of RSSI + * @param max_carrier_sense_time time to sense the channel + * + * @return true if there is no active transmission + * in the channel, false otherwise + */ + virtual bool perform_carrier_sense(radio_modems_t modem, + uint32_t freq, + int16_t rssi_threshold, + uint32_t max_carrier_sense_time); + + /** + * Sets the radio in CAD mode + * + */ + virtual void start_cad(void); + + /** + * Check if the given RF is in range + * + * @param frequency frequency needed to be checked + */ + virtual bool check_rf_frequency(uint32_t frequency); + + /** Sets the radio in continuous wave transmission mode + * + * @param freq Channel RF frequency + * @param power Sets the output power [dBm] + * @param time Transmission mode timeout [s] + */ + virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time); + + /** + * Acquire exclusive access + */ + virtual void lock(void); + + /** + * Release exclusive access + */ + virtual void unlock(void); + +private: + + // SPI and chip select control + SPI _spi; + DigitalOut _chip_select; + + // module rest control + DigitalInOut _reset_ctl; + + // Interrupt controls + InterruptIn _dio0_ctl; + InterruptIn _dio1_ctl; + InterruptIn _dio2_ctl; + InterruptIn _dio3_ctl; + InterruptIn _dio4_ctl; + InterruptIn _dio5_ctl; + + // Radio specific controls + DigitalOut _rf_switch_ctl1; + DigitalOut _rf_switch_ctl2; + DigitalOut _txctl; + DigitalOut _rxctl; + DigitalInOut _ant_switch; + DigitalOut _pwr_amp_ctl; + + // Contains all RF control pin names + // This storage is needed even after assigning the + // pins to corresponding object, as the driver needs to know + // which control pins are connected and which are not. This + // variation is inherent to driver because of target configuration. + rf_ctrls _rf_ctrls; + + // Structure containing all user and network specified settings + // for radio module + radio_settings_t _rf_settings; + + // Structure containing function pointers to the stack callbacks + radio_events_t *_radio_events; + + // Data buffer used for both TX and RX + // Size of this buffer is configurable via Mbed config system + // Default is 256 bytes + uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE]; + + // TX/RX Timers - all use milisecond units + Timeout tx_timeout_timer; + Timeout rx_timeout_timer; + Timeout rx_timeout_sync_word; + +#ifdef MBED_CONF_RTOS_PRESENT + // Thread to handle interrupts + Thread irq_thread; +#endif + + // Access protection + PlatformMutex mutex; + + // helper functions + void setup_registers(); + void default_antenna_switch_ctrls(); + void set_antenna_switch(uint8_t operation_mode); + void setup_spi(); + void gpio_init(); + void gpio_deinit(); + void setup_interrupts(); + void set_modem(uint8_t modem); + void set_operation_mode(uint8_t mode); + void set_low_power_mode(bool status); + void set_sx1272_variant_type(); + uint8_t get_pa_conf_reg(); + void set_rf_tx_power(int8_t power); + int16_t get_rssi(radio_modems_t modem); + uint8_t get_fsk_bw_reg_val(uint32_t bandwidth); + void write_to_register(uint8_t addr, uint8_t data); + void write_to_register(uint8_t addr, uint8_t *data, uint8_t size); + uint8_t read_register(uint8_t addr); + void read_register(uint8_t addr, uint8_t *buffer, uint8_t size); + void write_fifo(uint8_t *buffer, uint8_t size); + void read_fifo(uint8_t *buffer, uint8_t size); + void transmit(uint32_t timeout); + void rf_irq_task(void); + + // ISRs + void dio0_irq_isr(); + void dio1_irq_isr(); + void dio2_irq_isr(); + void dio3_irq_isr(); + void dio4_irq_isr(); + void dio5_irq_isr(); + void timeout_irq_isr(); + + // Handlers called by thread in response to signal + void handle_dio0_irq(); + void handle_dio1_irq(); + void handle_dio2_irq(); + void handle_dio3_irq(); + void handle_dio4_irq(); + void handle_dio5_irq(); + void handle_timeout_irq(); +}; + +#endif /* SX1272_LORARADIO_H_ */ diff --git a/SX1272/mbed_lib.json b/SX1272/mbed_lib.json new file mode 100644 index 0000000000..d114658abe --- /dev/null +++ b/SX1272/mbed_lib.json @@ -0,0 +1,13 @@ +{ + "name": "sx1272-lora-driver", + "config": { + "spi-frequency": { + "help": "SPI frequency, Default: 8 MHz", + "value": 8000000 + }, + "buffer-size": { + "help": "Max. buffer size the radio can handle, Default: 256 B", + "value": 256 + } + } +} diff --git a/SX1272/registers/sx1272Regs-Fsk.h b/SX1272/registers/sx1272Regs-Fsk.h new file mode 100644 index 0000000000..04d1fbd800 --- /dev/null +++ b/SX1272/registers/sx1272Regs-Fsk.h @@ -0,0 +1,1138 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C) 2015 Semtech + +Description: SX1272 FSK modem registers and bits definitions + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ +#ifndef __SX1272_REGS_FSK_H__ +#define __SX1272_REGS_FSK_H__ + +/*! + * ============================================================================ + * SX1272 Internal registers Address + * ============================================================================ + */ +#define REG_FIFO 0x00 +// Common settings +#define REG_OPMODE 0x01 +#define REG_BITRATEMSB 0x02 +#define REG_BITRATELSB 0x03 +#define REG_FDEVMSB 0x04 +#define REG_FDEVLSB 0x05 +#define REG_FRFMSB 0x06 +#define REG_FRFMID 0x07 +#define REG_FRFLSB 0x08 +// Tx settings +#define REG_PACONFIG 0x09 +#define REG_PARAMP 0x0A +#define REG_OCP 0x0B +// Rx settings +#define REG_LNA 0x0C +#define REG_RXCONFIG 0x0D +#define REG_RSSICONFIG 0x0E +#define REG_RSSICOLLISION 0x0F +#define REG_RSSITHRESH 0x10 +#define REG_RSSIVALUE 0x11 +#define REG_RXBW 0x12 +#define REG_AFCBW 0x13 +#define REG_OOKPEAK 0x14 +#define REG_OOKFIX 0x15 +#define REG_OOKAVG 0x16 +#define REG_RES17 0x17 +#define REG_RES18 0x18 +#define REG_RES19 0x19 +#define REG_AFCFEI 0x1A +#define REG_AFCMSB 0x1B +#define REG_AFCLSB 0x1C +#define REG_FEIMSB 0x1D +#define REG_FEILSB 0x1E +#define REG_PREAMBLEDETECT 0x1F +#define REG_RXTIMEOUT1 0x20 +#define REG_RXTIMEOUT2 0x21 +#define REG_RXTIMEOUT3 0x22 +#define REG_RXDELAY 0x23 +// Oscillator settings +#define REG_OSC 0x24 +// Packet handler settings +#define REG_PREAMBLEMSB 0x25 +#define REG_PREAMBLELSB 0x26 +#define REG_SYNCCONFIG 0x27 +#define REG_SYNCVALUE1 0x28 +#define REG_SYNCVALUE2 0x29 +#define REG_SYNCVALUE3 0x2A +#define REG_SYNCVALUE4 0x2B +#define REG_SYNCVALUE5 0x2C +#define REG_SYNCVALUE6 0x2D +#define REG_SYNCVALUE7 0x2E +#define REG_SYNCVALUE8 0x2F +#define REG_PACKETCONFIG1 0x30 +#define REG_PACKETCONFIG2 0x31 +#define REG_PAYLOADLENGTH 0x32 +#define REG_NODEADRS 0x33 +#define REG_BROADCASTADRS 0x34 +#define REG_FIFOTHRESH 0x35 +// SM settings +#define REG_SEQCONFIG1 0x36 +#define REG_SEQCONFIG2 0x37 +#define REG_TIMERRESOL 0x38 +#define REG_TIMER1COEF 0x39 +#define REG_TIMER2COEF 0x3A +// Service settings +#define REG_IMAGECAL 0x3B +#define REG_TEMP 0x3C +#define REG_LOWBAT 0x3D +// Status +#define REG_IRQFLAGS1 0x3E +#define REG_IRQFLAGS2 0x3F +// I/O settings +#define REG_DIOMAPPING1 0x40 +#define REG_DIOMAPPING2 0x41 +// Version +#define REG_VERSION 0x42 +// Additional settings +#define REG_AGCREF 0x43 +#define REG_AGCTHRESH1 0x44 +#define REG_AGCTHRESH2 0x45 +#define REG_AGCTHRESH3 0x46 +#define REG_PLLHOP 0x4B +#define REG_TCXO 0x58 +#define REG_PADAC 0x5A +#define REG_PLL 0x5C +#define REG_PLLLOWPN 0x5E +#define REG_FORMERTEMP 0x6C +#define REG_BITRATEFRAC 0x70 + +/*! + * ============================================================================ + * SX1272 FSK bits control definition + * ============================================================================ + */ + +/*! + * RegFifo + */ + +/*! + * RegOpMode + */ +#define RF_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RF_OPMODE_LONGRANGEMODE_OFF 0x00 +#define RF_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RF_OPMODE_MODULATIONTYPE_MASK 0x9F +#define RF_OPMODE_MODULATIONTYPE_FSK 0x00 // Default +#define RF_OPMODE_MODULATIONTYPE_OOK 0x20 + +#define RF_OPMODE_MODULATIONSHAPING_MASK 0xE7 +#define RF_OPMODE_MODULATIONSHAPING_00 0x00 // Default +#define RF_OPMODE_MODULATIONSHAPING_01 0x08 +#define RF_OPMODE_MODULATIONSHAPING_10 0x10 +#define RF_OPMODE_MODULATIONSHAPING_11 0x18 + +#define RF_OPMODE_MASK 0xF8 +#define RF_OPMODE_SLEEP 0x00 +#define RF_OPMODE_STANDBY 0x01 // Default +#define RF_OPMODE_SYNTHESIZER_TX 0x02 +#define RF_OPMODE_TRANSMITTER 0x03 +#define RF_OPMODE_SYNTHESIZER_RX 0x04 +#define RF_OPMODE_RECEIVER 0x05 + +/*! + * RegBitRate (bits/sec) + */ +#define RF_BITRATEMSB_1200_BPS 0x68 +#define RF_BITRATELSB_1200_BPS 0x2B +#define RF_BITRATEMSB_2400_BPS 0x34 +#define RF_BITRATELSB_2400_BPS 0x15 +#define RF_BITRATEMSB_4800_BPS 0x1A // Default +#define RF_BITRATELSB_4800_BPS 0x0B // Default +#define RF_BITRATEMSB_9600_BPS 0x0D +#define RF_BITRATELSB_9600_BPS 0x05 +#define RF_BITRATEMSB_15000_BPS 0x08 +#define RF_BITRATELSB_15000_BPS 0x55 +#define RF_BITRATEMSB_19200_BPS 0x06 +#define RF_BITRATELSB_19200_BPS 0x83 +#define RF_BITRATEMSB_38400_BPS 0x03 +#define RF_BITRATELSB_38400_BPS 0x41 +#define RF_BITRATEMSB_76800_BPS 0x01 +#define RF_BITRATELSB_76800_BPS 0xA1 +#define RF_BITRATEMSB_153600_BPS 0x00 +#define RF_BITRATELSB_153600_BPS 0xD0 +#define RF_BITRATEMSB_57600_BPS 0x02 +#define RF_BITRATELSB_57600_BPS 0x2C +#define RF_BITRATEMSB_115200_BPS 0x01 +#define RF_BITRATELSB_115200_BPS 0x16 +#define RF_BITRATEMSB_12500_BPS 0x0A +#define RF_BITRATELSB_12500_BPS 0x00 +#define RF_BITRATEMSB_25000_BPS 0x05 +#define RF_BITRATELSB_25000_BPS 0x00 +#define RF_BITRATEMSB_50000_BPS 0x02 +#define RF_BITRATELSB_50000_BPS 0x80 +#define RF_BITRATEMSB_100000_BPS 0x01 +#define RF_BITRATELSB_100000_BPS 0x40 +#define RF_BITRATEMSB_150000_BPS 0x00 +#define RF_BITRATELSB_150000_BPS 0xD5 +#define RF_BITRATEMSB_200000_BPS 0x00 +#define RF_BITRATELSB_200000_BPS 0xA0 +#define RF_BITRATEMSB_250000_BPS 0x00 +#define RF_BITRATELSB_250000_BPS 0x80 +#define RF_BITRATEMSB_32768_BPS 0x03 +#define RF_BITRATELSB_32768_BPS 0xD1 + +/*! + * RegFdev (Hz) + */ +#define RF_FDEVMSB_2000_HZ 0x00 +#define RF_FDEVLSB_2000_HZ 0x21 +#define RF_FDEVMSB_5000_HZ 0x00 // Default +#define RF_FDEVLSB_5000_HZ 0x52 // Default +#define RF_FDEVMSB_10000_HZ 0x00 +#define RF_FDEVLSB_10000_HZ 0xA4 +#define RF_FDEVMSB_15000_HZ 0x00 +#define RF_FDEVLSB_15000_HZ 0xF6 +#define RF_FDEVMSB_20000_HZ 0x01 +#define RF_FDEVLSB_20000_HZ 0x48 +#define RF_FDEVMSB_25000_HZ 0x01 +#define RF_FDEVLSB_25000_HZ 0x9A +#define RF_FDEVMSB_30000_HZ 0x01 +#define RF_FDEVLSB_30000_HZ 0xEC +#define RF_FDEVMSB_35000_HZ 0x02 +#define RF_FDEVLSB_35000_HZ 0x3D +#define RF_FDEVMSB_40000_HZ 0x02 +#define RF_FDEVLSB_40000_HZ 0x8F +#define RF_FDEVMSB_45000_HZ 0x02 +#define RF_FDEVLSB_45000_HZ 0xE1 +#define RF_FDEVMSB_50000_HZ 0x03 +#define RF_FDEVLSB_50000_HZ 0x33 +#define RF_FDEVMSB_55000_HZ 0x03 +#define RF_FDEVLSB_55000_HZ 0x85 +#define RF_FDEVMSB_60000_HZ 0x03 +#define RF_FDEVLSB_60000_HZ 0xD7 +#define RF_FDEVMSB_65000_HZ 0x04 +#define RF_FDEVLSB_65000_HZ 0x29 +#define RF_FDEVMSB_70000_HZ 0x04 +#define RF_FDEVLSB_70000_HZ 0x7B +#define RF_FDEVMSB_75000_HZ 0x04 +#define RF_FDEVLSB_75000_HZ 0xCD +#define RF_FDEVMSB_80000_HZ 0x05 +#define RF_FDEVLSB_80000_HZ 0x1F +#define RF_FDEVMSB_85000_HZ 0x05 +#define RF_FDEVLSB_85000_HZ 0x71 +#define RF_FDEVMSB_90000_HZ 0x05 +#define RF_FDEVLSB_90000_HZ 0xC3 +#define RF_FDEVMSB_95000_HZ 0x06 +#define RF_FDEVLSB_95000_HZ 0x14 +#define RF_FDEVMSB_100000_HZ 0x06 +#define RF_FDEVLSB_100000_HZ 0x66 +#define RF_FDEVMSB_110000_HZ 0x07 +#define RF_FDEVLSB_110000_HZ 0x0A +#define RF_FDEVMSB_120000_HZ 0x07 +#define RF_FDEVLSB_120000_HZ 0xAE +#define RF_FDEVMSB_130000_HZ 0x08 +#define RF_FDEVLSB_130000_HZ 0x52 +#define RF_FDEVMSB_140000_HZ 0x08 +#define RF_FDEVLSB_140000_HZ 0xF6 +#define RF_FDEVMSB_150000_HZ 0x09 +#define RF_FDEVLSB_150000_HZ 0x9A +#define RF_FDEVMSB_160000_HZ 0x0A +#define RF_FDEVLSB_160000_HZ 0x3D +#define RF_FDEVMSB_170000_HZ 0x0A +#define RF_FDEVLSB_170000_HZ 0xE1 +#define RF_FDEVMSB_180000_HZ 0x0B +#define RF_FDEVLSB_180000_HZ 0x85 +#define RF_FDEVMSB_190000_HZ 0x0C +#define RF_FDEVLSB_190000_HZ 0x29 +#define RF_FDEVMSB_200000_HZ 0x0C +#define RF_FDEVLSB_200000_HZ 0xCD + +/*! + * RegFrf (MHz) + */ +#define RF_FRFMSB_863_MHZ 0xD7 +#define RF_FRFMID_863_MHZ 0xC0 +#define RF_FRFLSB_863_MHZ 0x00 +#define RF_FRFMSB_864_MHZ 0xD8 +#define RF_FRFMID_864_MHZ 0x00 +#define RF_FRFLSB_864_MHZ 0x00 +#define RF_FRFMSB_865_MHZ 0xD8 +#define RF_FRFMID_865_MHZ 0x40 +#define RF_FRFLSB_865_MHZ 0x00 +#define RF_FRFMSB_866_MHZ 0xD8 +#define RF_FRFMID_866_MHZ 0x80 +#define RF_FRFLSB_866_MHZ 0x00 +#define RF_FRFMSB_867_MHZ 0xD8 +#define RF_FRFMID_867_MHZ 0xC0 +#define RF_FRFLSB_867_MHZ 0x00 +#define RF_FRFMSB_868_MHZ 0xD9 +#define RF_FRFMID_868_MHZ 0x00 +#define RF_FRFLSB_868_MHZ 0x00 +#define RF_FRFMSB_869_MHZ 0xD9 +#define RF_FRFMID_869_MHZ 0x40 +#define RF_FRFLSB_869_MHZ 0x00 +#define RF_FRFMSB_870_MHZ 0xD9 +#define RF_FRFMID_870_MHZ 0x80 +#define RF_FRFLSB_870_MHZ 0x00 + +#define RF_FRFMSB_902_MHZ 0xE1 +#define RF_FRFMID_902_MHZ 0x80 +#define RF_FRFLSB_902_MHZ 0x00 +#define RF_FRFMSB_903_MHZ 0xE1 +#define RF_FRFMID_903_MHZ 0xC0 +#define RF_FRFLSB_903_MHZ 0x00 +#define RF_FRFMSB_904_MHZ 0xE2 +#define RF_FRFMID_904_MHZ 0x00 +#define RF_FRFLSB_904_MHZ 0x00 +#define RF_FRFMSB_905_MHZ 0xE2 +#define RF_FRFMID_905_MHZ 0x40 +#define RF_FRFLSB_905_MHZ 0x00 +#define RF_FRFMSB_906_MHZ 0xE2 +#define RF_FRFMID_906_MHZ 0x80 +#define RF_FRFLSB_906_MHZ 0x00 +#define RF_FRFMSB_907_MHZ 0xE2 +#define RF_FRFMID_907_MHZ 0xC0 +#define RF_FRFLSB_907_MHZ 0x00 +#define RF_FRFMSB_908_MHZ 0xE3 +#define RF_FRFMID_908_MHZ 0x00 +#define RF_FRFLSB_908_MHZ 0x00 +#define RF_FRFMSB_909_MHZ 0xE3 +#define RF_FRFMID_909_MHZ 0x40 +#define RF_FRFLSB_909_MHZ 0x00 +#define RF_FRFMSB_910_MHZ 0xE3 +#define RF_FRFMID_910_MHZ 0x80 +#define RF_FRFLSB_910_MHZ 0x00 +#define RF_FRFMSB_911_MHZ 0xE3 +#define RF_FRFMID_911_MHZ 0xC0 +#define RF_FRFLSB_911_MHZ 0x00 +#define RF_FRFMSB_912_MHZ 0xE4 +#define RF_FRFMID_912_MHZ 0x00 +#define RF_FRFLSB_912_MHZ 0x00 +#define RF_FRFMSB_913_MHZ 0xE4 +#define RF_FRFMID_913_MHZ 0x40 +#define RF_FRFLSB_913_MHZ 0x00 +#define RF_FRFMSB_914_MHZ 0xE4 +#define RF_FRFMID_914_MHZ 0x80 +#define RF_FRFLSB_914_MHZ 0x00 +#define RF_FRFMSB_915_MHZ 0xE4 // Default +#define RF_FRFMID_915_MHZ 0xC0 // Default +#define RF_FRFLSB_915_MHZ 0x00 // Default +#define RF_FRFMSB_916_MHZ 0xE5 +#define RF_FRFMID_916_MHZ 0x00 +#define RF_FRFLSB_916_MHZ 0x00 +#define RF_FRFMSB_917_MHZ 0xE5 +#define RF_FRFMID_917_MHZ 0x40 +#define RF_FRFLSB_917_MHZ 0x00 +#define RF_FRFMSB_918_MHZ 0xE5 +#define RF_FRFMID_918_MHZ 0x80 +#define RF_FRFLSB_918_MHZ 0x00 +#define RF_FRFMSB_919_MHZ 0xE5 +#define RF_FRFMID_919_MHZ 0xC0 +#define RF_FRFLSB_919_MHZ 0x00 +#define RF_FRFMSB_920_MHZ 0xE6 +#define RF_FRFMID_920_MHZ 0x00 +#define RF_FRFLSB_920_MHZ 0x00 +#define RF_FRFMSB_921_MHZ 0xE6 +#define RF_FRFMID_921_MHZ 0x40 +#define RF_FRFLSB_921_MHZ 0x00 +#define RF_FRFMSB_922_MHZ 0xE6 +#define RF_FRFMID_922_MHZ 0x80 +#define RF_FRFLSB_922_MHZ 0x00 +#define RF_FRFMSB_923_MHZ 0xE6 +#define RF_FRFMID_923_MHZ 0xC0 +#define RF_FRFLSB_923_MHZ 0x00 +#define RF_FRFMSB_924_MHZ 0xE7 +#define RF_FRFMID_924_MHZ 0x00 +#define RF_FRFLSB_924_MHZ 0x00 +#define RF_FRFMSB_925_MHZ 0xE7 +#define RF_FRFMID_925_MHZ 0x40 +#define RF_FRFLSB_925_MHZ 0x00 +#define RF_FRFMSB_926_MHZ 0xE7 +#define RF_FRFMID_926_MHZ 0x80 +#define RF_FRFLSB_926_MHZ 0x00 +#define RF_FRFMSB_927_MHZ 0xE7 +#define RF_FRFMID_927_MHZ 0xC0 +#define RF_FRFLSB_927_MHZ 0x00 +#define RF_FRFMSB_928_MHZ 0xE8 +#define RF_FRFMID_928_MHZ 0x00 +#define RF_FRFLSB_928_MHZ 0x00 + +/*! + * RegPaConfig + */ +#define RF_PACONFIG_PASELECT_MASK 0x7F +#define RF_PACONFIG_PASELECT_PABOOST 0x80 +#define RF_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RF_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +/*! + * RegPaRamp + */ +#define RF_PARAMP_LOWPNTXPLL_MASK 0xEF +#define RF_PARAMP_LOWPNTXPLL_OFF 0x10 // Default +#define RF_PARAMP_LOWPNTXPLL_ON 0x00 + +#define RF_PARAMP_MASK 0xF0 +#define RF_PARAMP_3400_US 0x00 +#define RF_PARAMP_2000_US 0x01 +#define RF_PARAMP_1000_US 0x02 +#define RF_PARAMP_0500_US 0x03 +#define RF_PARAMP_0250_US 0x04 +#define RF_PARAMP_0125_US 0x05 +#define RF_PARAMP_0100_US 0x06 +#define RF_PARAMP_0062_US 0x07 +#define RF_PARAMP_0050_US 0x08 +#define RF_PARAMP_0040_US 0x09 // Default +#define RF_PARAMP_0031_US 0x0A +#define RF_PARAMP_0025_US 0x0B +#define RF_PARAMP_0020_US 0x0C +#define RF_PARAMP_0015_US 0x0D +#define RF_PARAMP_0012_US 0x0E +#define RF_PARAMP_0010_US 0x0F + +/*! + * RegOcp + */ +#define RF_OCP_MASK 0xDF +#define RF_OCP_ON 0x20 // Default +#define RF_OCP_OFF 0x00 + +#define RF_OCP_TRIM_MASK 0xE0 +#define RF_OCP_TRIM_045_MA 0x00 +#define RF_OCP_TRIM_050_MA 0x01 +#define RF_OCP_TRIM_055_MA 0x02 +#define RF_OCP_TRIM_060_MA 0x03 +#define RF_OCP_TRIM_065_MA 0x04 +#define RF_OCP_TRIM_070_MA 0x05 +#define RF_OCP_TRIM_075_MA 0x06 +#define RF_OCP_TRIM_080_MA 0x07 +#define RF_OCP_TRIM_085_MA 0x08 +#define RF_OCP_TRIM_090_MA 0x09 +#define RF_OCP_TRIM_095_MA 0x0A +#define RF_OCP_TRIM_100_MA 0x0B // Default +#define RF_OCP_TRIM_105_MA 0x0C +#define RF_OCP_TRIM_110_MA 0x0D +#define RF_OCP_TRIM_115_MA 0x0E +#define RF_OCP_TRIM_120_MA 0x0F +#define RF_OCP_TRIM_130_MA 0x10 +#define RF_OCP_TRIM_140_MA 0x11 +#define RF_OCP_TRIM_150_MA 0x12 +#define RF_OCP_TRIM_160_MA 0x13 +#define RF_OCP_TRIM_170_MA 0x14 +#define RF_OCP_TRIM_180_MA 0x15 +#define RF_OCP_TRIM_190_MA 0x16 +#define RF_OCP_TRIM_200_MA 0x17 +#define RF_OCP_TRIM_210_MA 0x18 +#define RF_OCP_TRIM_220_MA 0x19 +#define RF_OCP_TRIM_230_MA 0x1A +#define RF_OCP_TRIM_240_MA 0x1B + +/*! + * RegLna + */ +#define RF_LNA_GAIN_MASK 0x1F +#define RF_LNA_GAIN_G1 0x20 // Default +#define RF_LNA_GAIN_G2 0x40 +#define RF_LNA_GAIN_G3 0x60 +#define RF_LNA_GAIN_G4 0x80 +#define RF_LNA_GAIN_G5 0xA0 +#define RF_LNA_GAIN_G6 0xC0 + +#define RF_LNA_BOOST_MASK 0xFC +#define RF_LNA_BOOST_OFF 0x00 // Default +#define RF_LNA_BOOST_ON 0x03 + +/*! + * RegRxConfig + */ +#define RF_RXCONFIG_RESTARTRXONCOLLISION_MASK 0x7F +#define RF_RXCONFIG_RESTARTRXONCOLLISION_ON 0x80 +#define RF_RXCONFIG_RESTARTRXONCOLLISION_OFF 0x00 // Default + +#define RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK 0x40 // Write only + +#define RF_RXCONFIG_RESTARTRXWITHPLLLOCK 0x20 // Write only + +#define RF_RXCONFIG_AFCAUTO_MASK 0xEF +#define RF_RXCONFIG_AFCAUTO_ON 0x10 +#define RF_RXCONFIG_AFCAUTO_OFF 0x00 // Default + +#define RF_RXCONFIG_AGCAUTO_MASK 0xF7 +#define RF_RXCONFIG_AGCAUTO_ON 0x08 // Default +#define RF_RXCONFIG_AGCAUTO_OFF 0x00 + +#define RF_RXCONFIG_RXTRIGER_MASK 0xF8 +#define RF_RXCONFIG_RXTRIGER_OFF 0x00 +#define RF_RXCONFIG_RXTRIGER_RSSI 0x01 +#define RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT 0x06 // Default +#define RF_RXCONFIG_RXTRIGER_RSSI_PREAMBLEDETECT 0x07 + +/*! + * RegRssiConfig + */ +#define RF_RSSICONFIG_OFFSET_MASK 0x07 +#define RF_RSSICONFIG_OFFSET_P_00_DB 0x00 // Default +#define RF_RSSICONFIG_OFFSET_P_01_DB 0x08 +#define RF_RSSICONFIG_OFFSET_P_02_DB 0x10 +#define RF_RSSICONFIG_OFFSET_P_03_DB 0x18 +#define RF_RSSICONFIG_OFFSET_P_04_DB 0x20 +#define RF_RSSICONFIG_OFFSET_P_05_DB 0x28 +#define RF_RSSICONFIG_OFFSET_P_06_DB 0x30 +#define RF_RSSICONFIG_OFFSET_P_07_DB 0x38 +#define RF_RSSICONFIG_OFFSET_P_08_DB 0x40 +#define RF_RSSICONFIG_OFFSET_P_09_DB 0x48 +#define RF_RSSICONFIG_OFFSET_P_10_DB 0x50 +#define RF_RSSICONFIG_OFFSET_P_11_DB 0x58 +#define RF_RSSICONFIG_OFFSET_P_12_DB 0x60 +#define RF_RSSICONFIG_OFFSET_P_13_DB 0x68 +#define RF_RSSICONFIG_OFFSET_P_14_DB 0x70 +#define RF_RSSICONFIG_OFFSET_P_15_DB 0x78 +#define RF_RSSICONFIG_OFFSET_M_16_DB 0x80 +#define RF_RSSICONFIG_OFFSET_M_15_DB 0x88 +#define RF_RSSICONFIG_OFFSET_M_14_DB 0x90 +#define RF_RSSICONFIG_OFFSET_M_13_DB 0x98 +#define RF_RSSICONFIG_OFFSET_M_12_DB 0xA0 +#define RF_RSSICONFIG_OFFSET_M_11_DB 0xA8 +#define RF_RSSICONFIG_OFFSET_M_10_DB 0xB0 +#define RF_RSSICONFIG_OFFSET_M_09_DB 0xB8 +#define RF_RSSICONFIG_OFFSET_M_08_DB 0xC0 +#define RF_RSSICONFIG_OFFSET_M_07_DB 0xC8 +#define RF_RSSICONFIG_OFFSET_M_06_DB 0xD0 +#define RF_RSSICONFIG_OFFSET_M_05_DB 0xD8 +#define RF_RSSICONFIG_OFFSET_M_04_DB 0xE0 +#define RF_RSSICONFIG_OFFSET_M_03_DB 0xE8 +#define RF_RSSICONFIG_OFFSET_M_02_DB 0xF0 +#define RF_RSSICONFIG_OFFSET_M_01_DB 0xF8 + +#define RF_RSSICONFIG_SMOOTHING_MASK 0xF8 +#define RF_RSSICONFIG_SMOOTHING_2 0x00 +#define RF_RSSICONFIG_SMOOTHING_4 0x01 +#define RF_RSSICONFIG_SMOOTHING_8 0x02 // Default +#define RF_RSSICONFIG_SMOOTHING_16 0x03 +#define RF_RSSICONFIG_SMOOTHING_32 0x04 +#define RF_RSSICONFIG_SMOOTHING_64 0x05 +#define RF_RSSICONFIG_SMOOTHING_128 0x06 +#define RF_RSSICONFIG_SMOOTHING_256 0x07 + +/*! + * RegRssiCollision + */ +#define RF_RSSICOLISION_THRESHOLD 0x0A // Default + +/*! + * RegRssiThresh + */ +#define RF_RSSITHRESH_THRESHOLD 0xFF // Default + +/*! + * RegRssiValue (Read Only) + */ + +/*! + * RegRxBw + */ +#define RF_RXBW_MANT_MASK 0xE7 +#define RF_RXBW_MANT_16 0x00 +#define RF_RXBW_MANT_20 0x08 +#define RF_RXBW_MANT_24 0x10 // Default + +#define RF_RXBW_EXP_MASK 0xF8 +#define RF_RXBW_EXP_0 0x00 +#define RF_RXBW_EXP_1 0x01 +#define RF_RXBW_EXP_2 0x02 +#define RF_RXBW_EXP_3 0x03 +#define RF_RXBW_EXP_4 0x04 +#define RF_RXBW_EXP_5 0x05 // Default +#define RF_RXBW_EXP_6 0x06 +#define RF_RXBW_EXP_7 0x07 + +/*! + * RegAfcBw + */ +#define RF_AFCBW_MANTAFC_MASK 0xE7 +#define RF_AFCBW_MANTAFC_16 0x00 +#define RF_AFCBW_MANTAFC_20 0x08 // Default +#define RF_AFCBW_MANTAFC_24 0x10 + +#define RF_AFCBW_EXPAFC_MASK 0xF8 +#define RF_AFCBW_EXPAFC_0 0x00 +#define RF_AFCBW_EXPAFC_1 0x01 +#define RF_AFCBW_EXPAFC_2 0x02 +#define RF_AFCBW_EXPAFC_3 0x03 // Default +#define RF_AFCBW_EXPAFC_4 0x04 +#define RF_AFCBW_EXPAFC_5 0x05 +#define RF_AFCBW_EXPAFC_6 0x06 +#define RF_AFCBW_EXPAFC_7 0x07 + +/*! + * RegOokPeak + */ +#define RF_OOKPEAK_BITSYNC_MASK 0xDF // Default +#define RF_OOKPEAK_BITSYNC_ON 0x20 // Default +#define RF_OOKPEAK_BITSYNC_OFF 0x00 + +#define RF_OOKPEAK_OOKTHRESHTYPE_MASK 0xE7 +#define RF_OOKPEAK_OOKTHRESHTYPE_FIXED 0x00 +#define RF_OOKPEAK_OOKTHRESHTYPE_PEAK 0x08 // Default +#define RF_OOKPEAK_OOKTHRESHTYPE_AVERAGE 0x10 + +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_MASK 0xF8 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_0_5_DB 0x00 // Default +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_0_DB 0x01 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_5_DB 0x02 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_2_0_DB 0x03 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_3_0_DB 0x04 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_4_0_DB 0x05 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_5_0_DB 0x06 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_6_0_DB 0x07 + +/*! + * RegOokFix + */ +#define RF_OOKFIX_OOKFIXEDTHRESHOLD 0x0C // Default + +/*! + * RegOokAvg + */ +#define RF_OOKAVG_OOKPEAKTHRESHDEC_MASK 0x1F +#define RF_OOKAVG_OOKPEAKTHRESHDEC_000 0x00 // Default +#define RF_OOKAVG_OOKPEAKTHRESHDEC_001 0x20 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_010 0x40 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_011 0x60 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_100 0x80 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_101 0xA0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_110 0xC0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_111 0xE0 + +#define RF_OOKAVG_AVERAGEOFFSET_MASK 0xF3 +#define RF_OOKAVG_AVERAGEOFFSET_0_DB 0x00 // Default +#define RF_OOKAVG_AVERAGEOFFSET_2_DB 0x04 +#define RF_OOKAVG_AVERAGEOFFSET_4_DB 0x08 +#define RF_OOKAVG_AVERAGEOFFSET_6_DB 0x0C + +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_MASK 0xFC +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_00 0x00 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_01 0x01 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_10 0x02 // Default +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_11 0x03 + +/*! + * RegAfcFei + */ +#define RF_AFCFEI_AGCSTART 0x10 + +#define RF_AFCFEI_AFCCLEAR 0x02 + +#define RF_AFCFEI_AFCAUTOCLEAR_MASK 0xFE +#define RF_AFCFEI_AFCAUTOCLEAR_ON 0x01 +#define RF_AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default + +/*! + * RegAfcMsb (Read Only) + */ + +/*! + * RegAfcLsb (Read Only) + */ + +/*! + * RegFeiMsb (Read Only) + */ + +/*! + * RegFeiLsb (Read Only) + */ + +/*! + * RegPreambleDetect + */ +#define RF_PREAMBLEDETECT_DETECTOR_MASK 0x7F +#define RF_PREAMBLEDETECT_DETECTOR_ON 0x80 // Default +#define RF_PREAMBLEDETECT_DETECTOR_OFF 0x00 + +#define RF_PREAMBLEDETECT_DETECTORSIZE_MASK 0x9F +#define RF_PREAMBLEDETECT_DETECTORSIZE_1 0x00 +#define RF_PREAMBLEDETECT_DETECTORSIZE_2 0x20 // Default +#define RF_PREAMBLEDETECT_DETECTORSIZE_3 0x40 +#define RF_PREAMBLEDETECT_DETECTORSIZE_4 0x60 + +#define RF_PREAMBLEDETECT_DETECTORTOL_MASK 0xE0 +#define RF_PREAMBLEDETECT_DETECTORTOL_0 0x00 +#define RF_PREAMBLEDETECT_DETECTORTOL_1 0x01 +#define RF_PREAMBLEDETECT_DETECTORTOL_2 0x02 +#define RF_PREAMBLEDETECT_DETECTORTOL_3 0x03 +#define RF_PREAMBLEDETECT_DETECTORTOL_4 0x04 +#define RF_PREAMBLEDETECT_DETECTORTOL_5 0x05 +#define RF_PREAMBLEDETECT_DETECTORTOL_6 0x06 +#define RF_PREAMBLEDETECT_DETECTORTOL_7 0x07 +#define RF_PREAMBLEDETECT_DETECTORTOL_8 0x08 +#define RF_PREAMBLEDETECT_DETECTORTOL_9 0x09 +#define RF_PREAMBLEDETECT_DETECTORTOL_10 0x0A // Default +#define RF_PREAMBLEDETECT_DETECTORTOL_11 0x0B +#define RF_PREAMBLEDETECT_DETECTORTOL_12 0x0C +#define RF_PREAMBLEDETECT_DETECTORTOL_13 0x0D +#define RF_PREAMBLEDETECT_DETECTORTOL_14 0x0E +#define RF_PREAMBLEDETECT_DETECTORTOL_15 0x0F +#define RF_PREAMBLEDETECT_DETECTORTOL_16 0x10 +#define RF_PREAMBLEDETECT_DETECTORTOL_17 0x11 +#define RF_PREAMBLEDETECT_DETECTORTOL_18 0x12 +#define RF_PREAMBLEDETECT_DETECTORTOL_19 0x13 +#define RF_PREAMBLEDETECT_DETECTORTOL_20 0x14 +#define RF_PREAMBLEDETECT_DETECTORTOL_21 0x15 +#define RF_PREAMBLEDETECT_DETECTORTOL_22 0x16 +#define RF_PREAMBLEDETECT_DETECTORTOL_23 0x17 +#define RF_PREAMBLEDETECT_DETECTORTOL_24 0x18 +#define RF_PREAMBLEDETECT_DETECTORTOL_25 0x19 +#define RF_PREAMBLEDETECT_DETECTORTOL_26 0x1A +#define RF_PREAMBLEDETECT_DETECTORTOL_27 0x1B +#define RF_PREAMBLEDETECT_DETECTORTOL_28 0x1C +#define RF_PREAMBLEDETECT_DETECTORTOL_29 0x1D +#define RF_PREAMBLEDETECT_DETECTORTOL_30 0x1E +#define RF_PREAMBLEDETECT_DETECTORTOL_31 0x1F + +/*! + * RegRxTimeout1 + */ +#define RF_RXTIMEOUT1_TIMEOUTRXRSSI 0x00 // Default + +/*! + * RegRxTimeout2 + */ +#define RF_RXTIMEOUT2_TIMEOUTRXPREAMBLE 0x00 // Default + +/*! + * RegRxTimeout3 + */ +#define RF_RXTIMEOUT3_TIMEOUTSIGNALSYNC 0x00 // Default + +/*! + * RegRxDelay + */ +#define RF_RXDELAY_INTERPACKETRXDELAY 0x00 // Default + +/*! + * RegOsc + */ +#define RF_OSC_RCCALSTART 0x08 + +#define RF_OSC_CLKOUT_MASK 0xF8 +#define RF_OSC_CLKOUT_32_MHZ 0x00 +#define RF_OSC_CLKOUT_16_MHZ 0x01 +#define RF_OSC_CLKOUT_8_MHZ 0x02 +#define RF_OSC_CLKOUT_4_MHZ 0x03 +#define RF_OSC_CLKOUT_2_MHZ 0x04 +#define RF_OSC_CLKOUT_1_MHZ 0x05 +#define RF_OSC_CLKOUT_RC 0x06 +#define RF_OSC_CLKOUT_OFF 0x07 // Default + +/*! + * RegPreambleMsb/RegPreambleLsb + */ +#define RF_PREAMBLEMSB_SIZE 0x00 // Default +#define RF_PREAMBLELSB_SIZE 0x03 // Default + +/*! + * RegSyncConfig + */ +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_MASK 0x3F +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON 0x80 // Default +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_OFF 0x40 +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_OFF 0x00 + + +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_MASK 0xDF +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_55 0x20 +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_AA 0x00 // Default + +#define RF_SYNCCONFIG_SYNC_MASK 0xEF +#define RF_SYNCCONFIG_SYNC_ON 0x10 // Default +#define RF_SYNCCONFIG_SYNC_OFF 0x00 + +#define RF_SYNCCONFIG_FIFOFILLCONDITION_MASK 0xF7 +#define RF_SYNCCONFIG_FIFOFILLCONDITION_AUTO 0x00 // Default +#define RF_SYNCCONFIG_FIFOFILLCONDITION_MANUAL 0x08 + +#define RF_SYNCCONFIG_SYNCSIZE_MASK 0xF8 +#define RF_SYNCCONFIG_SYNCSIZE_1 0x00 +#define RF_SYNCCONFIG_SYNCSIZE_2 0x01 +#define RF_SYNCCONFIG_SYNCSIZE_3 0x02 +#define RF_SYNCCONFIG_SYNCSIZE_4 0x03 // Default +#define RF_SYNCCONFIG_SYNCSIZE_5 0x04 +#define RF_SYNCCONFIG_SYNCSIZE_6 0x05 +#define RF_SYNCCONFIG_SYNCSIZE_7 0x06 +#define RF_SYNCCONFIG_SYNCSIZE_8 0x07 + +/*! + * RegSyncValue1-8 + */ +#define RF_SYNCVALUE1_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE2_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE3_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE4_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE5_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE6_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE7_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE8_SYNCVALUE 0x01 // Default + +/*! + * RegPacketConfig1 + */ +#define RF_PACKETCONFIG1_PACKETFORMAT_MASK 0x7F +#define RF_PACKETCONFIG1_PACKETFORMAT_FIXED 0x00 +#define RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE 0x80 // Default + +#define RF_PACKETCONFIG1_DCFREE_MASK 0x9F +#define RF_PACKETCONFIG1_DCFREE_OFF 0x00 // Default +#define RF_PACKETCONFIG1_DCFREE_MANCHESTER 0x20 +#define RF_PACKETCONFIG1_DCFREE_WHITENING 0x40 + +#define RF_PACKETCONFIG1_CRC_MASK 0xEF +#define RF_PACKETCONFIG1_CRC_ON 0x10 // Default +#define RF_PACKETCONFIG1_CRC_OFF 0x00 + +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_MASK 0xF7 +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_ON 0x00 // Default +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08 + +#define RF_PACKETCONFIG1_ADDRSFILTERING_MASK 0xF9 +#define RF_PACKETCONFIG1_ADDRSFILTERING_OFF 0x00 // Default +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODE 0x02 +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST 0x04 + +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_MASK 0xFE +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT 0x00 // Default +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_IBM 0x01 + +/*! + * RegPacketConfig2 + */ +#define RF_PACKETCONFIG2_DATAMODE_MASK 0xBF +#define RF_PACKETCONFIG2_DATAMODE_CONTINUOUS 0x00 +#define RF_PACKETCONFIG2_DATAMODE_PACKET 0x40 // Default + +#define RF_PACKETCONFIG2_IOHOME_MASK 0xDF +#define RF_PACKETCONFIG2_IOHOME_ON 0x20 +#define RF_PACKETCONFIG2_IOHOME_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_BEACON_MASK 0xF7 +#define RF_PACKETCONFIG2_BEACON_ON 0x08 +#define RF_PACKETCONFIG2_BEACON_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_PAYLOADLENGTH_MSB_MASK 0xF8 + +/*! + * RegPayloadLength + */ +#define RF_PAYLOADLENGTH_LENGTH 0x40 // Default + +/*! + * RegNodeAdrs + */ +#define RF_NODEADDRESS_ADDRESS 0x00 + +/*! + * RegBroadcastAdrs + */ +#define RF_BROADCASTADDRESS_ADDRESS 0x00 + +/*! + * RegFifoThresh + */ +#define RF_FIFOTHRESH_TXSTARTCONDITION_MASK 0x7F +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFOTHRESH 0x00 +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY 0x80 // Default + +#define RF_FIFOTHRESH_FIFOTHRESHOLD_MASK 0xC0 +#define RF_FIFOTHRESH_FIFOTHRESHOLD_THRESHOLD 0x0F // Default + +/*! + * RegSeqConfig1 + */ +#define RF_SEQCONFIG1_SEQUENCER_START 0x80 + +#define RF_SEQCONFIG1_SEQUENCER_STOP 0x40 + +#define RF_SEQCONFIG1_IDLEMODE_MASK 0xDF +#define RF_SEQCONFIG1_IDLEMODE_SLEEP 0x20 +#define RF_SEQCONFIG1_IDLEMODE_STANDBY 0x00 // Default + +#define RF_SEQCONFIG1_FROMSTART_MASK 0xE7 +#define RF_SEQCONFIG1_FROMSTART_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMSTART_TORX 0x08 +#define RF_SEQCONFIG1_FROMSTART_TOTX 0x10 +#define RF_SEQCONFIG1_FROMSTART_TOTX_ONFIFOLEVEL 0x18 + +#define RF_SEQCONFIG1_LPS_MASK 0xFB +#define RF_SEQCONFIG1_LPS_SEQUENCER_OFF 0x00 // Default +#define RF_SEQCONFIG1_LPS_IDLE 0x04 + +#define RF_SEQCONFIG1_FROMIDLE_MASK 0xFD +#define RF_SEQCONFIG1_FROMIDLE_TOTX 0x00 // Default +#define RF_SEQCONFIG1_FROMIDLE_TORX 0x02 + +#define RF_SEQCONFIG1_FROMTX_MASK 0xFE +#define RF_SEQCONFIG1_FROMTX_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMTX_TORX 0x01 + +/*! + * RegSeqConfig2 + */ +#define RF_SEQCONFIG2_FROMRX_MASK 0x1F +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_000 0x00 // Default +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONPLDRDY 0x20 +#define RF_SEQCONFIG2_FROMRX_TOLPS_ONPLDRDY 0x40 +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONCRCOK 0x60 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONRSSI 0x80 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONSYNC 0xA0 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONPREAMBLE 0xC0 +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_111 0xE0 + +#define RF_SEQCONFIG2_FROMRXTIMEOUT_MASK 0xE7 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TORXRESTART 0x00 // Default +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOTX 0x08 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOLPS 0x10 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOSEQUENCEROFF 0x18 + +#define RF_SEQCONFIG2_FROMRXPKT_MASK 0xF8 +#define RF_SEQCONFIG2_FROMRXPKT_TOSEQUENCEROFF 0x00 // Default +#define RF_SEQCONFIG2_FROMRXPKT_TOTX_ONFIFOEMPTY 0x01 +#define RF_SEQCONFIG2_FROMRXPKT_TOLPS 0x02 +#define RF_SEQCONFIG2_FROMRXPKT_TOSYNTHESIZERRX 0x03 +#define RF_SEQCONFIG2_FROMRXPKT_TORX 0x04 + +/*! + * RegTimerResol + */ +#define RF_TIMERRESOL_TIMER1RESOL_MASK 0xF3 +#define RF_TIMERRESOL_TIMER1RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER1RESOL_000064_US 0x04 +#define RF_TIMERRESOL_TIMER1RESOL_004100_US 0x08 +#define RF_TIMERRESOL_TIMER1RESOL_262000_US 0x0C + +#define RF_TIMERRESOL_TIMER2RESOL_MASK 0xFC +#define RF_TIMERRESOL_TIMER2RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER2RESOL_000064_US 0x01 +#define RF_TIMERRESOL_TIMER2RESOL_004100_US 0x02 +#define RF_TIMERRESOL_TIMER2RESOL_262000_US 0x03 + +/*! + * RegTimer1Coef + */ +#define RF_TIMER1COEF_TIMER1COEFFICIENT 0xF5 // Default + +/*! + * RegTimer2Coef + */ +#define RF_TIMER2COEF_TIMER2COEFFICIENT 0x20 // Default + +/*! + * RegImageCal + */ +#define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F +#define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 +#define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default + +#define RF_IMAGECAL_IMAGECAL_MASK 0xBF +#define RF_IMAGECAL_IMAGECAL_START 0x40 + +#define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 +#define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default + +#define RF_IMAGECAL_TEMPCHANGE_HIGHER 0x08 +#define RF_IMAGECAL_TEMPCHANGE_LOWER 0x00 + +#define RF_IMAGECAL_TEMPTHRESHOLD_MASK 0xF9 +#define RF_IMAGECAL_TEMPTHRESHOLD_05 0x00 +#define RF_IMAGECAL_TEMPTHRESHOLD_10 0x02 // Default +#define RF_IMAGECAL_TEMPTHRESHOLD_15 0x04 +#define RF_IMAGECAL_TEMPTHRESHOLD_20 0x06 + +#define RF_IMAGECAL_TEMPMONITOR_MASK 0xFE +#define RF_IMAGECAL_TEMPMONITOR_ON 0x00 // Default +#define RF_IMAGECAL_TEMPMONITOR_OFF 0x01 + +/*! + * RegTemp (Read Only) + */ + +/*! + * RegLowBat + */ +#define RF_LOWBAT_MASK 0xF7 +#define RF_LOWBAT_ON 0x08 +#define RF_LOWBAT_OFF 0x00 // Default + +#define RF_LOWBAT_TRIM_MASK 0xF8 +#define RF_LOWBAT_TRIM_1695 0x00 +#define RF_LOWBAT_TRIM_1764 0x01 +#define RF_LOWBAT_TRIM_1835 0x02 // Default +#define RF_LOWBAT_TRIM_1905 0x03 +#define RF_LOWBAT_TRIM_1976 0x04 +#define RF_LOWBAT_TRIM_2045 0x05 +#define RF_LOWBAT_TRIM_2116 0x06 +#define RF_LOWBAT_TRIM_2185 0x07 + +/*! + * RegIrqFlags1 + */ +#define RF_IRQFLAGS1_MODEREADY 0x80 + +#define RF_IRQFLAGS1_RXREADY 0x40 + +#define RF_IRQFLAGS1_TXREADY 0x20 + +#define RF_IRQFLAGS1_PLLLOCK 0x10 + +#define RF_IRQFLAGS1_RSSI 0x08 + +#define RF_IRQFLAGS1_TIMEOUT 0x04 + +#define RF_IRQFLAGS1_PREAMBLEDETECT 0x02 + +#define RF_IRQFLAGS1_SYNCADDRESSMATCH 0x01 + +/*! + * RegIrqFlags2 + */ +#define RF_IRQFLAGS2_FIFOFULL 0x80 + +#define RF_IRQFLAGS2_FIFOEMPTY 0x40 + +#define RF_IRQFLAGS2_FIFOLEVEL 0x20 + +#define RF_IRQFLAGS2_FIFOOVERRUN 0x10 + +#define RF_IRQFLAGS2_PACKETSENT 0x08 + +#define RF_IRQFLAGS2_PAYLOADREADY 0x04 + +#define RF_IRQFLAGS2_CRCOK 0x02 + +#define RF_IRQFLAGS2_LOWBAT 0x01 + +/*! + * RegDioMapping1 + */ +#define RF_DIOMAPPING1_DIO0_MASK 0x3F +#define RF_DIOMAPPING1_DIO0_00 0x00 // Default +#define RF_DIOMAPPING1_DIO0_01 0x40 +#define RF_DIOMAPPING1_DIO0_10 0x80 +#define RF_DIOMAPPING1_DIO0_11 0xC0 + +#define RF_DIOMAPPING1_DIO1_MASK 0xCF +#define RF_DIOMAPPING1_DIO1_00 0x00 // Default +#define RF_DIOMAPPING1_DIO1_01 0x10 +#define RF_DIOMAPPING1_DIO1_10 0x20 +#define RF_DIOMAPPING1_DIO1_11 0x30 + +#define RF_DIOMAPPING1_DIO2_MASK 0xF3 +#define RF_DIOMAPPING1_DIO2_00 0x00 // Default +#define RF_DIOMAPPING1_DIO2_01 0x04 +#define RF_DIOMAPPING1_DIO2_10 0x08 +#define RF_DIOMAPPING1_DIO2_11 0x0C + +#define RF_DIOMAPPING1_DIO3_MASK 0xFC +#define RF_DIOMAPPING1_DIO3_00 0x00 // Default +#define RF_DIOMAPPING1_DIO3_01 0x01 +#define RF_DIOMAPPING1_DIO3_10 0x02 +#define RF_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RF_DIOMAPPING2_DIO4_MASK 0x3F +#define RF_DIOMAPPING2_DIO4_00 0x00 // Default +#define RF_DIOMAPPING2_DIO4_01 0x40 +#define RF_DIOMAPPING2_DIO4_10 0x80 +#define RF_DIOMAPPING2_DIO4_11 0xC0 + +#define RF_DIOMAPPING2_DIO5_MASK 0xCF +#define RF_DIOMAPPING2_DIO5_00 0x00 // Default +#define RF_DIOMAPPING2_DIO5_01 0x10 +#define RF_DIOMAPPING2_DIO5_10 0x20 +#define RF_DIOMAPPING2_DIO5_11 0x30 + +#define RF_DIOMAPPING2_MAP_MASK 0xFE +#define RF_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RF_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegPllHop + */ +#define RF_PLLHOP_FASTHOP_MASK 0x7F +#define RF_PLLHOP_FASTHOP_ON 0x80 +#define RF_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RF_TCXO_TCXOINPUT_MASK 0xEF +#define RF_TCXO_TCXOINPUT_ON 0x10 +#define RF_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RF_PADAC_20DBM_MASK 0xF8 +#define RF_PADAC_20DBM_ON 0x07 +#define RF_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegPll + */ +#define RF_PLL_BANDWIDTH_MASK 0x3F +#define RF_PLL_BANDWIDTH_75 0x00 +#define RF_PLL_BANDWIDTH_150 0x40 +#define RF_PLL_BANDWIDTH_225 0x80 +#define RF_PLL_BANDWIDTH_300 0xC0 // Default + +/*! + * RegPllLowPn + */ +#define RF_PLLLOWPN_BANDWIDTH_MASK 0x3F +#define RF_PLLLOWPN_BANDWIDTH_75 0x00 +#define RF_PLLLOWPN_BANDWIDTH_150 0x40 +#define RF_PLLLOWPN_BANDWIDTH_225 0x80 +#define RF_PLLLOWPN_BANDWIDTH_300 0xC0 // Default + +/*! + * RegFormerTemp + */ + +/*! + * RegBitrateFrac + */ +#define RF_BITRATEFRAC_MASK 0xF0 + +#endif // __SX1272_REGS_FSK_H__ diff --git a/SX1272/registers/sx1272Regs-LoRa.h b/SX1272/registers/sx1272Regs-LoRa.h new file mode 100644 index 0000000000..457af29fe5 --- /dev/null +++ b/SX1272/registers/sx1272Regs-LoRa.h @@ -0,0 +1,549 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C) 2015 Semtech + +Description: SX1272 LoRa modem registers and bits definitions + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ +#ifndef __SX1272_REGS_LORA_H__ +#define __SX1272_REGS_LORA_H__ + +/*! + * ============================================================================ + * SX1272 Internal registers Address + * ============================================================================ + */ +#define REG_LR_FIFO 0x00 +// Common settings +#define REG_LR_OPMODE 0x01 +#define REG_LR_FRFMSB 0x06 +#define REG_LR_FRFMID 0x07 +#define REG_LR_FRFLSB 0x08 +// Tx settings +#define REG_LR_PACONFIG 0x09 +#define REG_LR_PARAMP 0x0A +#define REG_LR_OCP 0x0B +// Rx settings +#define REG_LR_LNA 0x0C +// LoRa registers +#define REG_LR_FIFOADDRPTR 0x0D +#define REG_LR_FIFOTXBASEADDR 0x0E +#define REG_LR_FIFORXBASEADDR 0x0F +#define REG_LR_FIFORXCURRENTADDR 0x10 +#define REG_LR_IRQFLAGSMASK 0x11 +#define REG_LR_IRQFLAGS 0x12 +#define REG_LR_RXNBBYTES 0x13 +#define REG_LR_RXHEADERCNTVALUEMSB 0x14 +#define REG_LR_RXHEADERCNTVALUELSB 0x15 +#define REG_LR_RXPACKETCNTVALUEMSB 0x16 +#define REG_LR_RXPACKETCNTVALUELSB 0x17 +#define REG_LR_MODEMSTAT 0x18 +#define REG_LR_PKTSNRVALUE 0x19 +#define REG_LR_PKTRSSIVALUE 0x1A +#define REG_LR_RSSIVALUE 0x1B +#define REG_LR_HOPCHANNEL 0x1C +#define REG_LR_MODEMCONFIG1 0x1D +#define REG_LR_MODEMCONFIG2 0x1E +#define REG_LR_SYMBTIMEOUTLSB 0x1F +#define REG_LR_PREAMBLEMSB 0x20 +#define REG_LR_PREAMBLELSB 0x21 +#define REG_LR_PAYLOADLENGTH 0x22 +#define REG_LR_PAYLOADMAXLENGTH 0x23 +#define REG_LR_HOPPERIOD 0x24 +#define REG_LR_FIFORXBYTEADDR 0x25 +#define REG_LR_FEIMSB 0x28 +#define REG_LR_FEIMID 0x29 +#define REG_LR_FEILSB 0x2A +#define REG_LR_RSSIWIDEBAND 0x2C +#define REG_LR_DETECTOPTIMIZE 0x31 +#define REG_LR_INVERTIQ 0x33 +#define REG_LR_DETECTIONTHRESHOLD 0x37 +#define REG_LR_SYNCWORD 0x39 +#define REG_LR_INVERTIQ2 0x3B + +// end of documented register in datasheet +// I/O settings +#define REG_LR_DIOMAPPING1 0x40 +#define REG_LR_DIOMAPPING2 0x41 +// Version +#define REG_LR_VERSION 0x42 +// Additional settings +#define REG_LR_AGCREF 0x43 +#define REG_LR_AGCTHRESH1 0x44 +#define REG_LR_AGCTHRESH2 0x45 +#define REG_LR_AGCTHRESH3 0x46 +#define REG_LR_PLLHOP 0x4B +#define REG_LR_TCXO 0x58 +#define REG_LR_PADAC 0x5A +#define REG_LR_PLL 0x5C +#define REG_LR_PLLLOWPN 0x5E +#define REG_LR_FORMERTEMP 0x6C + +/*! + * ============================================================================ + * SX1272 LoRa bits control definition + * ============================================================================ + */ + +/*! + * RegFifo + */ + +/*! + * RegOpMode + */ +#define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default +#define RFLR_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF +#define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40 +#define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default + +#define RFLR_OPMODE_MASK 0xF8 +#define RFLR_OPMODE_SLEEP 0x00 +#define RFLR_OPMODE_STANDBY 0x01 // Default +#define RFLR_OPMODE_SYNTHESIZER_TX 0x02 +#define RFLR_OPMODE_TRANSMITTER 0x03 +#define RFLR_OPMODE_SYNTHESIZER_RX 0x04 +#define RFLR_OPMODE_RECEIVER 0x05 +// LoRa specific modes +#define RFLR_OPMODE_RECEIVER_SINGLE 0x06 +#define RFLR_OPMODE_CAD 0x07 + +/*! + * RegFrf (MHz) + */ +#define RFLR_FRFMSB_915_MHZ 0xE4 // Default +#define RFLR_FRFMID_915_MHZ 0xC0 // Default +#define RFLR_FRFLSB_915_MHZ 0x00 // Default + +/*! + * RegPaConfig + */ +#define RFLR_PACONFIG_PASELECT_MASK 0x7F +#define RFLR_PACONFIG_PASELECT_PABOOST 0x80 +#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +/*! + * RegPaRamp + */ +#define RFLR_PARAMP_LOWPNTXPLL_MASK 0xE0 +#define RFLR_PARAMP_LOWPNTXPLL_OFF 0x10 // Default +#define RFLR_PARAMP_LOWPNTXPLL_ON 0x00 + +#define RFLR_PARAMP_MASK 0xF0 +#define RFLR_PARAMP_3400_US 0x00 +#define RFLR_PARAMP_2000_US 0x01 +#define RFLR_PARAMP_1000_US 0x02 +#define RFLR_PARAMP_0500_US 0x03 +#define RFLR_PARAMP_0250_US 0x04 +#define RFLR_PARAMP_0125_US 0x05 +#define RFLR_PARAMP_0100_US 0x06 +#define RFLR_PARAMP_0062_US 0x07 +#define RFLR_PARAMP_0050_US 0x08 +#define RFLR_PARAMP_0040_US 0x09 // Default +#define RFLR_PARAMP_0031_US 0x0A +#define RFLR_PARAMP_0025_US 0x0B +#define RFLR_PARAMP_0020_US 0x0C +#define RFLR_PARAMP_0015_US 0x0D +#define RFLR_PARAMP_0012_US 0x0E +#define RFLR_PARAMP_0010_US 0x0F + +/*! + * RegOcp + */ +#define RFLR_OCP_MASK 0xDF +#define RFLR_OCP_ON 0x20 // Default +#define RFLR_OCP_OFF 0x00 + +#define RFLR_OCP_TRIM_MASK 0xE0 +#define RFLR_OCP_TRIM_045_MA 0x00 +#define RFLR_OCP_TRIM_050_MA 0x01 +#define RFLR_OCP_TRIM_055_MA 0x02 +#define RFLR_OCP_TRIM_060_MA 0x03 +#define RFLR_OCP_TRIM_065_MA 0x04 +#define RFLR_OCP_TRIM_070_MA 0x05 +#define RFLR_OCP_TRIM_075_MA 0x06 +#define RFLR_OCP_TRIM_080_MA 0x07 +#define RFLR_OCP_TRIM_085_MA 0x08 +#define RFLR_OCP_TRIM_090_MA 0x09 +#define RFLR_OCP_TRIM_095_MA 0x0A +#define RFLR_OCP_TRIM_100_MA 0x0B // Default +#define RFLR_OCP_TRIM_105_MA 0x0C +#define RFLR_OCP_TRIM_110_MA 0x0D +#define RFLR_OCP_TRIM_115_MA 0x0E +#define RFLR_OCP_TRIM_120_MA 0x0F +#define RFLR_OCP_TRIM_130_MA 0x10 +#define RFLR_OCP_TRIM_140_MA 0x11 +#define RFLR_OCP_TRIM_150_MA 0x12 +#define RFLR_OCP_TRIM_160_MA 0x13 +#define RFLR_OCP_TRIM_170_MA 0x14 +#define RFLR_OCP_TRIM_180_MA 0x15 +#define RFLR_OCP_TRIM_190_MA 0x16 +#define RFLR_OCP_TRIM_200_MA 0x17 +#define RFLR_OCP_TRIM_210_MA 0x18 +#define RFLR_OCP_TRIM_220_MA 0x19 +#define RFLR_OCP_TRIM_230_MA 0x1A +#define RFLR_OCP_TRIM_240_MA 0x1B + +/*! + * RegLna + */ +#define RFLR_LNA_GAIN_MASK 0x1F +#define RFLR_LNA_GAIN_G1 0x20 // Default +#define RFLR_LNA_GAIN_G2 0x40 +#define RFLR_LNA_GAIN_G3 0x60 +#define RFLR_LNA_GAIN_G4 0x80 +#define RFLR_LNA_GAIN_G5 0xA0 +#define RFLR_LNA_GAIN_G6 0xC0 + +#define RFLR_LNA_BOOST_MASK 0xFC +#define RFLR_LNA_BOOST_OFF 0x00 // Default +#define RFLR_LNA_BOOST_ON 0x03 + +/*! + * RegFifoAddrPtr + */ +#define RFLR_FIFOADDRPTR 0x00 // Default + +/*! + * RegFifoTxBaseAddr + */ +#define RFLR_FIFOTXBASEADDR 0x80 // Default + +/*! + * RegFifoTxBaseAddr + */ +#define RFLR_FIFORXBASEADDR 0x00 // Default + +/*! + * RegFifoRxCurrentAddr (Read Only) + */ + +/*! + * RegIrqFlagsMask + */ +#define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80 +#define RFLR_IRQFLAGS_RXDONE_MASK 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10 +#define RFLR_IRQFLAGS_TXDONE_MASK 0x08 +#define RFLR_IRQFLAGS_CADDONE_MASK 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02 +#define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01 + +/*! + * RegIrqFlags + */ +#define RFLR_IRQFLAGS_RXTIMEOUT 0x80 +#define RFLR_IRQFLAGS_RXDONE 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER 0x10 +#define RFLR_IRQFLAGS_TXDONE 0x08 +#define RFLR_IRQFLAGS_CADDONE 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02 +#define RFLR_IRQFLAGS_CADDETECTED 0x01 + +/*! + * RegFifoRxNbBytes (Read Only) + */ + +/*! + * RegRxHeaderCntValueMsb (Read Only) + */ + +/*! + * RegRxHeaderCntValueLsb (Read Only) + */ + +/*! + * RegRxPacketCntValueMsb (Read Only) + */ + +/*! + * RegRxPacketCntValueLsb (Read Only) + */ + +/*! + * RegModemStat (Read Only) + */ +#define RFLR_MODEMSTAT_RX_CR_MASK 0x1F +#define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0 + +/*! + * RegPktSnrValue (Read Only) + */ + +/*! + * RegPktRssiValue (Read Only) + */ + +/*! + * RegRssiValue (Read Only) + */ + +/*! + * RegHopChannel (Read Only) + */ +#define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F +#define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80 +#define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default + +#define RFLR_HOPCHANNEL_CRCONPAYLOAD_MASK 0xBF +#define RFLR_HOPCHANNEL_CRCONPAYLOAD_ON 0x40 +#define RFLR_HOPCHANNEL_CRCONPAYLOAD_OFF 0x00 // Default + +#define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F + +/*! + * RegModemConfig1 + */ +#define RFLR_MODEMCONFIG1_BW_MASK 0x3F +#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x00 // Default +#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x40 +#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x80 + +#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xC7 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x08 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x10 // Default +#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x18 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x20 + +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFB +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x04 +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK 0xFD +#define RFLR_MODEMCONFIG1_RXPAYLOADCRC_ON 0x02 +#define RFLR_MODEMCONFIG1_RXPAYLOADCRC_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK 0xFE +#define RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_ON 0x01 +#define RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_OFF 0x00 // Default + +/*! + * RegModemConfig2 + */ +#define RFLR_MODEMCONFIG2_SF_MASK 0x0F +#define RFLR_MODEMCONFIG2_SF_6 0x60 +#define RFLR_MODEMCONFIG2_SF_7 0x70 // Default +#define RFLR_MODEMCONFIG2_SF_8 0x80 +#define RFLR_MODEMCONFIG2_SF_9 0x90 +#define RFLR_MODEMCONFIG2_SF_10 0xA0 +#define RFLR_MODEMCONFIG2_SF_11 0xB0 +#define RFLR_MODEMCONFIG2_SF_12 0xC0 + +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00 + +#define RFLR_MODEMCONFIG2_AGCAUTO_MASK 0xFB +#define RFLR_MODEMCONFIG2_AGCAUTO_ON 0x04 // Default +#define RFLR_MODEMCONFIG2_AGCAUTO_OFF 0x00 + +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default + +/*! + * RegSymbTimeoutLsb + */ +#define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default + +/*! + * RegPreambleLengthMsb + */ +#define RFLR_PREAMBLELENGTHMSB 0x00 // Default + +/*! + * RegPreambleLengthLsb + */ +#define RFLR_PREAMBLELENGTHLSB 0x08 // Default + +/*! + * RegPayloadLength + */ +#define RFLR_PAYLOADLENGTH 0x0E // Default + +/*! + * RegPayloadMaxLength + */ +#define RFLR_PAYLOADMAXLENGTH 0xFF // Default + +/*! + * RegHopPeriod + */ +#define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default + +/*! + * RegFifoRxByteAddr (Read Only) + */ + +/*! + * RegFeiMsb (Read Only) + */ + +/*! + * RegFeiMid (Read Only) + */ + +/*! + * RegFeiLsb (Read Only) + */ + +/*! + * RegRssiWideband (Read Only) + */ + +/*! + * RegDetectOptimize + */ +#define RFLR_DETECTIONOPTIMIZE_MASK 0xF8 +#define RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 0x03 // Default +#define RFLR_DETECTIONOPTIMIZE_SF6 0x05 + +/*! + * RegInvertIQ + */ +#define RFLR_INVERTIQ_RX_MASK 0xBF +#define RFLR_INVERTIQ_RX_OFF 0x00 +#define RFLR_INVERTIQ_RX_ON 0x40 +#define RFLR_INVERTIQ_TX_MASK 0xFE +#define RFLR_INVERTIQ_TX_OFF 0x01 +#define RFLR_INVERTIQ_TX_ON 0x00 + +/*! + * RegDetectionThreshold + */ +#define RFLR_DETECTIONTHRESH_SF7_TO_SF12 0x0A // Default +#define RFLR_DETECTIONTHRESH_SF6 0x0C + +/*! + * RegInvertIQ2 + */ +#define RFLR_INVERTIQ2_ON 0x19 +#define RFLR_INVERTIQ2_OFF 0x1D + +/*! + * RegDioMapping1 + */ +#define RFLR_DIOMAPPING1_DIO0_MASK 0x3F +#define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO0_01 0x40 +#define RFLR_DIOMAPPING1_DIO0_10 0x80 +#define RFLR_DIOMAPPING1_DIO0_11 0xC0 + +#define RFLR_DIOMAPPING1_DIO1_MASK 0xCF +#define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO1_01 0x10 +#define RFLR_DIOMAPPING1_DIO1_10 0x20 +#define RFLR_DIOMAPPING1_DIO1_11 0x30 + +#define RFLR_DIOMAPPING1_DIO2_MASK 0xF3 +#define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO2_01 0x04 +#define RFLR_DIOMAPPING1_DIO2_10 0x08 +#define RFLR_DIOMAPPING1_DIO2_11 0x0C + +#define RFLR_DIOMAPPING1_DIO3_MASK 0xFC +#define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO3_01 0x01 +#define RFLR_DIOMAPPING1_DIO3_10 0x02 +#define RFLR_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RFLR_DIOMAPPING2_DIO4_MASK 0x3F +#define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO4_01 0x40 +#define RFLR_DIOMAPPING2_DIO4_10 0x80 +#define RFLR_DIOMAPPING2_DIO4_11 0xC0 + +#define RFLR_DIOMAPPING2_DIO5_MASK 0xCF +#define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO5_01 0x10 +#define RFLR_DIOMAPPING2_DIO5_10 0x20 +#define RFLR_DIOMAPPING2_DIO5_11 0x30 + +#define RFLR_DIOMAPPING2_MAP_MASK 0xFE +#define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegPllHop + */ +#define RFLR_PLLHOP_FASTHOP_MASK 0x7F +#define RFLR_PLLHOP_FASTHOP_ON 0x80 +#define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RFLR_TCXO_TCXOINPUT_MASK 0xEF +#define RFLR_TCXO_TCXOINPUT_ON 0x10 +#define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RFLR_PADAC_20DBM_MASK 0xF8 +#define RFLR_PADAC_20DBM_ON 0x07 +#define RFLR_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegPll + */ +#define RFLR_PLL_BANDWIDTH_MASK 0x3F +#define RFLR_PLL_BANDWIDTH_75 0x00 +#define RFLR_PLL_BANDWIDTH_150 0x40 +#define RFLR_PLL_BANDWIDTH_225 0x80 +#define RFLR_PLL_BANDWIDTH_300 0xC0 // Default + +/*! + * RegPllLowPn + */ +#define RFLR_PLLLOWPN_BANDWIDTH_MASK 0x3F +#define RFLR_PLLLOWPN_BANDWIDTH_75 0x00 +#define RFLR_PLLLOWPN_BANDWIDTH_150 0x40 +#define RFLR_PLLLOWPN_BANDWIDTH_225 0x80 +#define RFLR_PLLLOWPN_BANDWIDTH_300 0xC0 // Default + +/*! + * RegFormerTemp + */ + +#endif // __SX1272_REGS_LORA_H__ diff --git a/SX1276/README.md b/SX1276/README.md new file mode 100644 index 0000000000..beab581a04 --- /dev/null +++ b/SX1276/README.md @@ -0,0 +1 @@ +# Mbed enabled SX1276 LoRa/FSK radio driver diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp new file mode 100644 index 0000000000..7c57f1c492 --- /dev/null +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -0,0 +1,2308 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#include +#include //rint +#include +#include "mbed.h" +#include "SX1276_LoRaRadio.h" +#include "sx1276Regs-Fsk.h" +#include "sx1276Regs-LoRa.h" + +/*! + * Sync word for Private LoRa networks + */ +#define LORA_MAC_PRIVATE_SYNCWORD 0x12 + +/*! + * Sync word for Public LoRa networks + */ +#define LORA_MAC_PUBLIC_SYNCWORD 0x34 + +/*! + * SX1276 definitions + */ +#define XTAL_FREQ 32000000 +#define FREQ_STEP 61.03515625 + +#define RX_BUFFER_SIZE 256 + +/*! + * Constant values need to compute the RSSI value + */ +#define RSSI_OFFSET_LF -164.0 +#define RSSI_OFFSET_HF -157.0 +#define RF_MID_BAND_THRESH 525000000 + +/*! + * FSK bandwidth definition + */ +typedef struct +{ + uint32_t bandwidth; + uint8_t register_value; +} fsk_bw_t; + +/*! + * Radio registers definition + */ +typedef struct +{ + uint8_t modem; + uint8_t addr; + uint8_t value; +} radio_registers_t; + +#define RADIO_INIT_REGISTERS_VALUE \ +{ \ + { MODEM_FSK , REG_LNA , 0x23 },\ + { MODEM_FSK , REG_RXCONFIG , 0x1E },\ + { MODEM_FSK , REG_RSSICONFIG , 0xD2 },\ + { MODEM_FSK , REG_AFCFEI , 0x01 },\ + { MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },\ + { MODEM_FSK , REG_OSC , 0x07 },\ + { MODEM_FSK , REG_SYNCCONFIG , 0x12 },\ + { MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },\ + { MODEM_FSK , REG_SYNCVALUE2 , 0x94 },\ + { MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },\ + { MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },\ + { MODEM_FSK , REG_FIFOTHRESH , 0x8F },\ + { MODEM_FSK , REG_IMAGECAL , 0x02 },\ + { MODEM_FSK , REG_DIOMAPPING1 , 0x00 },\ + { MODEM_FSK , REG_DIOMAPPING2 , 0x30 },\ + { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\ +} + +static const fsk_bw_t fsk_bandwidths[] = +{ + { 2600 , 0x17 }, + { 3100 , 0x0F }, + { 3900 , 0x07 }, + { 5200 , 0x16 }, + { 6300 , 0x0E }, + { 7800 , 0x06 }, + { 10400 , 0x15 }, + { 12500 , 0x0D }, + { 15600 , 0x05 }, + { 20800 , 0x14 }, + { 25000 , 0x0C }, + { 31300 , 0x04 }, + { 41700 , 0x13 }, + { 50000 , 0x0B }, + { 62500 , 0x03 }, + { 83333 , 0x12 }, + { 100000, 0x0A }, + { 125000, 0x02 }, + { 166700, 0x11 }, + { 200000, 0x09 }, + { 250000, 0x01 }, + { 300000, 0x00 }, // Invalid bandwidth +}; + +/** + * SPI read/write masks + */ +#define SPI_WRITE_CMD 0x80 +#define SPI_READ_CMD 0x7F + +/** + * Signals + */ +#define SIG_DIO0 0x01 +#define SIG_DIO1 0x02 +#define SIG_DIO2 0x04 +#define SIG_DIO3 0x08 +#define SIG_DIO4 0x10 +#define SIG_DIO5 0x20 +#define SIG_TIMOUT 0x40 + +/** + * Radio hardware registers initialization + */ +static const radio_registers_t radio_reg_init[] = RADIO_INIT_REGISTERS_VALUE; + +enum RadioVariant { + SX1276MB1LAS = 0, + SX1276MB1MAS +}; + +#ifdef MBED_SX1276_LORA_RADIO_SPI_FREQUENCY +#define SPI_FREQUENCY MBED_SX1276_LORA_RADIO_SPI_FREQUENCY +#else +#define SPI_FREQUENCY 8000000 +#endif + +static uint8_t radio_variant; + +/** + * Constructor + */ +SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi, PinName spi_miso, + PinName spi_sclk, PinName nss, PinName reset, PinName dio0, + PinName dio1, PinName dio2, PinName dio3, PinName dio4, + PinName dio5, PinName rf_switch_ctl1, PinName rf_switch_ctl2, + PinName txctl, PinName rxctl, PinName antswitch, + PinName pwr_amp_ctl, PinName tcxo) + : _spi(spi_mosi, spi_miso, spi_sclk), + _chip_select(nss, 1), _reset_ctl(reset), + _dio0_ctl(dio0), _dio1_ctl(dio1), _dio2_ctl(dio2), _dio3_ctl(dio3), + _dio4_ctl(dio4), _dio5_ctl(dio5), _rf_switch_ctl1(rf_switch_ctl1, 0), + _rf_switch_ctl2(rf_switch_ctl2, 0),_txctl(txctl, 0), _rxctl(rxctl, 0), + _ant_switch(antswitch, PIN_INPUT, PullUp, 0), _pwr_amp_ctl(pwr_amp_ctl), + _tcxo(tcxo) + +#ifdef MBED_CONF_RTOS_PRESENT + , irq_thread(osPriorityRealtime, 1024) +#endif +{ + _rf_ctrls.ant_switch = antswitch; + _rf_ctrls.pwr_amp_ctl = pwr_amp_ctl; + _rf_ctrls.rf_switch_ctl1 = rf_switch_ctl1; + _rf_ctrls.rf_switch_ctl2 = rf_switch_ctl2; + _rf_ctrls.rxctl = rxctl; + _rf_ctrls.txctl = txctl; + _rf_ctrls.tcxo = tcxo; + + _radio_events = NULL; + + // Detect Murata based on pin configuration + if (pwr_amp_ctl != NC && txctl != NC && rxctl != NC && tcxo != NC) { + is_murata = true; + } else { + is_murata = false; + } + +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.start(mbed::callback(this, &SX1276_LoRaRadio::rf_irq_task)); +#endif +} + +/** + * Destructor + */ +SX1276_LoRaRadio::~SX1276_LoRaRadio() +{ + +} + +/***************************************************************************** + * Public APIs * + ****************************************************************************/ +/** + * Acquire lock + */ +void SX1276_LoRaRadio::lock(void) +{ + mutex.lock(); +} + +/** + * Release lock + */ +void SX1276_LoRaRadio::unlock(void) +{ + mutex.unlock(); +} + +/** + * Initializes radio module + */ +void SX1276_LoRaRadio::init_radio(radio_events_t *events) +{ + _radio_events = events; + + // Reset the radio transceiver + radio_reset(); + + if (is_murata) { + // Only used for bands < 125 kHz, so probably not needed? + _tcxo = 1; + } else { + // Setup radio variant type + set_sx1276_variant_type(); + } + + // setup SPI frequency + // default is 8MHz although, configurable through + // SPI_FREQUENCY macro + setup_spi(); + + // Calibrate radio receiver chain + rx_chain_calibration(); + + // set radio mode to sleep + set_operation_mode(RF_OPMODE_SLEEP); + + // Setup radio registers to defaults + setup_registers(); + + // set modem type - defaults to FSK here + set_modem(MODEM_FSK); + + // set state to be idle + _rf_settings.state = RF_IDLE; + + // Setup interrupts on DIO pins + setup_interrupts(); +} + +/** + * Can be used by application/stack or the driver itself + */ +void SX1276_LoRaRadio::radio_reset() +{ + _reset_ctl.output(); + _reset_ctl = 0; + wait_ms(2); + _reset_ctl.input(); + wait_ms(6); +} + +/** + * TODO: The purpose of this API is unclear. + * Need to start an internal discussion. + */ +bool SX1276_LoRaRadio::check_rf_frequency(uint32_t frequency) +{ + // Implement check. Currently all frequencies are supported ? What band ? + return true; +} + +/** + * Returns current status of the radio state machine + */ +uint8_t SX1276_LoRaRadio::get_status(void) +{ + return _rf_settings.state; +} + +/** + * Sets up carrier frequency + */ +void SX1276_LoRaRadio::set_channel(uint32_t freq) +{ + _rf_settings.channel = freq; + freq = (uint32_t) ((double) freq / (double) FREQ_STEP); + write_to_register(REG_FRFMSB, (uint8_t) ((freq >> 16) & 0xFF)); + write_to_register(REG_FRFMID, (uint8_t) ((freq >> 8) & 0xFF)); + write_to_register(REG_FRFLSB, (uint8_t) (freq & 0xFF)); +} + +/** + * Generates 32 bit random number based upon RSSI monitoring + * Used for various calculation by the stack for example dev nonce + * + * When this API is used modem is set in LoRa mode and all interrupts are + * masked. If the user had been using FSK mode, it should be noted that a + * change of mode is required again because the registers have changed. + * In addition to that RX and TX configuration APIs should be called again in + * order to have correct desires setup. + */ +uint32_t SX1276_LoRaRadio::random( void ) +{ + uint8_t i; + uint32_t rnd = 0; + + /* + * Radio setup for random number generation + */ + set_modem( MODEM_LORA ); + + // Disable LoRa modem interrupts + write_to_register( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED ); + + // Set radio in continuous reception + set_operation_mode(RF_OPMODE_RECEIVER); + + for (i = 0; i < 32; i++) { + wait_ms(1); + // Unfiltered RSSI value reading. Only takes the LSB value + rnd |= ((uint32_t) read_register( REG_LR_RSSIWIDEBAND) & 0x01) << i; + } + + sleep(); + + return rnd; +} + +/** + * Sets up receiver related configurations + * + * Must be called before setting the radio in rx mode + */ +void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidth_afc, + uint16_t preamble_len, + uint16_t symb_timeout, bool fix_len, + uint8_t payload_len, bool crc_on, + bool freq_hop_on, uint8_t hop_period, + bool iq_inverted, bool rx_continuous) +{ + set_modem(modem); + + switch (modem) { + case MODEM_FSK: + _rf_settings.fsk.bandwidth = bandwidth; + _rf_settings.fsk.datarate = datarate; + _rf_settings.fsk.bandwidth_afc = bandwidth_afc; + _rf_settings.fsk.fix_len = fix_len; + _rf_settings.fsk.payload_len = payload_len; + _rf_settings.fsk.crc_on = crc_on; + _rf_settings.fsk.iq_inverted = iq_inverted; + _rf_settings.fsk.rx_continuous = rx_continuous; + _rf_settings.fsk.preamble_len = preamble_len; + _rf_settings.fsk.rx_single_timeout = symb_timeout + * ((1.0 / (double) datarate) * 8.0) * 1e3; + + datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); + write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8)); + write_to_register(REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); + + write_to_register(REG_RXBW, get_fsk_bw_reg_val(bandwidth)); + write_to_register(REG_AFCBW, get_fsk_bw_reg_val(bandwidth_afc)); + + write_to_register(REG_PREAMBLEMSB, + (uint8_t) ((preamble_len >> 8) & 0xFF)); + write_to_register(REG_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF)); + + if (fix_len == 1) { + write_to_register(REG_PAYLOADLENGTH, payload_len); + } else { + write_to_register(REG_PAYLOADLENGTH, 0xFF); // Set payload length to the maximum + } + + write_to_register( + REG_PACKETCONFIG1, + (read_register(REG_PACKETCONFIG1) + & RF_PACKETCONFIG1_CRC_MASK + & RF_PACKETCONFIG1_PACKETFORMAT_MASK) + | ((fix_len == 1) ? + RF_PACKETCONFIG1_PACKETFORMAT_FIXED : + RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) + | (crc_on << 4)); + + // TODO why packet mode 2 ? + write_to_register(REG_PACKETCONFIG2, (read_register(REG_PACKETCONFIG2) + | RF_PACKETCONFIG2_DATAMODE_PACKET)); + + break; + + case MODEM_LORA: + + if (bandwidth > 2) { + // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported + while (1) + ; + // TODO Return a proper error from here + } + + // stupid hack. TODO think something better + bandwidth+=7; + + _rf_settings.lora.bandwidth = bandwidth; + _rf_settings.lora.datarate = datarate; + _rf_settings.lora.coderate = coderate; + _rf_settings.lora.preamble_len = preamble_len; + _rf_settings.lora.fix_len = fix_len; + _rf_settings.lora.payload_len = payload_len; + _rf_settings.lora.crc_on = crc_on; + _rf_settings.lora.freq_hop_on = freq_hop_on; + _rf_settings.lora.hop_period = hop_period; + _rf_settings.lora.iq_inverted = iq_inverted; + _rf_settings.lora.rx_continuous = rx_continuous; + + if (datarate > 12) { + datarate = 12; + } else if (datarate < 6) { + datarate = 6; + } + + if (((bandwidth == 7) && ((datarate == 11) || (datarate == 12))) + || ((bandwidth == 8) && (datarate == 12))) { + _rf_settings.lora.low_datarate_optimize = 0x01; + } else { + _rf_settings.lora.low_datarate_optimize = 0x00; + } + + write_to_register(REG_LR_MODEMCONFIG1, (read_register( REG_LR_MODEMCONFIG1) + & RFLR_MODEMCONFIG1_BW_MASK + & RFLR_MODEMCONFIG1_CODINGRATE_MASK + & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK) + | (bandwidth << 4) + | (coderate << 1) | fix_len); + + write_to_register(REG_LR_MODEMCONFIG2, (read_register( REG_LR_MODEMCONFIG2) + & RFLR_MODEMCONFIG2_SF_MASK + & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK + & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK) + | (datarate << 4) + | (crc_on << 2) + | ((symb_timeout >> 8) + & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK)); + + write_to_register(REG_LR_MODEMCONFIG3, (read_register( REG_LR_MODEMCONFIG3) + & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) + | (_rf_settings.lora.low_datarate_optimize << 3)); + + write_to_register(REG_LR_SYMBTIMEOUTLSB, (uint8_t) (symb_timeout & 0xFF)); + + write_to_register(REG_LR_PREAMBLEMSB, (uint8_t) ((preamble_len >> 8) & 0xFF)); + write_to_register(REG_LR_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF)); + + if (fix_len == 1) { + write_to_register(REG_LR_PAYLOADLENGTH, payload_len); + } + + if (_rf_settings.lora.freq_hop_on == true) { + write_to_register(REG_LR_PLLHOP, (read_register( REG_LR_PLLHOP) + & RFLR_PLLHOP_FASTHOP_MASK) + | RFLR_PLLHOP_FASTHOP_ON); + write_to_register(REG_LR_HOPPERIOD,_rf_settings.lora.hop_period); + } + + if ((bandwidth == 9) && (_rf_settings.channel > RF_MID_BAND_THRESH)) { + // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth + write_to_register(REG_LR_TEST36, 0x02); + write_to_register(REG_LR_TEST3A, 0x64); + } else if (bandwidth == 9) { + // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth + write_to_register(REG_LR_TEST36, 0x02); + write_to_register(REG_LR_TEST3A, 0x7F); + } else { + // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth + write_to_register(REG_LR_TEST36, 0x03); + } + + if (datarate == 6) { + write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) + & RFLR_DETECTIONOPTIMIZE_MASK) + | RFLR_DETECTIONOPTIMIZE_SF6); + write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF6); + } else { + write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) + & RFLR_DETECTIONOPTIMIZE_MASK) + | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); + write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12); + } + break; + + default: + break; + } +} + +/** + * Sets up transmitter related configuration + * + * Must be called before putting the radio module in Tx mode or trying + * to send + */ +void SX1276_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power, + uint32_t fdev, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint16_t preamble_len, bool fix_len, + bool crc_on, bool freq_hop_on, + uint8_t hop_period, bool iq_inverted, + uint32_t timeout) +{ + set_modem(modem); + set_rf_tx_power(power); + + switch (modem) { + case MODEM_FSK: + _rf_settings.fsk.power = power; + _rf_settings.fsk.f_dev = fdev; + _rf_settings.fsk.bandwidth = bandwidth; + _rf_settings.fsk.datarate = datarate; + _rf_settings.fsk.preamble_len = preamble_len; + _rf_settings.fsk.fix_len = fix_len; + _rf_settings.fsk.crc_on = crc_on; + _rf_settings.fsk.iq_inverted = iq_inverted; + _rf_settings.fsk.tx_timeout = timeout; + + fdev = (uint16_t) ((double) fdev / (double) FREQ_STEP); + write_to_register( REG_FDEVMSB, (uint8_t) (fdev >> 8)); + write_to_register( REG_FDEVLSB, (uint8_t) (fdev & 0xFF)); + + datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); + write_to_register( REG_BITRATEMSB, (uint8_t) (datarate >> 8)); + write_to_register( REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); + + write_to_register( REG_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); + write_to_register( REG_PREAMBLELSB, preamble_len & 0xFF); + + write_to_register(REG_PACKETCONFIG1, + (read_register( REG_PACKETCONFIG1) & + RF_PACKETCONFIG1_CRC_MASK & + RF_PACKETCONFIG1_PACKETFORMAT_MASK) + | ((fix_len == 1) ? + RF_PACKETCONFIG1_PACKETFORMAT_FIXED : + RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) + | (crc_on << 4)); + write_to_register(REG_PACKETCONFIG2, + (read_register( REG_PACKETCONFIG2) + | RF_PACKETCONFIG2_DATAMODE_PACKET)); + + break; + + case MODEM_LORA: + _rf_settings.lora.power = power; + if (bandwidth > 2) { + // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported + while (1) + ; + } + bandwidth += 7; + _rf_settings.lora.bandwidth = bandwidth; + _rf_settings.lora.datarate = datarate; + _rf_settings.lora.coderate = coderate; + _rf_settings.lora.preamble_len = preamble_len; + _rf_settings.lora.fix_len = fix_len; + _rf_settings.lora.freq_hop_on = freq_hop_on; + _rf_settings.lora.hop_period = hop_period; + _rf_settings.lora.crc_on = crc_on; + _rf_settings.lora.iq_inverted = iq_inverted; + _rf_settings.lora.tx_timeout = timeout; + + if (datarate > 12) { + datarate = 12; + } else if (datarate < 6) { + datarate = 6; + } + if (((bandwidth == 7) && ((datarate == 11) || (datarate == 12))) + || ((bandwidth == 8) && (datarate == 12))) { + _rf_settings.lora.low_datarate_optimize = 0x01; + } else { + _rf_settings.lora.low_datarate_optimize = 0x00; + } + + if (_rf_settings.lora.freq_hop_on == true) { + write_to_register(REG_LR_PLLHOP, (read_register(REG_LR_PLLHOP) + & RFLR_PLLHOP_FASTHOP_MASK) + | RFLR_PLLHOP_FASTHOP_ON); + write_to_register( REG_LR_HOPPERIOD, _rf_settings.lora.hop_period); + } + + write_to_register(REG_LR_MODEMCONFIG1, (read_register( REG_LR_MODEMCONFIG1) + & RFLR_MODEMCONFIG1_BW_MASK + & RFLR_MODEMCONFIG1_CODINGRATE_MASK + & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK) | (bandwidth << 4) + | (coderate << 1) | fix_len); + + write_to_register(REG_LR_MODEMCONFIG2, (read_register( REG_LR_MODEMCONFIG2) + & RFLR_MODEMCONFIG2_SF_MASK + & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK) + | (datarate << 4) + | (crc_on << 2)); + + write_to_register(REG_LR_MODEMCONFIG3, (read_register(REG_LR_MODEMCONFIG3) + & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) + | (_rf_settings.lora.low_datarate_optimize << 3)); + + write_to_register(REG_LR_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); + write_to_register(REG_LR_PREAMBLELSB, preamble_len & 0xFF); + + if (datarate == 6) { + write_to_register(REG_LR_DETECTOPTIMIZE, (read_register( REG_LR_DETECTOPTIMIZE) + & RFLR_DETECTIONOPTIMIZE_MASK) | RFLR_DETECTIONOPTIMIZE_SF6); + write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF6); + } else { + write_to_register(REG_LR_DETECTOPTIMIZE, (read_register( REG_LR_DETECTOPTIMIZE) + & RFLR_DETECTIONOPTIMIZE_MASK) | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); + write_to_register( REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12); + } + + break; + } +} + +/** + * Calculates time on Air i.e., dwell time for a single packet + * + * Crucial for the stack in order to calculate dwell time so as to control + * duty cycling. + */ +uint32_t SX1276_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) +{ + uint32_t airTime = 0; + + switch (modem) { + case MODEM_FSK: + airTime = + rint((8 * (_rf_settings.fsk.preamble_len + + ((read_register( REG_SYNCCONFIG) + & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1) + + ((_rf_settings.fsk.fix_len == 0x01) ? + 0.0 : 1.0) + + (((read_register( REG_PACKETCONFIG1) + & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK) + != 0x00) ? 1.0 : 0) + pkt_len + + ((_rf_settings.fsk.crc_on == 0x01) ? + 2.0 : 0)) + / _rf_settings.fsk.datarate) * 1e3); + + break; + case MODEM_LORA: + double bw = 0.0; + // REMARK: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported + switch (_rf_settings.lora.bandwidth) { + //case 0: // 7.8 kHz + // bw = 78e2; + // break; + //case 1: // 10.4 kHz + // bw = 104e2; + // break; + //case 2: // 15.6 kHz + // bw = 156e2; + // break; + //case 3: // 20.8 kHz + // bw = 208e2; + // break; + //case 4: // 31.2 kHz + // bw = 312e2; + // break; + //case 5: // 41.4 kHz + // bw = 414e2; + // break; + //case 6: // 62.5 kHz + // bw = 625e2; + // break; + case 7: // 125 kHz + bw = 125e3; + break; + case 8: // 250 kHz + bw = 250e3; + break; + case 9: // 500 kHz + bw = 500e3; + break; + } + + // Symbol rate : time for one symbol (secs) + double rs = bw / (1 << _rf_settings.lora.datarate); + double ts = 1 / rs; + // time of preamble + double tPreamble = (_rf_settings.lora.preamble_len + 4.25) * ts; + // Symbol length of payload and time + double tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28 + + 16 * _rf_settings.lora.crc_on + - (_rf_settings.lora.fix_len ? 20 : 0)) + / (double) (4 + * (_rf_settings.lora.datarate + - ((_rf_settings.lora.low_datarate_optimize > 0) + ? 2 : 0)))) + * (_rf_settings.lora.coderate + 4); + double nPayload = 8 + ((tmp > 0) ? tmp : 0); + double tPayload = nPayload * ts; + // Time on air + double tOnAir = tPreamble + tPayload; + // return ms secs + airTime = floor(tOnAir * 1e3 + 0.999); + + break; + } + + return airTime; +} + +/** + * Prepares and sends the radio packet out in the air + */ +void SX1276_LoRaRadio::send(uint8_t *buffer, uint8_t size) +{ + uint32_t tx_timeout = 0; + + switch (_rf_settings.modem) { + case MODEM_FSK: + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = size; + + if (_rf_settings.fsk.fix_len == false) { + write_fifo((uint8_t*) &size, 1); + } else { + write_to_register(REG_PAYLOADLENGTH, size); + } + + if ((size > 0) && (size <= 64)) { + _rf_settings.fsk_packet_handler.chunk_size = size; + } else { + memcpy(_data_buffer, buffer, size); + _rf_settings.fsk_packet_handler.chunk_size = 32; + } + + // Write payload buffer + write_fifo(buffer, _rf_settings.fsk_packet_handler.chunk_size); + _rf_settings.fsk_packet_handler.nb_bytes += + _rf_settings.fsk_packet_handler.chunk_size; + tx_timeout = _rf_settings.fsk.tx_timeout; + + break; + + case MODEM_LORA: + if (_rf_settings.lora.iq_inverted == true) { + write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) + & RFLR_INVERTIQ_TX_MASK + & RFLR_INVERTIQ_RX_MASK) + | RFLR_INVERTIQ_RX_OFF + | RFLR_INVERTIQ_TX_ON)); + write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); + } else { + write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ) + & RFLR_INVERTIQ_TX_MASK + & RFLR_INVERTIQ_RX_MASK) + | RFLR_INVERTIQ_RX_OFF + | RFLR_INVERTIQ_TX_OFF)); + write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); + } + + _rf_settings.lora_packet_handler.size = size; + + // Initializes the payload size + write_to_register(REG_LR_PAYLOADLENGTH, size); + + // Full buffer used for Tx + write_to_register(REG_LR_FIFOTXBASEADDR, 0); + write_to_register(REG_LR_FIFOADDRPTR, 0); + + // FIFO operations can not take place in Sleep mode + if ((read_register( REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) { + standby(); + wait_ms(1); + } + // write_to_register payload buffer + write_fifo(buffer, size); + tx_timeout = _rf_settings.lora.tx_timeout; + + break; + } + + transmit(tx_timeout); +} + +/** + * sets the radio module to sleep + */ + +void SX1276_LoRaRadio::sleep() +{ + // stop timers + tx_timeout_timer.detach(); + rx_timeout_timer.detach(); + + // put module in sleep mode + set_operation_mode(RF_OPMODE_SLEEP); +} + +/** + * Put radio in Standby mode + */ +void SX1276_LoRaRadio::standby( void ) +{ + tx_timeout_timer.detach(); + rx_timeout_timer.detach(); + + set_operation_mode(RF_OPMODE_STANDBY); + _rf_settings.state = RF_IDLE; +} + +/** + * Sets the radio module in receive mode + * + * A DIO4 interrupt let's the state machine know that a preamble is detected + * and finally a DIO0 interrupt let's the state machine know that a packet is + * ready to be read from the FIFO + */ +void SX1276_LoRaRadio::receive(uint32_t timeout) +{ + switch (_rf_settings.modem) { + case MODEM_FSK: + if (timeout == 0 && _rf_settings.fsk.rx_continuous == false) { + // user messed up probably timeout was 0 but mode was not + // continuous, force it to be continuous + _rf_settings.fsk.rx_continuous = true; + } + + // DIO0=PayloadReady + // DIO1=FifoLevel + // DIO2=SyncAddr + // DIO3=FifoEmpty + // DIO4=Preamble + // DIO5=ModeReady + write_to_register(REG_DIOMAPPING1, (read_register( REG_DIOMAPPING1) + & RF_DIOMAPPING1_DIO0_MASK + & RF_DIOMAPPING1_DIO1_MASK + & RF_DIOMAPPING1_DIO2_MASK) + | RF_DIOMAPPING1_DIO0_00 + | RF_DIOMAPPING1_DIO1_00 + | RF_DIOMAPPING1_DIO2_11); + + write_to_register(REG_DIOMAPPING2, (read_register( REG_DIOMAPPING2) + & RF_DIOMAPPING2_DIO4_MASK + & RF_DIOMAPPING2_MAP_MASK) + | RF_DIOMAPPING2_DIO4_11 + | RF_DIOMAPPING2_MAP_PREAMBLEDETECT); + + _rf_settings.fsk_packet_handler.fifo_thresh = + read_register(REG_FIFOTHRESH) & 0x3F; + + write_to_register(REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON + | RF_RXCONFIG_AGCAUTO_ON + | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT); + + _rf_settings.fsk_packet_handler.preamble_detected = false; + _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; + + break; + + case MODEM_LORA: + if (timeout == 0 && _rf_settings.lora.rx_continuous == false) { + // user messed up probably timeout was 0 but mode was not + // continuous, force it to be continuous + _rf_settings.lora.rx_continuous = true; + } + if (_rf_settings.lora.iq_inverted == true) { + write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ) + & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) + | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF)); + write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); + } else { + write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ) + & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) + | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF)); + write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); + } + + // ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal + if (_rf_settings.lora.bandwidth < 9) { + write_to_register(REG_LR_DETECTOPTIMIZE, + read_register(REG_LR_DETECTOPTIMIZE) & 0x7F); + write_to_register(REG_LR_TEST30, 0x00); + switch (_rf_settings.lora.bandwidth) { + case 0: // 7.8 kHz + write_to_register( REG_LR_TEST2F, 0x48); + set_channel(_rf_settings.channel + 7.81e3); + break; + case 1: // 10.4 kHz + write_to_register( REG_LR_TEST2F, 0x44); + set_channel(_rf_settings.channel + 10.42e3); + break; + case 2: // 15.6 kHz + write_to_register( REG_LR_TEST2F, 0x44); + set_channel(_rf_settings.channel + 15.62e3); + break; + case 3: // 20.8 kHz + write_to_register( REG_LR_TEST2F, 0x44); + set_channel(_rf_settings.channel + 20.83e3); + break; + case 4: // 31.2 kHz + write_to_register( REG_LR_TEST2F, 0x44); + set_channel(_rf_settings.channel + 31.25e3); + break; + case 5: // 41.4 kHz + write_to_register( REG_LR_TEST2F, 0x44); + set_channel(_rf_settings.channel + 41.67e3); + break; + case 6: // 62.5 kHz + write_to_register( REG_LR_TEST2F, 0x40); + break; + case 7: // 125 kHz + write_to_register( REG_LR_TEST2F, 0x40); + break; + case 8: // 250 kHz + write_to_register( REG_LR_TEST2F, 0x40); + break; + } + } else { + write_to_register( REG_LR_DETECTOPTIMIZE, + read_register( REG_LR_DETECTOPTIMIZE) | 0x80); + } + + if (_rf_settings.lora.freq_hop_on == true) { + write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_VALIDHEADER + | RFLR_IRQFLAGS_TXDONE + | RFLR_IRQFLAGS_CADDONE + | RFLR_IRQFLAGS_CADDETECTED); + + // DIO0=RxDone, DIO2=FhssChangeChannel + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) + & RFLR_DIOMAPPING1_DIO0_MASK + & RFLR_DIOMAPPING1_DIO2_MASK) + | RFLR_DIOMAPPING1_DIO0_00 + | RFLR_DIOMAPPING1_DIO2_00); + } else { + write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_VALIDHEADER + | RFLR_IRQFLAGS_TXDONE + | RFLR_IRQFLAGS_CADDONE + | RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL + | RFLR_IRQFLAGS_CADDETECTED); + + // DIO0=RxDone + write_to_register(REG_DIOMAPPING1, (read_register( REG_DIOMAPPING1) + & RFLR_DIOMAPPING1_DIO0_MASK) + | RFLR_DIOMAPPING1_DIO0_00); + } + write_to_register(REG_LR_FIFORXBASEADDR, 0); + write_to_register(REG_LR_FIFOADDRPTR, 0); + + break; + } + + memset(_data_buffer, 0, (size_t) MAX_DATA_BUFFER_SIZE); + + _rf_settings.state = RF_RX_RUNNING; + + if (timeout != 0) { + rx_timeout_timer.attach_us( + callback(this, &SX1276_LoRaRadio::timeout_irq_isr), + timeout * 1e3); + } + + if (_rf_settings.modem == MODEM_FSK) { + set_operation_mode(RF_OPMODE_RECEIVER); + + if (_rf_settings.fsk.rx_continuous == false) { + rx_timeout_sync_word.attach_us( + callback(this, &SX1276_LoRaRadio::timeout_irq_isr), + _rf_settings.fsk.rx_single_timeout * 1e3); + } + + return; + } + + // If mode is LoRa set mode + if (_rf_settings.lora.rx_continuous == true) { + set_operation_mode(RFLR_OPMODE_RECEIVER); + } else { + set_operation_mode(RFLR_OPMODE_RECEIVER_SINGLE); + } +} + + +/** + * Perform carrier sensing + * + * Checks for a certain time if the RSSI is above a given threshold. + * This threshold determines if there is already a transmission going on + * in the channel or not. + * + */ +bool SX1276_LoRaRadio::perform_carrier_sense(radio_modems_t modem, + uint32_t freq, + int16_t rssi_threshold, + uint32_t max_carrier_sense_time) +{ + bool status = true; + int16_t rssi = 0; + + set_modem(modem); + set_channel(freq); + set_operation_mode(RF_OPMODE_RECEIVER); + + // hold on a bit, radio turn-around time + wait_ms(1); + + Timer elapsed_time; + elapsed_time.start(); + + // Perform carrier sense for maxCarrierSenseTime + while (elapsed_time.read_ms() < max_carrier_sense_time) { + rssi = get_rssi(modem); + + if (rssi > rssi_threshold) { + status = false; + break; + } + } + + sleep(); + return status; +} + +/** + * TODO: Making sure if this API is valid only for LoRa modulation ? + * + * Indicates if the node is part of a private or public network + */ +void SX1276_LoRaRadio::set_public_network(bool enable) +{ + set_modem(MODEM_LORA); + + _rf_settings.lora.public_network = enable; + if (enable == true) { + // Change lora modem SyncWord + write_to_register(REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD); + } else { + // Change lora modem SyncWord + write_to_register(REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD); + } + +} + +/** + * Puts a limit on the size of payload the module can handle + * By default it is MAX, i.e., 256 bytes + */ +void SX1276_LoRaRadio::set_max_payload_length(radio_modems_t modem, uint8_t max) +{ + set_modem(modem); + + switch (modem) { + case MODEM_FSK: + if (_rf_settings.fsk.fix_len == false) { + write_to_register(REG_PAYLOADLENGTH, max); + } + break; + case MODEM_LORA: + write_to_register(REG_LR_PAYLOADMAXLENGTH, max); + break; + } +} + +/** + * Channel Activity detection (can be done only in LoRa mode) + * + * If any activity on the channel is detected, an interrupt is asserted on + * DIO3. A callback will be generated to the stack/application upon the + * assertion of DIO3. + */ +void SX1276_LoRaRadio::start_cad() +{ + uint8_t reg_val; + + switch (_rf_settings.modem) { + case MODEM_FSK: + break; + case MODEM_LORA: + write_to_register(REG_LR_IRQFLAGSMASK, + RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL); + + // DIO3=CADDone + reg_val = read_register(REG_DIOMAPPING1); + write_to_register(REG_DIOMAPPING1, (reg_val & + RFLR_DIOMAPPING1_DIO3_MASK) | + RFLR_DIOMAPPING1_DIO3_00); + + set_operation_mode(RFLR_OPMODE_CAD); + + _rf_settings.state = RF_CAD; + + break; + default: + break; + } +} + +/** + * Set transmission in continuous wave mode + */ +void SX1276_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, + uint16_t time) +{ + uint8_t reg_val; + + set_channel(freq); + set_tx_config(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, time); + reg_val = read_register(REG_PACKETCONFIG2); + + write_to_register( REG_PACKETCONFIG2, (reg_val & RF_PACKETCONFIG2_DATAMODE_MASK ) ); + // Disable radio interrupts + write_to_register( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 ); + write_to_register( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 ); + + _rf_settings.state = RF_TX_RUNNING; + tx_timeout_timer.attach_us(callback(this, &SX1276_LoRaRadio::timeout_irq_isr), time*1e3); + set_operation_mode(RF_OPMODE_TRANSMITTER); +} + +/***************************************************************************** + * Private APIs * + ****************************************************************************/ +#ifdef MBED_CONF_RTOS_PRESENT +/** + * Thread task handling IRQs + */ +void SX1276_LoRaRadio::rf_irq_task(void) +{ + for (;;) { + osEvent event = irq_thread.signal_wait(0, osWaitForever); + if (event.status != osEventSignal) { + continue; + } + + lock(); + if (event.value.signals & SIG_DIO0) { + handle_dio0_irq(); + } + if (event.value.signals & SIG_DIO1) { + handle_dio1_irq(); + } + if (event.value.signals & SIG_DIO2) { + handle_dio2_irq(); + } + if (event.value.signals & SIG_DIO3) { + handle_dio3_irq(); + } + if (event.value.signals & SIG_DIO4) { + handle_dio4_irq(); + } + if (event.value.signals & SIG_DIO5) { + handle_dio5_irq(); + } + if (event.value.signals & SIG_TIMOUT) { + handle_timeout_irq(); + } + unlock(); + } +} +#endif + +/** + * Writes a single byte to a given register + */ +void SX1276_LoRaRadio::write_to_register(uint8_t addr, uint8_t data) +{ + write_to_register(addr, &data, 1); +} + +/** + * Writes multiple bytes to a given register + */ +void SX1276_LoRaRadio::write_to_register(uint8_t addr, uint8_t *data, uint8_t size) +{ + // set chip-select low + _chip_select = 0; + + // set write command + _spi.write(addr | SPI_WRITE_CMD); + + // write data + for (uint8_t i = 0; i < size; i++) { + _spi.write(data[i]); + } + + // set chip-select high + _chip_select = 1; +} + +/** + * Reads the value of a single register + */ +uint8_t SX1276_LoRaRadio::read_register(uint8_t addr) +{ + uint8_t data; + read_register(addr, &data, 1); + return data; +} + +/** + * Reads multiple values from a given register + */ +void SX1276_LoRaRadio::read_register(uint8_t addr, uint8_t *buffer, uint8_t size) +{ + // set chip-select low + _chip_select = 0; + + // set read command + _spi.write(addr & SPI_READ_CMD); + + // read buffers + for (uint8_t i = 0; i < size; i++) { + buffer[i] = _spi.write(0); + } + + // set chip-select high + _chip_select = 1; +} + +/** + * Writes to FIIO provided by the chip + */ +void SX1276_LoRaRadio::write_fifo(uint8_t *buffer, uint8_t size) +{ + write_to_register(0, buffer, size); +} + +/** + * Reads from the FIFO provided by the chip + */ +void SX1276_LoRaRadio::read_fifo(uint8_t *buffer, uint8_t size) +{ + read_register(0, buffer, size); +} + +/** + * Sets up operation mode + */ +void SX1276_LoRaRadio::set_operation_mode(uint8_t mode) +{ + if (mode == RF_OPMODE_SLEEP) { + set_low_power_mode(); + } else { + set_low_power_mode(); + set_antenna_switch(mode); + } + + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RF_OPMODE_MASK) | mode); +} + +/** + * Sets the modem type to use + * + * At initialization FSK is chosen. Later stack or application + * can choose to change. + */ +void SX1276_LoRaRadio::set_modem(uint8_t modem ) +{ + if ((read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON) != 0 ) { + _rf_settings.modem = MODEM_LORA; + } else { + _rf_settings.modem = MODEM_FSK; + } + + if(_rf_settings.modem == modem ) { + // if the modem is already set + return; + } + + _rf_settings.modem = modem; + + switch(_rf_settings.modem) + { + default: + case MODEM_FSK: + // before changing modem mode, put the module to sleep + sleep(); + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) + | RFLR_OPMODE_LONGRANGEMODE_OFF); + + // Datasheet Tables 28, 29 DIO mapping + write_to_register(REG_DIOMAPPING1, 0x00); // sets DIO0-DI03 in default mode + write_to_register(REG_DIOMAPPING2, 0x30); // bits 4-5 are turned on i.e., + // DIO5 and DIO4=ModeReady + break; + case MODEM_LORA: + sleep(); + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) + | RFLR_OPMODE_LONGRANGEMODE_ON); + + // Datasheet Tables 17 DIO mapping for LoRa + // set to defaults + write_to_register(REG_DIOMAPPING1, 0x00); // DIO0 - DIO3 defaults + write_to_register(REG_DIOMAPPING2, 0x00); // DIO4 - DIO5 defaults + + break; + } +} + +/** + * Set the radio module variant + */ +void SX1276_LoRaRadio::set_sx1276_variant_type() +{ + _ant_switch.input(); + wait_ms(1); + if (_ant_switch == 1) { + radio_variant = SX1276MB1LAS; + } else { + radio_variant = SX1276MB1MAS; + } + _ant_switch.output(); + wait_ms(1); +} + +/** + * Sets up frequency for SPI module + * Reference DataSheet: 4.3 SPI Interface + */ +void SX1276_LoRaRadio::setup_spi() +{ + // SPI bus frequency + uint32_t spi_freq = SPI_FREQUENCY; + + // Hold chip-select high + _chip_select = 1; + _spi.format(8, 0); + +#if defined (TARGET_KL25Z) + //bus-clock frequency is halved -> double the SPI frequency to compensate + _spi.frequency(spi_freq * 2); +#else + // otherwise use default SPI frequency which is 8 MHz + _spi.frequency(spi_freq); +#endif + // 100 us wait to settle down + wait(0.1); +} + +/** + * Sets the radio registers to defaults + */ +void SX1276_LoRaRadio::setup_registers() +{ + for (unsigned int i = 0; i < sizeof(radio_reg_init) / sizeof(radio_registers_t); i++) { + set_modem(radio_reg_init[i].modem); + write_to_register(radio_reg_init[i].addr, radio_reg_init[i].value); + } +} + +/** + * Performs the Rx chain calibration for LF and HF bands + * + * Must be called just after the reset so all registers are at their + * default values. + */ +void SX1276_LoRaRadio::rx_chain_calibration(void) +{ + uint8_t regPaConfigInitVal; + uint32_t initialFreq; + + // Save context + regPaConfigInitVal = read_register( REG_PACONFIG ); + initialFreq = ( double )( ( ( uint32_t )this->read_register( REG_FRFMSB ) << 16 ) | + ( ( uint32_t )this->read_register( REG_FRFMID ) << 8 ) | + ( ( uint32_t )this->read_register( REG_FRFLSB ) ) ) * ( double )FREQ_STEP; + + // Cut the PA just in case, RFO output, power = -1 dBm + write_to_register( REG_PACONFIG, 0x00 ); + + // Launch Rx chain calibration for LF band + write_to_register (REG_IMAGECAL, (read_register(REG_IMAGECAL) + & RF_IMAGECAL_IMAGECAL_MASK) + | RF_IMAGECAL_IMAGECAL_START); + while((read_register(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING ) + == RF_IMAGECAL_IMAGECAL_RUNNING ) + { + } + + // Sets a Frequency in HF band + set_channel(868000000); + + // Launch Rx chain calibration for HF band + write_to_register (REG_IMAGECAL, (read_register(REG_IMAGECAL) + & RF_IMAGECAL_IMAGECAL_MASK ) + | RF_IMAGECAL_IMAGECAL_START ); + while((read_register(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING ) + == RF_IMAGECAL_IMAGECAL_RUNNING ) + { + // do nothing, just wait while rf image frequency calibration is done + } + + // Restore context + write_to_register( REG_PACONFIG, regPaConfigInitVal ); + set_channel(initialFreq); +} + +/** + * Gets FSK bandwidth values + * + * Gives either normal bandwidths or bandwidths for + * AFC (auto frequency correction) + */ +uint8_t SX1276_LoRaRadio::get_fsk_bw_reg_val(uint32_t bandwidth) +{ + uint8_t i; + + for (i = 0; i < (sizeof(fsk_bandwidths) / sizeof(fsk_bw_t)) - 1; i++) { + if ((bandwidth >= fsk_bandwidths[i].bandwidth) + && (bandwidth < fsk_bandwidths[i + 1].bandwidth)) { + return fsk_bandwidths[i].register_value; + } + } + // ERROR: Value not found + // This should never happen + while (1); +} + +uint8_t SX1276_LoRaRadio::get_pa_conf_reg(uint32_t channel) +{ + if (channel > RF_MID_BAND_THRESH) { + if (radio_variant == SX1276MB1LAS || is_murata) { + return RF_PACONFIG_PASELECT_PABOOST; + } else { + return RF_PACONFIG_PASELECT_RFO; + } + } else { + return RF_PACONFIG_PASELECT_RFO; + } +} + +/** + * Sets the transmit power for the module + */ +void SX1276_LoRaRadio::set_rf_tx_power(int8_t power) +{ + + uint8_t paConfig = 0; + uint8_t paDac = 0; + + paConfig = read_register(REG_PACONFIG); + paDac = read_register(REG_PADAC); + + paConfig = (paConfig & RF_PACONFIG_PASELECT_MASK) | get_pa_conf_reg(_rf_settings.channel); + paConfig = (paConfig & RF_PACONFIG_MAX_POWER_MASK) | 0x70; + + if ((paConfig & RF_PACONFIG_PASELECT_PABOOST) == RF_PACONFIG_PASELECT_PABOOST) { + if (power > 17) { + paDac = (paDac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_ON; + } else { + paDac = (paDac & RF_PADAC_20DBM_MASK) | RF_PADAC_20DBM_OFF; + } + if ((paDac & RF_PADAC_20DBM_ON) == RF_PADAC_20DBM_ON) { + if (power < 5) { + power = 5; + } + if (power > 20) { + power = 20; + } + paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK) + | (uint8_t) ((uint16_t) (power - 5) & 0x0F); + } else { + if (power < 2) { + power = 2; + } + if (power > 17) { + power = 17; + } + paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK) + | (uint8_t) ((uint16_t) (power - 2) & 0x0F); + } + } else { + if (power < -1) { + power = -1; + } + if (power > 14) { + power = 14; + } + paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK) + | (uint8_t) ((uint16_t) (power + 1) & 0x0F); + } + write_to_register( REG_PACONFIG, paConfig); + write_to_register( REG_PADAC, paDac); +} + +/** + * Actual TX - Transmit routine + * + * A DIO0 interrupt let the state machine know that a a packet is + * successfully sent, otherwise a TxTimeout is invoked. + * TxTimeout should never happen in normal circumstances as the radio should + * be able to send a packet out in the air no matter what. + */ +void SX1276_LoRaRadio::transmit(uint32_t timeout) +{ + switch (_rf_settings.modem) { + + case MODEM_FSK: + // DIO0=PacketSent + // DIO1=FifoEmpty + // DIO2=FifoFull + // DIO3=FifoEmpty + // DIO4=LowBat + // DIO5=ModeReady + write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) & + RF_DIOMAPPING1_DIO0_MASK & + RF_DIOMAPPING1_DIO1_MASK & + RF_DIOMAPPING1_DIO2_MASK) | + RF_DIOMAPPING1_DIO1_01); + + write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) & + RF_DIOMAPPING2_DIO4_MASK & + RF_DIOMAPPING2_MAP_MASK)); + _rf_settings.fsk_packet_handler.fifo_thresh = + read_register(REG_FIFOTHRESH) & 0x3F; + + break; + + case MODEM_LORA: + + if (_rf_settings.lora.freq_hop_on == true) { + write_to_register(REG_LR_IRQFLAGSMASK, + RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_CADDETECTED); + + // DIO0=tx_done, DIO2=fhss_change_channel + + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & + RFLR_DIOMAPPING1_DIO0_MASK & + RFLR_DIOMAPPING1_DIO2_MASK) | + RFLR_DIOMAPPING1_DIO0_01 | + RFLR_DIOMAPPING1_DIO2_00); + } else { + write_to_register(REG_LR_IRQFLAGSMASK, + RFLR_IRQFLAGS_RXTIMEOUT | + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED); + + // DIO0=tx_done + write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) & + RFLR_DIOMAPPING1_DIO0_MASK) | + RFLR_DIOMAPPING1_DIO0_01); + } + + break; + } + + _rf_settings.state = RF_TX_RUNNING; + tx_timeout_timer.attach_us(callback(this, + &SX1276_LoRaRadio::timeout_irq_isr), timeout*1e3); + set_operation_mode(RF_OPMODE_TRANSMITTER); +} + +/** + * Get RSSI from the module + */ +int16_t SX1276_LoRaRadio::get_rssi(radio_modems_t modem) +{ + int16_t rssi = 0; + + switch (modem) { + case MODEM_FSK: + rssi = -(read_register(REG_RSSIVALUE) >> 1); + break; + case MODEM_LORA: + if (_rf_settings.channel > RF_MID_BAND_THRESH) { + rssi = RSSI_OFFSET_HF + read_register(REG_LR_RSSIVALUE); + } else { + rssi = RSSI_OFFSET_LF + read_register(REG_LR_RSSIVALUE); + } + break; + default: + rssi = -1; + break; + } + return rssi; +} + +/** + * Sets the module in low power mode by disconnecting + * TX and RX submodules, turning off power amplifier etc. + */ +void SX1276_LoRaRadio::set_low_power_mode() +{ + + if (_rf_ctrls.rf_switch_ctl1 != NC) { + _rf_switch_ctl1 = 0; + } + + if (_rf_ctrls.rf_switch_ctl2 != NC) { + _rf_switch_ctl2 = 0; + } + + if (_rf_ctrls.pwr_amp_ctl != NC) { + _pwr_amp_ctl = 0; + } + + if (_rf_ctrls.txctl != NC) { + _txctl = 0; + } + + if (_rf_ctrls.txctl != NC) { + _rxctl = 0; + } + + if (_rf_ctrls.ant_switch != NC) { + _ant_switch = 0; + } +} + +/** + * Attaches ISRs to interrupt pins + */ +void SX1276_LoRaRadio::setup_interrupts() +{ + _dio0_ctl.rise(callback(this, &SX1276_LoRaRadio::dio0_irq_isr)); + _dio1_ctl.rise(callback(this, &SX1276_LoRaRadio::dio1_irq_isr)); + _dio2_ctl.rise(callback(this, &SX1276_LoRaRadio::dio2_irq_isr)); + _dio3_ctl.rise(callback(this, &SX1276_LoRaRadio::dio3_irq_isr)); + _dio4_ctl.rise(callback(this, &SX1276_LoRaRadio::dio4_irq_isr)); + if (!is_murata) { + _dio5_ctl.rise(callback(this, &SX1276_LoRaRadio::dio5_irq_isr)); + } +} + +/** + * Sets up radio latch position according to the + * radio mode + */ +void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode) +{ + // here we got to do ifdef for changing controls + // as some pins might be NC + switch (mode) { + case RFLR_OPMODE_TRANSMITTER: + if (_rf_ctrls.rf_switch_ctl1 != NC + && _rf_ctrls.rf_switch_ctl2 != NC) { + // module is in transmit mode and RF latch switches + // are connected. Check if power amplifier boost is + // setup or not + if ((read_register(REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST) + == RF_PACONFIG_PASELECT_PABOOST) { + _rf_switch_ctl1 = 1; + _rf_switch_ctl2 = 0; + } else { + // power amplifier not selected + _rf_switch_ctl1 = 0; + _rf_switch_ctl2 = 1; + } + } + if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) { + // module is in transmit mode and tx/rx submodule control + // pins are connected + if (is_murata) + { + if (read_register(REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST) { + _pwr_amp_ctl = 1; + _txctl = 0; + } else { + _pwr_amp_ctl = 0; + _txctl = 1; + } + } else + { + _txctl = 1; + } + _rxctl = 0; + } + if (_rf_ctrls.ant_switch != NC){ + _ant_switch = 1; + } + break; + case RFLR_OPMODE_RECEIVER: + case RFLR_OPMODE_RECEIVER_SINGLE: + case RFLR_OPMODE_CAD: + if (_rf_ctrls.rf_switch_ctl1 != NC + && _rf_ctrls.rf_switch_ctl2 != NC) { + // radio is in reception or CAD mode and RF latch switches + // are connected + _rf_switch_ctl1 = 1; + _rf_switch_ctl2 = 1; + } + if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) { + _txctl = 0; + _rxctl = 1; + } + if (_rf_ctrls.ant_switch != NC) { + _ant_switch = 0; + } + if (_rf_ctrls.pwr_amp_ctl != NC) { + _pwr_amp_ctl = 0; + } + break; + default: + // Enforce default case when any connected control pin is kept low. + if (_rf_ctrls.rf_switch_ctl1 != NC + && _rf_ctrls.rf_switch_ctl2 != NC) { + // radio is in reception or CAD mode and RF latch switches + // are connected + _rf_switch_ctl1 = 0; + _rf_switch_ctl2 = 0; + } + if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) { + _txctl = 0; + _rxctl = 0; + } + if (_rf_ctrls.ant_switch != NC) { + _ant_switch = 0; + } + if (_rf_ctrls.pwr_amp_ctl != NC) { + _pwr_amp_ctl = 0; + } + break; + } +} + +/***************************************************************************** + * Interrupt service routines (ISRs) - set signals to the irq_thread * + ****************************************************************************/ +void SX1276_LoRaRadio::dio0_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO0); +#else + handle_dio0_irq(); +#endif +} + +void SX1276_LoRaRadio::dio1_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO1); +#else + handle_dio1_irq(); +#endif +} + +void SX1276_LoRaRadio::dio2_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO2); +#else + handle_dio2_irq(); +#endif +} + +void SX1276_LoRaRadio::dio3_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO3); +#else + handle_dio3_irq(); +#endif +} + +void SX1276_LoRaRadio::dio4_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO4); +#else + handle_dio4_irq(); +#endif +} + +void SX1276_LoRaRadio::dio5_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_DIO5); +#else + handle_dio5_irq(); +#endif +} + +// This is not a hardware interrupt +// we invoke it ourselves based upon +// our timers +void SX1276_LoRaRadio::timeout_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.signal_set(SIG_TIMOUT); +#else + handle_timeout_irq(); +#endif +} + +/****************************************************************************** + * Interrupt Handlers * + *****************************************************************************/ + +void SX1276_LoRaRadio::handle_dio0_irq() +{ + volatile uint8_t irqFlags = 0; + + switch (_rf_settings.state) { + case RF_RX_RUNNING: + switch (_rf_settings.modem) { + case MODEM_FSK: + if (_rf_settings.fsk.crc_on == true) { + irqFlags = read_register(REG_IRQFLAGS2); + if ((irqFlags & RF_IRQFLAGS2_CRCOK) + != RF_IRQFLAGS2_CRCOK) { + // Clear Irqs + write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | + RF_IRQFLAGS1_PREAMBLEDETECT | + RF_IRQFLAGS1_SYNCADDRESSMATCH); + write_to_register(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); + + + if (_rf_settings.fsk.rx_continuous == false) { + rx_timeout_sync_word.detach(); + _rf_settings.state = RF_IDLE; + } else { + // Continuous mode restart Rx chain + write_to_register(REG_RXCONFIG, + read_register(REG_RXCONFIG) | + RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + } + + rx_timeout_timer.detach(); + + if ((_radio_events != NULL) + && (_radio_events->rx_error != NULL)) { + _radio_events->rx_error(); + } + _rf_settings.fsk_packet_handler.preamble_detected = false; + _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; + // break from here, a CRC error happened, RX_ERROR + // was notified. No need to go any further + break; + } + } + + // Read received packet size + if ((_rf_settings.fsk_packet_handler.size == 0) + && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) { + if (_rf_settings.fsk.fix_len == false) { + read_fifo((uint8_t*) &_rf_settings.fsk_packet_handler.size, 1); + } else { + _rf_settings.fsk_packet_handler.size = read_register(REG_PAYLOADLENGTH); + } + read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.nb_bytes += + (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + } else { + read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.nb_bytes += + (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + } + + if (_rf_settings.fsk.rx_continuous == false) { + _rf_settings.state = RF_IDLE; + rx_timeout_sync_word.detach(); + } else { + // Continuous mode restart Rx chain + write_to_register(REG_RXCONFIG, read_register(REG_RXCONFIG) + | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + } + + rx_timeout_timer.detach(); + + if ((_radio_events != NULL) && (_radio_events->rx_done != NULL)) { + _radio_events->rx_done( + _data_buffer, + _rf_settings.fsk_packet_handler.size, + _rf_settings.fsk_packet_handler.rssi_value, 0); + } + _rf_settings.fsk_packet_handler.preamble_detected = false; + _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; + break; + + case MODEM_LORA: { + int8_t snr = 0; + + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE); + + irqFlags = read_register(REG_LR_IRQFLAGS); + if ((irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK) + == RFLR_IRQFLAGS_PAYLOADCRCERROR) { + // Clear Irq + write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR); + + if (_rf_settings.lora.rx_continuous == false) { + _rf_settings.state = RF_IDLE; + } + rx_timeout_timer.detach(); + + if ((_radio_events != NULL) + && (_radio_events->rx_error != NULL)) { + _radio_events->rx_error(); + } + break; + } + + _rf_settings.lora_packet_handler.snr_value = read_register( + REG_LR_PKTSNRVALUE); + if (_rf_settings.lora_packet_handler.snr_value & 0x80) // The SNR sign bit is 1 + { + // Invert and divide by 4 + snr = ((~_rf_settings.lora_packet_handler.snr_value + 1) + & 0xFF) >> 2; + snr = -snr; + } else { + // Divide by 4 + snr = + (_rf_settings.lora_packet_handler.snr_value + & 0xFF) >> 2; + } + + int16_t rssi = read_register( REG_LR_PKTRSSIVALUE); + if (snr < 0) { + if (_rf_settings.channel > RF_MID_BAND_THRESH) { + _rf_settings.lora_packet_handler.rssi_value = + RSSI_OFFSET_HF + rssi + (rssi >> 4) + snr; + } else { + _rf_settings.lora_packet_handler.rssi_value = + RSSI_OFFSET_LF + rssi + (rssi >> 4) + snr; + } + } else { + if (_rf_settings.channel > RF_MID_BAND_THRESH) { + _rf_settings.lora_packet_handler.rssi_value = + RSSI_OFFSET_HF + rssi + (rssi >> 4); + } else { + _rf_settings.lora_packet_handler.rssi_value = + RSSI_OFFSET_LF + rssi + (rssi >> 4); + } + } + + _rf_settings.lora_packet_handler.size = read_register(REG_LR_RXNBBYTES); + read_fifo(_data_buffer, _rf_settings.lora_packet_handler.size); + + if (_rf_settings.lora.rx_continuous == false) { + _rf_settings.state = RF_IDLE; + } + rx_timeout_timer.detach(); + + if ((_radio_events != NULL) && (_radio_events->rx_done != NULL)) { + _radio_events->rx_done(_data_buffer, + _rf_settings.lora_packet_handler.size, + _rf_settings.lora_packet_handler.rssi_value, + _rf_settings.lora_packet_handler.snr_value); + } + } + break; + default: + break; + } + break; + case RF_TX_RUNNING: + tx_timeout_timer.detach(); + // TxDone interrupt + switch (_rf_settings.modem) { + case MODEM_LORA: + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE); + // Intentional fall through + case MODEM_FSK: + default: + _rf_settings.state = RF_IDLE; + if ((_radio_events != NULL) + && (_radio_events->tx_done != NULL)) { + _radio_events->tx_done(); + } + break; + } + break; + default: + break; + } +} + +void SX1276_LoRaRadio::handle_dio1_irq() +{ + switch (_rf_settings.state) { + case RF_RX_RUNNING: + switch (_rf_settings.modem) { + case MODEM_FSK: + // FifoLevel interrupt + // Read received packet size + if ((_rf_settings.fsk_packet_handler.size == 0) + && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) { + if (_rf_settings.fsk.fix_len == false) { + read_fifo((uint8_t*) &_rf_settings.fsk_packet_handler.size, 1); + } else { + _rf_settings.fsk_packet_handler.size = + read_register(REG_PAYLOADLENGTH); + } + } + + if ((_rf_settings.fsk_packet_handler.size + - _rf_settings.fsk_packet_handler.nb_bytes) + > _rf_settings.fsk_packet_handler.fifo_thresh) { + read_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes), + _rf_settings.fsk_packet_handler.fifo_thresh); + _rf_settings.fsk_packet_handler.nb_bytes += + _rf_settings.fsk_packet_handler.fifo_thresh; + } else { + read_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes), + _rf_settings.fsk_packet_handler.size + - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.nb_bytes += + (_rf_settings.fsk_packet_handler.size + - _rf_settings.fsk_packet_handler.nb_bytes); + } + + break; + + case MODEM_LORA: + // Sync time out + rx_timeout_timer.detach(); + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT); + _rf_settings.state = RF_IDLE; + if ((_radio_events != NULL) + && (_radio_events->rx_timeout != NULL)) { + _radio_events->rx_timeout(); + } + break; + default: + break; + } + + break; + + case RF_TX_RUNNING: + switch (_rf_settings.modem) { + case MODEM_FSK: + // FifoLevel interrupt + if ((_rf_settings.fsk_packet_handler.size + - _rf_settings.fsk_packet_handler.nb_bytes) + > _rf_settings.fsk_packet_handler.chunk_size) { + write_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes), + _rf_settings.fsk_packet_handler.chunk_size); + _rf_settings.fsk_packet_handler.nb_bytes += + _rf_settings.fsk_packet_handler.chunk_size; + } else { + // Write the last chunk of data + write_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, + _rf_settings.fsk_packet_handler.size + - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.nb_bytes += + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes; + } + + break; + + case MODEM_LORA: + break; + default: + break; + } + break; + default: + break; + } +} + +void SX1276_LoRaRadio::handle_dio2_irq(void) +{ + switch (_rf_settings.state) { + case RF_RX_RUNNING: + switch (_rf_settings.modem) { + case MODEM_FSK: + // DIO4 must have been asserted to set preamble_detected to true + if ((_rf_settings.fsk_packet_handler.preamble_detected == true) + && (_rf_settings.fsk_packet_handler.sync_word_detected == false)) { + if (_rf_settings.fsk.rx_continuous == false) { + rx_timeout_sync_word.detach(); + } + + _rf_settings.fsk_packet_handler.sync_word_detected = true; + + _rf_settings.fsk_packet_handler.rssi_value = + -(read_register(REG_RSSIVALUE) >> 1); + + _rf_settings.fsk_packet_handler.afc_value = + (int32_t) (double) (((uint16_t) read_register( + REG_AFCMSB) << 8) + | (uint16_t) read_register( REG_AFCLSB)) + * (double) FREQ_STEP; + _rf_settings.fsk_packet_handler.rx_gain = + (read_register( REG_LNA) >> 5) & 0x07; + } + + break; + + case MODEM_LORA: + if (_rf_settings.lora.freq_hop_on == true) { + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL); + + if ((_radio_events != NULL) + && (_radio_events->fhss_change_channel != NULL)) { + _radio_events->fhss_change_channel( + (read_register(REG_LR_HOPCHANNEL) + & RFLR_HOPCHANNEL_CHANNEL_MASK)); + } + } + + break; + + default: + break; + } + + break; + + case RF_TX_RUNNING: + switch (_rf_settings.modem) { + case MODEM_FSK: + break; + case MODEM_LORA: + if (_rf_settings.lora.freq_hop_on == true) { + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL); + + if ((_radio_events != NULL) + && (_radio_events->fhss_change_channel != NULL)) { + _radio_events->fhss_change_channel( + (read_register(REG_LR_HOPCHANNEL) + & RFLR_HOPCHANNEL_CHANNEL_MASK)); + } + } + break; + default: + break; + } + break; + default: + break; + } +} + +void SX1276_LoRaRadio::handle_dio3_irq(void) +{ + switch (_rf_settings.modem) { + case MODEM_FSK: + break; + case MODEM_LORA: + if ((read_register(REG_LR_IRQFLAGS) & RFLR_IRQFLAGS_CADDETECTED) + == RFLR_IRQFLAGS_CADDETECTED) { + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, + RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE); + if ((_radio_events != NULL) + && (_radio_events->cad_done != NULL)) { + _radio_events->cad_done(true); + } + } else { + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE); + if ((_radio_events != NULL) + && (_radio_events->cad_done != NULL)) { + _radio_events->cad_done(false); + } + } + break; + default: + break; + } +} + +void SX1276_LoRaRadio::handle_dio4_irq(void) +{ + // is asserted when a preamble is detected (FSK modem only) + switch (_rf_settings.modem) { + case MODEM_FSK: { + if (_rf_settings.fsk_packet_handler.preamble_detected == false) { + _rf_settings.fsk_packet_handler.preamble_detected = true; + } + } + break; + case MODEM_LORA: + break; + default: + break; + } +} + +void SX1276_LoRaRadio::handle_dio5_irq() +{ + switch (_rf_settings.modem) { + case MODEM_FSK: + break; + case MODEM_LORA: + break; + default: + break; + } +} + + +void SX1276_LoRaRadio::handle_timeout_irq() +{ + switch (_rf_settings.state) { + case RF_RX_RUNNING: + if (_rf_settings.modem == MODEM_FSK) { + _rf_settings.fsk_packet_handler.preamble_detected = false; + _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; + + // Clear Irqs + write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | + RF_IRQFLAGS1_PREAMBLEDETECT | + RF_IRQFLAGS1_SYNCADDRESSMATCH); + write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); + + if (_rf_settings.fsk.rx_continuous == true) { + // Continuous mode restart Rx chain + write_to_register( REG_RXCONFIG, + read_register(REG_RXCONFIG) | + RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + } else { + _rf_settings.state = RF_IDLE; + rx_timeout_sync_word.attach_us( + callback(this, &SX1276_LoRaRadio::timeout_irq_isr), + _rf_settings.fsk.rx_single_timeout * 1e3); + } + } + + if ((_radio_events != NULL) + && (_radio_events->rx_timeout != NULL)) { + _radio_events->rx_timeout(); + } + + break; + + case RF_TX_RUNNING: + // Tx timeout shouldn't happen. + // But it has been observed that when it happens it is a result of a + // corrupted SPI transfer + // The workaround is to put the radio in a known state. + // Thus, we re-initialize it. + + // Reset the radio + radio_reset(); + + // Initialize radio default values + set_operation_mode(RF_OPMODE_SLEEP); + + setup_registers(); + + set_modem(MODEM_FSK); + + // Restore previous network type setting. + set_public_network(_rf_settings.lora.public_network); + + _rf_settings.state = RF_IDLE; + if ((_radio_events != NULL) + && (_radio_events->tx_timeout != NULL)) { + _radio_events->tx_timeout(); + } + break; + default: + break; + } +} +// EOF diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h new file mode 100644 index 0000000000..79fd476c28 --- /dev/null +++ b/SX1276/SX1276_LoRaRadio.h @@ -0,0 +1,424 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2013 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) + + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef SX1276_LORARADIO_H_ +#define SX1276_LORARADIO_H_ + +#include "netsocket/LoRaRadio.h" + +#ifdef MBED_SX1276_LORARADIO_BUFFER_SIZE +#define MAX_DATA_BUFFER_SIZE MBED_SX1276_LORARADIO_BUFFER_SIZE +#else +#define MAX_DATA_BUFFER_SIZE 256 +#endif + +typedef struct { + PinName rf_switch_ctl1; + PinName rf_switch_ctl2; + PinName txctl; + PinName rxctl; + PinName ant_switch; + PinName pwr_amp_ctl; + PinName tcxo; +} rf_ctrls; + +/** + * Radio driver implementation for Semtech SX1272 plus variants. + * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. + */ +class SX1276_LoRaRadio: public LoRaRadio { +public: + /** + * Use this constructor if pin definitions are provided manually. + * The pins that are marked NC are optional. It is assumed that these + * pins are not connected until/unless configured otherwise. + * + * Note: Pin ant_switch is equivalent to RxTx pin at + * https://developer.mbed.org/components/SX1276MB1xAS/. + * Reading the state of this pin indicates if the radio module type is + * SX1276MB1LAS(North American frequency band supported) or SX1276MAS + * (European frequency band supported). + * Pin dio4 can be mapped to multiple pins on the board, please refer to + * schematic of your board. For reference look at + * https://developer.mbed.org/components/SX1276MB1xAS/ + * + * Most of the radio module control pins are not being used at the moment as + * the SX1276MB1xAS shield has not connected them. For consistency and future + * use we are leaving the pins in the constructor. For example, if in some + * setting SX1276 radio module gets connected to an external power amplifier + * or radio latch controls are connected. + */ + SX1276_LoRaRadio(PinName mosi, PinName miso, PinName sclk, PinName nss, + PinName reset, PinName dio0, PinName dio1, PinName dio2, + PinName dio3, PinName dio4, PinName dio5, + PinName rf_switch_ctl1=NC, + PinName rf_switch_ctl2=NC, PinName txctl = NC, + PinName rxctl = NC, PinName ant_switch = NC, + PinName pwr_amp_ctl = NC, + PinName tcxo = NC); + + /** + * Destructor + */ + virtual ~SX1276_LoRaRadio(); + + /** + * Registers radio events with the Mbed LoRaWAN stack and + * undergoes initialization steps if any + * + * @param events Structure containing the driver callback functions + */ + virtual void init_radio(radio_events_t *events); + + /** + * Resets the radio module + */ + virtual void radio_reset(); + + /** + * Put the RF module in sleep mode + */ + virtual void sleep(void); + + /** + * Sets the radio in standby mode + */ + virtual void standby(void); + + /** + * Sets the reception parameters + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param bandwidth Sets the bandwidth + * FSK : >= 2600 and <= 250000 Hz + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * @param datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * @param coderate Sets the coding rate ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * @param bandwidth_afc Sets the AFC Bandwidth ( FSK only ) + * FSK : >= 2600 and <= 250000 Hz + * LoRa: N/A ( set to 0 ) + * @param preamble_len Sets the Preamble length ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: Length in symbols ( the hardware adds 4 more symbols ) + * @param symb_timeout Sets the RxSingle timeout value + * FSK : timeout number of bytes + * LoRa: timeout in symbols + * @param fixLen Fixed length packets [0: variable, 1: fixed] + * @param payload_len Sets payload length when fixed lenght is used + * @param crc_on Enables/Disables the CRC [0: OFF, 1: ON] + * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) + * @param hop_period Number of symbols bewteen each hop (LoRa only) + * @param iq_inverted Inverts IQ signals ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * @param rx_continuous Sets the reception in continuous mode + * [false: single mode, true: continuous mode] + */ + virtual void set_rx_config (radio_modems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidth_afc, uint16_t preamble_len, + uint16_t symb_timeout, bool fix_len, + uint8_t payload_len, + bool crc_on, bool freq_hop_on, uint8_t hop_period, + bool iq_inverted, bool rx_continuous); + + /** + * Sets the transmission parameters + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param power Sets the output power [dBm] + * @param fdev Sets the frequency deviation ( FSK only ) + * FSK : [Hz] + * LoRa: 0 + * @param bandwidth Sets the bandwidth ( LoRa only ) + * FSK : 0 + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * @param datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * @param coderate Sets the coding rate ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * @param preamble_len Sets the preamble length + * @param fix_len Fixed length packets [0: variable, 1: fixed] + * @param crc_on Enables disables the CRC [0: OFF, 1: ON] + * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) + * @param hop_period Number of symbols bewteen each hop (LoRa only) + * @param iq_inverted Inverts IQ signals ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * @param timeout Transmission timeout [us] + */ + virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preamble_len, + bool fix_len, bool crc_on, bool freq_hop_on, + uint8_t hop_period, bool iq_inverted, uint32_t timeout); + + /** + * Sends the buffer of size + * + * Prepares the packet to be sent and sets the radio in transmission + * + * @param buffer Buffer pointer + * @param size Buffer size + */ + virtual void send(uint8_t *buffer, uint8_t size); + + /** + * Sets the radio in reception mode for the given time + * + * It should be noted that if the timeout is set to 0, it essentially + * puts the receiver in continuous mode and hence from thereon it should + * be treated as if in continuous mode. However, an appropriate way of + * setting the receiver in continuous mode is by using set_rx_config() + * API. + * + * @param timeout Reception timeout [ms] + * + */ + virtual void receive(uint32_t timeout); + + /** + * Sets the carrier frequency + * + * @param freq Channel RF frequency + */ + virtual void set_channel(uint32_t freq); + + /** + * Generates a 32 bits random value based on the RSSI readings + * + * Remark this function sets the radio in LoRa modem mode and disables + * all interrupts. + * After calling this function either Radio.SetRxConfig or + * Radio.SetTxConfig functions must be called. + * + * @return 32 bits random value + */ + virtual uint32_t random(void); + + /** + * Get radio status + * + * @param status Radio status [RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] + * @return Return current radio status + */ + virtual uint8_t get_status(void); + + /** + * Sets the maximum payload length + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param max Maximum payload length in bytes + */ + virtual void set_max_payload_length(radio_modems_t modem, uint8_t max); + + /** + * Sets the network to public or private + * + * Updates the sync byte. Applies to LoRa modem only + * + * @param enable if true, it enables a public network + */ + virtual void set_public_network(bool enable); + + /** + * Computes the packet time on air for the given payload + * + * Remark can only be called once SetRxConfig or SetTxConfig have been called + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param pkt_len Packet payload length + * @return Computed airTime for the given packet payload length + */ + virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len); + + /** + * Perform carrier sensing + * + * Checks for a certain time if the RSSI is above a given threshold. + * This threshold determines if there is already a transmission going on + * in the channel or not. + * + * @param modem Type of the radio modem + * @param freq Carrier frequency + * @param rssi_threshold Threshold value of RSSI + * @param max_carrier_sense_time time to sense the channel + * + * @return true if there is no active transmission + * in the channel, false otherwise + */ + virtual bool perform_carrier_sense(radio_modems_t modem, + uint32_t freq, + int16_t rssi_threshold, + uint32_t max_carrier_sense_time); + + /** + * Sets the radio in CAD mode + * + */ + virtual void start_cad(void); + + /** + * Check if the given RF is in range + * + * @param frequency frequency needed to be checked + */ + virtual bool check_rf_frequency(uint32_t frequency); + + /** Sets the radio in continuous wave transmission mode + * + * @param freq Channel RF frequency + * @param power Sets the output power [dBm] + * @param time Transmission mode timeout [s] + */ + virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time); + + /** + * Acquire exclusive access + */ + virtual void lock(void); + + /** + * Release exclusive access + */ + virtual void unlock(void); + +private: + + // SPI and chip select control + SPI _spi; + DigitalOut _chip_select; + + // module rest control + DigitalInOut _reset_ctl; + + // Interrupt controls + InterruptIn _dio0_ctl; + InterruptIn _dio1_ctl; + InterruptIn _dio2_ctl; + InterruptIn _dio3_ctl; + InterruptIn _dio4_ctl; + InterruptIn _dio5_ctl; + + // Radio specific controls + DigitalOut _rf_switch_ctl1; + DigitalOut _rf_switch_ctl2; + DigitalOut _txctl; + DigitalOut _rxctl; + DigitalInOut _ant_switch; + DigitalOut _pwr_amp_ctl; + DigitalOut _tcxo; + + // Contains all RF control pin names + // This storage is needed even after assigning the + // pins to corresponding object, as the driver needs to know + // which control pins are connected and which are not. This + // variation is inherent to driver because of target configuration. + rf_ctrls _rf_ctrls; + + // Structure containing all user and network specified settings + // for radio module + radio_settings_t _rf_settings; + + // Structure containing function pointers to the stack callbacks + radio_events_t *_radio_events; + + // Data buffer used for both TX and RX + // Size of this buffer is configurable via Mbed config system + // Default is 256 bytes + uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE]; + + // TX/RX Timers - all use milisecond units + Timeout tx_timeout_timer; + Timeout rx_timeout_timer; + Timeout rx_timeout_sync_word; + +#ifdef MBED_CONF_RTOS_PRESENT + // Thread to handle interrupts + Thread irq_thread; +#endif + + // Access protection + PlatformMutex mutex; + + // Murata board + bool is_murata; + + // helper functions + void setup_registers(); + void default_antenna_switch_ctrls(); + void set_antenna_switch(uint8_t operation_mode); + void setup_spi(); + void gpio_init(); + void gpio_deinit(); + void setup_interrupts(); + void set_operation_mode(uint8_t operation_mode); + void set_low_power_mode(); + void set_sx1276_variant_type(); + uint8_t get_pa_conf_reg(uint32_t channel); + void set_rf_tx_power(int8_t power); + int16_t get_rssi(radio_modems_t modem); + uint8_t get_fsk_bw_reg_val(uint32_t bandwidth); + void write_to_register(uint8_t addr, uint8_t data); + void write_to_register(uint8_t addr, uint8_t *data, uint8_t size); + uint8_t read_register(uint8_t addr); + void read_register(uint8_t addr, uint8_t *buffer, uint8_t size); + void write_fifo(uint8_t *buffer, uint8_t size); + void read_fifo(uint8_t *buffer, uint8_t size); + void transmit(uint32_t timeout); + void rf_irq_task(void); + void set_modem(uint8_t modem); + void rx_chain_calibration(void); + + // ISRs + void dio0_irq_isr(); + void dio1_irq_isr(); + void dio2_irq_isr(); + void dio3_irq_isr(); + void dio4_irq_isr(); + void dio5_irq_isr(); + void timeout_irq_isr(); + + // Handlers called by thread in response to signal + void handle_dio0_irq(); + void handle_dio1_irq(); + void handle_dio2_irq(); + void handle_dio3_irq(); + void handle_dio4_irq(); + void handle_dio5_irq(); + void handle_timeout_irq(); +}; + +#endif // SX1276_LORARADIO_H_ diff --git a/SX1276/mbed_lib.json b/SX1276/mbed_lib.json new file mode 100644 index 0000000000..ea629da86a --- /dev/null +++ b/SX1276/mbed_lib.json @@ -0,0 +1,13 @@ +{ + "name": "sx1276-lora-driver", + "config": { + "spi-frequency": { + "help": "SPI frequency, Default: 8 MHz", + "value": 8000000 + }, + "buffer-size": { + "help": "Max. buffer size the radio can handle, Default: 256 B", + "value": 256 + } + } +} diff --git a/SX1276/registers/sx1276Regs-Fsk.h b/SX1276/registers/sx1276Regs-Fsk.h new file mode 100644 index 0000000000..40472a399a --- /dev/null +++ b/SX1276/registers/sx1276Regs-Fsk.h @@ -0,0 +1,1138 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C) 2014 Semtech + +Description: SX1276 FSK modem registers and bits definitions + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ +#ifndef __SX1276_REGS_FSK_H__ +#define __SX1276_REGS_FSK_H__ + +/*! + * ============================================================================ + * SX1276 Internal registers Address + * ============================================================================ + */ +#define REG_FIFO 0x00 +// Common settings +#define REG_OPMODE 0x01 +#define REG_BITRATEMSB 0x02 +#define REG_BITRATELSB 0x03 +#define REG_FDEVMSB 0x04 +#define REG_FDEVLSB 0x05 +#define REG_FRFMSB 0x06 +#define REG_FRFMID 0x07 +#define REG_FRFLSB 0x08 +// Tx settings +#define REG_PACONFIG 0x09 +#define REG_PARAMP 0x0A +#define REG_OCP 0x0B +// Rx settings +#define REG_LNA 0x0C +#define REG_RXCONFIG 0x0D +#define REG_RSSICONFIG 0x0E +#define REG_RSSICOLLISION 0x0F +#define REG_RSSITHRESH 0x10 +#define REG_RSSIVALUE 0x11 +#define REG_RXBW 0x12 +#define REG_AFCBW 0x13 +#define REG_OOKPEAK 0x14 +#define REG_OOKFIX 0x15 +#define REG_OOKAVG 0x16 +#define REG_RES17 0x17 +#define REG_RES18 0x18 +#define REG_RES19 0x19 +#define REG_AFCFEI 0x1A +#define REG_AFCMSB 0x1B +#define REG_AFCLSB 0x1C +#define REG_FEIMSB 0x1D +#define REG_FEILSB 0x1E +#define REG_PREAMBLEDETECT 0x1F +#define REG_RXTIMEOUT1 0x20 +#define REG_RXTIMEOUT2 0x21 +#define REG_RXTIMEOUT3 0x22 +#define REG_RXDELAY 0x23 +// Oscillator settings +#define REG_OSC 0x24 +// Packet handler settings +#define REG_PREAMBLEMSB 0x25 +#define REG_PREAMBLELSB 0x26 +#define REG_SYNCCONFIG 0x27 +#define REG_SYNCVALUE1 0x28 +#define REG_SYNCVALUE2 0x29 +#define REG_SYNCVALUE3 0x2A +#define REG_SYNCVALUE4 0x2B +#define REG_SYNCVALUE5 0x2C +#define REG_SYNCVALUE6 0x2D +#define REG_SYNCVALUE7 0x2E +#define REG_SYNCVALUE8 0x2F +#define REG_PACKETCONFIG1 0x30 +#define REG_PACKETCONFIG2 0x31 +#define REG_PAYLOADLENGTH 0x32 +#define REG_NODEADRS 0x33 +#define REG_BROADCASTADRS 0x34 +#define REG_FIFOTHRESH 0x35 +// SM settings +#define REG_SEQCONFIG1 0x36 +#define REG_SEQCONFIG2 0x37 +#define REG_TIMERRESOL 0x38 +#define REG_TIMER1COEF 0x39 +#define REG_TIMER2COEF 0x3A +// Service settings +#define REG_IMAGECAL 0x3B +#define REG_TEMP 0x3C +#define REG_LOWBAT 0x3D +// Status +#define REG_IRQFLAGS1 0x3E +#define REG_IRQFLAGS2 0x3F +// I/O settings +#define REG_DIOMAPPING1 0x40 +#define REG_DIOMAPPING2 0x41 +// Version +#define REG_VERSION 0x42 +// Additional settings +#define REG_PLLHOP 0x44 +#define REG_TCXO 0x4B +#define REG_PADAC 0x4D +#define REG_FORMERTEMP 0x5B +#define REG_BITRATEFRAC 0x5D +#define REG_AGCREF 0x61 +#define REG_AGCTHRESH1 0x62 +#define REG_AGCTHRESH2 0x63 +#define REG_AGCTHRESH3 0x64 +#define REG_PLL 0x70 + +/*! + * ============================================================================ + * SX1276 FSK bits control definition + * ============================================================================ + */ + +/*! + * RegFifo + */ + +/*! + * RegOpMode + */ +#define RF_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RF_OPMODE_LONGRANGEMODE_OFF 0x00 +#define RF_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RF_OPMODE_MODULATIONTYPE_MASK 0x9F +#define RF_OPMODE_MODULATIONTYPE_FSK 0x00 // Default +#define RF_OPMODE_MODULATIONTYPE_OOK 0x20 + +#define RF_OPMODE_MODULATIONSHAPING_MASK 0xE7 +#define RF_OPMODE_MODULATIONSHAPING_00 0x00 // Default +#define RF_OPMODE_MODULATIONSHAPING_01 0x08 +#define RF_OPMODE_MODULATIONSHAPING_10 0x10 +#define RF_OPMODE_MODULATIONSHAPING_11 0x18 + +#define RF_OPMODE_MASK 0xF8 +#define RF_OPMODE_SLEEP 0x00 +#define RF_OPMODE_STANDBY 0x01 // Default +#define RF_OPMODE_SYNTHESIZER_TX 0x02 +#define RF_OPMODE_TRANSMITTER 0x03 +#define RF_OPMODE_SYNTHESIZER_RX 0x04 +#define RF_OPMODE_RECEIVER 0x05 + +/*! + * RegBitRate (bits/sec) + */ +#define RF_BITRATEMSB_1200_BPS 0x68 +#define RF_BITRATELSB_1200_BPS 0x2B +#define RF_BITRATEMSB_2400_BPS 0x34 +#define RF_BITRATELSB_2400_BPS 0x15 +#define RF_BITRATEMSB_4800_BPS 0x1A // Default +#define RF_BITRATELSB_4800_BPS 0x0B // Default +#define RF_BITRATEMSB_9600_BPS 0x0D +#define RF_BITRATELSB_9600_BPS 0x05 +#define RF_BITRATEMSB_15000_BPS 0x08 +#define RF_BITRATELSB_15000_BPS 0x55 +#define RF_BITRATEMSB_19200_BPS 0x06 +#define RF_BITRATELSB_19200_BPS 0x83 +#define RF_BITRATEMSB_38400_BPS 0x03 +#define RF_BITRATELSB_38400_BPS 0x41 +#define RF_BITRATEMSB_76800_BPS 0x01 +#define RF_BITRATELSB_76800_BPS 0xA1 +#define RF_BITRATEMSB_153600_BPS 0x00 +#define RF_BITRATELSB_153600_BPS 0xD0 +#define RF_BITRATEMSB_57600_BPS 0x02 +#define RF_BITRATELSB_57600_BPS 0x2C +#define RF_BITRATEMSB_115200_BPS 0x01 +#define RF_BITRATELSB_115200_BPS 0x16 +#define RF_BITRATEMSB_12500_BPS 0x0A +#define RF_BITRATELSB_12500_BPS 0x00 +#define RF_BITRATEMSB_25000_BPS 0x05 +#define RF_BITRATELSB_25000_BPS 0x00 +#define RF_BITRATEMSB_50000_BPS 0x02 +#define RF_BITRATELSB_50000_BPS 0x80 +#define RF_BITRATEMSB_100000_BPS 0x01 +#define RF_BITRATELSB_100000_BPS 0x40 +#define RF_BITRATEMSB_150000_BPS 0x00 +#define RF_BITRATELSB_150000_BPS 0xD5 +#define RF_BITRATEMSB_200000_BPS 0x00 +#define RF_BITRATELSB_200000_BPS 0xA0 +#define RF_BITRATEMSB_250000_BPS 0x00 +#define RF_BITRATELSB_250000_BPS 0x80 +#define RF_BITRATEMSB_32768_BPS 0x03 +#define RF_BITRATELSB_32768_BPS 0xD1 + +/*! + * RegFdev (Hz) + */ +#define RF_FDEVMSB_2000_HZ 0x00 +#define RF_FDEVLSB_2000_HZ 0x21 +#define RF_FDEVMSB_5000_HZ 0x00 // Default +#define RF_FDEVLSB_5000_HZ 0x52 // Default +#define RF_FDEVMSB_10000_HZ 0x00 +#define RF_FDEVLSB_10000_HZ 0xA4 +#define RF_FDEVMSB_15000_HZ 0x00 +#define RF_FDEVLSB_15000_HZ 0xF6 +#define RF_FDEVMSB_20000_HZ 0x01 +#define RF_FDEVLSB_20000_HZ 0x48 +#define RF_FDEVMSB_25000_HZ 0x01 +#define RF_FDEVLSB_25000_HZ 0x9A +#define RF_FDEVMSB_30000_HZ 0x01 +#define RF_FDEVLSB_30000_HZ 0xEC +#define RF_FDEVMSB_35000_HZ 0x02 +#define RF_FDEVLSB_35000_HZ 0x3D +#define RF_FDEVMSB_40000_HZ 0x02 +#define RF_FDEVLSB_40000_HZ 0x8F +#define RF_FDEVMSB_45000_HZ 0x02 +#define RF_FDEVLSB_45000_HZ 0xE1 +#define RF_FDEVMSB_50000_HZ 0x03 +#define RF_FDEVLSB_50000_HZ 0x33 +#define RF_FDEVMSB_55000_HZ 0x03 +#define RF_FDEVLSB_55000_HZ 0x85 +#define RF_FDEVMSB_60000_HZ 0x03 +#define RF_FDEVLSB_60000_HZ 0xD7 +#define RF_FDEVMSB_65000_HZ 0x04 +#define RF_FDEVLSB_65000_HZ 0x29 +#define RF_FDEVMSB_70000_HZ 0x04 +#define RF_FDEVLSB_70000_HZ 0x7B +#define RF_FDEVMSB_75000_HZ 0x04 +#define RF_FDEVLSB_75000_HZ 0xCD +#define RF_FDEVMSB_80000_HZ 0x05 +#define RF_FDEVLSB_80000_HZ 0x1F +#define RF_FDEVMSB_85000_HZ 0x05 +#define RF_FDEVLSB_85000_HZ 0x71 +#define RF_FDEVMSB_90000_HZ 0x05 +#define RF_FDEVLSB_90000_HZ 0xC3 +#define RF_FDEVMSB_95000_HZ 0x06 +#define RF_FDEVLSB_95000_HZ 0x14 +#define RF_FDEVMSB_100000_HZ 0x06 +#define RF_FDEVLSB_100000_HZ 0x66 +#define RF_FDEVMSB_110000_HZ 0x07 +#define RF_FDEVLSB_110000_HZ 0x0A +#define RF_FDEVMSB_120000_HZ 0x07 +#define RF_FDEVLSB_120000_HZ 0xAE +#define RF_FDEVMSB_130000_HZ 0x08 +#define RF_FDEVLSB_130000_HZ 0x52 +#define RF_FDEVMSB_140000_HZ 0x08 +#define RF_FDEVLSB_140000_HZ 0xF6 +#define RF_FDEVMSB_150000_HZ 0x09 +#define RF_FDEVLSB_150000_HZ 0x9A +#define RF_FDEVMSB_160000_HZ 0x0A +#define RF_FDEVLSB_160000_HZ 0x3D +#define RF_FDEVMSB_170000_HZ 0x0A +#define RF_FDEVLSB_170000_HZ 0xE1 +#define RF_FDEVMSB_180000_HZ 0x0B +#define RF_FDEVLSB_180000_HZ 0x85 +#define RF_FDEVMSB_190000_HZ 0x0C +#define RF_FDEVLSB_190000_HZ 0x29 +#define RF_FDEVMSB_200000_HZ 0x0C +#define RF_FDEVLSB_200000_HZ 0xCD + +/*! + * RegFrf (MHz) + */ +#define RF_FRFMSB_863_MHZ 0xD7 +#define RF_FRFMID_863_MHZ 0xC0 +#define RF_FRFLSB_863_MHZ 0x00 +#define RF_FRFMSB_864_MHZ 0xD8 +#define RF_FRFMID_864_MHZ 0x00 +#define RF_FRFLSB_864_MHZ 0x00 +#define RF_FRFMSB_865_MHZ 0xD8 +#define RF_FRFMID_865_MHZ 0x40 +#define RF_FRFLSB_865_MHZ 0x00 +#define RF_FRFMSB_866_MHZ 0xD8 +#define RF_FRFMID_866_MHZ 0x80 +#define RF_FRFLSB_866_MHZ 0x00 +#define RF_FRFMSB_867_MHZ 0xD8 +#define RF_FRFMID_867_MHZ 0xC0 +#define RF_FRFLSB_867_MHZ 0x00 +#define RF_FRFMSB_868_MHZ 0xD9 +#define RF_FRFMID_868_MHZ 0x00 +#define RF_FRFLSB_868_MHZ 0x00 +#define RF_FRFMSB_869_MHZ 0xD9 +#define RF_FRFMID_869_MHZ 0x40 +#define RF_FRFLSB_869_MHZ 0x00 +#define RF_FRFMSB_870_MHZ 0xD9 +#define RF_FRFMID_870_MHZ 0x80 +#define RF_FRFLSB_870_MHZ 0x00 + +#define RF_FRFMSB_902_MHZ 0xE1 +#define RF_FRFMID_902_MHZ 0x80 +#define RF_FRFLSB_902_MHZ 0x00 +#define RF_FRFMSB_903_MHZ 0xE1 +#define RF_FRFMID_903_MHZ 0xC0 +#define RF_FRFLSB_903_MHZ 0x00 +#define RF_FRFMSB_904_MHZ 0xE2 +#define RF_FRFMID_904_MHZ 0x00 +#define RF_FRFLSB_904_MHZ 0x00 +#define RF_FRFMSB_905_MHZ 0xE2 +#define RF_FRFMID_905_MHZ 0x40 +#define RF_FRFLSB_905_MHZ 0x00 +#define RF_FRFMSB_906_MHZ 0xE2 +#define RF_FRFMID_906_MHZ 0x80 +#define RF_FRFLSB_906_MHZ 0x00 +#define RF_FRFMSB_907_MHZ 0xE2 +#define RF_FRFMID_907_MHZ 0xC0 +#define RF_FRFLSB_907_MHZ 0x00 +#define RF_FRFMSB_908_MHZ 0xE3 +#define RF_FRFMID_908_MHZ 0x00 +#define RF_FRFLSB_908_MHZ 0x00 +#define RF_FRFMSB_909_MHZ 0xE3 +#define RF_FRFMID_909_MHZ 0x40 +#define RF_FRFLSB_909_MHZ 0x00 +#define RF_FRFMSB_910_MHZ 0xE3 +#define RF_FRFMID_910_MHZ 0x80 +#define RF_FRFLSB_910_MHZ 0x00 +#define RF_FRFMSB_911_MHZ 0xE3 +#define RF_FRFMID_911_MHZ 0xC0 +#define RF_FRFLSB_911_MHZ 0x00 +#define RF_FRFMSB_912_MHZ 0xE4 +#define RF_FRFMID_912_MHZ 0x00 +#define RF_FRFLSB_912_MHZ 0x00 +#define RF_FRFMSB_913_MHZ 0xE4 +#define RF_FRFMID_913_MHZ 0x40 +#define RF_FRFLSB_913_MHZ 0x00 +#define RF_FRFMSB_914_MHZ 0xE4 +#define RF_FRFMID_914_MHZ 0x80 +#define RF_FRFLSB_914_MHZ 0x00 +#define RF_FRFMSB_915_MHZ 0xE4 // Default +#define RF_FRFMID_915_MHZ 0xC0 // Default +#define RF_FRFLSB_915_MHZ 0x00 // Default +#define RF_FRFMSB_916_MHZ 0xE5 +#define RF_FRFMID_916_MHZ 0x00 +#define RF_FRFLSB_916_MHZ 0x00 +#define RF_FRFMSB_917_MHZ 0xE5 +#define RF_FRFMID_917_MHZ 0x40 +#define RF_FRFLSB_917_MHZ 0x00 +#define RF_FRFMSB_918_MHZ 0xE5 +#define RF_FRFMID_918_MHZ 0x80 +#define RF_FRFLSB_918_MHZ 0x00 +#define RF_FRFMSB_919_MHZ 0xE5 +#define RF_FRFMID_919_MHZ 0xC0 +#define RF_FRFLSB_919_MHZ 0x00 +#define RF_FRFMSB_920_MHZ 0xE6 +#define RF_FRFMID_920_MHZ 0x00 +#define RF_FRFLSB_920_MHZ 0x00 +#define RF_FRFMSB_921_MHZ 0xE6 +#define RF_FRFMID_921_MHZ 0x40 +#define RF_FRFLSB_921_MHZ 0x00 +#define RF_FRFMSB_922_MHZ 0xE6 +#define RF_FRFMID_922_MHZ 0x80 +#define RF_FRFLSB_922_MHZ 0x00 +#define RF_FRFMSB_923_MHZ 0xE6 +#define RF_FRFMID_923_MHZ 0xC0 +#define RF_FRFLSB_923_MHZ 0x00 +#define RF_FRFMSB_924_MHZ 0xE7 +#define RF_FRFMID_924_MHZ 0x00 +#define RF_FRFLSB_924_MHZ 0x00 +#define RF_FRFMSB_925_MHZ 0xE7 +#define RF_FRFMID_925_MHZ 0x40 +#define RF_FRFLSB_925_MHZ 0x00 +#define RF_FRFMSB_926_MHZ 0xE7 +#define RF_FRFMID_926_MHZ 0x80 +#define RF_FRFLSB_926_MHZ 0x00 +#define RF_FRFMSB_927_MHZ 0xE7 +#define RF_FRFMID_927_MHZ 0xC0 +#define RF_FRFLSB_927_MHZ 0x00 +#define RF_FRFMSB_928_MHZ 0xE8 +#define RF_FRFMID_928_MHZ 0x00 +#define RF_FRFLSB_928_MHZ 0x00 + +/*! + * RegPaConfig + */ +#define RF_PACONFIG_PASELECT_MASK 0x7F +#define RF_PACONFIG_PASELECT_PABOOST 0x80 +#define RF_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RF_PACONFIG_MAX_POWER_MASK 0x8F + +#define RF_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +/*! + * RegPaRamp + */ +#define RF_PARAMP_MODULATIONSHAPING_MASK 0x9F +#define RF_PARAMP_MODULATIONSHAPING_00 0x00 // Default +#define RF_PARAMP_MODULATIONSHAPING_01 0x20 +#define RF_PARAMP_MODULATIONSHAPING_10 0x40 +#define RF_PARAMP_MODULATIONSHAPING_11 0x60 + +#define RF_PARAMP_LOWPNTXPLL_MASK 0xEF +#define RF_PARAMP_LOWPNTXPLL_OFF 0x10 +#define RF_PARAMP_LOWPNTXPLL_ON 0x00 // Default + +#define RF_PARAMP_MASK 0xF0 +#define RF_PARAMP_3400_US 0x00 +#define RF_PARAMP_2000_US 0x01 +#define RF_PARAMP_1000_US 0x02 +#define RF_PARAMP_0500_US 0x03 +#define RF_PARAMP_0250_US 0x04 +#define RF_PARAMP_0125_US 0x05 +#define RF_PARAMP_0100_US 0x06 +#define RF_PARAMP_0062_US 0x07 +#define RF_PARAMP_0050_US 0x08 +#define RF_PARAMP_0040_US 0x09 // Default +#define RF_PARAMP_0031_US 0x0A +#define RF_PARAMP_0025_US 0x0B +#define RF_PARAMP_0020_US 0x0C +#define RF_PARAMP_0015_US 0x0D +#define RF_PARAMP_0012_US 0x0E +#define RF_PARAMP_0010_US 0x0F + +/*! + * RegOcp + */ +#define RF_OCP_MASK 0xDF +#define RF_OCP_ON 0x20 // Default +#define RF_OCP_OFF 0x00 + +#define RF_OCP_TRIM_MASK 0xE0 +#define RF_OCP_TRIM_045_MA 0x00 +#define RF_OCP_TRIM_050_MA 0x01 +#define RF_OCP_TRIM_055_MA 0x02 +#define RF_OCP_TRIM_060_MA 0x03 +#define RF_OCP_TRIM_065_MA 0x04 +#define RF_OCP_TRIM_070_MA 0x05 +#define RF_OCP_TRIM_075_MA 0x06 +#define RF_OCP_TRIM_080_MA 0x07 +#define RF_OCP_TRIM_085_MA 0x08 +#define RF_OCP_TRIM_090_MA 0x09 +#define RF_OCP_TRIM_095_MA 0x0A +#define RF_OCP_TRIM_100_MA 0x0B // Default +#define RF_OCP_TRIM_105_MA 0x0C +#define RF_OCP_TRIM_110_MA 0x0D +#define RF_OCP_TRIM_115_MA 0x0E +#define RF_OCP_TRIM_120_MA 0x0F +#define RF_OCP_TRIM_130_MA 0x10 +#define RF_OCP_TRIM_140_MA 0x11 +#define RF_OCP_TRIM_150_MA 0x12 +#define RF_OCP_TRIM_160_MA 0x13 +#define RF_OCP_TRIM_170_MA 0x14 +#define RF_OCP_TRIM_180_MA 0x15 +#define RF_OCP_TRIM_190_MA 0x16 +#define RF_OCP_TRIM_200_MA 0x17 +#define RF_OCP_TRIM_210_MA 0x18 +#define RF_OCP_TRIM_220_MA 0x19 +#define RF_OCP_TRIM_230_MA 0x1A +#define RF_OCP_TRIM_240_MA 0x1B + +/*! + * RegLna + */ +#define RF_LNA_GAIN_MASK 0x1F +#define RF_LNA_GAIN_G1 0x20 // Default +#define RF_LNA_GAIN_G2 0x40 +#define RF_LNA_GAIN_G3 0x60 +#define RF_LNA_GAIN_G4 0x80 +#define RF_LNA_GAIN_G5 0xA0 +#define RF_LNA_GAIN_G6 0xC0 + +#define RF_LNA_BOOST_MASK 0xFC +#define RF_LNA_BOOST_OFF 0x00 // Default +#define RF_LNA_BOOST_ON 0x03 + +/*! + * RegRxConfig + */ +#define RF_RXCONFIG_RESTARTRXONCOLLISION_MASK 0x7F +#define RF_RXCONFIG_RESTARTRXONCOLLISION_ON 0x80 +#define RF_RXCONFIG_RESTARTRXONCOLLISION_OFF 0x00 // Default + +#define RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK 0x40 // Write only + +#define RF_RXCONFIG_RESTARTRXWITHPLLLOCK 0x20 // Write only + +#define RF_RXCONFIG_AFCAUTO_MASK 0xEF +#define RF_RXCONFIG_AFCAUTO_ON 0x10 +#define RF_RXCONFIG_AFCAUTO_OFF 0x00 // Default + +#define RF_RXCONFIG_AGCAUTO_MASK 0xF7 +#define RF_RXCONFIG_AGCAUTO_ON 0x08 // Default +#define RF_RXCONFIG_AGCAUTO_OFF 0x00 + +#define RF_RXCONFIG_RXTRIGER_MASK 0xF8 +#define RF_RXCONFIG_RXTRIGER_OFF 0x00 +#define RF_RXCONFIG_RXTRIGER_RSSI 0x01 +#define RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT 0x06 // Default +#define RF_RXCONFIG_RXTRIGER_RSSI_PREAMBLEDETECT 0x07 + +/*! + * RegRssiConfig + */ +#define RF_RSSICONFIG_OFFSET_MASK 0x07 +#define RF_RSSICONFIG_OFFSET_P_00_DB 0x00 // Default +#define RF_RSSICONFIG_OFFSET_P_01_DB 0x08 +#define RF_RSSICONFIG_OFFSET_P_02_DB 0x10 +#define RF_RSSICONFIG_OFFSET_P_03_DB 0x18 +#define RF_RSSICONFIG_OFFSET_P_04_DB 0x20 +#define RF_RSSICONFIG_OFFSET_P_05_DB 0x28 +#define RF_RSSICONFIG_OFFSET_P_06_DB 0x30 +#define RF_RSSICONFIG_OFFSET_P_07_DB 0x38 +#define RF_RSSICONFIG_OFFSET_P_08_DB 0x40 +#define RF_RSSICONFIG_OFFSET_P_09_DB 0x48 +#define RF_RSSICONFIG_OFFSET_P_10_DB 0x50 +#define RF_RSSICONFIG_OFFSET_P_11_DB 0x58 +#define RF_RSSICONFIG_OFFSET_P_12_DB 0x60 +#define RF_RSSICONFIG_OFFSET_P_13_DB 0x68 +#define RF_RSSICONFIG_OFFSET_P_14_DB 0x70 +#define RF_RSSICONFIG_OFFSET_P_15_DB 0x78 +#define RF_RSSICONFIG_OFFSET_M_16_DB 0x80 +#define RF_RSSICONFIG_OFFSET_M_15_DB 0x88 +#define RF_RSSICONFIG_OFFSET_M_14_DB 0x90 +#define RF_RSSICONFIG_OFFSET_M_13_DB 0x98 +#define RF_RSSICONFIG_OFFSET_M_12_DB 0xA0 +#define RF_RSSICONFIG_OFFSET_M_11_DB 0xA8 +#define RF_RSSICONFIG_OFFSET_M_10_DB 0xB0 +#define RF_RSSICONFIG_OFFSET_M_09_DB 0xB8 +#define RF_RSSICONFIG_OFFSET_M_08_DB 0xC0 +#define RF_RSSICONFIG_OFFSET_M_07_DB 0xC8 +#define RF_RSSICONFIG_OFFSET_M_06_DB 0xD0 +#define RF_RSSICONFIG_OFFSET_M_05_DB 0xD8 +#define RF_RSSICONFIG_OFFSET_M_04_DB 0xE0 +#define RF_RSSICONFIG_OFFSET_M_03_DB 0xE8 +#define RF_RSSICONFIG_OFFSET_M_02_DB 0xF0 +#define RF_RSSICONFIG_OFFSET_M_01_DB 0xF8 + +#define RF_RSSICONFIG_SMOOTHING_MASK 0xF8 +#define RF_RSSICONFIG_SMOOTHING_2 0x00 +#define RF_RSSICONFIG_SMOOTHING_4 0x01 +#define RF_RSSICONFIG_SMOOTHING_8 0x02 // Default +#define RF_RSSICONFIG_SMOOTHING_16 0x03 +#define RF_RSSICONFIG_SMOOTHING_32 0x04 +#define RF_RSSICONFIG_SMOOTHING_64 0x05 +#define RF_RSSICONFIG_SMOOTHING_128 0x06 +#define RF_RSSICONFIG_SMOOTHING_256 0x07 + +/*! + * RegRssiCollision + */ +#define RF_RSSICOLISION_THRESHOLD 0x0A // Default + +/*! + * RegRssiThresh + */ +#define RF_RSSITHRESH_THRESHOLD 0xFF // Default + +/*! + * RegRssiValue (Read Only) + */ + +/*! + * RegRxBw + */ +#define RF_RXBW_MANT_MASK 0xE7 +#define RF_RXBW_MANT_16 0x00 +#define RF_RXBW_MANT_20 0x08 +#define RF_RXBW_MANT_24 0x10 // Default + +#define RF_RXBW_EXP_MASK 0xF8 +#define RF_RXBW_EXP_0 0x00 +#define RF_RXBW_EXP_1 0x01 +#define RF_RXBW_EXP_2 0x02 +#define RF_RXBW_EXP_3 0x03 +#define RF_RXBW_EXP_4 0x04 +#define RF_RXBW_EXP_5 0x05 // Default +#define RF_RXBW_EXP_6 0x06 +#define RF_RXBW_EXP_7 0x07 + +/*! + * RegAfcBw + */ +#define RF_AFCBW_MANTAFC_MASK 0xE7 +#define RF_AFCBW_MANTAFC_16 0x00 +#define RF_AFCBW_MANTAFC_20 0x08 // Default +#define RF_AFCBW_MANTAFC_24 0x10 + +#define RF_AFCBW_EXPAFC_MASK 0xF8 +#define RF_AFCBW_EXPAFC_0 0x00 +#define RF_AFCBW_EXPAFC_1 0x01 +#define RF_AFCBW_EXPAFC_2 0x02 +#define RF_AFCBW_EXPAFC_3 0x03 // Default +#define RF_AFCBW_EXPAFC_4 0x04 +#define RF_AFCBW_EXPAFC_5 0x05 +#define RF_AFCBW_EXPAFC_6 0x06 +#define RF_AFCBW_EXPAFC_7 0x07 + +/*! + * RegOokPeak + */ +#define RF_OOKPEAK_BITSYNC_MASK 0xDF // Default +#define RF_OOKPEAK_BITSYNC_ON 0x20 // Default +#define RF_OOKPEAK_BITSYNC_OFF 0x00 + +#define RF_OOKPEAK_OOKTHRESHTYPE_MASK 0xE7 +#define RF_OOKPEAK_OOKTHRESHTYPE_FIXED 0x00 +#define RF_OOKPEAK_OOKTHRESHTYPE_PEAK 0x08 // Default +#define RF_OOKPEAK_OOKTHRESHTYPE_AVERAGE 0x10 + +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_MASK 0xF8 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_0_5_DB 0x00 // Default +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_0_DB 0x01 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_5_DB 0x02 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_2_0_DB 0x03 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_3_0_DB 0x04 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_4_0_DB 0x05 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_5_0_DB 0x06 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_6_0_DB 0x07 + +/*! + * RegOokFix + */ +#define RF_OOKFIX_OOKFIXEDTHRESHOLD 0x0C // Default + +/*! + * RegOokAvg + */ +#define RF_OOKAVG_OOKPEAKTHRESHDEC_MASK 0x1F +#define RF_OOKAVG_OOKPEAKTHRESHDEC_000 0x00 // Default +#define RF_OOKAVG_OOKPEAKTHRESHDEC_001 0x20 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_010 0x40 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_011 0x60 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_100 0x80 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_101 0xA0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_110 0xC0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_111 0xE0 + +#define RF_OOKAVG_AVERAGEOFFSET_MASK 0xF3 +#define RF_OOKAVG_AVERAGEOFFSET_0_DB 0x00 // Default +#define RF_OOKAVG_AVERAGEOFFSET_2_DB 0x04 +#define RF_OOKAVG_AVERAGEOFFSET_4_DB 0x08 +#define RF_OOKAVG_AVERAGEOFFSET_6_DB 0x0C + +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_MASK 0xFC +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_00 0x00 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_01 0x01 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_10 0x02 // Default +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_11 0x03 + +/*! + * RegAfcFei + */ +#define RF_AFCFEI_AGCSTART 0x10 + +#define RF_AFCFEI_AFCCLEAR 0x02 + +#define RF_AFCFEI_AFCAUTOCLEAR_MASK 0xFE +#define RF_AFCFEI_AFCAUTOCLEAR_ON 0x01 +#define RF_AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default + +/*! + * RegAfcMsb (Read Only) + */ + +/*! + * RegAfcLsb (Read Only) + */ + +/*! + * RegFeiMsb (Read Only) + */ + +/*! + * RegFeiLsb (Read Only) + */ + +/*! + * RegPreambleDetect + */ +#define RF_PREAMBLEDETECT_DETECTOR_MASK 0x7F +#define RF_PREAMBLEDETECT_DETECTOR_ON 0x80 // Default +#define RF_PREAMBLEDETECT_DETECTOR_OFF 0x00 + +#define RF_PREAMBLEDETECT_DETECTORSIZE_MASK 0x9F +#define RF_PREAMBLEDETECT_DETECTORSIZE_1 0x00 +#define RF_PREAMBLEDETECT_DETECTORSIZE_2 0x20 // Default +#define RF_PREAMBLEDETECT_DETECTORSIZE_3 0x40 +#define RF_PREAMBLEDETECT_DETECTORSIZE_4 0x60 + +#define RF_PREAMBLEDETECT_DETECTORTOL_MASK 0xE0 +#define RF_PREAMBLEDETECT_DETECTORTOL_0 0x00 +#define RF_PREAMBLEDETECT_DETECTORTOL_1 0x01 +#define RF_PREAMBLEDETECT_DETECTORTOL_2 0x02 +#define RF_PREAMBLEDETECT_DETECTORTOL_3 0x03 +#define RF_PREAMBLEDETECT_DETECTORTOL_4 0x04 +#define RF_PREAMBLEDETECT_DETECTORTOL_5 0x05 +#define RF_PREAMBLEDETECT_DETECTORTOL_6 0x06 +#define RF_PREAMBLEDETECT_DETECTORTOL_7 0x07 +#define RF_PREAMBLEDETECT_DETECTORTOL_8 0x08 +#define RF_PREAMBLEDETECT_DETECTORTOL_9 0x09 +#define RF_PREAMBLEDETECT_DETECTORTOL_10 0x0A // Default +#define RF_PREAMBLEDETECT_DETECTORTOL_11 0x0B +#define RF_PREAMBLEDETECT_DETECTORTOL_12 0x0C +#define RF_PREAMBLEDETECT_DETECTORTOL_13 0x0D +#define RF_PREAMBLEDETECT_DETECTORTOL_14 0x0E +#define RF_PREAMBLEDETECT_DETECTORTOL_15 0x0F +#define RF_PREAMBLEDETECT_DETECTORTOL_16 0x10 +#define RF_PREAMBLEDETECT_DETECTORTOL_17 0x11 +#define RF_PREAMBLEDETECT_DETECTORTOL_18 0x12 +#define RF_PREAMBLEDETECT_DETECTORTOL_19 0x13 +#define RF_PREAMBLEDETECT_DETECTORTOL_20 0x14 +#define RF_PREAMBLEDETECT_DETECTORTOL_21 0x15 +#define RF_PREAMBLEDETECT_DETECTORTOL_22 0x16 +#define RF_PREAMBLEDETECT_DETECTORTOL_23 0x17 +#define RF_PREAMBLEDETECT_DETECTORTOL_24 0x18 +#define RF_PREAMBLEDETECT_DETECTORTOL_25 0x19 +#define RF_PREAMBLEDETECT_DETECTORTOL_26 0x1A +#define RF_PREAMBLEDETECT_DETECTORTOL_27 0x1B +#define RF_PREAMBLEDETECT_DETECTORTOL_28 0x1C +#define RF_PREAMBLEDETECT_DETECTORTOL_29 0x1D +#define RF_PREAMBLEDETECT_DETECTORTOL_30 0x1E +#define RF_PREAMBLEDETECT_DETECTORTOL_31 0x1F + +/*! + * RegRxTimeout1 + */ +#define RF_RXTIMEOUT1_TIMEOUTRXRSSI 0x00 // Default + +/*! + * RegRxTimeout2 + */ +#define RF_RXTIMEOUT2_TIMEOUTRXPREAMBLE 0x00 // Default + +/*! + * RegRxTimeout3 + */ +#define RF_RXTIMEOUT3_TIMEOUTSIGNALSYNC 0x00 // Default + +/*! + * RegRxDelay + */ +#define RF_RXDELAY_INTERPACKETRXDELAY 0x00 // Default + +/*! + * RegOsc + */ +#define RF_OSC_RCCALSTART 0x08 + +#define RF_OSC_CLKOUT_MASK 0xF8 +#define RF_OSC_CLKOUT_32_MHZ 0x00 +#define RF_OSC_CLKOUT_16_MHZ 0x01 +#define RF_OSC_CLKOUT_8_MHZ 0x02 +#define RF_OSC_CLKOUT_4_MHZ 0x03 +#define RF_OSC_CLKOUT_2_MHZ 0x04 +#define RF_OSC_CLKOUT_1_MHZ 0x05 // Default +#define RF_OSC_CLKOUT_RC 0x06 +#define RF_OSC_CLKOUT_OFF 0x07 + +/*! + * RegPreambleMsb/RegPreambleLsb + */ +#define RF_PREAMBLEMSB_SIZE 0x00 // Default +#define RF_PREAMBLELSB_SIZE 0x03 // Default + +/*! + * RegSyncConfig + */ +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_MASK 0x3F +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON 0x80 // Default +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_OFF 0x40 +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_OFF 0x00 + + +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_MASK 0xDF +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_55 0x20 +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_AA 0x00 // Default + +#define RF_SYNCCONFIG_SYNC_MASK 0xEF +#define RF_SYNCCONFIG_SYNC_ON 0x10 // Default +#define RF_SYNCCONFIG_SYNC_OFF 0x00 + + +#define RF_SYNCCONFIG_SYNCSIZE_MASK 0xF8 +#define RF_SYNCCONFIG_SYNCSIZE_1 0x00 +#define RF_SYNCCONFIG_SYNCSIZE_2 0x01 +#define RF_SYNCCONFIG_SYNCSIZE_3 0x02 +#define RF_SYNCCONFIG_SYNCSIZE_4 0x03 // Default +#define RF_SYNCCONFIG_SYNCSIZE_5 0x04 +#define RF_SYNCCONFIG_SYNCSIZE_6 0x05 +#define RF_SYNCCONFIG_SYNCSIZE_7 0x06 +#define RF_SYNCCONFIG_SYNCSIZE_8 0x07 + +/*! + * RegSyncValue1-8 + */ +#define RF_SYNCVALUE1_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE2_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE3_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE4_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE5_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE6_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE7_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE8_SYNCVALUE 0x01 // Default + +/*! + * RegPacketConfig1 + */ +#define RF_PACKETCONFIG1_PACKETFORMAT_MASK 0x7F +#define RF_PACKETCONFIG1_PACKETFORMAT_FIXED 0x00 +#define RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE 0x80 // Default + +#define RF_PACKETCONFIG1_DCFREE_MASK 0x9F +#define RF_PACKETCONFIG1_DCFREE_OFF 0x00 // Default +#define RF_PACKETCONFIG1_DCFREE_MANCHESTER 0x20 +#define RF_PACKETCONFIG1_DCFREE_WHITENING 0x40 + +#define RF_PACKETCONFIG1_CRC_MASK 0xEF +#define RF_PACKETCONFIG1_CRC_ON 0x10 // Default +#define RF_PACKETCONFIG1_CRC_OFF 0x00 + +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_MASK 0xF7 +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_ON 0x00 // Default +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08 + +#define RF_PACKETCONFIG1_ADDRSFILTERING_MASK 0xF9 +#define RF_PACKETCONFIG1_ADDRSFILTERING_OFF 0x00 // Default +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODE 0x02 +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST 0x04 + +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_MASK 0xFE +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT 0x00 // Default +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_IBM 0x01 + +/*! + * RegPacketConfig2 + */ + +#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE_MASK 0x7F +#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE 0x80 +#define RF_PACKETCONFIG2_WMBUS_CRC_DISABLE 0x00 // Default + +#define RF_PACKETCONFIG2_DATAMODE_MASK 0xBF +#define RF_PACKETCONFIG2_DATAMODE_CONTINUOUS 0x00 +#define RF_PACKETCONFIG2_DATAMODE_PACKET 0x40 // Default + +#define RF_PACKETCONFIG2_IOHOME_MASK 0xDF +#define RF_PACKETCONFIG2_IOHOME_ON 0x20 +#define RF_PACKETCONFIG2_IOHOME_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_BEACON_MASK 0xF7 +#define RF_PACKETCONFIG2_BEACON_ON 0x08 +#define RF_PACKETCONFIG2_BEACON_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_PAYLOADLENGTH_MSB_MASK 0xF8 + +/*! + * RegPayloadLength + */ +#define RF_PAYLOADLENGTH_LENGTH 0x40 // Default + +/*! + * RegNodeAdrs + */ +#define RF_NODEADDRESS_ADDRESS 0x00 + +/*! + * RegBroadcastAdrs + */ +#define RF_BROADCASTADDRESS_ADDRESS 0x00 + +/*! + * RegFifoThresh + */ +#define RF_FIFOTHRESH_TXSTARTCONDITION_MASK 0x7F +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFOTHRESH 0x00 // Default +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY 0x80 + +#define RF_FIFOTHRESH_FIFOTHRESHOLD_MASK 0xC0 +#define RF_FIFOTHRESH_FIFOTHRESHOLD_THRESHOLD 0x0F // Default + +/*! + * RegSeqConfig1 + */ +#define RF_SEQCONFIG1_SEQUENCER_START 0x80 + +#define RF_SEQCONFIG1_SEQUENCER_STOP 0x40 + +#define RF_SEQCONFIG1_IDLEMODE_MASK 0xDF +#define RF_SEQCONFIG1_IDLEMODE_SLEEP 0x20 +#define RF_SEQCONFIG1_IDLEMODE_STANDBY 0x00 // Default + +#define RF_SEQCONFIG1_FROMSTART_MASK 0xE7 +#define RF_SEQCONFIG1_FROMSTART_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMSTART_TORX 0x08 +#define RF_SEQCONFIG1_FROMSTART_TOTX 0x10 +#define RF_SEQCONFIG1_FROMSTART_TOTX_ONFIFOLEVEL 0x18 + +#define RF_SEQCONFIG1_LPS_MASK 0xFB +#define RF_SEQCONFIG1_LPS_SEQUENCER_OFF 0x00 // Default +#define RF_SEQCONFIG1_LPS_IDLE 0x04 + +#define RF_SEQCONFIG1_FROMIDLE_MASK 0xFD +#define RF_SEQCONFIG1_FROMIDLE_TOTX 0x00 // Default +#define RF_SEQCONFIG1_FROMIDLE_TORX 0x02 + +#define RF_SEQCONFIG1_FROMTX_MASK 0xFE +#define RF_SEQCONFIG1_FROMTX_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMTX_TORX 0x01 + +/*! + * RegSeqConfig2 + */ +#define RF_SEQCONFIG2_FROMRX_MASK 0x1F +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_000 0x00 // Default +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONPLDRDY 0x20 +#define RF_SEQCONFIG2_FROMRX_TOLPS_ONPLDRDY 0x40 +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONCRCOK 0x60 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONRSSI 0x80 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONSYNC 0xA0 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONPREAMBLE 0xC0 +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_111 0xE0 + +#define RF_SEQCONFIG2_FROMRXTIMEOUT_MASK 0xE7 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TORXRESTART 0x00 // Default +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOTX 0x08 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOLPS 0x10 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOSEQUENCEROFF 0x18 + +#define RF_SEQCONFIG2_FROMRXPKT_MASK 0xF8 +#define RF_SEQCONFIG2_FROMRXPKT_TOSEQUENCEROFF 0x00 // Default +#define RF_SEQCONFIG2_FROMRXPKT_TOTX_ONFIFOEMPTY 0x01 +#define RF_SEQCONFIG2_FROMRXPKT_TOLPS 0x02 +#define RF_SEQCONFIG2_FROMRXPKT_TOSYNTHESIZERRX 0x03 +#define RF_SEQCONFIG2_FROMRXPKT_TORX 0x04 + +/*! + * RegTimerResol + */ +#define RF_TIMERRESOL_TIMER1RESOL_MASK 0xF3 +#define RF_TIMERRESOL_TIMER1RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER1RESOL_000064_US 0x04 +#define RF_TIMERRESOL_TIMER1RESOL_004100_US 0x08 +#define RF_TIMERRESOL_TIMER1RESOL_262000_US 0x0C + +#define RF_TIMERRESOL_TIMER2RESOL_MASK 0xFC +#define RF_TIMERRESOL_TIMER2RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER2RESOL_000064_US 0x01 +#define RF_TIMERRESOL_TIMER2RESOL_004100_US 0x02 +#define RF_TIMERRESOL_TIMER2RESOL_262000_US 0x03 + +/*! + * RegTimer1Coef + */ +#define RF_TIMER1COEF_TIMER1COEFFICIENT 0xF5 // Default + +/*! + * RegTimer2Coef + */ +#define RF_TIMER2COEF_TIMER2COEFFICIENT 0x20 // Default + +/*! + * RegImageCal + */ +#define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F +#define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 +#define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default + +#define RF_IMAGECAL_IMAGECAL_MASK 0xBF +#define RF_IMAGECAL_IMAGECAL_START 0x40 + +#define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 +#define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default + +#define RF_IMAGECAL_TEMPCHANGE_HIGHER 0x08 +#define RF_IMAGECAL_TEMPCHANGE_LOWER 0x00 + +#define RF_IMAGECAL_TEMPTHRESHOLD_MASK 0xF9 +#define RF_IMAGECAL_TEMPTHRESHOLD_05 0x00 +#define RF_IMAGECAL_TEMPTHRESHOLD_10 0x02 // Default +#define RF_IMAGECAL_TEMPTHRESHOLD_15 0x04 +#define RF_IMAGECAL_TEMPTHRESHOLD_20 0x06 + +#define RF_IMAGECAL_TEMPMONITOR_MASK 0xFE +#define RF_IMAGECAL_TEMPMONITOR_ON 0x00 // Default +#define RF_IMAGECAL_TEMPMONITOR_OFF 0x01 + +/*! + * RegTemp (Read Only) + */ + +/*! + * RegLowBat + */ +#define RF_LOWBAT_MASK 0xF7 +#define RF_LOWBAT_ON 0x08 +#define RF_LOWBAT_OFF 0x00 // Default + +#define RF_LOWBAT_TRIM_MASK 0xF8 +#define RF_LOWBAT_TRIM_1695 0x00 +#define RF_LOWBAT_TRIM_1764 0x01 +#define RF_LOWBAT_TRIM_1835 0x02 // Default +#define RF_LOWBAT_TRIM_1905 0x03 +#define RF_LOWBAT_TRIM_1976 0x04 +#define RF_LOWBAT_TRIM_2045 0x05 +#define RF_LOWBAT_TRIM_2116 0x06 +#define RF_LOWBAT_TRIM_2185 0x07 + +/*! + * RegIrqFlags1 + */ +#define RF_IRQFLAGS1_MODEREADY 0x80 + +#define RF_IRQFLAGS1_RXREADY 0x40 + +#define RF_IRQFLAGS1_TXREADY 0x20 + +#define RF_IRQFLAGS1_PLLLOCK 0x10 + +#define RF_IRQFLAGS1_RSSI 0x08 + +#define RF_IRQFLAGS1_TIMEOUT 0x04 + +#define RF_IRQFLAGS1_PREAMBLEDETECT 0x02 + +#define RF_IRQFLAGS1_SYNCADDRESSMATCH 0x01 + +/*! + * RegIrqFlags2 + */ +#define RF_IRQFLAGS2_FIFOFULL 0x80 + +#define RF_IRQFLAGS2_FIFOEMPTY 0x40 + +#define RF_IRQFLAGS2_FIFOLEVEL 0x20 + +#define RF_IRQFLAGS2_FIFOOVERRUN 0x10 + +#define RF_IRQFLAGS2_PACKETSENT 0x08 + +#define RF_IRQFLAGS2_PAYLOADREADY 0x04 + +#define RF_IRQFLAGS2_CRCOK 0x02 + +#define RF_IRQFLAGS2_LOWBAT 0x01 + +/*! + * RegDioMapping1 + */ +#define RF_DIOMAPPING1_DIO0_MASK 0x3F +#define RF_DIOMAPPING1_DIO0_00 0x00 // Default +#define RF_DIOMAPPING1_DIO0_01 0x40 +#define RF_DIOMAPPING1_DIO0_10 0x80 +#define RF_DIOMAPPING1_DIO0_11 0xC0 + +#define RF_DIOMAPPING1_DIO1_MASK 0xCF +#define RF_DIOMAPPING1_DIO1_00 0x00 // Default +#define RF_DIOMAPPING1_DIO1_01 0x10 +#define RF_DIOMAPPING1_DIO1_10 0x20 +#define RF_DIOMAPPING1_DIO1_11 0x30 + +#define RF_DIOMAPPING1_DIO2_MASK 0xF3 +#define RF_DIOMAPPING1_DIO2_00 0x00 // Default +#define RF_DIOMAPPING1_DIO2_01 0x04 +#define RF_DIOMAPPING1_DIO2_10 0x08 +#define RF_DIOMAPPING1_DIO2_11 0x0C + +#define RF_DIOMAPPING1_DIO3_MASK 0xFC +#define RF_DIOMAPPING1_DIO3_00 0x00 // Default +#define RF_DIOMAPPING1_DIO3_01 0x01 +#define RF_DIOMAPPING1_DIO3_10 0x02 +#define RF_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RF_DIOMAPPING2_DIO4_MASK 0x3F +#define RF_DIOMAPPING2_DIO4_00 0x00 // Default +#define RF_DIOMAPPING2_DIO4_01 0x40 +#define RF_DIOMAPPING2_DIO4_10 0x80 +#define RF_DIOMAPPING2_DIO4_11 0xC0 + +#define RF_DIOMAPPING2_DIO5_MASK 0xCF +#define RF_DIOMAPPING2_DIO5_00 0x00 // Default +#define RF_DIOMAPPING2_DIO5_01 0x10 +#define RF_DIOMAPPING2_DIO5_10 0x20 +#define RF_DIOMAPPING2_DIO5_11 0x30 + +#define RF_DIOMAPPING2_MAP_MASK 0xFE +#define RF_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RF_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegPllHop + */ +#define RF_PLLHOP_FASTHOP_MASK 0x7F +#define RF_PLLHOP_FASTHOP_ON 0x80 +#define RF_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RF_TCXO_TCXOINPUT_MASK 0xEF +#define RF_TCXO_TCXOINPUT_ON 0x10 +#define RF_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RF_PADAC_20DBM_MASK 0xF8 +#define RF_PADAC_20DBM_ON 0x07 +#define RF_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegFormerTemp + */ + +/*! + * RegBitrateFrac + */ +#define RF_BITRATEFRAC_MASK 0xF0 + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegPll + */ +#define RF_PLL_BANDWIDTH_MASK 0x3F +#define RF_PLL_BANDWIDTH_75 0x00 +#define RF_PLL_BANDWIDTH_150 0x40 +#define RF_PLL_BANDWIDTH_225 0x80 +#define RF_PLL_BANDWIDTH_300 0xC0 // Default + +#endif // __SX1276_REGS_FSK_H__ diff --git a/SX1276/registers/sx1276Regs-LoRa.h b/SX1276/registers/sx1276Regs-LoRa.h new file mode 100644 index 0000000000..ca501c1496 --- /dev/null +++ b/SX1276/registers/sx1276Regs-LoRa.h @@ -0,0 +1,569 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C) 2014 Semtech + +Description: SX1276 LoRa modem registers and bits definitions + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ +#ifndef __SX1276_REGS_LORA_H__ +#define __SX1276_REGS_LORA_H__ + +/*! + * ============================================================================ + * SX1276 Internal registers Address + * ============================================================================ + */ +#define REG_LR_FIFO 0x00 +// Common settings +#define REG_LR_OPMODE 0x01 +#define REG_LR_FRFMSB 0x06 +#define REG_LR_FRFMID 0x07 +#define REG_LR_FRFLSB 0x08 +// Tx settings +#define REG_LR_PACONFIG 0x09 +#define REG_LR_PARAMP 0x0A +#define REG_LR_OCP 0x0B +// Rx settings +#define REG_LR_LNA 0x0C +// LoRa registers +#define REG_LR_FIFOADDRPTR 0x0D +#define REG_LR_FIFOTXBASEADDR 0x0E +#define REG_LR_FIFORXBASEADDR 0x0F +#define REG_LR_FIFORXCURRENTADDR 0x10 +#define REG_LR_IRQFLAGSMASK 0x11 +#define REG_LR_IRQFLAGS 0x12 +#define REG_LR_RXNBBYTES 0x13 +#define REG_LR_RXHEADERCNTVALUEMSB 0x14 +#define REG_LR_RXHEADERCNTVALUELSB 0x15 +#define REG_LR_RXPACKETCNTVALUEMSB 0x16 +#define REG_LR_RXPACKETCNTVALUELSB 0x17 +#define REG_LR_MODEMSTAT 0x18 +#define REG_LR_PKTSNRVALUE 0x19 +#define REG_LR_PKTRSSIVALUE 0x1A +#define REG_LR_RSSIVALUE 0x1B +#define REG_LR_HOPCHANNEL 0x1C +#define REG_LR_MODEMCONFIG1 0x1D +#define REG_LR_MODEMCONFIG2 0x1E +#define REG_LR_SYMBTIMEOUTLSB 0x1F +#define REG_LR_PREAMBLEMSB 0x20 +#define REG_LR_PREAMBLELSB 0x21 +#define REG_LR_PAYLOADLENGTH 0x22 +#define REG_LR_PAYLOADMAXLENGTH 0x23 +#define REG_LR_HOPPERIOD 0x24 +#define REG_LR_FIFORXBYTEADDR 0x25 +#define REG_LR_MODEMCONFIG3 0x26 +#define REG_LR_FEIMSB 0x28 +#define REG_LR_FEIMID 0x29 +#define REG_LR_FEILSB 0x2A +#define REG_LR_RSSIWIDEBAND 0x2C +#define REG_LR_TEST2F 0x2F +#define REG_LR_TEST30 0x30 +#define REG_LR_DETECTOPTIMIZE 0x31 +#define REG_LR_INVERTIQ 0x33 +#define REG_LR_TEST36 0x36 +#define REG_LR_DETECTIONTHRESHOLD 0x37 +#define REG_LR_SYNCWORD 0x39 +#define REG_LR_TEST3A 0x3A +#define REG_LR_INVERTIQ2 0x3B + +// end of documented register in datasheet +// I/O settings +#define REG_LR_DIOMAPPING1 0x40 +#define REG_LR_DIOMAPPING2 0x41 +// Version +#define REG_LR_VERSION 0x42 +// Additional settings +#define REG_LR_PLLHOP 0x44 +#define REG_LR_TCXO 0x4B +#define REG_LR_PADAC 0x4D +#define REG_LR_FORMERTEMP 0x5B +#define REG_LR_BITRATEFRAC 0x5D +#define REG_LR_AGCREF 0x61 +#define REG_LR_AGCTHRESH1 0x62 +#define REG_LR_AGCTHRESH2 0x63 +#define REG_LR_AGCTHRESH3 0x64 +#define REG_LR_PLL 0x70 + +/*! + * ============================================================================ + * SX1276 LoRa bits control definition + * ============================================================================ + */ + +/*! + * RegFifo + */ + +/*! + * RegOpMode + */ +#define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default +#define RFLR_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF +#define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40 +#define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default + +#define RFLR_OPMODE_FREQMODE_ACCESS_MASK 0xF7 +#define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default +#define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00 + +#define RFLR_OPMODE_MASK 0xF8 +#define RFLR_OPMODE_SLEEP 0x00 +#define RFLR_OPMODE_STANDBY 0x01 // Default +#define RFLR_OPMODE_SYNTHESIZER_TX 0x02 +#define RFLR_OPMODE_TRANSMITTER 0x03 +#define RFLR_OPMODE_SYNTHESIZER_RX 0x04 +#define RFLR_OPMODE_RECEIVER 0x05 +// LoRa specific modes +#define RFLR_OPMODE_RECEIVER_SINGLE 0x06 +#define RFLR_OPMODE_CAD 0x07 + +/*! + * RegFrf (MHz) + */ +#define RFLR_FRFMSB_434_MHZ 0x6C // Default +#define RFLR_FRFMID_434_MHZ 0x80 // Default +#define RFLR_FRFLSB_434_MHZ 0x00 // Default + +/*! + * RegPaConfig + */ +#define RFLR_PACONFIG_PASELECT_MASK 0x7F +#define RFLR_PACONFIG_PASELECT_PABOOST 0x80 +#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RFLR_PACONFIG_MAX_POWER_MASK 0x8F + +#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +/*! + * RegPaRamp + */ +#define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF +#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10 +#define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default + +#define RFLR_PARAMP_MASK 0xF0 +#define RFLR_PARAMP_3400_US 0x00 +#define RFLR_PARAMP_2000_US 0x01 +#define RFLR_PARAMP_1000_US 0x02 +#define RFLR_PARAMP_0500_US 0x03 +#define RFLR_PARAMP_0250_US 0x04 +#define RFLR_PARAMP_0125_US 0x05 +#define RFLR_PARAMP_0100_US 0x06 +#define RFLR_PARAMP_0062_US 0x07 +#define RFLR_PARAMP_0050_US 0x08 +#define RFLR_PARAMP_0040_US 0x09 // Default +#define RFLR_PARAMP_0031_US 0x0A +#define RFLR_PARAMP_0025_US 0x0B +#define RFLR_PARAMP_0020_US 0x0C +#define RFLR_PARAMP_0015_US 0x0D +#define RFLR_PARAMP_0012_US 0x0E +#define RFLR_PARAMP_0010_US 0x0F + +/*! + * RegOcp + */ +#define RFLR_OCP_MASK 0xDF +#define RFLR_OCP_ON 0x20 // Default +#define RFLR_OCP_OFF 0x00 + +#define RFLR_OCP_TRIM_MASK 0xE0 +#define RFLR_OCP_TRIM_045_MA 0x00 +#define RFLR_OCP_TRIM_050_MA 0x01 +#define RFLR_OCP_TRIM_055_MA 0x02 +#define RFLR_OCP_TRIM_060_MA 0x03 +#define RFLR_OCP_TRIM_065_MA 0x04 +#define RFLR_OCP_TRIM_070_MA 0x05 +#define RFLR_OCP_TRIM_075_MA 0x06 +#define RFLR_OCP_TRIM_080_MA 0x07 +#define RFLR_OCP_TRIM_085_MA 0x08 +#define RFLR_OCP_TRIM_090_MA 0x09 +#define RFLR_OCP_TRIM_095_MA 0x0A +#define RFLR_OCP_TRIM_100_MA 0x0B // Default +#define RFLR_OCP_TRIM_105_MA 0x0C +#define RFLR_OCP_TRIM_110_MA 0x0D +#define RFLR_OCP_TRIM_115_MA 0x0E +#define RFLR_OCP_TRIM_120_MA 0x0F +#define RFLR_OCP_TRIM_130_MA 0x10 +#define RFLR_OCP_TRIM_140_MA 0x11 +#define RFLR_OCP_TRIM_150_MA 0x12 +#define RFLR_OCP_TRIM_160_MA 0x13 +#define RFLR_OCP_TRIM_170_MA 0x14 +#define RFLR_OCP_TRIM_180_MA 0x15 +#define RFLR_OCP_TRIM_190_MA 0x16 +#define RFLR_OCP_TRIM_200_MA 0x17 +#define RFLR_OCP_TRIM_210_MA 0x18 +#define RFLR_OCP_TRIM_220_MA 0x19 +#define RFLR_OCP_TRIM_230_MA 0x1A +#define RFLR_OCP_TRIM_240_MA 0x1B + +/*! + * RegLna + */ +#define RFLR_LNA_GAIN_MASK 0x1F +#define RFLR_LNA_GAIN_G1 0x20 // Default +#define RFLR_LNA_GAIN_G2 0x40 +#define RFLR_LNA_GAIN_G3 0x60 +#define RFLR_LNA_GAIN_G4 0x80 +#define RFLR_LNA_GAIN_G5 0xA0 +#define RFLR_LNA_GAIN_G6 0xC0 + +#define RFLR_LNA_BOOST_LF_MASK 0xE7 +#define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default + +#define RFLR_LNA_BOOST_HF_MASK 0xFC +#define RFLR_LNA_BOOST_HF_OFF 0x00 // Default +#define RFLR_LNA_BOOST_HF_ON 0x03 + +/*! + * RegFifoAddrPtr + */ +#define RFLR_FIFOADDRPTR 0x00 // Default + +/*! + * RegFifoTxBaseAddr + */ +#define RFLR_FIFOTXBASEADDR 0x80 // Default + +/*! + * RegFifoTxBaseAddr + */ +#define RFLR_FIFORXBASEADDR 0x00 // Default + +/*! + * RegFifoRxCurrentAddr (Read Only) + */ + +/*! + * RegIrqFlagsMask + */ +#define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80 +#define RFLR_IRQFLAGS_RXDONE_MASK 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10 +#define RFLR_IRQFLAGS_TXDONE_MASK 0x08 +#define RFLR_IRQFLAGS_CADDONE_MASK 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02 +#define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01 + +/*! + * RegIrqFlags + */ +#define RFLR_IRQFLAGS_RXTIMEOUT 0x80 +#define RFLR_IRQFLAGS_RXDONE 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER 0x10 +#define RFLR_IRQFLAGS_TXDONE 0x08 +#define RFLR_IRQFLAGS_CADDONE 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02 +#define RFLR_IRQFLAGS_CADDETECTED 0x01 + +/*! + * RegFifoRxNbBytes (Read Only) + */ + +/*! + * RegRxHeaderCntValueMsb (Read Only) + */ + +/*! + * RegRxHeaderCntValueLsb (Read Only) + */ + +/*! + * RegRxPacketCntValueMsb (Read Only) + */ + +/*! + * RegRxPacketCntValueLsb (Read Only) + */ + +/*! + * RegModemStat (Read Only) + */ +#define RFLR_MODEMSTAT_RX_CR_MASK 0x1F +#define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0 + +/*! + * RegPktSnrValue (Read Only) + */ + +/*! + * RegPktRssiValue (Read Only) + */ + +/*! + * RegRssiValue (Read Only) + */ + +/*! + * RegHopChannel (Read Only) + */ +#define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F +#define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80 +#define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default + +#define RFLR_HOPCHANNEL_CRCONPAYLOAD_MASK 0xBF +#define RFLR_HOPCHANNEL_CRCONPAYLOAD_ON 0x40 +#define RFLR_HOPCHANNEL_CRCONPAYLOAD_OFF 0x00 // Default + +#define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F + +/*! + * RegModemConfig1 + */ +#define RFLR_MODEMCONFIG1_BW_MASK 0x0F +#define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00 +#define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10 +#define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20 +#define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30 +#define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40 +#define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50 +#define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60 +#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default +#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80 +#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90 + +#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default +#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08 + +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01 +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default + +/*! + * RegModemConfig2 + */ +#define RFLR_MODEMCONFIG2_SF_MASK 0x0F +#define RFLR_MODEMCONFIG2_SF_6 0x60 +#define RFLR_MODEMCONFIG2_SF_7 0x70 // Default +#define RFLR_MODEMCONFIG2_SF_8 0x80 +#define RFLR_MODEMCONFIG2_SF_9 0x90 +#define RFLR_MODEMCONFIG2_SF_10 0xA0 +#define RFLR_MODEMCONFIG2_SF_11 0xB0 +#define RFLR_MODEMCONFIG2_SF_12 0xC0 + +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00 + +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK 0xFB +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04 +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default + +/*! + * RegSymbTimeoutLsb + */ +#define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default + +/*! + * RegPreambleLengthMsb + */ +#define RFLR_PREAMBLELENGTHMSB 0x00 // Default + +/*! + * RegPreambleLengthLsb + */ +#define RFLR_PREAMBLELENGTHLSB 0x08 // Default + +/*! + * RegPayloadLength + */ +#define RFLR_PAYLOADLENGTH 0x0E // Default + +/*! + * RegPayloadMaxLength + */ +#define RFLR_PAYLOADMAXLENGTH 0xFF // Default + +/*! + * RegHopPeriod + */ +#define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default + +/*! + * RegFifoRxByteAddr (Read Only) + */ + +/*! + * RegModemConfig3 + */ +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK 0xF7 +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON 0x08 +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG3_AGCAUTO_MASK 0xFB +#define RFLR_MODEMCONFIG3_AGCAUTO_ON 0x04 // Default +#define RFLR_MODEMCONFIG3_AGCAUTO_OFF 0x00 + +/*! + * RegFeiMsb (Read Only) + */ + +/*! + * RegFeiMid (Read Only) + */ + +/*! + * RegFeiLsb (Read Only) + */ + +/*! + * RegRssiWideband (Read Only) + */ + +/*! + * RegDetectOptimize + */ +#define RFLR_DETECTIONOPTIMIZE_MASK 0xF8 +#define RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 0x03 // Default +#define RFLR_DETECTIONOPTIMIZE_SF6 0x05 + +/*! + * RegInvertIQ + */ +#define RFLR_INVERTIQ_RX_MASK 0xBF +#define RFLR_INVERTIQ_RX_OFF 0x00 +#define RFLR_INVERTIQ_RX_ON 0x40 +#define RFLR_INVERTIQ_TX_MASK 0xFE +#define RFLR_INVERTIQ_TX_OFF 0x01 +#define RFLR_INVERTIQ_TX_ON 0x00 + +/*! + * RegDetectionThreshold + */ +#define RFLR_DETECTIONTHRESH_SF7_TO_SF12 0x0A // Default +#define RFLR_DETECTIONTHRESH_SF6 0x0C + +/*! + * RegInvertIQ2 + */ +#define RFLR_INVERTIQ2_ON 0x19 +#define RFLR_INVERTIQ2_OFF 0x1D + +/*! + * RegDioMapping1 + */ +#define RFLR_DIOMAPPING1_DIO0_MASK 0x3F +#define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO0_01 0x40 +#define RFLR_DIOMAPPING1_DIO0_10 0x80 +#define RFLR_DIOMAPPING1_DIO0_11 0xC0 + +#define RFLR_DIOMAPPING1_DIO1_MASK 0xCF +#define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO1_01 0x10 +#define RFLR_DIOMAPPING1_DIO1_10 0x20 +#define RFLR_DIOMAPPING1_DIO1_11 0x30 + +#define RFLR_DIOMAPPING1_DIO2_MASK 0xF3 +#define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO2_01 0x04 +#define RFLR_DIOMAPPING1_DIO2_10 0x08 +#define RFLR_DIOMAPPING1_DIO2_11 0x0C + +#define RFLR_DIOMAPPING1_DIO3_MASK 0xFC +#define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO3_01 0x01 +#define RFLR_DIOMAPPING1_DIO3_10 0x02 +#define RFLR_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RFLR_DIOMAPPING2_DIO4_MASK 0x3F +#define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO4_01 0x40 +#define RFLR_DIOMAPPING2_DIO4_10 0x80 +#define RFLR_DIOMAPPING2_DIO4_11 0xC0 + +#define RFLR_DIOMAPPING2_DIO5_MASK 0xCF +#define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO5_01 0x10 +#define RFLR_DIOMAPPING2_DIO5_10 0x20 +#define RFLR_DIOMAPPING2_DIO5_11 0x30 + +#define RFLR_DIOMAPPING2_MAP_MASK 0xFE +#define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegPllHop + */ +#define RFLR_PLLHOP_FASTHOP_MASK 0x7F +#define RFLR_PLLHOP_FASTHOP_ON 0x80 +#define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RFLR_TCXO_TCXOINPUT_MASK 0xEF +#define RFLR_TCXO_TCXOINPUT_ON 0x10 +#define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RFLR_PADAC_20DBM_MASK 0xF8 +#define RFLR_PADAC_20DBM_ON 0x07 +#define RFLR_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegFormerTemp + */ + +/*! + * RegBitrateFrac + */ +#define RF_BITRATEFRAC_MASK 0xF0 + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegPll + */ +#define RF_PLL_BANDWIDTH_MASK 0x3F +#define RF_PLL_BANDWIDTH_75 0x00 +#define RF_PLL_BANDWIDTH_150 0x40 +#define RF_PLL_BANDWIDTH_225 0x80 +#define RF_PLL_BANDWIDTH_300 0xC0 // Default + +#endif // __SX1276_REGS_LORA_H__ From 622d50b56df04bea93234b005f1825dd26386c1d Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 15 Dec 2017 10:50:24 +0200 Subject: [PATCH 02/42] Removing namespace pollution & rf ctrls refactor rf_ctrls is a data structure that holds all control pins for a certain LoRa Radio. Same data structure was being used in both SX1272 and SX1276 drivers. As we are heading towards putting both drivers in the same repo and as the plan is to use them togather, i.e., both header files could be included we need to move this data structure to a common location so that the name does not collide. In addition to that we have tried to reduce namespace pollution caused by the driver header files. --- SX1272/SX1272_LoRaRadio.h | 57 +++++++++++++++++++------------------ SX1276/SX1276_LoRaRadio.h | 60 +++++++++++++++++++-------------------- 2 files changed, 58 insertions(+), 59 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index c99d237207..05a2ad89f7 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -26,23 +26,24 @@ SPDX-License-Identifier: BSD-3-Clause #ifndef SX1272_LORARADIO_H_ #define SX1272_LORARADIO_H_ +#include "PinNames.h" +#include "InterruptIn.h" +#include "DigitalOut.h" +#include "DigitalInOut.h" +#include "SPI.h" +#include "Timeout.h" +#ifdef MBED_CONF_RTOS_PRESENT + #include "rtos/Thread.h" +#endif #include "netsocket/LoRaRadio.h" + #ifdef MBED_SX1272_LORARADIO_BUFFER_SIZE #define MAX_DATA_BUFFER_SIZE MBED_SX1272_LORARADIO_BUFFER_SIZE #else #define MAX_DATA_BUFFER_SIZE 256 #endif -typedef struct { - PinName rf_switch_ctl1; - PinName rf_switch_ctl2; - PinName txctl; - PinName rxctl; - PinName ant_switch; - PinName pwr_amp_ctl; -} rf_ctrls; - /** * Radio driver implementation for Semtech SX1272 plus variants. * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. @@ -301,27 +302,27 @@ public: private: // SPI and chip select control - SPI _spi; - DigitalOut _chip_select; + mbed::SPI _spi; + mbed::DigitalOut _chip_select; // module rest control - DigitalInOut _reset_ctl; + mbed::DigitalInOut _reset_ctl; // Interrupt controls - InterruptIn _dio0_ctl; - InterruptIn _dio1_ctl; - InterruptIn _dio2_ctl; - InterruptIn _dio3_ctl; - InterruptIn _dio4_ctl; - InterruptIn _dio5_ctl; + mbed::InterruptIn _dio0_ctl; + mbed::InterruptIn _dio1_ctl; + mbed::InterruptIn _dio2_ctl; + mbed::InterruptIn _dio3_ctl; + mbed::InterruptIn _dio4_ctl; + mbed::InterruptIn _dio5_ctl; // Radio specific controls - DigitalOut _rf_switch_ctl1; - DigitalOut _rf_switch_ctl2; - DigitalOut _txctl; - DigitalOut _rxctl; - DigitalInOut _ant_switch; - DigitalOut _pwr_amp_ctl; + mbed::DigitalOut _rf_switch_ctl1; + mbed::DigitalOut _rf_switch_ctl2; + mbed::DigitalOut _txctl; + mbed::DigitalOut _rxctl; + mbed::DigitalInOut _ant_switch; + mbed::DigitalOut _pwr_amp_ctl; // Contains all RF control pin names // This storage is needed even after assigning the @@ -343,13 +344,13 @@ private: uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE]; // TX/RX Timers - all use milisecond units - Timeout tx_timeout_timer; - Timeout rx_timeout_timer; - Timeout rx_timeout_sync_word; + mbed::Timeout tx_timeout_timer; + mbed::Timeout rx_timeout_timer; + mbed::Timeout rx_timeout_sync_word; #ifdef MBED_CONF_RTOS_PRESENT // Thread to handle interrupts - Thread irq_thread; + rtos::Thread irq_thread; #endif // Access protection diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index 79fd476c28..6c3489d54a 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -26,6 +26,15 @@ SPDX-License-Identifier: BSD-3-Clause #ifndef SX1276_LORARADIO_H_ #define SX1276_LORARADIO_H_ +#include "PinNames.h" +#include "InterruptIn.h" +#include "DigitalOut.h" +#include "DigitalInOut.h" +#include "SPI.h" +#include "Timeout.h" +#ifdef MBED_CONF_RTOS_PRESENT + #include "rtos/Thread.h" +#endif #include "netsocket/LoRaRadio.h" #ifdef MBED_SX1276_LORARADIO_BUFFER_SIZE @@ -34,16 +43,6 @@ SPDX-License-Identifier: BSD-3-Clause #define MAX_DATA_BUFFER_SIZE 256 #endif -typedef struct { - PinName rf_switch_ctl1; - PinName rf_switch_ctl2; - PinName txctl; - PinName rxctl; - PinName ant_switch; - PinName pwr_amp_ctl; - PinName tcxo; -} rf_ctrls; - /** * Radio driver implementation for Semtech SX1272 plus variants. * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. @@ -318,28 +317,28 @@ public: private: // SPI and chip select control - SPI _spi; - DigitalOut _chip_select; + mbed::SPI _spi; + mbed::DigitalOut _chip_select; // module rest control - DigitalInOut _reset_ctl; + mbed::DigitalInOut _reset_ctl; // Interrupt controls - InterruptIn _dio0_ctl; - InterruptIn _dio1_ctl; - InterruptIn _dio2_ctl; - InterruptIn _dio3_ctl; - InterruptIn _dio4_ctl; - InterruptIn _dio5_ctl; + mbed::InterruptIn _dio0_ctl; + mbed::InterruptIn _dio1_ctl; + mbed::InterruptIn _dio2_ctl; + mbed::InterruptIn _dio3_ctl; + mbed::InterruptIn _dio4_ctl; + mbed::InterruptIn _dio5_ctl; // Radio specific controls - DigitalOut _rf_switch_ctl1; - DigitalOut _rf_switch_ctl2; - DigitalOut _txctl; - DigitalOut _rxctl; - DigitalInOut _ant_switch; - DigitalOut _pwr_amp_ctl; - DigitalOut _tcxo; + mbed::DigitalOut _rf_switch_ctl1; + mbed::DigitalOut _rf_switch_ctl2; + mbed::DigitalOut _txctl; + mbed::DigitalOut _rxctl; + mbed::DigitalInOut _ant_switch; + mbed::DigitalOut _pwr_amp_ctl; + mbed::DigitalOut _tcxo; // Contains all RF control pin names // This storage is needed even after assigning the @@ -361,13 +360,13 @@ private: uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE]; // TX/RX Timers - all use milisecond units - Timeout tx_timeout_timer; - Timeout rx_timeout_timer; - Timeout rx_timeout_sync_word; + mbed::Timeout tx_timeout_timer; + mbed::Timeout rx_timeout_timer; + mbed::Timeout rx_timeout_sync_word; #ifdef MBED_CONF_RTOS_PRESENT // Thread to handle interrupts - Thread irq_thread; + rtos::Thread irq_thread; #endif // Access protection @@ -419,6 +418,5 @@ private: void handle_dio4_irq(); void handle_dio5_irq(); void handle_timeout_irq(); -}; #endif // SX1276_LORARADIO_H_ From 6f039691d75a8683c3d582fc6470aa60602b98c6 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Mon, 18 Dec 2017 14:31:39 +0200 Subject: [PATCH 03/42] Buffer Size and missing terminator for SX127 class For some unknown reason (may be a rebase issue) Mbed config name for the drivers was not spell correctly inside the source macro definition. Alongwith that the SX1276 driver was missing a class terminator. --- SX1272/SX1272_LoRaRadio.cpp | 2 +- SX1272/SX1272_LoRaRadio.h | 8 ++++---- SX1276/SX1276_LoRaRadio.cpp | 2 +- SX1276/SX1276_LoRaRadio.h | 9 +++++---- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 698428e9bb..caae521e27 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -953,7 +953,7 @@ void SX1272_LoRaRadio::receive(uint32_t timeout) break; } - memset(_data_buffer, 0, (size_t) MAX_DATA_BUFFER_SIZE); + memset(_data_buffer, 0, (size_t) MAX_DATA_BUFFER_SIZE_SX172); _rf_settings.state = RF_RX_RUNNING; diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index 05a2ad89f7..34931b350b 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -38,10 +38,10 @@ SPDX-License-Identifier: BSD-3-Clause #include "netsocket/LoRaRadio.h" -#ifdef MBED_SX1272_LORARADIO_BUFFER_SIZE -#define MAX_DATA_BUFFER_SIZE MBED_SX1272_LORARADIO_BUFFER_SIZE +#ifdef MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE +#define MAX_DATA_BUFFER_SIZE_SX172 MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE #else -#define MAX_DATA_BUFFER_SIZE 256 +#define MAX_DATA_BUFFER_SIZE_SX172 256 #endif /** @@ -341,7 +341,7 @@ private: // Data buffer used for both TX and RX // Size of this buffer is configurable via Mbed config system // Default is 256 bytes - uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE]; + uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX172]; // TX/RX Timers - all use milisecond units mbed::Timeout tx_timeout_timer; diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 7c57f1c492..4dadf6ad43 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -978,7 +978,7 @@ void SX1276_LoRaRadio::receive(uint32_t timeout) break; } - memset(_data_buffer, 0, (size_t) MAX_DATA_BUFFER_SIZE); + memset(_data_buffer, 0, (size_t) MAX_DATA_BUFFER_SIZE_SX1276); _rf_settings.state = RF_RX_RUNNING; diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index 6c3489d54a..6456d139a5 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -37,10 +37,10 @@ SPDX-License-Identifier: BSD-3-Clause #endif #include "netsocket/LoRaRadio.h" -#ifdef MBED_SX1276_LORARADIO_BUFFER_SIZE -#define MAX_DATA_BUFFER_SIZE MBED_SX1276_LORARADIO_BUFFER_SIZE +#ifdef MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE +#define MAX_DATA_BUFFER_SIZE_SX1276 MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE #else -#define MAX_DATA_BUFFER_SIZE 256 +#define MAX_DATA_BUFFER_SIZE_SX1276 256 #endif /** @@ -357,7 +357,7 @@ private: // Data buffer used for both TX and RX // Size of this buffer is configurable via Mbed config system // Default is 256 bytes - uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE]; + uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX1276]; // TX/RX Timers - all use milisecond units mbed::Timeout tx_timeout_timer; @@ -418,5 +418,6 @@ private: void handle_dio4_irq(); void handle_dio5_irq(); void handle_timeout_irq(); +}; #endif // SX1276_LORARADIO_H_ From c882dd6e6ec136bae88cdbfeaaf62a75d2ef5a37 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Wed, 3 Jan 2018 17:15:29 +0200 Subject: [PATCH 04/42] [IOTCELL-284] Removing NULL checks from Callbacks In respose to the radio event callback change from c style callbacks to Mbed callbacks, we need to remove NULL checks from the driver code as the callbacks itself are not pointers anymore. However, thanks to template magic, we can check if callback is assigned or not. If its not not assigned, it is default constructed to NULL which we can check by boolean operator. --- SX1272/SX1272_LoRaRadio.cpp | 24 ++++++++++++------------ SX1276/SX1276_LoRaRadio.cpp | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index caae521e27..edd6251d12 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -1720,7 +1720,7 @@ void SX1272_LoRaRadio::handle_dio0_irq() rx_timeout_timer.detach(); if ((_radio_events != NULL) - && (_radio_events->rx_error != NULL)) { + && (_radio_events->rx_error)) { _radio_events->rx_error(); } _rf_settings.fsk_packet_handler.preamble_detected = false; @@ -1763,7 +1763,7 @@ void SX1272_LoRaRadio::handle_dio0_irq() rx_timeout_timer.detach(); - if ((_radio_events != NULL) && (_radio_events->rx_done != NULL)) { + if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done( _data_buffer, _rf_settings.fsk_packet_handler.size, @@ -1793,7 +1793,7 @@ void SX1272_LoRaRadio::handle_dio0_irq() rx_timeout_timer.detach(); if ((_radio_events != NULL) - && (_radio_events->rx_error != NULL)) { + && (_radio_events->rx_error)) { _radio_events->rx_error(); } break; @@ -1828,7 +1828,7 @@ void SX1272_LoRaRadio::handle_dio0_irq() rx_timeout_timer.detach(); if ((_radio_events != NULL) - && (_radio_events->rx_done != NULL)) { + && (_radio_events->rx_done)) { _radio_events->rx_done( _data_buffer, _rf_settings.lora_packet_handler.size, @@ -1853,7 +1853,7 @@ void SX1272_LoRaRadio::handle_dio0_irq() default: _rf_settings.state = RF_IDLE; if ((_radio_events != NULL) - && (_radio_events->tx_done != NULL)) { + && (_radio_events->tx_done)) { _radio_events->tx_done(); } break; @@ -1901,7 +1901,7 @@ void SX1272_LoRaRadio::handle_dio1_irq() // Sync time out rx_timeout_timer.detach( ); _rf_settings.state = RF_IDLE; - if ((_radio_events != NULL) && (_radio_events->rx_timeout != NULL)) { + if ((_radio_events != NULL) && (_radio_events->rx_timeout)) { _radio_events->rx_timeout(); } break; @@ -1969,7 +1969,7 @@ void SX1272_LoRaRadio::handle_dio2_irq(void) // Clear Irq write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); - if( ( _radio_events != NULL ) && (_radio_events->fhss_change_channel != NULL ) ) + if( ( _radio_events != NULL ) && (_radio_events->fhss_change_channel ) ) { _radio_events->fhss_change_channel((read_register( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK )); } @@ -1990,7 +1990,7 @@ void SX1272_LoRaRadio::handle_dio2_irq(void) // Clear Irq write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); - if( (_radio_events != NULL ) && ( _radio_events->fhss_change_channel != NULL ) ) + if( (_radio_events != NULL ) && ( _radio_events->fhss_change_channel ) ) { _radio_events->fhss_change_channel((read_register( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK )); } @@ -2016,7 +2016,7 @@ void SX1272_LoRaRadio::handle_dio3_irq( void ) { // Clear Irq write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE ); - if( ( _radio_events != NULL ) && ( _radio_events->cad_done != NULL ) ) + if( ( _radio_events != NULL ) && ( _radio_events->cad_done ) ) { _radio_events->cad_done( true ); } @@ -2025,7 +2025,7 @@ void SX1272_LoRaRadio::handle_dio3_irq( void ) { // Clear Irq write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE ); - if( ( _radio_events != NULL ) && ( _radio_events->cad_done != NULL ) ) + if( ( _radio_events != NULL ) && ( _radio_events->cad_done ) ) { _radio_events->cad_done( false ); } @@ -2099,7 +2099,7 @@ void SX1272_LoRaRadio::handle_timeout_irq() } } - if((_radio_events != NULL) && (_radio_events->rx_timeout != NULL)) { + if((_radio_events != NULL) && (_radio_events->rx_timeout)) { _radio_events->rx_timeout(); } @@ -2126,7 +2126,7 @@ void SX1272_LoRaRadio::handle_timeout_irq() set_public_network(_rf_settings.lora.public_network); _rf_settings.state = RF_IDLE; - if( ( _radio_events != NULL ) && ( _radio_events->tx_timeout != NULL ) ) + if( ( _radio_events != NULL ) && ( _radio_events->tx_timeout ) ) { _radio_events->tx_timeout( ); } diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 4dadf6ad43..9f6d0bc6db 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -1860,7 +1860,7 @@ void SX1276_LoRaRadio::handle_dio0_irq() rx_timeout_timer.detach(); if ((_radio_events != NULL) - && (_radio_events->rx_error != NULL)) { + && (_radio_events->rx_error)) { _radio_events->rx_error(); } _rf_settings.fsk_packet_handler.preamble_detected = false; @@ -1903,7 +1903,7 @@ void SX1276_LoRaRadio::handle_dio0_irq() rx_timeout_timer.detach(); - if ((_radio_events != NULL) && (_radio_events->rx_done != NULL)) { + if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done( _data_buffer, _rf_settings.fsk_packet_handler.size, @@ -1933,7 +1933,7 @@ void SX1276_LoRaRadio::handle_dio0_irq() rx_timeout_timer.detach(); if ((_radio_events != NULL) - && (_radio_events->rx_error != NULL)) { + && (_radio_events->rx_error)) { _radio_events->rx_error(); } break; @@ -1981,7 +1981,7 @@ void SX1276_LoRaRadio::handle_dio0_irq() } rx_timeout_timer.detach(); - if ((_radio_events != NULL) && (_radio_events->rx_done != NULL)) { + if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done(_data_buffer, _rf_settings.lora_packet_handler.size, _rf_settings.lora_packet_handler.rssi_value, @@ -2005,7 +2005,7 @@ void SX1276_LoRaRadio::handle_dio0_irq() default: _rf_settings.state = RF_IDLE; if ((_radio_events != NULL) - && (_radio_events->tx_done != NULL)) { + && (_radio_events->tx_done)) { _radio_events->tx_done(); } break; @@ -2059,7 +2059,7 @@ void SX1276_LoRaRadio::handle_dio1_irq() write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT); _rf_settings.state = RF_IDLE; if ((_radio_events != NULL) - && (_radio_events->rx_timeout != NULL)) { + && (_radio_events->rx_timeout)) { _radio_events->rx_timeout(); } break; @@ -2138,7 +2138,7 @@ void SX1276_LoRaRadio::handle_dio2_irq(void) RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL); if ((_radio_events != NULL) - && (_radio_events->fhss_change_channel != NULL)) { + && (_radio_events->fhss_change_channel)) { _radio_events->fhss_change_channel( (read_register(REG_LR_HOPCHANNEL) & RFLR_HOPCHANNEL_CHANNEL_MASK)); @@ -2164,7 +2164,7 @@ void SX1276_LoRaRadio::handle_dio2_irq(void) RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL); if ((_radio_events != NULL) - && (_radio_events->fhss_change_channel != NULL)) { + && (_radio_events->fhss_change_channel)) { _radio_events->fhss_change_channel( (read_register(REG_LR_HOPCHANNEL) & RFLR_HOPCHANNEL_CHANNEL_MASK)); @@ -2192,14 +2192,14 @@ void SX1276_LoRaRadio::handle_dio3_irq(void) write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE); if ((_radio_events != NULL) - && (_radio_events->cad_done != NULL)) { + && (_radio_events->cad_done)) { _radio_events->cad_done(true); } } else { // Clear Irq write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE); if ((_radio_events != NULL) - && (_radio_events->cad_done != NULL)) { + && (_radio_events->cad_done)) { _radio_events->cad_done(false); } } @@ -2269,7 +2269,7 @@ void SX1276_LoRaRadio::handle_timeout_irq() } if ((_radio_events != NULL) - && (_radio_events->rx_timeout != NULL)) { + && (_radio_events->rx_timeout)) { _radio_events->rx_timeout(); } @@ -2297,7 +2297,7 @@ void SX1276_LoRaRadio::handle_timeout_irq() _rf_settings.state = RF_IDLE; if ((_radio_events != NULL) - && (_radio_events->tx_timeout != NULL)) { + && (_radio_events->tx_timeout)) { _radio_events->tx_timeout(); } break; From 63b5c8453eb677eccd88c391fd76ddd55dbc8876 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Thu, 4 Jan 2018 13:33:00 +0200 Subject: [PATCH 05/42] Add support for Multitech xDot module xDot module does not have external antenna control pins nor DIO5 pin connected. --- SX1272/SX1272_LoRaRadio.cpp | 26 ++++++++++++-------------- SX1272/SX1272_LoRaRadio.h | 3 +++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index edd6251d12..c35aea2a6b 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -185,6 +185,8 @@ SX1272_LoRaRadio::SX1272_LoRaRadio(PinName spi_mosi, PinName spi_miso, _rf_ctrls.rxctl = rxctl; _rf_ctrls.txctl = txctl; + _dio5_pin = dio5; + _radio_events = NULL; #ifdef MBED_CONF_RTOS_PRESENT @@ -1330,9 +1332,10 @@ void SX1272_LoRaRadio::default_antenna_switch_ctrls() _rf_switch_ctl2 = 0; } - if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) - _txctl = 0; - _rxctl = 0; + if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) { + _txctl = 0; + _rxctl = 0; + } } /** @@ -1500,12 +1503,9 @@ void SX1272_LoRaRadio::set_antenna_switch(uint8_t mode) _txctl = 1; _rxctl = 0; } else if (_rf_ctrls.ant_switch != NC){ - MBED_ASSERT(_rf_ctrls.ant_switch == NC); _ant_switch = 1; } else { - // Either None of the control pins are connected or wrong - // combination of controls pins. Break the system right here. - MBED_ASSERT(false); + // None of the control pins are connected. } break; case RFLR_OPMODE_RECEIVER: @@ -1523,9 +1523,7 @@ void SX1272_LoRaRadio::set_antenna_switch(uint8_t mode) } else if (_rf_ctrls.ant_switch != NC) { _ant_switch = 0; } else { - // Either None of the control pins are connected or wrong - // combination of controls pins. Break the system right here. - MBED_ASSERT(false); + // None of the control pins are connected. } break; default: @@ -1542,9 +1540,7 @@ void SX1272_LoRaRadio::set_antenna_switch(uint8_t mode) } else if (_rf_ctrls.ant_switch != NC) { _ant_switch = 0; } else { - // Either None of the control pins are connected or wrong - // combination of controls pins. Break the system right here. - MBED_ASSERT(false); + // None of the control pins are connected. } break; } @@ -1584,7 +1580,9 @@ void SX1272_LoRaRadio::setup_interrupts() _dio2_ctl.rise(callback(this, &SX1272_LoRaRadio::dio2_irq_isr)); _dio3_ctl.rise(callback(this, &SX1272_LoRaRadio::dio3_irq_isr)); _dio4_ctl.rise(callback(this, &SX1272_LoRaRadio::dio4_irq_isr)); - _dio5_ctl.rise(callback(this, &SX1272_LoRaRadio::dio5_irq_isr)); + if (_dio5_pin != NC) { + _dio5_ctl.rise(callback(this, &SX1272_LoRaRadio::dio5_irq_isr)); + } } /** diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index 34931b350b..bf6892cee8 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -331,6 +331,9 @@ private: // variation is inherent to driver because of target configuration. rf_ctrls _rf_ctrls; + // DIO5 PinName. We need to store this as not all modules have it connected + PinName _dio5_pin; + // Structure containing all user and network specified settings // for radio module radio_settings_t _rf_settings; From 863decda1898b93ef6a11a5bd79227e9583e65ff Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Mon, 8 Jan 2018 14:08:27 +0200 Subject: [PATCH 06/42] Enable PA_BOOST for xDOT module --- SX1272/SX1272_LoRaRadio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index c35aea2a6b..d9642d3aef 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -1344,7 +1344,7 @@ void SX1272_LoRaRadio::default_antenna_switch_ctrls() uint8_t SX1272_LoRaRadio::get_pa_conf_reg() { -#if defined(TARGET_MTS_MDOT_F411RE) +#if defined(TARGET_MTS_MDOT_F411RE) || defined(TARGET_XDOT_L151CC) return RF_PACONFIG_PASELECT_PABOOST; #endif if (radio_variant == SX1272MB1DCS) { From 7407a282fba0bfcff4a195494544ef84d9d1a475 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Tue, 16 Jan 2018 10:28:46 +0200 Subject: [PATCH 07/42] Use PA_BOOST for WISE-1510 module --- SX1276/SX1276_LoRaRadio.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 9f6d0bc6db..4008683319 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -1451,6 +1451,9 @@ uint8_t SX1276_LoRaRadio::get_fsk_bw_reg_val(uint32_t bandwidth) uint8_t SX1276_LoRaRadio::get_pa_conf_reg(uint32_t channel) { +#if TARGET_WISE_1510 + return RF_PACONFIG_PASELECT_PABOOST; +#else if (channel > RF_MID_BAND_THRESH) { if (radio_variant == SX1276MB1LAS || is_murata) { return RF_PACONFIG_PASELECT_PABOOST; @@ -1460,6 +1463,7 @@ uint8_t SX1276_LoRaRadio::get_pa_conf_reg(uint32_t channel) } else { return RF_PACONFIG_PASELECT_RFO; } +#endif } /** From b520b5a702dcb726175f85abbc126062f01d0763 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Tue, 30 Jan 2018 15:16:26 +0200 Subject: [PATCH 08/42] Set up DIO4 and 5 interrupts only if pins are connected For example muRata modules do not have DIO4 and DIO5 pins connected. If these pins are not connected, driver should not try to set up interrupt handlers for those. --- SX1272/SX1272_LoRaRadio.cpp | 6 ++++-- SX1272/SX1272_LoRaRadio.h | 3 ++- SX1276/SX1276_LoRaRadio.cpp | 9 +++++++-- SX1276/SX1276_LoRaRadio.h | 4 ++++ 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index d9642d3aef..5842f7a7db 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -185,6 +185,7 @@ SX1272_LoRaRadio::SX1272_LoRaRadio(PinName spi_mosi, PinName spi_miso, _rf_ctrls.rxctl = rxctl; _rf_ctrls.txctl = txctl; + _dio4_pin = dio4; _dio5_pin = dio5; _radio_events = NULL; @@ -1579,7 +1580,9 @@ void SX1272_LoRaRadio::setup_interrupts() _dio1_ctl.rise(callback(this, &SX1272_LoRaRadio::dio1_irq_isr)); _dio2_ctl.rise(callback(this, &SX1272_LoRaRadio::dio2_irq_isr)); _dio3_ctl.rise(callback(this, &SX1272_LoRaRadio::dio3_irq_isr)); - _dio4_ctl.rise(callback(this, &SX1272_LoRaRadio::dio4_irq_isr)); + if (_dio4_pin != NC) { + _dio4_ctl.rise(callback(this, &SX1272_LoRaRadio::dio4_irq_isr)); + } if (_dio5_pin != NC) { _dio5_ctl.rise(callback(this, &SX1272_LoRaRadio::dio5_irq_isr)); } @@ -1591,7 +1594,6 @@ void SX1272_LoRaRadio::setup_interrupts() */ void SX1272_LoRaRadio::set_low_power_mode(bool status) { - if( RadioIsActive != status ) { RadioIsActive = status; diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index bf6892cee8..dce68e37c6 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -331,7 +331,8 @@ private: // variation is inherent to driver because of target configuration. rf_ctrls _rf_ctrls; - // DIO5 PinName. We need to store this as not all modules have it connected + // We need these PinNames as not all modules have those connected + PinName _dio4_pin; PinName _dio5_pin; // Structure containing all user and network specified settings diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 4008683319..c8fbae1311 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -184,6 +184,9 @@ SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi, PinName spi_miso, _rf_ctrls.txctl = txctl; _rf_ctrls.tcxo = tcxo; + _dio4_pin = dio4; + _dio5_pin = dio5; + _radio_events = NULL; // Detect Murata based on pin configuration @@ -1662,8 +1665,10 @@ void SX1276_LoRaRadio::setup_interrupts() _dio1_ctl.rise(callback(this, &SX1276_LoRaRadio::dio1_irq_isr)); _dio2_ctl.rise(callback(this, &SX1276_LoRaRadio::dio2_irq_isr)); _dio3_ctl.rise(callback(this, &SX1276_LoRaRadio::dio3_irq_isr)); - _dio4_ctl.rise(callback(this, &SX1276_LoRaRadio::dio4_irq_isr)); - if (!is_murata) { + if (_dio4_pin != NC) { + _dio4_ctl.rise(callback(this, &SX1276_LoRaRadio::dio4_irq_isr)); + } + if (_dio5_pin != NC) { _dio5_ctl.rise(callback(this, &SX1276_LoRaRadio::dio5_irq_isr)); } } diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index 6456d139a5..b277f269b4 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -347,6 +347,10 @@ private: // variation is inherent to driver because of target configuration. rf_ctrls _rf_ctrls; + // We need these PinNames as not all modules have those connected + PinName _dio4_pin; + PinName _dio5_pin; + // Structure containing all user and network specified settings // for radio module radio_settings_t _rf_settings; From cfa70a7e40642fa6272cdf0e01ec9053e65c9fde Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Wed, 7 Feb 2018 11:04:49 +0200 Subject: [PATCH 09/42] Add MTB_MTS_XDOT target --- SX1272/SX1272_LoRaRadio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 5842f7a7db..5125107f5e 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -1345,7 +1345,7 @@ void SX1272_LoRaRadio::default_antenna_switch_ctrls() uint8_t SX1272_LoRaRadio::get_pa_conf_reg() { -#if defined(TARGET_MTS_MDOT_F411RE) || defined(TARGET_XDOT_L151CC) +#if defined(TARGET_MTS_MDOT_F411RE) || defined(TARGET_XDOT_L151CC) || defined(TARGET_MTB_MTS_XDOT) return RF_PACONFIG_PASELECT_PABOOST; #endif if (radio_variant == SX1272MB1DCS) { From 6f45d34e0417e6790c91caaac852d64c36d9a4a8 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 9 Feb 2018 12:33:43 +0200 Subject: [PATCH 10/42] Fixing paths to LoRaRadio and warnings LoRaRadio is now moved to feature/lorawan from feature/netsocket. --- SX1272/SX1272_LoRaRadio.cpp | 2 +- SX1272/SX1272_LoRaRadio.h | 2 +- SX1276/SX1276_LoRaRadio.cpp | 2 +- SX1276/SX1276_LoRaRadio.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 5125107f5e..b2a8c1ef3c 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -1053,7 +1053,7 @@ bool SX1272_LoRaRadio::perform_carrier_sense(radio_modems_t modem, elapsed_time.start(); // Perform carrier sense for maxCarrierSenseTime - while (elapsed_time.read_ms() < max_carrier_sense_time) { + while (elapsed_time.read_ms() < (int)max_carrier_sense_time) { rssi = get_rssi(modem); if (rssi > rssi_threshold) { diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index dce68e37c6..c3c70107dd 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -35,7 +35,7 @@ SPDX-License-Identifier: BSD-3-Clause #ifdef MBED_CONF_RTOS_PRESENT #include "rtos/Thread.h" #endif -#include "netsocket/LoRaRadio.h" +#include "lorawan/LoRaRadio.h" #ifdef MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index c8fbae1311..14fed89757 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -1039,7 +1039,7 @@ bool SX1276_LoRaRadio::perform_carrier_sense(radio_modems_t modem, elapsed_time.start(); // Perform carrier sense for maxCarrierSenseTime - while (elapsed_time.read_ms() < max_carrier_sense_time) { + while (elapsed_time.read_ms() < (int)max_carrier_sense_time) { rssi = get_rssi(modem); if (rssi > rssi_threshold) { diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index b277f269b4..f758c1740a 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -35,7 +35,7 @@ SPDX-License-Identifier: BSD-3-Clause #ifdef MBED_CONF_RTOS_PRESENT #include "rtos/Thread.h" #endif -#include "netsocket/LoRaRadio.h" +#include "lorawan/LoRaRadio.h" #ifdef MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE #define MAX_DATA_BUFFER_SIZE_SX1276 MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE From 9f2ad37f4fd6381a1fdca322d751313f2c3c17b9 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Thu, 8 Feb 2018 11:02:21 +0200 Subject: [PATCH 11/42] Change WISE-1510 target to new name --- SX1276/SX1276_LoRaRadio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 14fed89757..5e7f7a6760 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -1454,7 +1454,7 @@ uint8_t SX1276_LoRaRadio::get_fsk_bw_reg_val(uint32_t bandwidth) uint8_t SX1276_LoRaRadio::get_pa_conf_reg(uint32_t channel) { -#if TARGET_WISE_1510 +#if TARGET_MTB_ADV_WISE_1510 return RF_PACONFIG_PASELECT_PABOOST; #else if (channel > RF_MID_BAND_THRESH) { From e5bd56e0fce7354d4a10d367874625ac335fdfaf Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Wed, 14 Feb 2018 12:33:58 +0200 Subject: [PATCH 12/42] Enable TCXO always if pin is defined --- SX1276/SX1276_LoRaRadio.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 5e7f7a6760..88901a6f7a 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -196,6 +196,10 @@ SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi, PinName spi_miso, is_murata = false; } + if (tcxo != NC) { + _tcxo = 1; + } + #ifdef MBED_CONF_RTOS_PRESENT irq_thread.start(mbed::callback(this, &SX1276_LoRaRadio::rf_irq_task)); #endif @@ -238,10 +242,7 @@ void SX1276_LoRaRadio::init_radio(radio_events_t *events) // Reset the radio transceiver radio_reset(); - if (is_murata) { - // Only used for bands < 125 kHz, so probably not needed? - _tcxo = 1; - } else { + if (!is_murata) { // Setup radio variant type set_sx1276_variant_type(); } From 247d8a5777060f1bae949b0c554c124bc5102e27 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Thu, 15 Feb 2018 14:27:43 +0200 Subject: [PATCH 13/42] Add TCXO pin for SX1272 Also reformatted constructor params list to more readable format --- SX1272/SX1272_LoRaRadio.cpp | 40 +++++++++++++++++++++++++++---------- SX1272/SX1272_LoRaRadio.h | 26 +++++++++++++++++------- SX1276/SX1276_LoRaRadio.cpp | 36 +++++++++++++++++++++++---------- SX1276/SX1276_LoRaRadio.h | 22 ++++++++++++++------ 4 files changed, 90 insertions(+), 34 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index b2a8c1ef3c..4ebd2ef792 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -163,17 +163,33 @@ static bool RadioIsActive = false; /** * Constructor */ -SX1272_LoRaRadio::SX1272_LoRaRadio(PinName spi_mosi, PinName spi_miso, - PinName spi_sclk, PinName nss, PinName reset, PinName dio0, PinName dio1, - PinName dio2, PinName dio3, PinName dio4, PinName dio5, PinName rf_switch_ctl1, - PinName rf_switch_ctl2, - PinName txctl, PinName rxctl, PinName antswitch, PinName pwr_amp_ctl) +SX1272_LoRaRadio::SX1272_LoRaRadio(PinName spi_mosi, + PinName spi_miso, + PinName spi_sclk, + PinName nss, + PinName reset, + PinName dio0, + PinName dio1, + PinName dio2, + PinName dio3, + PinName dio4, + PinName dio5, + PinName rf_switch_ctl1, + PinName rf_switch_ctl2, + PinName txctl, + PinName rxctl, + PinName antswitch, + PinName pwr_amp_ctl, + PinName tcxo) : _spi(spi_mosi, spi_miso, spi_sclk), - _chip_select(nss, 1), _reset_ctl(reset), - _dio0_ctl(dio0), _dio1_ctl(dio1), _dio2_ctl(dio2), _dio3_ctl(dio3), - _dio4_ctl(dio4), _dio5_ctl(dio5), _rf_switch_ctl1(rf_switch_ctl1, 0), - _rf_switch_ctl2(rf_switch_ctl2, 0),_txctl(txctl, 0), _rxctl(rxctl, 0), - _ant_switch(antswitch, PIN_INPUT, PullUp, 0), _pwr_amp_ctl(pwr_amp_ctl) + _chip_select(nss, 1), + _reset_ctl(reset), + _dio0_ctl(dio0), _dio1_ctl(dio1), _dio2_ctl(dio2), _dio3_ctl(dio3), _dio4_ctl(dio4), _dio5_ctl(dio5), + _rf_switch_ctl1(rf_switch_ctl1, 0), _rf_switch_ctl2(rf_switch_ctl2, 0), _txctl(txctl, 0), _rxctl(rxctl, 0), + _ant_switch(antswitch, PIN_INPUT, PullUp, 0), + _pwr_amp_ctl(pwr_amp_ctl), + _tcxo(tcxo) + #ifdef MBED_CONF_RTOS_PRESENT , irq_thread(osPriorityRealtime, 1024) #endif @@ -190,6 +206,10 @@ SX1272_LoRaRadio::SX1272_LoRaRadio(PinName spi_mosi, PinName spi_miso, _radio_events = NULL; + if (tcxo != NC) { + _tcxo = 1; + } + #ifdef MBED_CONF_RTOS_PRESENT irq_thread.start(mbed::callback(this, &SX1272_LoRaRadio::rf_irq_task)); #endif diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index c3c70107dd..fef418d148 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -55,13 +55,24 @@ public: * The pins that are marked NC are optional. It is assumed that these * pins are not connected until/unless configured otherwise. */ - SX1272_LoRaRadio(PinName mosi, PinName miso, PinName sclk, PinName nss, - PinName reset, PinName dio0, PinName dio1, PinName dio2, - PinName dio3, PinName dio4, PinName dio5, - PinName rf_switch_ctl1=NC, - PinName rf_switch_ctl2=NC, PinName txctl = NC, - PinName rxctl = NC, PinName ant_switch = NC, - PinName pwr_amp_ctl = NC); + SX1272_LoRaRadio(PinName mosi, + PinName miso, + PinName sclk, + PinName nss, + PinName reset, + PinName dio0, + PinName dio1, + PinName dio2, + PinName dio3, + PinName dio4, + PinName dio5, + PinName rf_switch_ctl1 = NC, + PinName rf_switch_ctl2 = NC, + PinName txctl = NC, + PinName rxctl = NC, + PinName ant_switch = NC, + PinName pwr_amp_ctl = NC, + PinName tcxo = NC); /** * Destructor @@ -323,6 +334,7 @@ private: mbed::DigitalOut _rxctl; mbed::DigitalInOut _ant_switch; mbed::DigitalOut _pwr_amp_ctl; + mbed::DigitalOut _tcxo; // Contains all RF control pin names // This storage is needed even after assigning the diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 88901a6f7a..a1689eab2e 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -158,18 +158,32 @@ static uint8_t radio_variant; /** * Constructor */ -SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi, PinName spi_miso, - PinName spi_sclk, PinName nss, PinName reset, PinName dio0, - PinName dio1, PinName dio2, PinName dio3, PinName dio4, - PinName dio5, PinName rf_switch_ctl1, PinName rf_switch_ctl2, - PinName txctl, PinName rxctl, PinName antswitch, - PinName pwr_amp_ctl, PinName tcxo) +SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi, + PinName spi_miso, + PinName spi_sclk, + PinName nss, + PinName reset, + PinName dio0, + PinName dio1, + PinName dio2, + PinName dio3, + PinName dio4, + PinName dio5, + PinName rf_switch_ctl1, + PinName rf_switch_ctl2, + PinName txctl, + PinName rxctl, + PinName antswitch, + PinName pwr_amp_ctl, + PinName tcxo) : _spi(spi_mosi, spi_miso, spi_sclk), - _chip_select(nss, 1), _reset_ctl(reset), - _dio0_ctl(dio0), _dio1_ctl(dio1), _dio2_ctl(dio2), _dio3_ctl(dio3), - _dio4_ctl(dio4), _dio5_ctl(dio5), _rf_switch_ctl1(rf_switch_ctl1, 0), - _rf_switch_ctl2(rf_switch_ctl2, 0),_txctl(txctl, 0), _rxctl(rxctl, 0), - _ant_switch(antswitch, PIN_INPUT, PullUp, 0), _pwr_amp_ctl(pwr_amp_ctl), + _chip_select(nss, 1), + _reset_ctl(reset), + _dio0_ctl(dio0), _dio1_ctl(dio1), _dio2_ctl(dio2), _dio3_ctl(dio3), _dio4_ctl(dio4), _dio5_ctl(dio5), + _rf_switch_ctl1(rf_switch_ctl1, 0), _rf_switch_ctl2(rf_switch_ctl2, 0), + _txctl(txctl, 0), _rxctl(rxctl, 0), + _ant_switch(antswitch, PIN_INPUT, PullUp, 0), + _pwr_amp_ctl(pwr_amp_ctl), _tcxo(tcxo) #ifdef MBED_CONF_RTOS_PRESENT diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index f758c1740a..5f038826e4 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -69,12 +69,22 @@ public: * setting SX1276 radio module gets connected to an external power amplifier * or radio latch controls are connected. */ - SX1276_LoRaRadio(PinName mosi, PinName miso, PinName sclk, PinName nss, - PinName reset, PinName dio0, PinName dio1, PinName dio2, - PinName dio3, PinName dio4, PinName dio5, - PinName rf_switch_ctl1=NC, - PinName rf_switch_ctl2=NC, PinName txctl = NC, - PinName rxctl = NC, PinName ant_switch = NC, + SX1276_LoRaRadio(PinName mosi, + PinName miso, + PinName sclk, + PinName nss, + PinName reset, + PinName dio0, + PinName dio1, + PinName dio2, + PinName dio3, + PinName dio4, + PinName dio5, + PinName rf_switch_ctl1 = NC, + PinName rf_switch_ctl2 = NC, + PinName txctl = NC, + PinName rxctl = NC, + PinName ant_switch = NC, PinName pwr_amp_ctl = NC, PinName tcxo = NC); From 94b11beea518161e4d21aa1f437a4ed1d1cf0f61 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Mon, 19 Feb 2018 13:19:11 +0200 Subject: [PATCH 14/42] Checking for pins being NC before writing NXP Hal provides a write API on DigitalOut::write() that asserts if pin is NC and we try to perform an operation on it. This behaviour is not consistent among various Hals in Mbed-OS. However, we now check the pin ourselves in the driver just like 1276. --- SX1272/SX1272_LoRaRadio.cpp | 45 +++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 4ebd2ef792..fc7635a598 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -158,7 +158,7 @@ static uint8_t radio_variant; /** * Flag used to set the RF switch control pins in low power mode when the radio is not active. */ -static bool RadioIsActive = false; +static bool radio_is_active = false; /** * Constructor @@ -1614,23 +1614,34 @@ void SX1272_LoRaRadio::setup_interrupts() */ void SX1272_LoRaRadio::set_low_power_mode(bool status) { - if( RadioIsActive != status ) - { - RadioIsActive = status; + if (radio_is_active != status) { + radio_is_active = status; - if( status == false ) - { - // Its safe to not check for pin connections here as the write() - // would do nothing if pin is not connected - _rf_switch_ctl1 = 0; - _rf_switch_ctl2 = 0; - _pwr_amp_ctl = 0; - _txctl = 0; - _rxctl = 0; - } - else - { - default_antenna_switch_ctrls( ); + if (status == false) { + if (_rf_ctrls.rf_switch_ctl1 != NC) { + _rf_switch_ctl1 = 0; + } + if (_rf_ctrls.rf_switch_ctl2 != NC) { + _rf_switch_ctl2 = 0; + } + + if (_rf_ctrls.pwr_amp_ctl != NC) { + _pwr_amp_ctl = 0; + } + + if (_rf_ctrls.txctl != NC) { + _txctl = 0; + } + + if (_rf_ctrls.txctl != NC) { + _rxctl = 0; + } + + if (_rf_ctrls.ant_switch != NC) { + _ant_switch = 0; + } + } else { + default_antenna_switch_ctrls(); } } } From 87335ab5e71f52d69936ad2388102df995708a79 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Thu, 8 Mar 2018 14:11:22 +0200 Subject: [PATCH 15/42] Fix IAR compiler warnings preamble_detected and sync_word_detected are uint8_t integer type variables so those should not be compared to (boolean) true/false values. Fixed to use 1 and 0 values instead. --- SX1272/SX1272_LoRaRadio.cpp | 25 ++++++++++++------------- SX1276/SX1276_LoRaRadio.cpp | 26 +++++++++++++------------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index fc7635a598..41aab461f1 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -913,8 +913,8 @@ void SX1272_LoRaRadio::receive(uint32_t timeout) RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT); - _rf_settings.fsk_packet_handler.preamble_detected = false; - _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; _rf_settings.fsk_packet_handler.size = 0; @@ -1754,8 +1754,8 @@ void SX1272_LoRaRadio::handle_dio0_irq() && (_radio_events->rx_error)) { _radio_events->rx_error(); } - _rf_settings.fsk_packet_handler.preamble_detected = false; - _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; _rf_settings.fsk_packet_handler.size = 0; // break from here, a CRC error happened, RX_ERROR @@ -1800,8 +1800,8 @@ void SX1272_LoRaRadio::handle_dio0_irq() _rf_settings.fsk_packet_handler.size, _rf_settings.fsk_packet_handler.rssi_value, 0); } - _rf_settings.fsk_packet_handler.preamble_detected = false; - _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; _rf_settings.fsk_packet_handler.size = 0; break; @@ -1978,13 +1978,13 @@ void SX1272_LoRaRadio::handle_dio2_irq(void) case MODEM_FSK: // DIO4 must have been asserted to set preamble_detected to true - if( ( _rf_settings.fsk_packet_handler.preamble_detected == true ) && ( _rf_settings.fsk_packet_handler.sync_word_detected == false ) ) + if( ( _rf_settings.fsk_packet_handler.preamble_detected == 1 ) && ( _rf_settings.fsk_packet_handler.sync_word_detected == 0 ) ) { if (_rf_settings.fsk.rx_continuous == false) { rx_timeout_sync_word.detach( ); } - _rf_settings.fsk_packet_handler.sync_word_detected = true; + _rf_settings.fsk_packet_handler.sync_word_detected = 1; _rf_settings.fsk_packet_handler.rssi_value = -( read_register( REG_RSSIVALUE ) >> 1 ); @@ -2072,9 +2072,8 @@ void SX1272_LoRaRadio::handle_dio4_irq(void) // is asserted when a preamble is detected (FSK modem only) switch (_rf_settings.modem) { case MODEM_FSK: { - if (_rf_settings.fsk_packet_handler.preamble_detected - == false) { - _rf_settings.fsk_packet_handler.preamble_detected = true; + if (_rf_settings.fsk_packet_handler.preamble_detected == 0) { + _rf_settings.fsk_packet_handler.preamble_detected = 1; } } break; @@ -2105,8 +2104,8 @@ void SX1272_LoRaRadio::handle_timeout_irq() { case RF_RX_RUNNING: if( _rf_settings.modem == MODEM_FSK ) { - _rf_settings.fsk_packet_handler.preamble_detected = false; - _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; _rf_settings.fsk_packet_handler.size = 0; diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index a1689eab2e..cb3d67d737 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -896,8 +896,8 @@ void SX1276_LoRaRadio::receive(uint32_t timeout) | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT); - _rf_settings.fsk_packet_handler.preamble_detected = false; - _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; _rf_settings.fsk_packet_handler.size = 0; @@ -1887,8 +1887,8 @@ void SX1276_LoRaRadio::handle_dio0_irq() && (_radio_events->rx_error)) { _radio_events->rx_error(); } - _rf_settings.fsk_packet_handler.preamble_detected = false; - _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; _rf_settings.fsk_packet_handler.size = 0; // break from here, a CRC error happened, RX_ERROR @@ -1933,8 +1933,8 @@ void SX1276_LoRaRadio::handle_dio0_irq() _rf_settings.fsk_packet_handler.size, _rf_settings.fsk_packet_handler.rssi_value, 0); } - _rf_settings.fsk_packet_handler.preamble_detected = false; - _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; _rf_settings.fsk_packet_handler.size = 0; break; @@ -2133,13 +2133,13 @@ void SX1276_LoRaRadio::handle_dio2_irq(void) switch (_rf_settings.modem) { case MODEM_FSK: // DIO4 must have been asserted to set preamble_detected to true - if ((_rf_settings.fsk_packet_handler.preamble_detected == true) - && (_rf_settings.fsk_packet_handler.sync_word_detected == false)) { + if ((_rf_settings.fsk_packet_handler.preamble_detected == 1) + && (_rf_settings.fsk_packet_handler.sync_word_detected == 0)) { if (_rf_settings.fsk.rx_continuous == false) { rx_timeout_sync_word.detach(); } - _rf_settings.fsk_packet_handler.sync_word_detected = true; + _rf_settings.fsk_packet_handler.sync_word_detected = 1; _rf_settings.fsk_packet_handler.rssi_value = -(read_register(REG_RSSIVALUE) >> 1); @@ -2238,8 +2238,8 @@ void SX1276_LoRaRadio::handle_dio4_irq(void) // is asserted when a preamble is detected (FSK modem only) switch (_rf_settings.modem) { case MODEM_FSK: { - if (_rf_settings.fsk_packet_handler.preamble_detected == false) { - _rf_settings.fsk_packet_handler.preamble_detected = true; + if (_rf_settings.fsk_packet_handler.preamble_detected == 0) { + _rf_settings.fsk_packet_handler.preamble_detected = 1; } } break; @@ -2268,8 +2268,8 @@ void SX1276_LoRaRadio::handle_timeout_irq() switch (_rf_settings.state) { case RF_RX_RUNNING: if (_rf_settings.modem == MODEM_FSK) { - _rf_settings.fsk_packet_handler.preamble_detected = false; - _rf_settings.fsk_packet_handler.sync_word_detected = false; + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; _rf_settings.fsk_packet_handler.size = 0; From c5ee52293fee29aea3479d20e92ca2c1fc1ddaff Mon Sep 17 00:00:00 2001 From: Antti Kauppila Date: Sun, 11 Mar 2018 11:34:27 +0200 Subject: [PATCH 16/42] Added flagging for DEVICE_SPI --- SX1272/SX1272_LoRaRadio.cpp | 8 ++++++++ SX1272/SX1272_LoRaRadio.h | 5 +++++ SX1276/SX1276_LoRaRadio.cpp | 6 ++++++ SX1276/SX1276_LoRaRadio.h | 6 ++++++ 4 files changed, 25 insertions(+) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 41aab461f1..808ae76e9a 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -27,10 +27,13 @@ SPDX-License-Identifier: BSD-3-Clause #include //rint #include #include "mbed.h" + #include "SX1272_LoRaRadio.h" #include "sx1272Regs-Fsk.h" #include "sx1272Regs-LoRa.h" +#ifdef DEVICE_SPI + #if defined(FEATURE_COMMON_PAL) #include "mbed_trace.h" #define TRACE_GROUP "LRAD" @@ -55,6 +58,8 @@ SPDX-License-Identifier: BSD-3-Clause #define XTAL_FREQ 32000000 #define FREQ_STEP 61.03515625 + + enum RadioVariant { SX1272MB2XAS = 0, SX1272MB1DCS @@ -2165,3 +2170,6 @@ void SX1272_LoRaRadio::handle_timeout_irq() break; } } + +#endif //DEVICE_SPI + diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index fef418d148..ca8ae21022 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -32,11 +32,14 @@ SPDX-License-Identifier: BSD-3-Clause #include "DigitalInOut.h" #include "SPI.h" #include "Timeout.h" +#include "platform/PlatformMutex.h" #ifdef MBED_CONF_RTOS_PRESENT #include "rtos/Thread.h" #endif + #include "lorawan/LoRaRadio.h" +#ifdef DEVICE_SPI #ifdef MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE #define MAX_DATA_BUFFER_SIZE_SX172 MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE @@ -416,4 +419,6 @@ private: void handle_timeout_irq(); }; +#endif //DEVICE_SPI + #endif /* SX1272_LORARADIO_H_ */ diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index cb3d67d737..b1fd0916dd 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -30,6 +30,8 @@ SPDX-License-Identifier: BSD-3-Clause #include "sx1276Regs-Fsk.h" #include "sx1276Regs-LoRa.h" +#ifdef DEVICE_SPI + /*! * Sync word for Private LoRa networks */ @@ -55,6 +57,7 @@ SPDX-License-Identifier: BSD-3-Clause #define RSSI_OFFSET_HF -157.0 #define RF_MID_BAND_THRESH 525000000 + /*! * FSK bandwidth definition */ @@ -2330,3 +2333,6 @@ void SX1276_LoRaRadio::handle_timeout_irq() } } // EOF + +#endif //DEVICE_SPI + diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index 5f038826e4..3f3e442729 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -32,9 +32,11 @@ SPDX-License-Identifier: BSD-3-Clause #include "DigitalInOut.h" #include "SPI.h" #include "Timeout.h" +#include "platform/PlatformMutex.h" #ifdef MBED_CONF_RTOS_PRESENT #include "rtos/Thread.h" #endif + #include "lorawan/LoRaRadio.h" #ifdef MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE @@ -43,6 +45,8 @@ SPDX-License-Identifier: BSD-3-Clause #define MAX_DATA_BUFFER_SIZE_SX1276 256 #endif +#ifdef DEVICE_SPI + /** * Radio driver implementation for Semtech SX1272 plus variants. * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. @@ -434,4 +438,6 @@ private: void handle_timeout_irq(); }; +#endif //DEVICE_SPI + #endif // SX1276_LORARADIO_H_ From a8fef8fbeef14839d6eb624a0403043a6f3bd305 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Wed, 11 Apr 2018 09:21:49 +0300 Subject: [PATCH 17/42] Remove product specific variables and target flags Since variant detection is using ant_switch pin, it is now only used if that pin has been connected. Otherwise generic variant code is used. --- SX1272/SX1272_LoRaRadio.cpp | 33 +++++++++++++----------- SX1276/SX1276_LoRaRadio.cpp | 50 ++++++++++++++++--------------------- SX1276/SX1276_LoRaRadio.h | 3 --- 3 files changed, 39 insertions(+), 47 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 808ae76e9a..82f6f3b280 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -61,7 +61,8 @@ SPDX-License-Identifier: BSD-3-Clause enum RadioVariant { - SX1272MB2XAS = 0, + SX1272UNDEFINED = 0, + SX1272MB2XAS, SX1272MB1DCS }; @@ -1369,15 +1370,13 @@ void SX1272_LoRaRadio::default_antenna_switch_ctrls() */ uint8_t SX1272_LoRaRadio::get_pa_conf_reg() { - -#if defined(TARGET_MTS_MDOT_F411RE) || defined(TARGET_XDOT_L151CC) || defined(TARGET_MTB_MTS_XDOT) - return RF_PACONFIG_PASELECT_PABOOST; -#endif - if (radio_variant == SX1272MB1DCS) { + if (radio_variant == SX1272UNDEFINED) { return RF_PACONFIG_PASELECT_PABOOST; + } else if (radio_variant == SX1272MB1DCS) { + return RF_PACONFIG_PASELECT_PABOOST; + } else { + return RF_PACONFIG_PASELECT_RFO; } - - return RF_PACONFIG_PASELECT_RFO; } /** @@ -1488,15 +1487,19 @@ void SX1272_LoRaRadio::setup_registers() */ void SX1272_LoRaRadio::set_sx1272_variant_type() { - _ant_switch.input(); - wait_ms(1); - if (_ant_switch == 1) { - radio_variant = SX1272MB1DCS; + if (_rf_ctrls.ant_switch != NC){ + _ant_switch.input(); + wait_ms(1); + if (_ant_switch == 1) { + radio_variant = SX1272MB1DCS; + } else { + radio_variant = SX1272MB2XAS; + } + _ant_switch.output(); + wait_ms(1); } else { - radio_variant = SX1272MB2XAS; + radio_variant = SX1272UNDEFINED; } - _ant_switch.output(); - wait_ms(1); } /** diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index b1fd0916dd..ab03264776 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -146,7 +146,8 @@ static const fsk_bw_t fsk_bandwidths[] = static const radio_registers_t radio_reg_init[] = RADIO_INIT_REGISTERS_VALUE; enum RadioVariant { - SX1276MB1LAS = 0, + SX1276UNDEFINED = 0, + SX1276MB1LAS, SX1276MB1MAS }; @@ -206,13 +207,6 @@ SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi, _radio_events = NULL; - // Detect Murata based on pin configuration - if (pwr_amp_ctl != NC && txctl != NC && rxctl != NC && tcxo != NC) { - is_murata = true; - } else { - is_murata = false; - } - if (tcxo != NC) { _tcxo = 1; } @@ -259,10 +253,8 @@ void SX1276_LoRaRadio::init_radio(radio_events_t *events) // Reset the radio transceiver radio_reset(); - if (!is_murata) { - // Setup radio variant type - set_sx1276_variant_type(); - } + // Setup radio variant type + set_sx1276_variant_type(); // setup SPI frequency // default is 8MHz although, configurable through @@ -1356,15 +1348,19 @@ void SX1276_LoRaRadio::set_modem(uint8_t modem ) */ void SX1276_LoRaRadio::set_sx1276_variant_type() { - _ant_switch.input(); - wait_ms(1); - if (_ant_switch == 1) { - radio_variant = SX1276MB1LAS; + if (_rf_ctrls.ant_switch != NC) { + _ant_switch.input(); + wait_ms(1); + if (_ant_switch == 1) { + radio_variant = SX1276MB1LAS; + } else { + radio_variant = SX1276MB1MAS; + } + _ant_switch.output(); + wait_ms(1); } else { - radio_variant = SX1276MB1MAS; + radio_variant = SX1276UNDEFINED; } - _ant_switch.output(); - wait_ms(1); } /** @@ -1472,11 +1468,10 @@ uint8_t SX1276_LoRaRadio::get_fsk_bw_reg_val(uint32_t bandwidth) uint8_t SX1276_LoRaRadio::get_pa_conf_reg(uint32_t channel) { -#if TARGET_MTB_ADV_WISE_1510 - return RF_PACONFIG_PASELECT_PABOOST; -#else - if (channel > RF_MID_BAND_THRESH) { - if (radio_variant == SX1276MB1LAS || is_murata) { + if (radio_variant == SX1276UNDEFINED) { + return RF_PACONFIG_PASELECT_PABOOST; + } else if (channel > RF_MID_BAND_THRESH) { + if (radio_variant == SX1276MB1LAS) { return RF_PACONFIG_PASELECT_PABOOST; } else { return RF_PACONFIG_PASELECT_RFO; @@ -1484,7 +1479,6 @@ uint8_t SX1276_LoRaRadio::get_pa_conf_reg(uint32_t channel) } else { return RF_PACONFIG_PASELECT_RFO; } -#endif } /** @@ -1719,8 +1713,7 @@ void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode) if (_rf_ctrls.txctl != NC && _rf_ctrls.rxctl != NC) { // module is in transmit mode and tx/rx submodule control // pins are connected - if (is_murata) - { + if (_rf_ctrls.pwr_amp_ctl != NC) { if (read_register(REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST) { _pwr_amp_ctl = 1; _txctl = 0; @@ -1728,8 +1721,7 @@ void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode) _pwr_amp_ctl = 0; _txctl = 1; } - } else - { + } else { _txctl = 1; } _rxctl = 0; diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index 3f3e442729..fbcf69d9d8 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -390,9 +390,6 @@ private: // Access protection PlatformMutex mutex; - // Murata board - bool is_murata; - // helper functions void setup_registers(); void default_antenna_switch_ctrls(); From 4691c37c6b2d0d4a013a0659f5770022e69a3c4a Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Thu, 19 Apr 2018 11:53:07 +0300 Subject: [PATCH 18/42] Change static variables to class members Some variables were still defind as static in sources but as drivers are now C++ classes, these variables should be members of the class. --- SX1272/SX1272_LoRaRadio.cpp | 10 +++------- SX1272/SX1272_LoRaRadio.h | 7 +++++++ SX1276/SX1276_LoRaRadio.cpp | 6 +----- SX1276/SX1276_LoRaRadio.h | 2 ++ 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 82f6f3b280..511a668eea 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -80,7 +80,7 @@ typedef struct */ typedef struct { - modem_type modem; + modem_type modem; uint8_t addr; uint8_t value; } radio_registers_t; @@ -159,12 +159,6 @@ const fsk_bw_t fsk_bandwidths[] = */ static const radio_registers_t radio_reg_init[] = RADIO_INIT_REGISTERS_VALUE; -static uint8_t radio_variant; - -/** - * Flag used to set the RF switch control pins in low power mode when the radio is not active. - */ -static bool radio_is_active = false; /** * Constructor @@ -216,6 +210,8 @@ SX1272_LoRaRadio::SX1272_LoRaRadio(PinName spi_mosi, _tcxo = 1; } + radio_is_active = false; + #ifdef MBED_CONF_RTOS_PRESENT irq_thread.start(mbed::callback(this, &SX1272_LoRaRadio::rf_irq_task)); #endif diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index ca8ae21022..9e2538550f 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -375,6 +375,13 @@ private: // Access protection PlatformMutex mutex; + uint8_t radio_variant; + + /** + * Flag used to set the RF switch control pins in low power mode when the radio is not active. + */ + bool radio_is_active; + // helper functions void setup_registers(); void default_antenna_switch_ctrls(); diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index ab03264776..0151f8c643 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -48,8 +48,6 @@ SPDX-License-Identifier: BSD-3-Clause #define XTAL_FREQ 32000000 #define FREQ_STEP 61.03515625 -#define RX_BUFFER_SIZE 256 - /*! * Constant values need to compute the RSSI value */ @@ -72,7 +70,7 @@ typedef struct */ typedef struct { - uint8_t modem; + uint8_t modem; uint8_t addr; uint8_t value; } radio_registers_t; @@ -157,8 +155,6 @@ enum RadioVariant { #define SPI_FREQUENCY 8000000 #endif -static uint8_t radio_variant; - /** * Constructor */ diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index fbcf69d9d8..d4216b2b24 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -390,6 +390,8 @@ private: // Access protection PlatformMutex mutex; + uint8_t radio_variant; + // helper functions void setup_registers(); void default_antenna_switch_ctrls(); From ab8b6915dee22a35bbcee38c3c9a63872af02487 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Mon, 14 May 2018 10:51:45 +0300 Subject: [PATCH 19/42] Remove usage of DEVICE_SPI flag DEVICE_SPI flag is no longer needed as our CI only builds mbed-os-example-lorawan to targets which really have lora hw. --- SX1272/SX1272_LoRaRadio.cpp | 5 ----- SX1272/SX1272_LoRaRadio.h | 4 ---- SX1276/SX1276_LoRaRadio.cpp | 5 ----- SX1276/SX1276_LoRaRadio.h | 4 ---- 4 files changed, 18 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 511a668eea..aa7c713c0d 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -32,8 +32,6 @@ SPDX-License-Identifier: BSD-3-Clause #include "sx1272Regs-Fsk.h" #include "sx1272Regs-LoRa.h" -#ifdef DEVICE_SPI - #if defined(FEATURE_COMMON_PAL) #include "mbed_trace.h" #define TRACE_GROUP "LRAD" @@ -2169,6 +2167,3 @@ void SX1272_LoRaRadio::handle_timeout_irq() break; } } - -#endif //DEVICE_SPI - diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index 9e2538550f..12d5cd40ea 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -39,8 +39,6 @@ SPDX-License-Identifier: BSD-3-Clause #include "lorawan/LoRaRadio.h" -#ifdef DEVICE_SPI - #ifdef MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE #define MAX_DATA_BUFFER_SIZE_SX172 MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE #else @@ -426,6 +424,4 @@ private: void handle_timeout_irq(); }; -#endif //DEVICE_SPI - #endif /* SX1272_LORARADIO_H_ */ diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 0151f8c643..09cdad760b 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -30,8 +30,6 @@ SPDX-License-Identifier: BSD-3-Clause #include "sx1276Regs-Fsk.h" #include "sx1276Regs-LoRa.h" -#ifdef DEVICE_SPI - /*! * Sync word for Private LoRa networks */ @@ -2321,6 +2319,3 @@ void SX1276_LoRaRadio::handle_timeout_irq() } } // EOF - -#endif //DEVICE_SPI - diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index d4216b2b24..6c48106826 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -45,8 +45,6 @@ SPDX-License-Identifier: BSD-3-Clause #define MAX_DATA_BUFFER_SIZE_SX1276 256 #endif -#ifdef DEVICE_SPI - /** * Radio driver implementation for Semtech SX1272 plus variants. * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. @@ -437,6 +435,4 @@ private: void handle_timeout_irq(); }; -#endif //DEVICE_SPI - #endif // SX1276_LORARADIO_H_ From 4982a156a4a604d365c25ea10c1eda10cfbc423d Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Tue, 15 May 2018 14:46:02 +0300 Subject: [PATCH 20/42] Remove obsolete FEATURE_COMMON_PAL flag mbed-trace no longer requires COMMON_PAL. --- SX1272/SX1272_LoRaRadio.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index aa7c713c0d..cb7b4aa6ca 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -32,15 +32,6 @@ SPDX-License-Identifier: BSD-3-Clause #include "sx1272Regs-Fsk.h" #include "sx1272Regs-LoRa.h" -#if defined(FEATURE_COMMON_PAL) -#include "mbed_trace.h" -#define TRACE_GROUP "LRAD" -#else -#define tr_debug(...) (void(0)) //dummies if feature common pal is not added -#define tr_info(...) (void(0)) //dummies if feature common pal is not added -#define tr_error(...) (void(0)) //dummies if feature common pal is not added -#endif //defined(FEATURE_COMMON_PAL) - #ifdef MBED_SX1272_LORA_RADIO_SPI_FREQUENCY #define SPI_FREQUENCY MBED_SX1272_LORA_RADIO_SPI_FREQUENCY #else From c4dd25eec9ae30f9532e498ea7e2cacd758c733e Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Fri, 18 May 2018 08:55:32 +0300 Subject: [PATCH 21/42] Fix correct pin check for rxctl Fixes issue #20 --- SX1272/SX1272_LoRaRadio.cpp | 2 +- SX1276/SX1276_LoRaRadio.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index cb7b4aa6ca..d7d9a41377 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -1626,7 +1626,7 @@ void SX1272_LoRaRadio::set_low_power_mode(bool status) _txctl = 0; } - if (_rf_ctrls.txctl != NC) { + if (_rf_ctrls.rxctl != NC) { _rxctl = 0; } diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 09cdad760b..227838e962 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -1653,7 +1653,7 @@ void SX1276_LoRaRadio::set_low_power_mode() _txctl = 0; } - if (_rf_ctrls.txctl != NC) { + if (_rf_ctrls.rxctl != NC) { _rxctl = 0; } From 70908415fcd83c3aba1b7bcd64693d85fcd1791d Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 15 Jun 2018 15:03:20 +0300 Subject: [PATCH 22/42] Removing software RX timeouts in RX chain Both in FSK and LoRa mode, we do not rely on software timers anymore. This makes our timing precise and enables us to consume less power. It also gives us flexibility which we need for future deep sleep venture as Mbed OS timeout class may lock the sleep manager if not using low power timers. --- SX1272/SX1272_LoRaRadio.cpp | 97 ++++++++---------- SX1272/SX1272_LoRaRadio.h | 9 +- SX1276/SX1276_LoRaRadio.cpp | 190 ++++++++++++++---------------------- SX1276/SX1276_LoRaRadio.h | 9 +- 4 files changed, 122 insertions(+), 183 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index d7d9a41377..a7b160f46b 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -306,7 +306,6 @@ void SX1272_LoRaRadio::sleep() { // stop timers tx_timeout_timer.detach(); - rx_timeout_timer.detach(); // put module in sleep mode set_operation_mode(RF_OPMODE_SLEEP); @@ -415,8 +414,7 @@ void SX1272_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, _rf_settings.fsk.iq_inverted = iq_inverted; _rf_settings.fsk.rx_continuous = rx_continuous; _rf_settings.fsk.preamble_len = preamble_len; - _rf_settings.fsk.rx_single_timeout = - symb_timeout * ((1.0 / (double) datarate) * 8.0) * 1e3; + _rf_settings.fsk.rx_single_timeout = (symb_timeout + 1) / 2; // dividing by 2 as our detector size is 2 symbols (16 bytes) datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8)); @@ -867,19 +865,13 @@ void SX1272_LoRaRadio::transmit(uint32_t timeout) * and finally a DIO0 interrupt let's the state machine know that a packet is * ready to be read from the FIFO */ -void SX1272_LoRaRadio::receive(uint32_t timeout) +void SX1272_LoRaRadio::receive(uint32_t) { switch (_rf_settings.modem) { case MODEM_FSK: - if (timeout == 0 && _rf_settings.fsk.rx_continuous == false) { - // user messed up probably timeout was 0 but mode was not - // continuous, force it to be continuous - _rf_settings.fsk.rx_continuous = true; - } - // DIO0=PayloadReady // DIO1=FifoLevel - // DIO2=SyncAddr + // DIO2=RxTimeout // DIO3=FifoEmpty // DIO4=Preamble // DIO5=ModeReady @@ -889,7 +881,7 @@ void SX1272_LoRaRadio::receive(uint32_t timeout) RF_DIOMAPPING1_DIO2_MASK) | RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | - RF_DIOMAPPING1_DIO2_11); + RF_DIOMAPPING1_DIO2_10); write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) & RF_DIOMAPPING2_DIO4_MASK & @@ -904,6 +896,11 @@ void SX1272_LoRaRadio::receive(uint32_t timeout) RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT); + write_to_register(REG_RXTIMEOUT2, _rf_settings.fsk.rx_single_timeout <= 255 ? + _rf_settings.fsk.rx_single_timeout : 255); + write_to_register(REG_RXTIMEOUT3, 0x00); + write_to_register(REG_RXTIMEOUT1, 0x00); + _rf_settings.fsk_packet_handler.preamble_detected = 0; _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; @@ -912,11 +909,6 @@ void SX1272_LoRaRadio::receive(uint32_t timeout) break; case MODEM_LORA: - if (timeout == 0 && _rf_settings.lora.rx_continuous == false) { - // user messed up probably timeout was 0 but mode was not - // continuous, force it to be continuous - _rf_settings.lora.rx_continuous = true; - } if (_rf_settings.lora.iq_inverted == true) { write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) & @@ -971,21 +963,8 @@ void SX1272_LoRaRadio::receive(uint32_t timeout) _rf_settings.state = RF_RX_RUNNING; - if (timeout != 0) { - rx_timeout_timer.attach_us(callback(this, - &SX1272_LoRaRadio::timeout_irq_isr), - timeout*1e3); - } - if (_rf_settings.modem == MODEM_FSK) { set_operation_mode(RF_OPMODE_RECEIVER); - - if (_rf_settings.fsk.rx_continuous == false) { - rx_timeout_sync_word.attach_us(callback(this, - &SX1272_LoRaRadio::timeout_irq_isr), - _rf_settings.fsk.rx_single_timeout * 1e3); - } - return; } @@ -1144,8 +1123,6 @@ void SX1272_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, void SX1272_LoRaRadio::standby( void ) { tx_timeout_timer.detach(); - rx_timeout_timer.detach(); - set_operation_mode(RF_OPMODE_STANDBY); _rf_settings.state = RF_IDLE; } @@ -1732,7 +1709,6 @@ void SX1272_LoRaRadio::handle_dio0_irq() if (_rf_settings.fsk.rx_continuous == false) { - rx_timeout_sync_word.detach(); _rf_settings.state = RF_IDLE; } else { // Continuous mode restart Rx chain @@ -1741,8 +1717,6 @@ void SX1272_LoRaRadio::handle_dio0_irq() RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); } - rx_timeout_timer.detach(); - if ((_radio_events != NULL) && (_radio_events->rx_error)) { _radio_events->rx_error(); @@ -1757,6 +1731,15 @@ void SX1272_LoRaRadio::handle_dio0_irq() } } + // This block was moved from dio2_handler. + // We can have a snapshot of RSSI here as at this point it + // should be more smoothed out. + _rf_settings.fsk_packet_handler.rssi_value = -(read_register(REG_RSSIVALUE) >> 1); + _rf_settings.fsk_packet_handler.afc_value = (int32_t)(double)(((uint16_t)read_register(REG_AFCMSB) << 8) | + (uint16_t)read_register(REG_AFCLSB)) * + (double)FREQ_STEP; + _rf_settings.fsk_packet_handler.rx_gain = (read_register(REG_LNA) >> 5) & 0x07; + // Read received packet size if ((_rf_settings.fsk_packet_handler.size == 0) && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) { @@ -1778,15 +1761,12 @@ void SX1272_LoRaRadio::handle_dio0_irq() if (_rf_settings.fsk.rx_continuous == false) { _rf_settings.state = RF_IDLE; - rx_timeout_sync_word.detach(); } else { // Continuous mode restart Rx chain write_to_register(REG_RXCONFIG, read_register(REG_RXCONFIG) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); } - rx_timeout_timer.detach(); - if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done( _data_buffer, @@ -1814,7 +1794,6 @@ void SX1272_LoRaRadio::handle_dio0_irq() if (_rf_settings.lora.rx_continuous == false) { _rf_settings.state = RF_IDLE; } - rx_timeout_timer.detach(); if ((_radio_events != NULL) && (_radio_events->rx_error)) { @@ -1849,7 +1828,6 @@ void SX1272_LoRaRadio::handle_dio0_irq() if (_rf_settings.lora.rx_continuous == false) { _rf_settings.state = RF_IDLE; } - rx_timeout_timer.detach(); if ((_radio_events != NULL) && (_radio_events->rx_done)) { @@ -1923,7 +1901,6 @@ void SX1272_LoRaRadio::handle_dio1_irq() break; case MODEM_LORA: // Sync time out - rx_timeout_timer.detach( ); _rf_settings.state = RF_IDLE; if ((_radio_events != NULL) && (_radio_events->rx_timeout)) { _radio_events->rx_timeout(); @@ -1969,23 +1946,33 @@ void SX1272_LoRaRadio::handle_dio2_irq(void) switch( _rf_settings.modem ) { case MODEM_FSK: + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; - // DIO4 must have been asserted to set preamble_detected to true - if( ( _rf_settings.fsk_packet_handler.preamble_detected == 1 ) && ( _rf_settings.fsk_packet_handler.sync_word_detected == 0 ) ) - { - if (_rf_settings.fsk.rx_continuous == false) { - rx_timeout_sync_word.detach( ); - } + // Clear Irqs + write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | + RF_IRQFLAGS1_PREAMBLEDETECT | + RF_IRQFLAGS1_SYNCADDRESSMATCH | + RF_IRQFLAGS1_TIMEOUT); - _rf_settings.fsk_packet_handler.sync_word_detected = 1; + write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); - _rf_settings.fsk_packet_handler.rssi_value = -( read_register( REG_RSSIVALUE ) >> 1 ); - - _rf_settings.fsk_packet_handler.afc_value = ( int32_t )( double )( ( ( uint16_t )read_register( REG_AFCMSB ) << 8 ) | - ( uint16_t )read_register( REG_AFCLSB ) ) * - ( double )FREQ_STEP; - _rf_settings.fsk_packet_handler.rx_gain = ( read_register( REG_LNA ) >> 5 ) & 0x07; + if (_rf_settings.fsk.rx_continuous == true) { + // Continuous mode restart Rx chain + write_to_register( REG_RXCONFIG, + read_register(REG_RXCONFIG) | + RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + } else { + _rf_settings.state = RF_IDLE; } + + if ((_radio_events != NULL) + && (_radio_events->rx_timeout)) { + _radio_events->rx_timeout(); + } + break; case MODEM_LORA: if( _rf_settings.lora.freq_hop_on == true ) @@ -2117,8 +2104,6 @@ void SX1272_LoRaRadio::handle_timeout_irq() else { _rf_settings.state = RF_IDLE; - rx_timeout_sync_word.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr), - _rf_settings.fsk.rx_single_timeout * 1e3); } } diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index 12d5cd40ea..748eacf638 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -203,7 +203,7 @@ public: * @param timeout Reception timeout [ms] * */ - virtual void receive(uint32_t timeout); + virtual void receive(uint32_t /**timeout**/); /** * Sets the carrier frequency @@ -360,10 +360,11 @@ private: // Default is 256 bytes uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX172]; - // TX/RX Timers - all use milisecond units + // TX timer in ms. This timer is used as a fail safe for TX. + // If the chip fails to transmit, its a fatal error, reflecting + // some catastrophic bus failure etc. We wish to have the control + // back from the driver in such a case. mbed::Timeout tx_timeout_timer; - mbed::Timeout rx_timeout_timer; - mbed::Timeout rx_timeout_sync_word; #ifdef MBED_CONF_RTOS_PRESENT // Thread to handle interrupts diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 227838e962..113124a7a0 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -337,7 +337,7 @@ uint32_t SX1276_LoRaRadio::random( void ) set_modem( MODEM_LORA ); // Disable LoRa modem interrupts - write_to_register( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | + write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | RFLR_IRQFLAGS_RXDONE | RFLR_IRQFLAGS_PAYLOADCRCERROR | RFLR_IRQFLAGS_VALIDHEADER | @@ -387,8 +387,7 @@ void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, _rf_settings.fsk.iq_inverted = iq_inverted; _rf_settings.fsk.rx_continuous = rx_continuous; _rf_settings.fsk.preamble_len = preamble_len; - _rf_settings.fsk.rx_single_timeout = symb_timeout - * ((1.0 / (double) datarate) * 8.0) * 1e3; + _rf_settings.fsk.rx_single_timeout = (symb_timeout + 1) / 2; // dividing by 2 as our detector size is 2 symbols (16 bytes) datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8)); @@ -397,8 +396,7 @@ void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, write_to_register(REG_RXBW, get_fsk_bw_reg_val(bandwidth)); write_to_register(REG_AFCBW, get_fsk_bw_reg_val(bandwidth_afc)); - write_to_register(REG_PREAMBLEMSB, - (uint8_t) ((preamble_len >> 8) & 0xFF)); + write_to_register(REG_PREAMBLEMSB, (uint8_t) ((preamble_len >> 8) & 0xFF)); write_to_register(REG_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF)); if (fix_len == 1) { @@ -823,7 +821,6 @@ void SX1276_LoRaRadio::sleep() { // stop timers tx_timeout_timer.detach(); - rx_timeout_timer.detach(); // put module in sleep mode set_operation_mode(RF_OPMODE_SLEEP); @@ -835,7 +832,6 @@ void SX1276_LoRaRadio::sleep() void SX1276_LoRaRadio::standby( void ) { tx_timeout_timer.detach(); - rx_timeout_timer.detach(); set_operation_mode(RF_OPMODE_STANDBY); _rf_settings.state = RF_IDLE; @@ -848,29 +844,24 @@ void SX1276_LoRaRadio::standby( void ) * and finally a DIO0 interrupt let's the state machine know that a packet is * ready to be read from the FIFO */ -void SX1276_LoRaRadio::receive(uint32_t timeout) +void SX1276_LoRaRadio::receive(uint32_t) { switch (_rf_settings.modem) { case MODEM_FSK: - if (timeout == 0 && _rf_settings.fsk.rx_continuous == false) { - // user messed up probably timeout was 0 but mode was not - // continuous, force it to be continuous - _rf_settings.fsk.rx_continuous = true; - } - // DIO0=PayloadReady + // DIO0=PayloadReady/PacketSent // DIO1=FifoLevel - // DIO2=SyncAddr - // DIO3=FifoEmpty - // DIO4=Preamble - // DIO5=ModeReady + // DIO2=RxTimeout + // DIO3=FifoEmpty? + // DIO4=PreambleDetect + // DIO5=ModeReady? write_to_register(REG_DIOMAPPING1, (read_register( REG_DIOMAPPING1) & RF_DIOMAPPING1_DIO0_MASK & RF_DIOMAPPING1_DIO1_MASK & RF_DIOMAPPING1_DIO2_MASK) | RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 - | RF_DIOMAPPING1_DIO2_11); + | RF_DIOMAPPING1_DIO2_10); write_to_register(REG_DIOMAPPING2, (read_register( REG_DIOMAPPING2) & RF_DIOMAPPING2_DIO4_MASK @@ -885,6 +876,13 @@ void SX1276_LoRaRadio::receive(uint32_t timeout) | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT); + if (!_rf_settings.fsk.rx_continuous) { + write_to_register(REG_RXTIMEOUT2, _rf_settings.fsk.rx_single_timeout <= 255 ? + _rf_settings.fsk.rx_single_timeout : 255); + write_to_register(REG_RXTIMEOUT3, 0x00); + write_to_register(REG_RXTIMEOUT1, 0x00); + } + _rf_settings.fsk_packet_handler.preamble_detected = 0; _rf_settings.fsk_packet_handler.sync_word_detected = 0; _rf_settings.fsk_packet_handler.nb_bytes = 0; @@ -893,11 +891,7 @@ void SX1276_LoRaRadio::receive(uint32_t timeout) break; case MODEM_LORA: - if (timeout == 0 && _rf_settings.lora.rx_continuous == false) { - // user messed up probably timeout was 0 but mode was not - // continuous, force it to be continuous - _rf_settings.lora.rx_continuous = true; - } + if (_rf_settings.lora.iq_inverted == true) { write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) @@ -989,21 +983,8 @@ void SX1276_LoRaRadio::receive(uint32_t timeout) _rf_settings.state = RF_RX_RUNNING; - if (timeout != 0) { - rx_timeout_timer.attach_us( - callback(this, &SX1276_LoRaRadio::timeout_irq_isr), - timeout * 1e3); - } - if (_rf_settings.modem == MODEM_FSK) { set_operation_mode(RF_OPMODE_RECEIVER); - - if (_rf_settings.fsk.rx_continuous == false) { - rx_timeout_sync_word.attach_us( - callback(this, &SX1276_LoRaRadio::timeout_irq_isr), - _rf_settings.fsk.rx_single_timeout * 1e3); - } - return; } @@ -1859,9 +1840,7 @@ void SX1276_LoRaRadio::handle_dio0_irq() RF_IRQFLAGS1_SYNCADDRESSMATCH); write_to_register(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); - if (_rf_settings.fsk.rx_continuous == false) { - rx_timeout_sync_word.detach(); _rf_settings.state = RF_IDLE; } else { // Continuous mode restart Rx chain @@ -1870,8 +1849,6 @@ void SX1276_LoRaRadio::handle_dio0_irq() RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); } - rx_timeout_timer.detach(); - if ((_radio_events != NULL) && (_radio_events->rx_error)) { _radio_events->rx_error(); @@ -1886,6 +1863,19 @@ void SX1276_LoRaRadio::handle_dio0_irq() } } + // This block was moved from dio2_handler. + // We can have a snapshot of RSSI here as at this point it + // should be more smoothed out. + _rf_settings.fsk_packet_handler.rssi_value = + -(read_register(REG_RSSIVALUE) >> 1); + + _rf_settings.fsk_packet_handler.afc_value = + (int32_t) (double) (((uint16_t) read_register(REG_AFCMSB) << 8) + | (uint16_t) read_register( REG_AFCLSB)) + * (double) FREQ_STEP; + _rf_settings.fsk_packet_handler.rx_gain = + (read_register( REG_LNA) >> 5) & 0x07; + // Read received packet size if ((_rf_settings.fsk_packet_handler.size == 0) && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) { @@ -1907,15 +1897,12 @@ void SX1276_LoRaRadio::handle_dio0_irq() if (_rf_settings.fsk.rx_continuous == false) { _rf_settings.state = RF_IDLE; - rx_timeout_sync_word.detach(); } else { // Continuous mode restart Rx chain write_to_register(REG_RXCONFIG, read_register(REG_RXCONFIG) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); } - rx_timeout_timer.detach(); - if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done( _data_buffer, @@ -1943,7 +1930,6 @@ void SX1276_LoRaRadio::handle_dio0_irq() if (_rf_settings.lora.rx_continuous == false) { _rf_settings.state = RF_IDLE; } - rx_timeout_timer.detach(); if ((_radio_events != NULL) && (_radio_events->rx_error)) { @@ -1992,7 +1978,6 @@ void SX1276_LoRaRadio::handle_dio0_irq() if (_rf_settings.lora.rx_continuous == false) { _rf_settings.state = RF_IDLE; } - rx_timeout_timer.detach(); if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done(_data_buffer, @@ -2066,8 +2051,6 @@ void SX1276_LoRaRadio::handle_dio1_irq() break; case MODEM_LORA: - // Sync time out - rx_timeout_timer.detach(); // Clear Irq write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT); _rf_settings.state = RF_IDLE; @@ -2121,25 +2104,31 @@ void SX1276_LoRaRadio::handle_dio2_irq(void) case RF_RX_RUNNING: switch (_rf_settings.modem) { case MODEM_FSK: - // DIO4 must have been asserted to set preamble_detected to true - if ((_rf_settings.fsk_packet_handler.preamble_detected == 1) - && (_rf_settings.fsk_packet_handler.sync_word_detected == 0)) { - if (_rf_settings.fsk.rx_continuous == false) { - rx_timeout_sync_word.detach(); - } + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; - _rf_settings.fsk_packet_handler.sync_word_detected = 1; + // Clear Irqs + write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | + RF_IRQFLAGS1_PREAMBLEDETECT | + RF_IRQFLAGS1_SYNCADDRESSMATCH | + RF_IRQFLAGS1_TIMEOUT); - _rf_settings.fsk_packet_handler.rssi_value = - -(read_register(REG_RSSIVALUE) >> 1); + write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); - _rf_settings.fsk_packet_handler.afc_value = - (int32_t) (double) (((uint16_t) read_register( - REG_AFCMSB) << 8) - | (uint16_t) read_register( REG_AFCLSB)) - * (double) FREQ_STEP; - _rf_settings.fsk_packet_handler.rx_gain = - (read_register( REG_LNA) >> 5) & 0x07; + if (_rf_settings.fsk.rx_continuous == true) { + // Continuous mode restart Rx chain + write_to_register( REG_RXCONFIG, + read_register(REG_RXCONFIG) | + RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + } else { + _rf_settings.state = RF_IDLE; + } + + if ((_radio_events != NULL) + && (_radio_events->rx_timeout)) { + _radio_events->rx_timeout(); } break; @@ -2254,68 +2243,31 @@ void SX1276_LoRaRadio::handle_dio5_irq() void SX1276_LoRaRadio::handle_timeout_irq() { - switch (_rf_settings.state) { - case RF_RX_RUNNING: - if (_rf_settings.modem == MODEM_FSK) { - _rf_settings.fsk_packet_handler.preamble_detected = 0; - _rf_settings.fsk_packet_handler.sync_word_detected = 0; - _rf_settings.fsk_packet_handler.nb_bytes = 0; - _rf_settings.fsk_packet_handler.size = 0; + if (_rf_settings.state == RF_TX_RUNNING) { + // Tx timeout shouldn't happen. + // But it has been observed that when it happens it is a result of a + // corrupted SPI transfer + // The workaround is to put the radio in a known state. + // Thus, we re-initialize it. - // Clear Irqs - write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | - RF_IRQFLAGS1_PREAMBLEDETECT | - RF_IRQFLAGS1_SYNCADDRESSMATCH); - write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); + // Reset the radio + radio_reset(); - if (_rf_settings.fsk.rx_continuous == true) { - // Continuous mode restart Rx chain - write_to_register( REG_RXCONFIG, - read_register(REG_RXCONFIG) | - RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); - } else { - _rf_settings.state = RF_IDLE; - rx_timeout_sync_word.attach_us( - callback(this, &SX1276_LoRaRadio::timeout_irq_isr), - _rf_settings.fsk.rx_single_timeout * 1e3); - } - } + // Initialize radio default values + set_operation_mode(RF_OPMODE_SLEEP); - if ((_radio_events != NULL) - && (_radio_events->rx_timeout)) { - _radio_events->rx_timeout(); - } + setup_registers(); - break; + set_modem(MODEM_FSK); - case RF_TX_RUNNING: - // Tx timeout shouldn't happen. - // But it has been observed that when it happens it is a result of a - // corrupted SPI transfer - // The workaround is to put the radio in a known state. - // Thus, we re-initialize it. + // Restore previous network type setting. + set_public_network(_rf_settings.lora.public_network); - // Reset the radio - radio_reset(); + _rf_settings.state = RF_IDLE; + if ((_radio_events != NULL) && (_radio_events->tx_timeout)) { + _radio_events->tx_timeout(); + } - // Initialize radio default values - set_operation_mode(RF_OPMODE_SLEEP); - - setup_registers(); - - set_modem(MODEM_FSK); - - // Restore previous network type setting. - set_public_network(_rf_settings.lora.public_network); - - _rf_settings.state = RF_IDLE; - if ((_radio_events != NULL) - && (_radio_events->tx_timeout)) { - _radio_events->tx_timeout(); - } - break; - default: - break; } } // EOF diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index 6c48106826..e6b9b02c93 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -218,7 +218,7 @@ public: * @param timeout Reception timeout [ms] * */ - virtual void receive(uint32_t timeout); + virtual void receive(uint32_t /**timeout**/); /** * Sets the carrier frequency @@ -375,10 +375,11 @@ private: // Default is 256 bytes uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX1276]; - // TX/RX Timers - all use milisecond units + // TX timer in ms. This timer is used as a fail safe for TX. + // If the chip fails to transmit, its a fatal error, reflecting + // some catastrophic bus failure etc. We wish to have the control + // back from the driver in such a case. mbed::Timeout tx_timeout_timer; - mbed::Timeout rx_timeout_timer; - mbed::Timeout rx_timeout_sync_word; #ifdef MBED_CONF_RTOS_PRESENT // Thread to handle interrupts From 1a452545bb79fc853d94acba99f7d97c715a9bba Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Wed, 20 Jun 2018 13:58:57 +0300 Subject: [PATCH 23/42] Changing double precision to float We shouldn't use double precision as most of te embedded processors may not support it. --- SX1272/SX1272_LoRaRadio.cpp | 46 +++++++++++++++--------------- SX1276/SX1276_LoRaRadio.cpp | 57 ++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index a7b160f46b..434fab070c 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -284,7 +284,7 @@ bool SX1272_LoRaRadio::check_rf_frequency(uint32_t frequency) void SX1272_LoRaRadio::set_channel(uint32_t freq) { _rf_settings.channel = freq; - freq = (uint32_t) ((double) freq / (double) FREQ_STEP); + freq = (uint32_t) ((float) freq / (float) FREQ_STEP); write_to_register(REG_FRFMSB, (uint8_t) ((freq >> 16) & 0xFF)); write_to_register(REG_FRFMID, (uint8_t) ((freq >> 8) & 0xFF)); write_to_register(REG_FRFLSB, (uint8_t) (freq & 0xFF)); @@ -416,7 +416,7 @@ void SX1272_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, _rf_settings.fsk.preamble_len = preamble_len; _rf_settings.fsk.rx_single_timeout = (symb_timeout + 1) / 2; // dividing by 2 as our detector size is 2 symbols (16 bytes) - datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); + datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate); write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8)); write_to_register(REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); @@ -545,11 +545,11 @@ void SX1272_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power, _rf_settings.fsk.iq_inverted = iq_inverted; _rf_settings.fsk.tx_timeout = timeout; - fdev = (uint16_t) ((double) fdev / (double) FREQ_STEP); + fdev = (uint16_t) ((float) fdev / (float) FREQ_STEP); write_to_register( REG_FDEVMSB, (uint8_t) (fdev >> 8)); write_to_register( REG_FDEVLSB, (uint8_t) (fdev & 0xFF)); - datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); + datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate); write_to_register( REG_BITRATEMSB, (uint8_t) (datarate >> 8)); write_to_register( REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); @@ -656,48 +656,48 @@ uint32_t SX1272_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) + ((read_register( REG_SYNCCONFIG) & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1) + ((_rf_settings.fsk.fix_len == 0x01) ? - 0.0 : 1.0) + 0.0f : 1.0f) + (((read_register( REG_PACKETCONFIG1) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK) - != 0x00) ? 1.0 : 0) + pkt_len + != 0x00) ? 1.0f : 0) + pkt_len + ((_rf_settings.fsk.crc_on == 0x01) ? - 2.0 : 0)) - / _rf_settings.fsk.datarate) * 1e3); + 2.0f : 0)) + / _rf_settings.fsk.datarate) * 1000); } break; case MODEM_LORA: { - double bw = 0.0; + float bw = 0.0f; switch (_rf_settings.lora.bandwidth) { case 0: // 125 kHz - bw = 125e3; + bw = 125000; break; case 1: // 250 kHz - bw = 250e3; + bw = 250000; break; case 2: // 500 kHz - bw = 500e3; + bw = 500000; break; } // Symbol rate : time for one symbol (secs) - double rs = bw / (1 << _rf_settings.lora.datarate); - double ts = 1 / rs; + float rs = bw / (1 << _rf_settings.lora.datarate); + float ts = 1 / rs; // time of preamble - double preamble_time = (_rf_settings.lora.preamble_len + 4.25) * ts; + float preamble_time = (_rf_settings.lora.preamble_len + 4.25f) * ts; // Symbol length of payload and time - double tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28 + float tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28 + 16 * _rf_settings.lora.crc_on - (_rf_settings.lora.fix_len ? 20 : 0)) - / (double) (4 * (_rf_settings.lora.datarate - + / (float) (4 * (_rf_settings.lora.datarate - ((_rf_settings.lora.low_datarate_optimize > 0) ? 2 : 0)))) * (_rf_settings.lora.coderate + 4); - double n_payload = 8 + ((tmp > 0) ? tmp : 0); - double t_payload = n_payload * ts; + float n_payload = 8 + ((tmp > 0) ? tmp : 0); + float t_payload = n_payload * ts; // Time on air - double t_onair = preamble_time + t_payload; + float t_onair = preamble_time + t_payload; // return ms secs - airtime = floor(t_onair * 1e3 + 0.999); + airtime = floor(t_onair * 1000 + 0.999f); } break; } @@ -1735,9 +1735,9 @@ void SX1272_LoRaRadio::handle_dio0_irq() // We can have a snapshot of RSSI here as at this point it // should be more smoothed out. _rf_settings.fsk_packet_handler.rssi_value = -(read_register(REG_RSSIVALUE) >> 1); - _rf_settings.fsk_packet_handler.afc_value = (int32_t)(double)(((uint16_t)read_register(REG_AFCMSB) << 8) | + _rf_settings.fsk_packet_handler.afc_value = (int32_t)(float)(((uint16_t)read_register(REG_AFCMSB) << 8) | (uint16_t)read_register(REG_AFCLSB)) * - (double)FREQ_STEP; + (float)FREQ_STEP; _rf_settings.fsk_packet_handler.rx_gain = (read_register(REG_LNA) >> 5) & 0x07; // Read received packet size diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 113124a7a0..dfd84cc157 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -310,7 +310,7 @@ uint8_t SX1276_LoRaRadio::get_status(void) void SX1276_LoRaRadio::set_channel(uint32_t freq) { _rf_settings.channel = freq; - freq = (uint32_t) ((double) freq / (double) FREQ_STEP); + freq = (uint32_t) ((float) freq / (float) FREQ_STEP); write_to_register(REG_FRFMSB, (uint8_t) ((freq >> 16) & 0xFF)); write_to_register(REG_FRFMID, (uint8_t) ((freq >> 8) & 0xFF)); write_to_register(REG_FRFLSB, (uint8_t) (freq & 0xFF)); @@ -389,7 +389,7 @@ void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, _rf_settings.fsk.preamble_len = preamble_len; _rf_settings.fsk.rx_single_timeout = (symb_timeout + 1) / 2; // dividing by 2 as our detector size is 2 symbols (16 bytes) - datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); + datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate); write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8)); write_to_register(REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); @@ -554,11 +554,11 @@ void SX1276_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power, _rf_settings.fsk.iq_inverted = iq_inverted; _rf_settings.fsk.tx_timeout = timeout; - fdev = (uint16_t) ((double) fdev / (double) FREQ_STEP); + fdev = (uint16_t) ((float) fdev / (float) FREQ_STEP); write_to_register( REG_FDEVMSB, (uint8_t) (fdev >> 8)); write_to_register( REG_FDEVLSB, (uint8_t) (fdev & 0xFF)); - datarate = (uint16_t) ((double) XTAL_FREQ / (double) datarate); + datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate); write_to_register( REG_BITRATEMSB, (uint8_t) (datarate >> 8)); write_to_register( REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); @@ -667,17 +667,17 @@ uint32_t SX1276_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) + ((read_register( REG_SYNCCONFIG) & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1) + ((_rf_settings.fsk.fix_len == 0x01) ? - 0.0 : 1.0) + 0.0f : 1.0f) + (((read_register( REG_PACKETCONFIG1) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK) - != 0x00) ? 1.0 : 0) + pkt_len + != 0x00) ? 1.0f : 0) + pkt_len + ((_rf_settings.fsk.crc_on == 0x01) ? 2.0 : 0)) - / _rf_settings.fsk.datarate) * 1e3); + / _rf_settings.fsk.datarate) * 1000); break; case MODEM_LORA: - double bw = 0.0; + float bw = 0.0f; // REMARK: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported switch (_rf_settings.lora.bandwidth) { //case 0: // 7.8 kHz @@ -702,36 +702,36 @@ uint32_t SX1276_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) // bw = 625e2; // break; case 7: // 125 kHz - bw = 125e3; + bw = 125000; break; case 8: // 250 kHz - bw = 250e3; + bw = 250000; break; case 9: // 500 kHz - bw = 500e3; + bw = 500000; break; } // Symbol rate : time for one symbol (secs) - double rs = bw / (1 << _rf_settings.lora.datarate); - double ts = 1 / rs; + float rs = bw / (1 << _rf_settings.lora.datarate); + float ts = 1 / rs; // time of preamble - double tPreamble = (_rf_settings.lora.preamble_len + 4.25) * ts; + float tPreamble = (_rf_settings.lora.preamble_len + 4.25f) * ts; // Symbol length of payload and time - double tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28 + float tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28 + 16 * _rf_settings.lora.crc_on - (_rf_settings.lora.fix_len ? 20 : 0)) - / (double) (4 + / (float) (4 * (_rf_settings.lora.datarate - ((_rf_settings.lora.low_datarate_optimize > 0) ? 2 : 0)))) * (_rf_settings.lora.coderate + 4); - double nPayload = 8 + ((tmp > 0) ? tmp : 0); - double tPayload = nPayload * ts; + float nPayload = 8 + ((tmp > 0) ? tmp : 0); + float tPayload = nPayload * ts; // Time on air - double tOnAir = tPreamble + tPayload; + float tOnAir = tPreamble + tPayload; // return ms secs - airTime = floor(tOnAir * 1e3 + 0.999); + airTime = floor(tOnAir * 1000 + 0.999f); break; } @@ -1054,7 +1054,6 @@ void SX1276_LoRaRadio::set_public_network(bool enable) // Change lora modem SyncWord write_to_register(REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD); } - } /** @@ -1134,7 +1133,7 @@ void SX1276_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, write_to_register( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 ); _rf_settings.state = RF_TX_RUNNING; - tx_timeout_timer.attach_us(callback(this, &SX1276_LoRaRadio::timeout_irq_isr), time*1e3); + tx_timeout_timer.attach_us(callback(this, &SX1276_LoRaRadio::timeout_irq_isr), time * 1000); set_operation_mode(RF_OPMODE_TRANSMITTER); } @@ -1386,12 +1385,12 @@ void SX1276_LoRaRadio::rx_chain_calibration(void) // Save context regPaConfigInitVal = read_register( REG_PACONFIG ); - initialFreq = ( double )( ( ( uint32_t )this->read_register( REG_FRFMSB ) << 16 ) | - ( ( uint32_t )this->read_register( REG_FRFMID ) << 8 ) | - ( ( uint32_t )this->read_register( REG_FRFLSB ) ) ) * ( double )FREQ_STEP; + initialFreq = (float) (((uint32_t) this->read_register(REG_FRFMSB) << 16) | + ((uint32_t) this->read_register(REG_FRFMID) << 8 ) | + ((uint32_t)this->read_register(REG_FRFLSB))) * (float) FREQ_STEP; // Cut the PA just in case, RFO output, power = -1 dBm - write_to_register( REG_PACONFIG, 0x00 ); + write_to_register(REG_PACONFIG, 0x00); // Launch Rx chain calibration for LF band write_to_register (REG_IMAGECAL, (read_register(REG_IMAGECAL) @@ -1582,7 +1581,7 @@ void SX1276_LoRaRadio::transmit(uint32_t timeout) _rf_settings.state = RF_TX_RUNNING; tx_timeout_timer.attach_us(callback(this, - &SX1276_LoRaRadio::timeout_irq_isr), timeout*1e3); + &SX1276_LoRaRadio::timeout_irq_isr), timeout * 1000); set_operation_mode(RF_OPMODE_TRANSMITTER); } @@ -1870,9 +1869,9 @@ void SX1276_LoRaRadio::handle_dio0_irq() -(read_register(REG_RSSIVALUE) >> 1); _rf_settings.fsk_packet_handler.afc_value = - (int32_t) (double) (((uint16_t) read_register(REG_AFCMSB) << 8) + (int32_t) (float) (((uint16_t) read_register(REG_AFCMSB) << 8) | (uint16_t) read_register( REG_AFCLSB)) - * (double) FREQ_STEP; + * (float) FREQ_STEP; _rf_settings.fsk_packet_handler.rx_gain = (read_register( REG_LNA) >> 5) & 0x07; From 914f037c5649dcb00bbfbc98c2466c4f0b50564b Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Thu, 21 Jun 2018 13:05:43 +0300 Subject: [PATCH 24/42] Deprecating receive(uint32_t) API We are deprecating receive(uint32_t) API in favour of receive(void) API because we are ditching software timeout timers in the driver for RX chain. --- SX1272/SX1272_LoRaRadio.cpp | 2 +- SX1272/SX1272_LoRaRadio.h | 25 ++++++++++++++----------- SX1276/SX1276_LoRaRadio.cpp | 2 +- SX1276/SX1276_LoRaRadio.h | 25 ++++++++++++++----------- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 434fab070c..b2d12c9437 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -865,7 +865,7 @@ void SX1272_LoRaRadio::transmit(uint32_t timeout) * and finally a DIO0 interrupt let's the state machine know that a packet is * ready to be read from the FIFO */ -void SX1272_LoRaRadio::receive(uint32_t) +void SX1272_LoRaRadio::receive(void) { switch (_rf_settings.modem) { case MODEM_FSK: diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index 748eacf638..705ece8c1b 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -192,18 +192,21 @@ public: virtual void send(uint8_t *buffer, uint8_t size); /** - * Sets the radio in reception mode for the given time - * - * It should be noted that if the timeout is set to 0, it essentially - * puts the receiver in continuous mode and hence from thereon it should - * be treated as if in continuous mode. However, an appropriate way of - * setting the receiver in continuous mode is by using set_rx_config() - * API. - * - * @param timeout Reception timeout [ms] - * + * For backwards compatibility */ - virtual void receive(uint32_t /**timeout**/); + virtual void receive(uint32_t timeout) + { + (void) timeout; + receive(); + } + + /** + * Sets the radio to receive + * + * All necessary configuration options for receptions are set in + * 'set_rx_config(parameters)' API. + */ + virtual void receive(void); /** * Sets the carrier frequency diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index dfd84cc157..bd8e1a1708 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -844,7 +844,7 @@ void SX1276_LoRaRadio::standby( void ) * and finally a DIO0 interrupt let's the state machine know that a packet is * ready to be read from the FIFO */ -void SX1276_LoRaRadio::receive(uint32_t) +void SX1276_LoRaRadio::receive(void) { switch (_rf_settings.modem) { case MODEM_FSK: diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index e6b9b02c93..244a1be8fc 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -207,18 +207,21 @@ public: virtual void send(uint8_t *buffer, uint8_t size); /** - * Sets the radio in reception mode for the given time - * - * It should be noted that if the timeout is set to 0, it essentially - * puts the receiver in continuous mode and hence from thereon it should - * be treated as if in continuous mode. However, an appropriate way of - * setting the receiver in continuous mode is by using set_rx_config() - * API. - * - * @param timeout Reception timeout [ms] - * + * For backwards compatibility */ - virtual void receive(uint32_t /**timeout**/); + virtual void receive(uint32_t timeout) + { + (void) timeout; + receive(); + } + + /** + * Sets the radio to receive + * + * All necessary configuration options for reception are set in + * 'set_rx_config(parameters)' API. + */ + virtual void receive(void); /** * Sets the carrier frequency From 1a5f2fc054d7fa18f9d83a544ff62168ed86ffa3 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Thu, 21 Jun 2018 13:10:45 +0300 Subject: [PATCH 25/42] Adding assert if rx timeout is out of range Rx timeout in symbols cannot become more than 255 as the preamble length is fixed. For diagonostics purposes we add an MBED_ASSERT. --- SX1272/SX1272_LoRaRadio.cpp | 13 +++++++++---- SX1276/SX1276_LoRaRadio.cpp | 7 +++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index b2d12c9437..e35df646b6 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -896,10 +896,15 @@ void SX1272_LoRaRadio::receive(void) RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT); - write_to_register(REG_RXTIMEOUT2, _rf_settings.fsk.rx_single_timeout <= 255 ? - _rf_settings.fsk.rx_single_timeout : 255); - write_to_register(REG_RXTIMEOUT3, 0x00); - write_to_register(REG_RXTIMEOUT1, 0x00); + if (!_rf_settings.fsk.rx_continuous) { + // the value for rx timeout in symbols cannot be more than 255 + // as the preamble length is fixed. We assert here for quick + // diagnostics + MBED_ASSERT(_rf_settings.fsk.rx_single_timeout <= 255); + write_to_register(REG_RXTIMEOUT2, _rf_settings.fsk.rx_single_timeout); + write_to_register(REG_RXTIMEOUT3, 0x00); + write_to_register(REG_RXTIMEOUT1, 0x00); + } _rf_settings.fsk_packet_handler.preamble_detected = 0; _rf_settings.fsk_packet_handler.sync_word_detected = 0; diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index bd8e1a1708..9708c5a584 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -877,8 +877,11 @@ void SX1276_LoRaRadio::receive(void) | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT); if (!_rf_settings.fsk.rx_continuous) { - write_to_register(REG_RXTIMEOUT2, _rf_settings.fsk.rx_single_timeout <= 255 ? - _rf_settings.fsk.rx_single_timeout : 255); + // the value for rx timeout in symbols cannot be more than 255 + // as the preamble length is fixed. We assert here for quick + // diagnostics + MBED_ASSERT(_rf_settings.fsk.rx_single_timeout <= 255); + write_to_register(REG_RXTIMEOUT2, _rf_settings.fsk.rx_single_timeout); write_to_register(REG_RXTIMEOUT3, 0x00); write_to_register(REG_RXTIMEOUT1, 0x00); } From 5532d9d1f4d7c57133aed48c023e332b2a5a24ba Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Wed, 27 Jun 2018 14:27:39 +0300 Subject: [PATCH 26/42] TX timeout issue fix In case of catastrophic bus failure at radio end, we shouldn't reset the chip as it will cause the chip to hang and then burst out interrupts in a fury resulting in an ISR queue overflow. rather than that we gracefully accept the failure and set the radio to sleep and set the state to idle. In addition to that we inform the upper layers about the failure. A little touch up to the FHSS case, was actually a leftover from the previous PR. We don't use FHSS mode, that was why we didn't catch in the testing. --- SX1272/SX1272_LoRaRadio.cpp | 79 ++++++++++--------------------------- SX1276/SX1276_LoRaRadio.cpp | 12 +++--- 2 files changed, 27 insertions(+), 64 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index e35df646b6..140a2ff40b 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -833,7 +833,7 @@ void SX1272_LoRaRadio::transmit(uint32_t timeout) RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK) | RFLR_DIOMAPPING1_DIO0_01 | - RFLR_DIOMAPPING1_DIO2_00); + RFLR_DIOMAPPING1_DIO2_01); } else { write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | @@ -854,7 +854,8 @@ void SX1272_LoRaRadio::transmit(uint32_t timeout) } _rf_settings.state = RF_TX_RUNNING; - tx_timeout_timer.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr), timeout*1e3); + tx_timeout_timer.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr), + timeout * 1000); set_operation_mode(RF_OPMODE_TRANSMITTER); } @@ -2082,69 +2083,31 @@ void SX1272_LoRaRadio::handle_dio5_irq() } } - void SX1272_LoRaRadio::handle_timeout_irq() { - switch(_rf_settings.state ) - { - case RF_RX_RUNNING: - if( _rf_settings.modem == MODEM_FSK ) { - _rf_settings.fsk_packet_handler.preamble_detected = 0; - _rf_settings.fsk_packet_handler.sync_word_detected = 0; - _rf_settings.fsk_packet_handler.nb_bytes = 0; - _rf_settings.fsk_packet_handler.size = 0; + tx_timeout_timer.detach(); - // Clear Irqs - write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | - RF_IRQFLAGS1_PREAMBLEDETECT | - RF_IRQFLAGS1_SYNCADDRESSMATCH); - write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); + if (_rf_settings.state == RF_TX_RUNNING) { + // Tx timeout shouldn't happen. + // But it has been observed that when it happens it is a result of a + // corrupted SPI transfer + // The workaround is to put the radio in a known state. + // Thus, we re-initialize it. - if( _rf_settings.fsk.rx_continuous == true ) - { - // Continuous mode restart Rx chain - write_to_register( REG_RXCONFIG, read_register(REG_RXCONFIG) | - RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); - } - else - { - _rf_settings.state = RF_IDLE; - } - } + // Initialize radio default values + set_operation_mode(RF_OPMODE_SLEEP); - if((_radio_events != NULL) && (_radio_events->rx_timeout)) { - _radio_events->rx_timeout(); - } + setup_registers(); - break; + set_modem(MODEM_FSK); - case RF_TX_RUNNING: - // Tx timeout shouldn't happen. - // But it has been observed that when it happens it is a result of a - // corrupted SPI transfer - // The workaround is to put the radio in a known state. - // Thus, we re-initialize it. + // Restore previous network type setting. + set_public_network(_rf_settings.lora.public_network); - // Reset the radio - radio_reset( ); + _rf_settings.state = RF_IDLE; - // Initialize radio default values - set_operation_mode( RF_OPMODE_SLEEP ); - - setup_registers(); - - set_modem(MODEM_FSK); - - // Restore previous network type setting. - set_public_network(_rf_settings.lora.public_network); - - _rf_settings.state = RF_IDLE; - if( ( _radio_events != NULL ) && ( _radio_events->tx_timeout ) ) - { - _radio_events->tx_timeout( ); - } - break; - default: - break; - } + if ((_radio_events != NULL) && (_radio_events->tx_timeout)) { + _radio_events->tx_timeout(); + } + } } diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 9708c5a584..fa95a4adf5 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -1562,7 +1562,7 @@ void SX1276_LoRaRadio::transmit(uint32_t timeout) RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK) | RFLR_DIOMAPPING1_DIO0_01 | - RFLR_DIOMAPPING1_DIO2_00); + RFLR_DIOMAPPING1_DIO2_01); } else { write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | @@ -1583,8 +1583,10 @@ void SX1276_LoRaRadio::transmit(uint32_t timeout) } _rf_settings.state = RF_TX_RUNNING; + tx_timeout_timer.attach_us(callback(this, &SX1276_LoRaRadio::timeout_irq_isr), timeout * 1000); + set_operation_mode(RF_OPMODE_TRANSMITTER); } @@ -2242,9 +2244,10 @@ void SX1276_LoRaRadio::handle_dio5_irq() } } - void SX1276_LoRaRadio::handle_timeout_irq() { + tx_timeout_timer.detach(); + if (_rf_settings.state == RF_TX_RUNNING) { // Tx timeout shouldn't happen. // But it has been observed that when it happens it is a result of a @@ -2252,9 +2255,6 @@ void SX1276_LoRaRadio::handle_timeout_irq() // The workaround is to put the radio in a known state. // Thus, we re-initialize it. - // Reset the radio - radio_reset(); - // Initialize radio default values set_operation_mode(RF_OPMODE_SLEEP); @@ -2266,10 +2266,10 @@ void SX1276_LoRaRadio::handle_timeout_irq() set_public_network(_rf_settings.lora.public_network); _rf_settings.state = RF_IDLE; + if ((_radio_events != NULL) && (_radio_events->tx_timeout)) { _radio_events->tx_timeout(); } - } } // EOF From 1a18f0a174c33b3ca0127fc0d5ad8902a4e3b50b Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Wed, 11 Jul 2018 11:48:42 +0300 Subject: [PATCH 27/42] Correcting buffer size and tx timer units This commit fixes two issues reported in #24 and #25. The default buffer size for the radio driver should have been 255 (0xFF) not 256. In addition to that it was pointed out that the tx timer values were inconsistent with the doc. All timer values are considered in ms except symbol timeout and the time value for set_tx_continuous_wave() API. --- SX1272/SX1272_LoRaRadio.cpp | 4 ++-- SX1272/SX1272_LoRaRadio.h | 4 ++-- SX1272/mbed_lib.json | 4 ++-- SX1276/SX1276_LoRaRadio.cpp | 11 ++++------- SX1276/SX1276_LoRaRadio.h | 4 ++-- SX1276/mbed_lib.json | 4 ++-- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 140a2ff40b..4da631da93 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -1110,7 +1110,7 @@ void SX1272_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, uint8_t reg_val; set_channel(freq); - set_tx_config(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, time); + set_tx_config(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, time * 1000); reg_val = read_register(REG_PACKETCONFIG2); write_to_register( REG_PACKETCONFIG2, (reg_val & RF_PACKETCONFIG2_DATAMODE_MASK ) ); @@ -1119,7 +1119,7 @@ void SX1272_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, write_to_register( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 ); _rf_settings.state = RF_TX_RUNNING; - tx_timeout_timer.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr), time*1e3); + tx_timeout_timer.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr), time * 1000000); set_operation_mode(RF_OPMODE_TRANSMITTER); } diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index 705ece8c1b..e5474e1dcf 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -42,7 +42,7 @@ SPDX-License-Identifier: BSD-3-Clause #ifdef MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE #define MAX_DATA_BUFFER_SIZE_SX172 MBED_CONF_SX1272_LORA_DRIVER_BUFFER_SIZE #else -#define MAX_DATA_BUFFER_SIZE_SX172 256 +#define MAX_DATA_BUFFER_SIZE_SX172 255 #endif /** @@ -173,7 +173,7 @@ public: * @param iq_inverted Inverts IQ signals ( LoRa only ) * FSK : N/A ( set to 0 ) * LoRa: [0: not inverted, 1: inverted] - * @param timeout Transmission timeout [us] + * @param timeout Transmission timeout [ms] */ virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, uint32_t bandwidth, uint32_t datarate, diff --git a/SX1272/mbed_lib.json b/SX1272/mbed_lib.json index d114658abe..23a1dfe215 100644 --- a/SX1272/mbed_lib.json +++ b/SX1272/mbed_lib.json @@ -6,8 +6,8 @@ "value": 8000000 }, "buffer-size": { - "help": "Max. buffer size the radio can handle, Default: 256 B", - "value": 256 + "help": "Max. buffer size the radio can handle, Default: 255 B", + "value": 255 } } } diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index fa95a4adf5..796b2bc79e 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -581,11 +581,8 @@ void SX1276_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power, case MODEM_LORA: _rf_settings.lora.power = power; - if (bandwidth > 2) { - // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported - while (1) - ; - } + // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported + MBED_ASSERT(bandwidth <= 2); bandwidth += 7; _rf_settings.lora.bandwidth = bandwidth; _rf_settings.lora.datarate = datarate; @@ -1127,7 +1124,7 @@ void SX1276_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, uint8_t reg_val; set_channel(freq); - set_tx_config(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, time); + set_tx_config(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, time * 1000); reg_val = read_register(REG_PACKETCONFIG2); write_to_register( REG_PACKETCONFIG2, (reg_val & RF_PACKETCONFIG2_DATAMODE_MASK ) ); @@ -1136,7 +1133,7 @@ void SX1276_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, write_to_register( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 ); _rf_settings.state = RF_TX_RUNNING; - tx_timeout_timer.attach_us(callback(this, &SX1276_LoRaRadio::timeout_irq_isr), time * 1000); + tx_timeout_timer.attach_us(callback(this, &SX1276_LoRaRadio::timeout_irq_isr), time * 1000000); set_operation_mode(RF_OPMODE_TRANSMITTER); } diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index 244a1be8fc..5293aad925 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -42,7 +42,7 @@ SPDX-License-Identifier: BSD-3-Clause #ifdef MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE #define MAX_DATA_BUFFER_SIZE_SX1276 MBED_CONF_SX1276_LORA_DRIVER_BUFFER_SIZE #else -#define MAX_DATA_BUFFER_SIZE_SX1276 256 +#define MAX_DATA_BUFFER_SIZE_SX1276 255 #endif /** @@ -188,7 +188,7 @@ public: * @param iq_inverted Inverts IQ signals ( LoRa only ) * FSK : N/A ( set to 0 ) * LoRa: [0: not inverted, 1: inverted] - * @param timeout Transmission timeout [us] + * @param timeout Transmission timeout [ms] */ virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, uint32_t bandwidth, uint32_t datarate, diff --git a/SX1276/mbed_lib.json b/SX1276/mbed_lib.json index ea629da86a..d173a44837 100644 --- a/SX1276/mbed_lib.json +++ b/SX1276/mbed_lib.json @@ -6,8 +6,8 @@ "value": 8000000 }, "buffer-size": { - "help": "Max. buffer size the radio can handle, Default: 256 B", - "value": 256 + "help": "Max. buffer size the radio can handle, Default: 255 B", + "value": 255 } } } From f067004d7988020f31d0b3c471afac3b0767987b Mon Sep 17 00:00:00 2001 From: mattbrown015 Date: Mon, 16 Jul 2018 10:48:46 +0100 Subject: [PATCH 28/42] Allow configuration of the radio variant --- SX1272/SX1272_LoRaRadio.cpp | 2 +- SX1272/mbed_lib.json | 4 ++++ SX1276/SX1276_LoRaRadio.cpp | 2 +- SX1276/mbed_lib.json | 4 ++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 4da631da93..60cc449ebc 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -1466,7 +1466,7 @@ void SX1272_LoRaRadio::set_sx1272_variant_type() _ant_switch.output(); wait_ms(1); } else { - radio_variant = SX1272UNDEFINED; + radio_variant = MBED_CONF_SX1272_LORA_DRIVER_RADIO_VARIANT; } } diff --git a/SX1272/mbed_lib.json b/SX1272/mbed_lib.json index 23a1dfe215..93b09d96b1 100644 --- a/SX1272/mbed_lib.json +++ b/SX1272/mbed_lib.json @@ -8,6 +8,10 @@ "buffer-size": { "help": "Max. buffer size the radio can handle, Default: 255 B", "value": 255 + }, + "radio-variant": { + "help": "Max. buffer size the radio can handle, Default: 255 B", + "value": "SX1272UNDEFINED" } } } diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 796b2bc79e..0b38dffcbc 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -1333,7 +1333,7 @@ void SX1276_LoRaRadio::set_sx1276_variant_type() _ant_switch.output(); wait_ms(1); } else { - radio_variant = SX1276UNDEFINED; + radio_variant = MBED_CONF_SX1276_LORA_DRIVER_RADIO_VARIANT; } } diff --git a/SX1276/mbed_lib.json b/SX1276/mbed_lib.json index d173a44837..040c3d2bd2 100644 --- a/SX1276/mbed_lib.json +++ b/SX1276/mbed_lib.json @@ -8,6 +8,10 @@ "buffer-size": { "help": "Max. buffer size the radio can handle, Default: 255 B", "value": 255 + }, + "radio-variant": { + "help": "Use to set the radio variant if the antenna switch input is not connected.", + "value": "SX1276UNDEFINED" } } } From a0540930dbf53ae4b1ca60e013021367188b522c Mon Sep 17 00:00:00 2001 From: mattbrown015 Date: Thu, 2 Aug 2018 12:11:41 +0100 Subject: [PATCH 29/42] Corrected 'help' in SX1272 config item --- SX1272/mbed_lib.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SX1272/mbed_lib.json b/SX1272/mbed_lib.json index 93b09d96b1..b72897888d 100644 --- a/SX1272/mbed_lib.json +++ b/SX1272/mbed_lib.json @@ -10,7 +10,7 @@ "value": 255 }, "radio-variant": { - "help": "Max. buffer size the radio can handle, Default: 255 B", + "help": "Use to set the radio variant if the antenna switch input is not connected.", "value": "SX1272UNDEFINED" } } From 0c7dce4ff9bd36cc37cfdcfdbffbfaba83864d2e Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Wed, 10 Oct 2018 14:09:22 +0300 Subject: [PATCH 30/42] Adding support for low power timeouts We had been on a mission to get rid of all the Timeout instances from the radio drivers. However, 'tx_timeout' is a necessary evil which runs every time we transmit so that we can inform the stack about any fatal errors. The side effect of this Timeout is that it was using high-res timeout which would lock the deep sleep and hence prevent the MCU to go to deep sleep. We have now added support for low power timeout and we check compile time if the platform supports low power timeout to use it in the driver. This means that now the 'tx_timeout' will not lock the deep sleep. --- SX1272/SX1272_LoRaRadio.h | 11 +++++++++-- SX1276/SX1276_LoRaRadio.h | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index e5474e1dcf..485a08b2ad 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -31,7 +31,6 @@ SPDX-License-Identifier: BSD-3-Clause #include "DigitalOut.h" #include "DigitalInOut.h" #include "SPI.h" -#include "Timeout.h" #include "platform/PlatformMutex.h" #ifdef MBED_CONF_RTOS_PRESENT #include "rtos/Thread.h" @@ -45,6 +44,14 @@ SPDX-License-Identifier: BSD-3-Clause #define MAX_DATA_BUFFER_SIZE_SX172 255 #endif +#if DEVICE_LPTICKER +#include "LowPowerTimeout.h" +#define ALIAS_LORAWAN_TIMER mbed::LowPowerTimeout +#else +#include "Timeout.h" +#define ALIAS_LORAWAN_TIMER mbed::Timeout +#endif + /** * Radio driver implementation for Semtech SX1272 plus variants. * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. @@ -367,7 +374,7 @@ private: // If the chip fails to transmit, its a fatal error, reflecting // some catastrophic bus failure etc. We wish to have the control // back from the driver in such a case. - mbed::Timeout tx_timeout_timer; + ALIAS_LORAWAN_TIMER tx_timeout_timer; #ifdef MBED_CONF_RTOS_PRESENT // Thread to handle interrupts diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index 5293aad925..a57e8bb937 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -31,7 +31,6 @@ SPDX-License-Identifier: BSD-3-Clause #include "DigitalOut.h" #include "DigitalInOut.h" #include "SPI.h" -#include "Timeout.h" #include "platform/PlatformMutex.h" #ifdef MBED_CONF_RTOS_PRESENT #include "rtos/Thread.h" @@ -45,6 +44,14 @@ SPDX-License-Identifier: BSD-3-Clause #define MAX_DATA_BUFFER_SIZE_SX1276 255 #endif +#if DEVICE_LPTICKER +#include "LowPowerTimeout.h" +#define ALIAS_LORAWAN_TIMER mbed::LowPowerTimeout +#else +#include "Timeout.h" +#define ALIAS_LORAWAN_TIMER mbed::Timeout +#endif + /** * Radio driver implementation for Semtech SX1272 plus variants. * Supports only SPI at the moment. Implements pure virtual LoRaRadio class. @@ -382,7 +389,7 @@ private: // If the chip fails to transmit, its a fatal error, reflecting // some catastrophic bus failure etc. We wish to have the control // back from the driver in such a case. - mbed::Timeout tx_timeout_timer; + ALIAS_LORAWAN_TIMER tx_timeout_timer; #ifdef MBED_CONF_RTOS_PRESENT // Thread to handle interrupts From 16958f814d505cfbbedfa16d9bf8b9dff0e0442b Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Tue, 27 Nov 2018 12:11:19 +0200 Subject: [PATCH 31/42] Using new rtos::Thread APIs Some of the rtos::Thread APIs like signal_set() and signal_wait() are noe deprecated. Although they are still backward compatible, we switch to the new APIs. --- SX1272/SX1272_LoRaRadio.cpp | 35 ++++++++++++++++------------------- SX1276/SX1276_LoRaRadio.cpp | 35 ++++++++++++++++------------------- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 60cc449ebc..d8d55df4f7 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -180,7 +180,7 @@ SX1272_LoRaRadio::SX1272_LoRaRadio(PinName spi_mosi, _tcxo(tcxo) #ifdef MBED_CONF_RTOS_PRESENT - , irq_thread(osPriorityRealtime, 1024) + , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX1272") #endif { _rf_ctrls.ant_switch = antswitch; @@ -1182,31 +1182,28 @@ uint32_t SX1272_LoRaRadio::random() void SX1272_LoRaRadio::rf_irq_task(void) { for (;;) { - osEvent event = irq_thread.signal_wait(0, osWaitForever); - if (event.status != osEventSignal) { - continue; - } + uint32_t flags = ThisThread::flags_wait_any(0x7FFFFFFF); lock(); - if (event.value.signals & SIG_DIO0) { + if (flags & SIG_DIO0) { handle_dio0_irq(); } - if (event.value.signals & SIG_DIO1) { + if (flags & SIG_DIO1) { handle_dio1_irq(); } - if (event.value.signals & SIG_DIO2) { + if (flags & SIG_DIO2) { handle_dio2_irq(); } - if (event.value.signals & SIG_DIO3) { + if (flags & SIG_DIO3) { handle_dio3_irq(); } - if (event.value.signals & SIG_DIO4) { + if (flags & SIG_DIO4) { handle_dio4_irq(); } - if (event.value.signals & SIG_DIO5) { + if (flags & SIG_DIO5) { handle_dio5_irq(); } - if (event.value.signals & SIG_TIMOUT) { + if (flags & SIG_TIMOUT) { handle_timeout_irq(); } unlock(); @@ -1628,7 +1625,7 @@ void SX1272_LoRaRadio::set_low_power_mode(bool status) void SX1272_LoRaRadio::dio0_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO0); + irq_thread.flags_set(SIG_DIO0); #else handle_dio0_irq(); #endif @@ -1637,7 +1634,7 @@ void SX1272_LoRaRadio::dio0_irq_isr() void SX1272_LoRaRadio::dio1_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO1); + irq_thread.flags_set(SIG_DIO1); #else handle_dio1_irq(); #endif @@ -1646,7 +1643,7 @@ void SX1272_LoRaRadio::dio1_irq_isr() void SX1272_LoRaRadio::dio2_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO2); + irq_thread.flags_set(SIG_DIO2); #else handle_dio2_irq(); #endif @@ -1655,7 +1652,7 @@ void SX1272_LoRaRadio::dio2_irq_isr() void SX1272_LoRaRadio::dio3_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO3); + irq_thread.flags_set(SIG_DIO3); #else handle_dio3_irq(); #endif @@ -1664,7 +1661,7 @@ void SX1272_LoRaRadio::dio3_irq_isr() void SX1272_LoRaRadio::dio4_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO4); + irq_thread.flags_set(SIG_DIO4); #else handle_dio4_irq(); #endif @@ -1673,7 +1670,7 @@ void SX1272_LoRaRadio::dio4_irq_isr() void SX1272_LoRaRadio::dio5_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO5); + irq_thread.flags_set(SIG_DIO5); #else handle_dio5_irq(); #endif @@ -1685,7 +1682,7 @@ void SX1272_LoRaRadio::dio5_irq_isr() void SX1272_LoRaRadio::timeout_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_TIMOUT); + irq_thread.flags_set(SIG_TIMOUT); #else handle_timeout_irq(); #endif diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 0b38dffcbc..6b017cc7c6 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -185,7 +185,7 @@ SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi, _tcxo(tcxo) #ifdef MBED_CONF_RTOS_PRESENT - , irq_thread(osPriorityRealtime, 1024) + , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX1276") #endif { _rf_ctrls.ant_switch = antswitch; @@ -1147,31 +1147,28 @@ void SX1276_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, void SX1276_LoRaRadio::rf_irq_task(void) { for (;;) { - osEvent event = irq_thread.signal_wait(0, osWaitForever); - if (event.status != osEventSignal) { - continue; - } + uint32_t flags = ThisThread::flags_wait_any(0x7FFFFFFF); lock(); - if (event.value.signals & SIG_DIO0) { + if (flags & SIG_DIO0) { handle_dio0_irq(); } - if (event.value.signals & SIG_DIO1) { + if (flags & SIG_DIO1) { handle_dio1_irq(); } - if (event.value.signals & SIG_DIO2) { + if (flags & SIG_DIO2) { handle_dio2_irq(); } - if (event.value.signals & SIG_DIO3) { + if (flags & SIG_DIO3) { handle_dio3_irq(); } - if (event.value.signals & SIG_DIO4) { + if (flags & SIG_DIO4) { handle_dio4_irq(); } - if (event.value.signals & SIG_DIO5) { + if (flags & SIG_DIO5) { handle_dio5_irq(); } - if (event.value.signals & SIG_TIMOUT) { + if (flags & SIG_TIMOUT) { handle_timeout_irq(); } unlock(); @@ -1756,7 +1753,7 @@ void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode) void SX1276_LoRaRadio::dio0_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO0); + irq_thread.flags_set(SIG_DIO0); #else handle_dio0_irq(); #endif @@ -1765,7 +1762,7 @@ void SX1276_LoRaRadio::dio0_irq_isr() void SX1276_LoRaRadio::dio1_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO1); + irq_thread.flags_set(SIG_DIO1); #else handle_dio1_irq(); #endif @@ -1774,7 +1771,7 @@ void SX1276_LoRaRadio::dio1_irq_isr() void SX1276_LoRaRadio::dio2_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO2); + irq_thread.flags_set(SIG_DIO2); #else handle_dio2_irq(); #endif @@ -1783,7 +1780,7 @@ void SX1276_LoRaRadio::dio2_irq_isr() void SX1276_LoRaRadio::dio3_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO3); + irq_thread.flags_set(SIG_DIO3); #else handle_dio3_irq(); #endif @@ -1792,7 +1789,7 @@ void SX1276_LoRaRadio::dio3_irq_isr() void SX1276_LoRaRadio::dio4_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO4); + irq_thread.flags_set(SIG_DIO4); #else handle_dio4_irq(); #endif @@ -1801,7 +1798,7 @@ void SX1276_LoRaRadio::dio4_irq_isr() void SX1276_LoRaRadio::dio5_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_DIO5); + irq_thread.flags_set(SIG_DIO5); #else handle_dio5_irq(); #endif @@ -1813,7 +1810,7 @@ void SX1276_LoRaRadio::dio5_irq_isr() void SX1276_LoRaRadio::timeout_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.signal_set(SIG_TIMOUT); + irq_thread.flags_set(SIG_TIMOUT); #else handle_timeout_irq(); #endif From bd00868a82cee1d95f644103fbaceeb1883ebd12 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 22 Mar 2019 17:56:48 +0200 Subject: [PATCH 32/42] Removing mbed.h inclusion It's better to include what we need rather than whole mbed.h. Small style knits. --- SX1272/SX1272_LoRaRadio.cpp | 2 +- SX1276/SX1276_LoRaRadio.cpp | 10 +++++++++- SX1276/SX1276_LoRaRadio.h | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index d8d55df4f7..47750c3ed8 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -332,7 +332,7 @@ void SX1272_LoRaRadio::set_operation_mode(uint8_t mode) * At initialization FSK is chosen. Later stack or application * can choose to change. */ -void SX1272_LoRaRadio::set_modem(uint8_t modem ) +void SX1272_LoRaRadio::set_modem(uint8_t modem) { if ((read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON) != 0 ) { _rf_settings.modem = MODEM_LORA; diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 6b017cc7c6..2f533fbf8d 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -25,7 +25,14 @@ SPDX-License-Identifier: BSD-3-Clause #include #include //rint #include -#include "mbed.h" +#include "PinNames.h" +#include "Callback.h" +#include "mbed_wait_api.h" +#include "Timer.h" +#ifdef MBED_CONF_RTOS_PRESENT +#include "ThisThread.h" +using namespace rtos; +#endif #include "SX1276_LoRaRadio.h" #include "sx1276Regs-Fsk.h" #include "sx1276Regs-LoRa.h" @@ -153,6 +160,7 @@ enum RadioVariant { #define SPI_FREQUENCY 8000000 #endif +using namespace mbed; /** * Constructor */ diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index a57e8bb937..aaf946f7fd 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -382,7 +382,7 @@ private: // Data buffer used for both TX and RX // Size of this buffer is configurable via Mbed config system - // Default is 256 bytes + // Default is 255 bytes uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX1276]; // TX timer in ms. This timer is used as a fail safe for TX. From 6012fa43cf9f2cae46fa9d424fe4051d00e157a2 Mon Sep 17 00:00:00 2001 From: Hasnain Virk Date: Fri, 22 Mar 2019 17:55:44 +0200 Subject: [PATCH 33/42] Adding SX126X radio driver Driver compatible with SX126X series. Operates by default with Cold Start sleep mode, i.e., the lowest possible power state while sleeping. RX boost mode supported and the driver can be configured to get RX gain at the orice of power. Default mode is normal RX gain. --- SX126X/SX126X_LoRaRadio.cpp | 1334 +++++++++++++++++++++++++++++++++++ SX126X/SX126X_LoRaRadio.h | 404 +++++++++++ SX126X/SleepMode.txt | 22 + SX126X/mbed_lib.json | 29 + SX126X/sx126x_ds.h | 612 ++++++++++++++++ 5 files changed, 2401 insertions(+) create mode 100644 SX126X/SX126X_LoRaRadio.cpp create mode 100644 SX126X/SX126X_LoRaRadio.h create mode 100644 SX126X/SleepMode.txt create mode 100644 SX126X/mbed_lib.json create mode 100644 SX126X/sx126x_ds.h diff --git a/SX126X/SX126X_LoRaRadio.cpp b/SX126X/SX126X_LoRaRadio.cpp new file mode 100644 index 0000000000..30cc5948bb --- /dev/null +++ b/SX126X/SX126X_LoRaRadio.cpp @@ -0,0 +1,1334 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2015 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis, Gregory Cristian & Gilbert Menth + +Copyright (c) 2019, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#include +#include "mbed_wait_api.h" +#include "Timer.h" +#include "SX126X_LoRaRadio.h" + +#ifdef MBED_CONF_SX126X_LORA_DRIVER_SPI_FREQUENCY +#define SPI_FREQUENCY MBED_CONF_SX126X_LORA_DRIVER_SPI_FREQUENCY +#else +#define SPI_FREQUENCY 16000000 +#endif + +using namespace mbed; +#ifdef MBED_CONF_RTOS_PRESENT +using namespace rtos; +/** + * Signals + */ +#define SIG_INTERRUPT 0x02 +#endif + +/*! + * FSK bandwidth definition + */ +typedef struct +{ + uint32_t bandwidth; + uint8_t register_value; +} fsk_bw_t; + +static const fsk_bw_t fsk_bandwidths[] = +{ + { 4800 , 0x1F }, + { 5800 , 0x17 }, + { 7300 , 0x0F }, + { 9700 , 0x1E }, + { 11700 , 0x16 }, + { 14600 , 0x0E }, + { 19500 , 0x1D }, + { 23400 , 0x15 }, + { 29300 , 0x0D }, + { 39000 , 0x1C }, + { 46900 , 0x14 }, + { 58600 , 0x0C }, + { 78200 , 0x1B }, + { 93800 , 0x13 }, + { 117300, 0x0B }, + { 156200, 0x1A }, + { 187200, 0x12 }, + { 234300, 0x0A }, + { 312000, 0x19 }, + { 373600, 0x11 }, + { 467000, 0x09 }, + { 500000, 0x00 }, // Invalid Bandwidth +}; + +const uint8_t sync_word[] = {0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00,0x00}; + +// in ms SF12 SF11 SF10 SF9 SF8 SF7 +const float lora_symbol_time[3][6] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024 }, // 125 KHz + { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512 }, // 250 KHz + { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256 }}; // 500 KHz + +SX126X_LoRaRadio::SX126X_LoRaRadio(PinName mosi, + PinName miso, + PinName sclk, + PinName nss, + PinName reset, + PinName dio1, + PinName busy, + PinName freq_select, + PinName device_select, + PinName crystal_select, + PinName ant_switch) + : _spi(mosi, miso, sclk), + _chip_select(nss, 1), + _reset_ctl(reset), + _dio1_ctl(dio1, PullNone), + _busy(busy, PullNone), + _freq_select(freq_select), + _dev_select(device_select), + _crystal_select(crystal_select, PullDown), + _ant_switch(ant_switch, PIN_INPUT, PullUp, 0) +#ifdef MBED_CONF_RTOS_PRESENT + , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX126X") +#endif +{ + _radio_events = NULL; + _reset_ctl = 1; + _image_calibrated = false; + _force_image_calibration = false; + _active_modem = MODEM_LORA; + +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.start(callback(this, &SX126X_LoRaRadio::rf_irq_task)); +#endif +} + +SX126X_LoRaRadio::~SX126X_LoRaRadio() +{ + +} + +/** + * Acquire lock + */ +void SX126X_LoRaRadio::lock(void) +{ + mutex.lock(); +} + +/** + * Release lock + */ +void SX126X_LoRaRadio::unlock(void) +{ + mutex.unlock(); +} + +#ifdef MBED_CONF_RTOS_PRESENT +/** + * Thread task handling IRQs + */ +void SX126X_LoRaRadio::rf_irq_task(void) +{ + for (;;) { + uint32_t flags = ThisThread::flags_wait_any(0x7FFFFFFF); + + lock(); + if (flags & SIG_INTERRUPT) { + handle_dio1_irq(); + } + unlock(); + } +} +#endif + +void SX126X_LoRaRadio::dio1_irq_isr() +{ +#ifdef MBED_CONF_RTOS_PRESENT + irq_thread.flags_set(SIG_INTERRUPT); +#else + handle_dio1_irq(); +#endif +} + +uint16_t SX126X_LoRaRadio::get_irq_status(void) +{ + uint8_t status[2]; + + read_opmode_command((uint8_t) RADIO_GET_IRQSTATUS, status, 2); + return (status[0] << 8) | status[1]; +} + +void SX126X_LoRaRadio::clear_irq_status(uint16_t irq) +{ + uint8_t buf[2]; + + buf[0] = (uint8_t) (((uint16_t) irq >> 8) & 0x00FF); + buf[1] = (uint8_t) ((uint16_t) irq & 0x00FF); + write_opmode_command((uint8_t) RADIO_CLR_IRQSTATUS, buf, 2); +} + +//TODO - Better do CAD here. CAD code is already part of the driver +// It needs to be hooked up to the stack (this API will need change +// and the stack will need changes too) +bool SX126X_LoRaRadio::perform_carrier_sense(radio_modems_t modem, + uint32_t freq, + int16_t rssi_threshold, + uint32_t max_carrier_sense_time) +{ + bool status = true; + int16_t rssi = 0; + + set_modem(modem); + set_channel(freq); + _reception_mode = RECEPTION_MODE_OTHER; + _rx_timeout = 0x00000000; + receive(); + + // hold on a bit, radio turn-around time + wait_ms(1); + + Timer elapsed_time; + elapsed_time.start(); + + // Perform carrier sense for maxCarrierSenseTime + while (elapsed_time.read_ms() < (int) max_carrier_sense_time) { + rssi = get_rssi(); + + if (rssi > rssi_threshold) { + status = false; + break; + } + } + + sleep(); + return status; +} + +void SX126X_LoRaRadio::start_cad(void) +{ + // TODO: CAD is more advanced in SX126X. We will need API change in LoRaRadio + // for this to act properly +} + +/** + * TODO: The purpose of this API is unclear. + * Need to start an internal discussion. + */ +bool SX126X_LoRaRadio::check_rf_frequency(uint32_t frequency) +{ + // Implement check. Currently all frequencies are supported ? What band ? + return true; +} + +void SX126X_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, + uint16_t time) +{ + // This is useless. We even removed the support from our MAC layer. +} + +void SX126X_LoRaRadio::handle_dio1_irq() +{ + uint16_t irq_status = get_irq_status(); + clear_irq_status(IRQ_RADIO_ALL); + + if ((irq_status & IRQ_TX_DONE) == IRQ_TX_DONE) { + if (_radio_events->tx_done) { + _radio_events->tx_done(); + } + } + + if ((irq_status & IRQ_RX_DONE) == IRQ_RX_DONE) { + if ((irq_status & IRQ_CRC_ERROR) == IRQ_CRC_ERROR) { + if (_radio_events && _radio_events->rx_error) { + _radio_events->rx_error(); + } + } else { + if (_radio_events->rx_done) { + uint8_t offset = 0; + uint8_t payload_len = 0; + int16_t rssi = 0; + int8_t snr = 0; + packet_status_t pkt_status; + + get_rx_buffer_status(&payload_len, &offset); + read_fifo(_data_buffer, payload_len, offset); + get_packet_status(&pkt_status); + if (pkt_status.modem_type == MODEM_FSK) { + rssi = pkt_status.params.gfsk.rssi_sync; + } else { + rssi = pkt_status.params.lora.rssi_pkt; + snr = pkt_status.params.lora.snr_pkt; + } + + _radio_events->rx_done(_data_buffer, payload_len, rssi, snr); + } + } + } + + if ((irq_status & IRQ_CAD_DONE) == IRQ_CAD_DONE) { + if (_radio_events->cad_done) { + _radio_events->cad_done((irq_status & IRQ_CAD_ACTIVITY_DETECTED) + == IRQ_CAD_ACTIVITY_DETECTED); + } + } + + if ((irq_status & IRQ_RX_TX_TIMEOUT) == IRQ_RX_TX_TIMEOUT) { + if ((_radio_events->tx_timeout) && (_operation_mode == MODE_TX)) { + _radio_events->tx_timeout(); + } else if ((_radio_events && _radio_events->rx_timeout) && (_operation_mode == MODE_RX)) { + _radio_events->rx_timeout(); + } + } +} + +void SX126X_LoRaRadio::set_device_ready(void) +{ + if (_operation_mode == MODE_SLEEP) { + wakeup(); + } +} + +void SX126X_LoRaRadio::calibrate_image(uint32_t freq) +{ + uint8_t cal_freq[2]; + + if (freq > 900000000) { + cal_freq[0] = 0xE1; + cal_freq[1] = 0xE9; + } else if (freq > 850000000) { + cal_freq[0] = 0xD7; + cal_freq[1] = 0xD8; + } else if (freq > 770000000) { + cal_freq[0] = 0xC1; + cal_freq[1] = 0xC5; + } else if (freq > 460000000) { + cal_freq[0] = 0x75; + cal_freq[1] = 0x81; + } else if (freq > 425000000) { + cal_freq[0] = 0x6B; + cal_freq[1] = 0x6F; + } + + write_opmode_command((uint8_t) RADIO_CALIBRATEIMAGE, cal_freq, 2); + + _image_calibrated = true; +} + +void SX126X_LoRaRadio::set_channel(uint32_t frequency) +{ +#if MBED_CONF_SX126X_LORA_DRIVER_SLEEP_MODE == 1 + // At this point, we are not sure what is the Modem type, set both + _mod_params.params.lora.operational_frequency = frequency; + _mod_params.params.gfsk.operational_frequency = frequency; +#endif + + uint8_t buf[4]; + uint32_t freq = 0; + + if ( _force_image_calibration || !_image_calibrated) { + calibrate_image(frequency); + _image_calibrated = true; + } + + freq = (uint32_t) ceil(((float) frequency / (float) FREQ_STEP)); + buf[0] = (uint8_t) ((freq >> 24) & 0xFF); + buf[1] = (uint8_t) ((freq >> 16) & 0xFF); + buf[2] = (uint8_t) ((freq >> 8) & 0xFF); + buf[3] = (uint8_t) (freq & 0xFF); + + write_opmode_command((uint8_t) RADIO_SET_RFFREQUENCY, buf, 4); +} + +/** + * Put radio in Standby mode + */ +void SX126X_LoRaRadio::standby(void) +{ + if (_operation_mode == MODE_STDBY_RC) { + return; + } + + set_device_ready(); + uint8_t standby_mode = MBED_CONF_SX126X_LORA_DRIVER_STANDBY_MODE; + write_opmode_command((uint8_t) RADIO_SET_STANDBY, &standby_mode, 1); + + if (standby_mode == STDBY_RC) { + _operation_mode = MODE_STDBY_RC; + } else { + _operation_mode = MODE_STDBY_XOSC; + } +} + +void SX126X_LoRaRadio::set_dio2_as_rfswitch_ctrl(uint8_t enable) +{ + write_opmode_command(RADIO_SET_RFSWITCHMODE, &enable, 1); +} + +void SX126X_LoRaRadio::set_dio3_as_tcxo_ctrl(radio_TCXO_ctrl_voltage_t voltage, + uint32_t timeout) +{ + uint8_t buf[4]; + + buf[0] = voltage & 0x07; + buf[1] = (uint8_t) ((timeout >> 16) & 0xFF); + buf[2] = (uint8_t) ((timeout >> 8) & 0xFF); + buf[3] = (uint8_t) (timeout & 0xFF); + + write_opmode_command(RADIO_SET_TCXOMODE, buf, 4); +} + +void SX126X_LoRaRadio::init_radio(radio_events_t *events) +{ + _radio_events = events; + + // attach DIO1 interrupt line to its respective ISR + _dio1_ctl.rise(callback(this, &SX126X_LoRaRadio::dio1_irq_isr)); + + uint8_t freq_support = get_frequency_support(); + + // Hold chip-select high + _chip_select = 1; + _spi.format(8, 0); + _spi.frequency(SPI_FREQUENCY); + // 100 us wait to settle down + wait_us(100); + + radio_reset(); + +#if MBED_CONF_LORA_PUBLIC_NETWORK + _network_mode_public = true; +#else + _network_mode_public = false; +#endif + + // this is a POR sequence + cold_start_wakeup(); +} + +void SX126X_LoRaRadio::cold_start_wakeup() +{ + uint8_t regulator_mode = MBED_CONF_SX126X_LORA_DRIVER_REGULATOR_MODE; + write_opmode_command(RADIO_SET_REGULATORMODE, ®ulator_mode, 1); + set_buffer_base_addr(0x00, 0x00); + + if (_crystal_select.is_connected() && _crystal_select == 0) { + caliberation_params_t calib_param; + set_dio3_as_tcxo_ctrl(TCXO_CTRL_1_7V, 320); //5 ms + calib_param.value = 0x7F; + write_opmode_command(RADIO_CALIBRATE, &calib_param.value, 1); + } + + set_dio2_as_rfswitch_ctrl(true); + + _operation_mode = MODE_STDBY_RC; + + set_modem(_active_modem); + + if (_active_modem == MODEM_LORA) { + set_public_network(_network_mode_public); + } +} + +void SX126X_LoRaRadio::set_public_network(bool enable) +{ + if (enable) { + // Change LoRa modem SyncWord + write_to_register(REG_LR_SYNCWORD, (LORA_MAC_PUBLIC_SYNCWORD >> 8) & 0xFF); + write_to_register(REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF); + } else { + // Change LoRa modem SyncWord + write_to_register(REG_LR_SYNCWORD, (LORA_MAC_PRIVATE_SYNCWORD >> 8) & 0xFF); + write_to_register(REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF); + } +} + +uint32_t SX126X_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) +{ + uint32_t air_time = 0; + + switch (modem) { + case MODEM_FSK: { + air_time = rint((8 * (_packet_params.params.gfsk.preamble_length + + (_packet_params.params.gfsk.syncword_length >> 3) + + ((_packet_params.params.gfsk.header_type + == RADIO_PACKET_FIXED_LENGTH) ? 0.0f : 1.0f) + pkt_len + + ((_packet_params.params.gfsk.crc_length == RADIO_CRC_2_BYTES) ? 2.0f : 0.0f)) + / _mod_params.params.gfsk.bit_rate) * 1000); + } + break; + case MODEM_LORA: { + float ts = lora_symbol_time[_mod_params.params.lora.bandwidth - 4][12 + - _mod_params.params.lora.spreading_factor]; + // time of preamble + float t_preamble = (_packet_params.params.lora.preamble_length + 4.25f) * ts; + // Symbol length of payload and time + float tmp = ceil((8 * pkt_len - 4 * _mod_params.params.lora.spreading_factor + + 28 + 16 * _packet_params.params.lora.crc_mode + - ((_packet_params.params.lora.header_type == LORA_PACKET_FIXED_LENGTH) ? 20 : 0)) + / (float) (4 * (_mod_params.params.lora.spreading_factor + - ((_mod_params.params.lora.low_datarate_optimization > 0) ? 2 : 0)))) + * ((_mod_params.params.lora.coding_rate % 4) + 4); + float n_payload = 8 + ((tmp > 0) ? tmp : 0); + float t_payload = n_payload * ts; + // Time on air + float tOnAir = t_preamble + t_payload; + // return milliseconds (as ts is in milliseconds) + air_time = floor(tOnAir + 0.999); + } + break; + } + + return air_time; +} + +void SX126X_LoRaRadio::radio_reset() +{ + _reset_ctl.output(); + _reset_ctl = 0; + // should be enough, required is 50-100 us + wait_ms(2); + _reset_ctl.input(); + // give some time for automatic image calibration + wait_ms(6); +} + +void SX126X_LoRaRadio::wakeup() +{ + // hold the NSS low, this should wakeup the chip. + // now we should wait for the _busy line to go low + if (_operation_mode == MODE_SLEEP) { + _chip_select = 0; + wait_us(100); + _chip_select = 1; + //wait_us(100); +#if MBED_CONF_SX126X_LORA_DRIVER_SLEEP_MODE == 1 + wait_us(3500); + // whenever we wakeup from Cold sleep state, we need to perform + // image calibration + _force_image_calibration = true; + cold_start_wakeup(); +#endif + } +} + +void SX126X_LoRaRadio::sleep(void) +{ + // warm start, power consumption 600 nA + uint8_t sleep_state = 0x04; + _operation_mode = MODE_SLEEP; + +#if MBED_CONF_SX126X_LORA_DRIVER_SLEEP_MODE == 1 + // cold start, power consumption 160 nA + sleep_state = 0x00; +#endif + + write_opmode_command(RADIO_SET_SLEEP, &sleep_state, 1); + wait_ms(2); +} + +uint32_t SX126X_LoRaRadio::random(void) +{ + set_modem(MODEM_LORA); + uint8_t buf[] = {0, 0, 0, 0}; + + // Set radio in continuous reception + _reception_mode = RECEPTION_MODE_OTHER; + _rx_timeout = 0xFFFFFFFF; + receive(); + wait_ms(1); + read_register(RANDOM_NUMBER_GENERATORBASEADDR, buf, 4); + standby(); + + return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; +} + +void SX126X_LoRaRadio::write_opmode_command(uint8_t cmd, uint8_t *buffer, uint16_t size) +{ + _chip_select = 0; + + while (_busy) { + // do nothing + } + + _spi.write(cmd); + + for (int i = 0; i < size; i++) { + _spi.write(buffer[i]); + } + + _chip_select = 1; +} + +void SX126X_LoRaRadio::read_opmode_command(uint8_t cmd, + uint8_t *buffer, uint16_t size) +{ + _chip_select = 0; + + while (_busy) { + // do nothing + } + + _spi.write(cmd); + _spi.write(0); + + for (int i = 0; i < size; i++) { + buffer[i] = _spi.write(0); + } + + _chip_select = 1; +} + +void SX126X_LoRaRadio::write_to_register(uint16_t addr, uint8_t data) +{ + write_to_register(addr, &data, 1); +} + +void SX126X_LoRaRadio::write_to_register(uint16_t addr, uint8_t *data, + uint8_t size) +{ + _chip_select = 0; + + _spi.write(RADIO_WRITE_REGISTER); + _spi.write((addr & 0xFF00) >> 8); + _spi.write(addr & 0x00FF); + + for (int i = 0; i < size; i++) { + _spi.write(data[i]); + } + + _chip_select = 1; +} + +uint8_t SX126X_LoRaRadio::read_register(uint16_t addr) +{ + uint8_t data; + read_register(addr, &data, 1); + return data; + +} + +void SX126X_LoRaRadio::read_register(uint16_t addr, uint8_t *buffer, + uint8_t size) +{ + _chip_select = 0; + + _spi.write(RADIO_READ_REGISTER); + _spi.write((addr & 0xFF00) >> 8); + _spi.write(addr & 0x00FF); + _spi.write(0); + + for (int i = 0; i < size; i++) { + buffer[i] = _spi.write(0); + } + + _chip_select = 1; +} + +void SX126X_LoRaRadio::write_fifo(uint8_t *buffer, uint8_t size) +{ + _chip_select = 0; + + _spi.write(RADIO_WRITE_BUFFER); + _spi.write(0); + + for (int i = 0; i < size; i++) { + _spi.write(buffer[i]); + } + + _chip_select = 1; +} + +void SX126X_LoRaRadio::set_modem(uint8_t modem) +{ + _active_modem = modem; + + // setting modem type must happen in stnadby mode + if (_operation_mode != MODE_STDBY_RC) { + standby(); + } + + write_opmode_command(RADIO_SET_PACKETTYPE, &_active_modem, 1); +} + +uint8_t SX126X_LoRaRadio::get_modem() +{ + return _active_modem; +} + +void SX126X_LoRaRadio::read_fifo(uint8_t *buffer, uint8_t size, uint8_t offset) +{ + _chip_select = 0; + + _spi.write(RADIO_READ_BUFFER); + _spi.write(offset); + _spi.write(0); + + for (int i = 0; i < size; i++) { + buffer[i] = _spi.write(0); + } + + _chip_select = 1; +} + +uint8_t SX126X_LoRaRadio::get_device_variant(void) +{ + uint16_t val = 0; + val = _dev_select.read_u16(); + + if (val <= 0x2000) { + return SX1262; + } else if (val <= 0xA000) { + return SX1268; + } else { + return SX1261; + } +} + +uint8_t SX126X_LoRaRadio::get_frequency_support(void) +{ + uint16_t val = 0; + val = _freq_select.read_u16(); + + if (val < 100) { + return ( MATCHING_FREQ_915); + } else if (val <= 0x3000) { + return ( MATCHING_FREQ_780); + } else if (val <= 0x4900) { // 0x4724 + return ( MATCHING_FREQ_490); + } else if (val <= 1) { + return ( MATCHING_FREQ_434); + } else if (val <= 1) { + return ( MATCHING_FREQ_280); + } else if (val <= 0xF000) { + return ( MATCHING_FREQ_169); + } else { + return ( MATCHING_FREQ_868); + } +} + +uint8_t SX126X_LoRaRadio::get_fsk_bw_reg_val(uint32_t bandwidth) +{ + uint8_t i; + + for (i = 0; i < (sizeof(fsk_bandwidths) / sizeof(fsk_bw_t)) - 1; i++) { + if ((bandwidth >= fsk_bandwidths[i].bandwidth) + && (bandwidth < fsk_bandwidths[i + 1].bandwidth)) { + return fsk_bandwidths[i].register_value; + } + } + // ERROR: Value not found + // This should never happen + while (1); +} + +void SX126X_LoRaRadio::set_max_payload_length(radio_modems_t modem, uint8_t max) +{ + if (modem == MODEM_LORA) { + _packet_params.params.lora.payload_length = max; + } else { + _packet_params.params.gfsk.payload_length = max; + } +} + +void SX126X_LoRaRadio::set_tx_config(radio_modems_t modem, + int8_t power, + uint32_t fdev, + uint32_t bandwidth, + uint32_t datarate, + uint8_t coderate, + uint16_t preamble_len, + bool fix_len, + bool crc_on, + bool freq_hop_on, + uint8_t hop_period, + bool iq_inverted, + uint32_t timeout) +{ + + uint8_t modem_type = (uint8_t) modem; + switch (modem_type) { + case MODEM_FSK: + _mod_params.modem_type = MODEM_FSK; + _mod_params.params.gfsk.bit_rate = datarate; + + _mod_params.params.gfsk.modulation_shaping = MOD_SHAPING_G_BT_1; + _mod_params.params.gfsk.bandwidth = get_fsk_bw_reg_val(bandwidth); + _mod_params.params.gfsk.fdev = fdev; + + _packet_params.modem_type = MODEM_FSK; + _packet_params.params.gfsk.preamble_length = (preamble_len << 3); // convert byte into bit + _packet_params.params.gfsk.preamble_min_detect = RADIO_PREAMBLE_DETECTOR_08_BITS; + _packet_params.params.gfsk.syncword_length = 3 << 3; // convert byte into bit + _packet_params.params.gfsk.addr_comp = RADIO_ADDRESSCOMP_FILT_OFF; + _packet_params.params.gfsk.header_type = (fix_len == true) ? + RADIO_PACKET_FIXED_LENGTH : + RADIO_PACKET_VARIABLE_LENGTH; + + if (crc_on) { + _packet_params.params.gfsk.crc_length = RADIO_CRC_2_BYTES_CCIT; + } else { + _packet_params.params.gfsk.crc_length = RADIO_CRC_OFF; + } + _packet_params.params.gfsk.whitening_mode = RADIO_DC_FREEWHITENING; + + set_modem(MODEM_FSK); + + write_to_register(REG_LR_SYNCWORDBASEADDRESS, (uint8_t *) sync_word, 8); + set_whitening_seed(0x01FF); + break; + + case MODEM_LORA: + _mod_params.modem_type = MODEM_LORA; + _mod_params.params.lora.spreading_factor = (lora_spread_factors_t) datarate; + _mod_params.params.lora.bandwidth = (lora_bandwidths_t) lora_bandwidhts[bandwidth]; + _mod_params.params.lora.coding_rate = (lora_coding_tates_t) coderate; + + if (((bandwidth == 0) && ((datarate == 11) || (datarate == 12))) + || ((bandwidth == 1) && (datarate == 12))) { + _mod_params.params.lora.low_datarate_optimization = 0x01; + } else { + _mod_params.params.lora.low_datarate_optimization = 0x00; + } + + _packet_params.modem_type = MODEM_LORA; + + if ((_mod_params.params.lora.spreading_factor == LORA_SF5) + || (_mod_params.params.lora.spreading_factor == LORA_SF6)) { + if (preamble_len < 12) { + _packet_params.params.lora.preamble_length = 12; + } else { + _packet_params.params.lora.preamble_length = preamble_len; + } + } else { + _packet_params.params.lora.preamble_length = preamble_len; + } + + _packet_params.params.lora.header_type = (lora_pkt_length_t) fix_len; + _packet_params.params.lora.crc_mode = (lora_crc_mode_t) crc_on; + _packet_params.params.lora.invert_IQ = (lora_IQ_mode_t) iq_inverted; + + set_modem(MODEM_LORA); + + break; + } + + _tx_power = power; + _tx_timeout = timeout; +} + +void SX126X_LoRaRadio::set_rx_config(radio_modems_t modem, + uint32_t bandwidth, + uint32_t datarate, + uint8_t coderate, + uint32_t bandwidthAfc, + uint16_t preamble_len, + uint16_t symb_timeout, + bool fix_len, + uint8_t payload_len, + bool crc_on, + bool freq_hop_on, + uint8_t hop_period, + bool iq_inverted, + bool rx_continuous) +{ + uint8_t max_payload_len; + (void) freq_hop_on; + (void) hop_period; + + if (rx_continuous) { + _reception_mode = RECEPTION_MODE_CONTINUOUS; + } else { + _reception_mode = RECEPTION_MODE_SINGLE; + } + + if (fix_len == true) { + max_payload_len = payload_len; + } else { + max_payload_len = 0xFF; + } + + uint8_t modem_type = (uint8_t) modem; + + switch (modem_type) { + case MODEM_FSK: { + _mod_params.modem_type = MODEM_FSK; + _mod_params.params.gfsk.bit_rate = datarate; + _mod_params.params.gfsk.modulation_shaping = MOD_SHAPING_G_BT_1; + _mod_params.params.gfsk.bandwidth = get_fsk_bw_reg_val(bandwidth); + + _packet_params.modem_type = MODEM_FSK; + _packet_params.params.gfsk.preamble_length = (preamble_len << 3); // convert byte into bit + _packet_params.params.gfsk.preamble_min_detect = + RADIO_PREAMBLE_DETECTOR_08_BITS; + _packet_params.params.gfsk.syncword_length = 3 << 3; // convert byte into bit + _packet_params.params.gfsk.addr_comp = RADIO_ADDRESSCOMP_FILT_OFF; + _packet_params.params.gfsk.header_type = + (fix_len == true) ? + RADIO_PACKET_FIXED_LENGTH : + RADIO_PACKET_VARIABLE_LENGTH; + _packet_params.params.gfsk.payload_length = max_payload_len; + + if (crc_on) { + _packet_params.params.gfsk.crc_length = RADIO_CRC_2_BYTES_CCIT; + } else { + _packet_params.params.gfsk.crc_length = RADIO_CRC_OFF; + } + + _packet_params.params.gfsk.whitening_mode = RADIO_DC_FREEWHITENING; + + set_modem(MODEM_FSK); + + write_to_register(REG_LR_SYNCWORDBASEADDRESS, (uint8_t *) sync_word, 8); + set_whitening_seed(0x01FF); + + _rx_timeout = (uint32_t) (symb_timeout + * ((1.0 / (float) datarate) * 8.0) * 1000); + + break; + } + + case MODEM_LORA: { + _rx_timeout_in_symbols = symb_timeout; + _mod_params.modem_type = MODEM_LORA; + _mod_params.params.lora.spreading_factor = + (lora_spread_factors_t) datarate; + _mod_params.params.lora.bandwidth = (lora_bandwidths_t) lora_bandwidhts[bandwidth]; + _mod_params.params.lora.coding_rate = + (lora_coding_tates_t) coderate; + + if (((bandwidth == 0) && ((datarate == 11) || (datarate == 12))) + || ((bandwidth == 1) && (datarate == 12))) { + _mod_params.params.lora.low_datarate_optimization = 0x01; + } else { + _mod_params.params.lora.low_datarate_optimization = 0x00; + } + + _packet_params.modem_type = MODEM_LORA; + + if ((_mod_params.params.lora.spreading_factor == LORA_SF5) + || (_mod_params.params.lora.spreading_factor == LORA_SF6)) { + if (preamble_len < 12) { + _packet_params.params.lora.preamble_length = 12; + } else { + _packet_params.params.lora.preamble_length = preamble_len; + } + } else { + _packet_params.params.lora.preamble_length = preamble_len; + } + + _packet_params.params.lora.header_type = (lora_pkt_length_t) fix_len; + _packet_params.params.lora.payload_length = max_payload_len; + _packet_params.params.lora.crc_mode = (lora_crc_mode_t) crc_on; + _packet_params.params.lora.invert_IQ = (lora_IQ_mode_t) iq_inverted; + + set_modem(MODEM_LORA); + + if (_reception_mode == RECEPTION_MODE_CONTINUOUS) { + _rx_timeout = 0xFFFFFFFF; + } else { + _rx_timeout = 0x00000000; + } + + break; + } + + default: + break; + } +} + +void SX126X_LoRaRadio::configure_dio_irq(uint16_t irq_mask, uint16_t dio1_mask, + uint16_t dio2_mask, uint16_t dio3_mask) +{ + uint8_t buf[8]; + + buf[0] = (uint8_t) ((irq_mask >> 8) & 0x00FF); + buf[1] = (uint8_t) (irq_mask & 0x00FF); + buf[2] = (uint8_t) ((dio1_mask >> 8) & 0x00FF); + buf[3] = (uint8_t) (dio1_mask & 0x00FF); + buf[4] = (uint8_t) ((dio2_mask >> 8) & 0x00FF); + buf[5] = (uint8_t) (dio2_mask & 0x00FF); + buf[6] = (uint8_t) ((dio3_mask >> 8) & 0x00FF); + buf[7] = (uint8_t) (dio3_mask & 0x00FF); + + write_opmode_command((uint8_t) RADIO_CFG_DIOIRQ, buf, 8); +} + +void SX126X_LoRaRadio::send(uint8_t *buffer, uint8_t size) +{ + set_tx_power(_tx_power); + configure_dio_irq(IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE ); + + set_modulation_params(&_mod_params); + set_packet_params(&_packet_params); + + write_fifo(buffer, size); + uint8_t buf[3]; + + // _tx_timeout in ms should be converted to us and then divided by + // 15.625 us. Check data-sheet 13.1.4 SetTX() section. + uint32_t timeout_scalled = ceil((_tx_timeout * 1000) / 15.625); + + buf[0] = (uint8_t) ((timeout_scalled >> 16) & 0xFF); + buf[1] = (uint8_t) ((timeout_scalled >> 8) & 0xFF); + buf[2] = (uint8_t) (timeout_scalled & 0xFF); + + write_opmode_command(RADIO_SET_TX, buf, 3); + + _operation_mode = MODE_TX; +} + + +void SX126X_LoRaRadio::receive(void) +{ + if (get_modem() == MODEM_LORA && _reception_mode != RECEPTION_MODE_CONTINUOUS) { + // Data-sheet Table 13-11: StopOnPreambParam + // We will use radio's internal timer to mark no reception. This behaviour + // is different from SX1272/SX1276 where we are relying on radio to stop + // at preamble detection. + // 0x00 means Timer will be stopped on SyncWord(FSK) or Header (LoRa) detection + // 0x01 means Timer is stopped on preamble detection + uint8_t stop_at_preamble = 0x01; + write_opmode_command(RADIO_SET_STOPRXTIMERONPREAMBLE, &stop_at_preamble, 1); + // Data-sheet 13.4.9 SetLoRaSymbNumTimeout + write_opmode_command(RADIO_SET_LORASYMBTIMEOUT, &_rx_timeout_in_symbols, 1); + } + + if (_reception_mode != RECEPTION_MODE_OTHER) { + configure_dio_irq(IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR , + IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR , + IRQ_RADIO_NONE, + IRQ_RADIO_NONE); + set_modulation_params(&_mod_params); + set_packet_params(&_packet_params); + } + + uint8_t buf[3]; + +#if MBED_CONF_SX126X_LORA_DRIVER_BOOST_RX + write_to_register(REG_RX_GAIN, 0x96); +#endif + + buf[0] = (uint8_t) ((_rx_timeout >> 16) & 0xFF); + buf[1] = (uint8_t) ((_rx_timeout >> 8) & 0xFF); + buf[2] = (uint8_t) (_rx_timeout & 0xFF); + + write_opmode_command(RADIO_SET_RX, buf, 3); + + _operation_mode = MODE_RX; +} + +// check data-sheet 13.1.14.1 PA optimal settings +void SX126X_LoRaRadio::set_tx_power(int8_t power) +{ + uint8_t buf[2]; + + if (get_device_variant() == SX1261) { + if (power >= 14) { + set_pa_config(0x04, 0x00, 0x01, 0x01); + power = 14; + } else if (power < 14){ + set_pa_config(0x01, 0x00, 0x01, 0x01); + } + + if (power < -3) { + power = -3; + } + write_to_register(REG_OCP, 0x18); // current max is 80 mA for the whole device + } else { + // sx1262 or sx1268 + if (power > 22) { + power = 22; + } else if (power < -3) { + power = -3; + } + + if (power <= 14) { + set_pa_config(0x02, 0x02, 0x00, 0x01); + } else { + set_pa_config(0x04, 0x07, 0x00, 0x01); + } + + write_to_register(REG_OCP, 0x38); // current max 160mA for the whole device + } + + buf[0] = power; + + if (_crystal_select.is_connected() && _crystal_select == 0) { + // TCXO + buf[1] = RADIO_RAMP_200_US; + } else { + // XTAL + buf[1] = RADIO_RAMP_20_US; + } + + write_opmode_command(RADIO_SET_TXPARAMS, buf, 2); +} + +void SX126X_LoRaRadio::set_modulation_params(modulation_params_t *params) +{ + uint8_t n; + uint32_t temp = 0; + uint8_t buf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + // Check if required configuration corresponds to the stored packet type + // If not, silently update radio packet type + if (_active_modem != params->modem_type) { + set_modem(params->modem_type); + } + + switch (params->modem_type) { + case MODEM_FSK: + n = 8; + temp = (uint32_t) (32 * ((float) XTAL_FREQ / (float) params->params.gfsk.bit_rate)); + buf[0] = (temp >> 16) & 0xFF; + buf[1] = (temp >> 8) & 0xFF; + buf[2] = temp & 0xFF; + buf[3] = params->params.gfsk.modulation_shaping; + buf[4] = params->params.gfsk.bandwidth; + temp = (uint32_t) ((float) params->params.gfsk.fdev / (float) FREQ_STEP); + buf[5] = (temp >> 16) & 0xFF; + buf[6] = (temp >> 8) & 0xFF; + buf[7] = (temp & 0xFF); + write_opmode_command(RADIO_SET_MODULATIONPARAMS, buf, n); + break; + + case MODEM_LORA: + n = 4; + buf[0] = params->params.lora.spreading_factor; + buf[1] = params->params.lora.bandwidth; + buf[2] = params->params.lora.coding_rate; + buf[3] = params->params.lora.low_datarate_optimization; + + write_opmode_command(RADIO_SET_MODULATIONPARAMS, buf, n); + break; + + default: + return; + } +} + +void SX126X_LoRaRadio::set_pa_config(uint8_t pa_DC, uint8_t hp_max, + uint8_t device_type, uint8_t pa_LUT ) +{ + uint8_t buf[4]; + + buf[0] = pa_DC; + buf[1] = hp_max; + buf[2] = device_type; + buf[3] = pa_LUT; + write_opmode_command(RADIO_SET_PACONFIG, buf, 4); +} + +void SX126X_LoRaRadio::set_crc_seed(uint16_t seed) +{ + if (_active_modem == MODEM_FSK) { + uint8_t buf[2]; + buf[0] = (uint8_t) ((seed >> 8) & 0xFF); + buf[1] = (uint8_t) (seed & 0xFF); + write_to_register(REG_LR_CRCSEEDBASEADDR, buf, 2); + } +} + +void SX126X_LoRaRadio::set_crc_polynomial(uint16_t polynomial) +{ + if (_active_modem == MODEM_FSK) { + uint8_t buf[2]; + buf[0] = (uint8_t) ((polynomial >> 8) & 0xFF); + buf[1] = (uint8_t) (polynomial & 0xFF); + write_to_register(REG_LR_CRCPOLYBASEADDR, buf, 2); + } +} + +void SX126X_LoRaRadio::set_whitening_seed(uint16_t seed) +{ + if (_active_modem == MODEM_FSK) { + uint8_t reg_value = read_register(REG_LR_WHITSEEDBASEADDR_MSB) & 0xFE; + reg_value = ((seed >> 8) & 0x01) | reg_value; + write_to_register(REG_LR_WHITSEEDBASEADDR_MSB, reg_value); // only 1 bit. + write_to_register(REG_LR_WHITSEEDBASEADDR_LSB, (uint8_t) seed); + } +} + +void SX126X_LoRaRadio::set_packet_params(packet_params_t *packet_params) +{ + uint8_t n; + uint8_t crc_val = 0; + uint8_t buf[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + // Check if required configuration corresponds to the stored packet type + // If not, silently update radio packet type + if (_active_modem != packet_params->modem_type) { + set_modem(packet_params->modem_type); + } + + switch (packet_params->modem_type) { + case MODEM_FSK: + if (packet_params->params.gfsk.crc_length == RADIO_CRC_2_BYTES_IBM) { + set_crc_seed(CRC_IBM_SEED); + set_crc_polynomial(CRC_POLYNOMIAL_IBM); + crc_val = RADIO_CRC_2_BYTES; + } else if (packet_params->params.gfsk.crc_length == RADIO_CRC_2_BYTES_CCIT) { + set_crc_seed(CRC_CCITT_SEED); + set_crc_polynomial(CRC_POLYNOMIAL_CCITT); + crc_val = RADIO_CRC_2_BYTES_INV; + } else { + crc_val = packet_params->params.gfsk.crc_length; + } + n = 9; + buf[0] = (packet_params->params.gfsk.preamble_length >> 8) & 0xFF; + buf[1] = packet_params->params.gfsk.preamble_length; + buf[2] = packet_params->params.gfsk.preamble_min_detect; + buf[3] = (packet_params->params.gfsk.syncword_length /*<< 3*/); // convert from byte to bit + buf[4] = packet_params->params.gfsk.addr_comp; + buf[5] = packet_params->params.gfsk.header_type; + buf[6] = packet_params->params.gfsk.payload_length; + buf[7] = crc_val; + buf[8] = packet_params->params.gfsk.whitening_mode; + break; + + case MODEM_LORA: + n = 6; + buf[0] = (packet_params->params.lora.preamble_length >> 8) & 0xFF; + buf[1] = packet_params->params.lora.preamble_length; + buf[2] = packet_params->params.lora.header_type; + buf[3] = packet_params->params.lora.payload_length; + buf[4] = packet_params->params.lora.crc_mode; + buf[5] = packet_params->params.lora.invert_IQ; + break; + default: + return; + } + write_opmode_command(RADIO_SET_PACKETPARAMS, buf, n); +} + +void SX126X_LoRaRadio::set_cad_params(lora_cad_symbols_t nb_symbols, + uint8_t det_peak, uint8_t det_min, + cad_exit_modes_t exit_mode, + uint32_t timeout) +{ + uint8_t buf[7]; + + buf[0] = (uint8_t) nb_symbols; + buf[1] = det_peak; + buf[2] = det_min; + buf[3] = (uint8_t) exit_mode; + buf[4] = (uint8_t) ((timeout >> 16) & 0xFF); + buf[5] = (uint8_t) ((timeout >> 8) & 0xFF); + buf[6] = (uint8_t) (timeout & 0xFF); + write_opmode_command((uint8_t) RADIO_SET_CADPARAMS, buf, 7); + + _operation_mode = MODE_CAD; +} + +void SX126X_LoRaRadio::set_buffer_base_addr(uint8_t tx_base_addr, uint8_t rx_base_addr) +{ + uint8_t buf[2]; + + buf[0] = tx_base_addr; + buf[1] = rx_base_addr; + write_opmode_command((uint8_t) RADIO_SET_BUFFERBASEADDRESS, buf, 2); +} + +uint8_t SX126X_LoRaRadio::get_status(void) +{ + if (_operation_mode != MODE_STDBY_RC || _operation_mode != MODE_SLEEP) { + return 0; + } + + return 0xFF; +} + +int8_t SX126X_LoRaRadio::get_rssi() +{ + uint8_t buf[1]; + int8_t rssi = 0; + + read_opmode_command((uint8_t) RADIO_GET_RSSIINST, buf, 1); + rssi = -buf[0] >> 1; + return rssi; +} + +void SX126X_LoRaRadio::get_rx_buffer_status(uint8_t *payload_len, + uint8_t *start_ptr) +{ + uint8_t status[2]; + + read_opmode_command((uint8_t) RADIO_GET_RXBUFFERSTATUS, status, 2); + + // In case of LORA fixed header, the payloadLength is obtained by reading + // the register REG_LR_PAYLOADLENGTH + if ((get_modem() == MODEM_LORA) && + (read_register(REG_LR_PACKETPARAMS) >> 7 == 1)) { + *payload_len = read_register(REG_LR_PAYLOADLENGTH); + } else { + *payload_len = status[0]; + } + + *start_ptr = status[1]; +} + +void SX126X_LoRaRadio::get_packet_status(packet_status_t *pkt_status) +{ + uint8_t status[3]; + + read_opmode_command((uint8_t) RADIO_GET_PACKETSTATUS, status, 3); + + pkt_status->modem_type = (radio_modems_t) get_modem(); + switch (pkt_status->modem_type) { + case MODEM_FSK: + pkt_status->params.gfsk.rx_status = status[0]; + pkt_status->params.gfsk.rssi_sync = -status[1] >> 1; + pkt_status->params.gfsk.rssi_avg = -status[2] >> 1; + pkt_status->params.gfsk.freq_error = 0; + break; + + case MODEM_LORA: + pkt_status->params.lora.rssi_pkt = -status[0] >> 1; + // Returns SNR value [dB] rounded to the nearest integer value + pkt_status->params.lora.snr_pkt = (((int8_t) status[1]) + 2) >> 2; + pkt_status->params.lora.signal_rssi_pkt = -status[2] >> 1; + break; + + default: + // In that specific case, we set everything in the pkt_status to zeros + // and reset the packet type accordingly + memset(pkt_status, 0, sizeof(packet_status_t)); + break; + } +} + +radio_error_t SX126X_LoRaRadio::get_device_errors(void) +{ + radio_error_t error; + + read_opmode_command((uint8_t) RADIO_GET_ERROR, (uint8_t *)&error, 2); + return error; +} + +void SX126X_LoRaRadio::clear_device_errors(void) +{ + uint8_t buf[2] = {0x00, 0x00}; + write_opmode_command((uint8_t) RADIO_CLR_ERROR, buf, 2); +} + diff --git a/SX126X/SX126X_LoRaRadio.h b/SX126X/SX126X_LoRaRadio.h new file mode 100644 index 0000000000..3b2bc410a5 --- /dev/null +++ b/SX126X/SX126X_LoRaRadio.h @@ -0,0 +1,404 @@ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2015 Semtech + ___ _____ _ ___ _ _____ ___ ___ ___ ___ +/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| +\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| +|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| +embedded.connectivity.solutions=============== + +Description: LoRaWAN stack layer that controls both MAC and PHY underneath + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis, Gregory Cristian & Gilbert Menth + +Copyright (c) 2019, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef MBED_LORA_RADIO_DRV_SX126X_LORARADIO_H_ +#define MBED_LORA_RADIO_DRV_SX126X_LORARADIO_H_ + +#include "mbed_critical.h" +#include "PinNames.h" +#include "InterruptIn.h" +#include "DigitalOut.h" +#include "DigitalInOut.h" +#include "DigitalIn.h" +#include "AnalogIn.h" +#include "SPI.h" +#include "platform/PlatformMutex.h" +#ifdef MBED_CONF_RTOS_PRESENT +#include "rtos/Thread.h" +#include "rtos/ThisThread.h" +#endif +#include "sx126x_ds.h" +#include "lorawan/LoRaRadio.h" + +#ifdef MBED_CONF_SX126X_LORA_DRIVER_BUFFER_SIZE +#define MAX_DATA_BUFFER_SIZE_SX126X MBED_CONF_SX126X_LORA_DRIVER_BUFFER_SIZE +#else +#define MAX_DATA_BUFFER_SIZE_SX126X 255 +#endif + +class SX126X_LoRaRadio : public LoRaRadio { + +public: + SX126X_LoRaRadio(PinName mosi, + PinName miso, + PinName sclk, + PinName nss, + PinName reset, + PinName dio1, + PinName busy, + PinName freq_select, + PinName device_select, + PinName crystal_select, + PinName ant_switch); + + virtual ~SX126X_LoRaRadio(); + + /** + * Registers radio events with the Mbed LoRaWAN stack and + * undergoes initialization steps if any + * + * @param events Structure containing the driver callback functions + */ + virtual void init_radio(radio_events_t *events); + + /** + * Resets the radio module + */ + virtual void radio_reset(); + + /** + * Put the RF module in sleep mode + */ + virtual void sleep(void); + + /** + * Sets the radio in standby mode + */ + virtual void standby(void); + + /** + * Sets the reception parameters + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param bandwidth Sets the bandwidth + * FSK : >= 2600 and <= 250000 Hz + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * @param datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * @param coderate Sets the coding rate ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * @param bandwidth_afc Sets the AFC Bandwidth ( FSK only ) + * FSK : >= 2600 and <= 250000 Hz + * LoRa: N/A ( set to 0 ) + * @param preamble_len Sets the Preamble length ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: Length in symbols ( the hardware adds 4 more symbols ) + * @param symb_timeout Sets the RxSingle timeout value + * FSK : timeout number of bytes + * LoRa: timeout in symbols + * @param fixLen Fixed length packets [0: variable, 1: fixed] + * @param payload_len Sets payload length when fixed lenght is used + * @param crc_on Enables/Disables the CRC [0: OFF, 1: ON] + * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) + * @param hop_period Number of symbols bewteen each hop (LoRa only) + * @param iq_inverted Inverts IQ signals ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * @param rx_continuous Sets the reception in continuous mode + * [false: single mode, true: continuous mode] + */ + virtual void set_rx_config (radio_modems_t modem, uint32_t bandwidth, + uint32_t datarate, uint8_t coderate, + uint32_t bandwidth_afc, uint16_t preamble_len, + uint16_t symb_timeout, bool fix_len, + uint8_t payload_len, + bool crc_on, bool freq_hop_on, uint8_t hop_period, + bool iq_inverted, bool rx_continuous); + + /** + * Sets the transmission parameters + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param power Sets the output power [dBm] + * @param fdev Sets the frequency deviation ( FSK only ) + * FSK : [Hz] + * LoRa: 0 + * @param bandwidth Sets the bandwidth ( LoRa only ) + * FSK : 0 + * LoRa: [0: 125 kHz, 1: 250 kHz, + * 2: 500 kHz, 3: Reserved] + * @param datarate Sets the Datarate + * FSK : 600..300000 bits/s + * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, + * 10: 1024, 11: 2048, 12: 4096 chips] + * @param coderate Sets the coding rate ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] + * @param preamble_len Sets the preamble length + * @param fix_len Fixed length packets [0: variable, 1: fixed] + * @param crc_on Enables disables the CRC [0: OFF, 1: ON] + * @param freq_hop_on Enables disables the intra-packet frequency hopping [0: OFF, 1: ON] (LoRa only) + * @param hop_period Number of symbols bewteen each hop (LoRa only) + * @param iq_inverted Inverts IQ signals ( LoRa only ) + * FSK : N/A ( set to 0 ) + * LoRa: [0: not inverted, 1: inverted] + * @param timeout Transmission timeout [ms] + */ + virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preamble_len, + bool fix_len, bool crc_on, bool freq_hop_on, + uint8_t hop_period, bool iq_inverted, uint32_t timeout); + + /** + * Sends the buffer of size + * + * Prepares the packet to be sent and sets the radio in transmission + * + * @param buffer Buffer pointer + * @param size Buffer size + */ + virtual void send(uint8_t *buffer, uint8_t size); + + /** + * Sets the radio to receive + * + * All necessary configuration options for reception are set in + * 'set_rx_config(parameters)' API. + */ + virtual void receive(void); + + /** + * Sets the carrier frequency + * + * @param freq Channel RF frequency + */ + virtual void set_channel(uint32_t freq); + + /** + * Generates a 32 bits random value based on the RSSI readings + * + * Remark this function sets the radio in LoRa modem mode and disables + * all interrupts. + * After calling this function either Radio.SetRxConfig or + * Radio.SetTxConfig functions must be called. + * + * @return 32 bits random value + */ + virtual uint32_t random(void); + + /** + * Get radio status + * + * @param status Radio status [RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] + * @return Return current radio status + */ + virtual uint8_t get_status(void); + + /** + * Sets the maximum payload length + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param max Maximum payload length in bytes + */ + virtual void set_max_payload_length(radio_modems_t modem, uint8_t max); + + /** + * Sets the network to public or private + * + * Updates the sync byte. Applies to LoRa modem only + * + * @param enable if true, it enables a public network + */ + virtual void set_public_network(bool enable); + + /** + * Computes the packet time on air for the given payload + * + * Remark can only be called once SetRxConfig or SetTxConfig have been called + * + * @param modem Radio modem to be used [0: FSK, 1: LoRa] + * @param pkt_len Packet payload length + * @return Computed airTime for the given packet payload length + */ + virtual uint32_t time_on_air(radio_modems_t modem, uint8_t pkt_len); + + /** + * Perform carrier sensing + * + * Checks for a certain time if the RSSI is above a given threshold. + * This threshold determines if there is already a transmission going on + * in the channel or not. + * + * @param modem Type of the radio modem + * @param freq Carrier frequency + * @param rssi_threshold Threshold value of RSSI + * @param max_carrier_sense_time time to sense the channel + * + * @return true if there is no active transmission + * in the channel, false otherwise + */ + virtual bool perform_carrier_sense(radio_modems_t modem, + uint32_t freq, + int16_t rssi_threshold, + uint32_t max_carrier_sense_time); + + /** + * Sets the radio in CAD mode + * + */ + virtual void start_cad(void); + + /** + * Check if the given RF is in range + * + * @param frequency frequency needed to be checked + */ + virtual bool check_rf_frequency(uint32_t frequency); + + /** Sets the radio in continuous wave transmission mode + * + * @param freq Channel RF frequency + * @param power Sets the output power [dBm] + * @param time Transmission mode timeout [s] + */ + virtual void set_tx_continuous_wave(uint32_t freq, int8_t power, uint16_t time); + + /** + * Acquire exclusive access + */ + virtual void lock(void); + + /** + * Release exclusive access + */ + virtual void unlock(void); + +private: + + // SPI and chip select control + mbed::SPI _spi; + mbed::DigitalOut _chip_select; + + // module rest control + mbed::DigitalInOut _reset_ctl; + + // Interrupt controls + mbed::InterruptIn _dio1_ctl;; + + // module busy control + mbed::DigitalIn _busy; + + // module frequency selection + mbed::AnalogIn _freq_select; + + // module device variant selection + mbed::AnalogIn _dev_select; + + // module TCXO/XTAL control + mbed::DigitalIn _crystal_select; + + // Radio specific controls (TX/RX duplexer switch control) + mbed::DigitalInOut _ant_switch; + + // Structure containing function pointers to the stack callbacks + radio_events_t *_radio_events; + + // Data buffer used for both TX and RX + // Size of this buffer is configurable via Mbed config system + // Default is 255 bytes + uint8_t _data_buffer[MAX_DATA_BUFFER_SIZE_SX126X]; + +#ifdef MBED_CONF_RTOS_PRESENT + // Thread to handle interrupts + rtos::Thread irq_thread; +#endif + + // Access protection + PlatformMutex mutex; + + // helper functions + void wakeup(); + void read_opmode_command(uint8_t cmd, uint8_t *buffer, uint16_t size); + void write_opmode_command(uint8_t cmd, uint8_t *buffer, uint16_t size); + void set_dio2_as_rfswitch_ctrl(uint8_t enable); + void set_dio3_as_tcxo_ctrl(radio_TCXO_ctrl_voltage_t voltage, uint32_t timeout); + uint8_t get_device_variant(void); + void set_device_ready(void); + int8_t get_rssi(); + uint8_t get_fsk_bw_reg_val(uint32_t bandwidth); + void write_to_register(uint16_t addr, uint8_t data); + void write_to_register(uint16_t addr, uint8_t *data, uint8_t size); + uint8_t read_register(uint16_t addr); + void read_register(uint16_t addr, uint8_t *buffer, uint8_t size); + void write_fifo(uint8_t *buffer, uint8_t size); + void read_fifo(uint8_t *buffer, uint8_t size, uint8_t offset); + void rf_irq_task(void); + void set_modem(uint8_t modem); + uint8_t get_modem(); + uint16_t get_irq_status(void); + uint8_t get_frequency_support(void); + + // ISR + void dio1_irq_isr(); + + // Handler called by thread in response to signal + void handle_dio1_irq(); + + void set_modulation_params(modulation_params_t *modulationParams); + void set_packet_params(packet_params_t *packet_params); + void set_cad_params(lora_cad_symbols_t nb_symbols, uint8_t det_peak, + uint8_t det_min, cad_exit_modes_t exit_mode, + uint32_t timeout); + void set_buffer_base_addr(uint8_t tx_base_addr, uint8_t rx_base_addr); + void get_rx_buffer_status(uint8_t *payload_len, uint8_t *rx_buffer_ptr); + void get_packet_status(packet_status_t *pkt_status); + radio_error_t get_device_errors(void); + void clear_device_errors(void); + void clear_irq_status(uint16_t irq); + void set_crc_seed(uint16_t seed); + void set_crc_polynomial(uint16_t polynomial); + void set_whitening_seed(uint16_t seed); + void set_pa_config( uint8_t pa_DC, uint8_t hp_max, uint8_t device_type, + uint8_t pa_LUT ); + void set_tx_power(int8_t power); + void calibrate_image(uint32_t freq); + void configure_dio_irq(uint16_t irq_mask, uint16_t dio1_mask, + uint16_t dio2_mask, uint16_t dio3_mask); + void cold_start_wakeup(); + +private: + uint8_t _active_modem; + uint8_t _standby_mode; + uint8_t _operation_mode; + uint8_t _reception_mode; + uint32_t _tx_timeout; + uint32_t _rx_timeout; + uint8_t _rx_timeout_in_symbols; + int8_t _tx_power; + bool _image_calibrated; + bool _force_image_calibration; + bool _network_mode_public; + + // Structure containing all user and network specified settings + // for radio module + modulation_params_t _mod_params; + packet_params_t _packet_params; +}; + +#endif /* MBED_LORA_RADIO_DRV_SX126X_LORARADIO_H_ */ diff --git a/SX126X/SleepMode.txt b/SX126X/SleepMode.txt new file mode 100644 index 0000000000..95b607f0fb --- /dev/null +++ b/SX126X/SleepMode.txt @@ -0,0 +1,22 @@ +Sleep Modes: + +The SX126X series LoRa radios define two different sleep modes, namely: + +i) Sleep mode with Cold Start (default mode in Mbed LoRaWAN stack) +ii) Sleep mode with Warm Start + + +Sleep mode with Warm Start: +This is the default sleep mode for this driver. Radio configurations are retained in this mode. +Typical power consumption in this mode is '600 nA'. + + +Sleep mode with Cold Start: +The driver can be configured to sleep with cold startup. This mode is the lowest power consuming state +for the SX126X series radios. No configurations are retained in this mode, that's why our driver takes +extra measures to keep backups of the configuration in the RAM. Typical power consumption in this mode +is '160 nA'. The radio takes about 3.5 milliseconds to wakeup properly because upon going to sleep all +components gets turned off. The radio thread blocks for that period of time. However, to reduce the impact +of this wakeup time on the time critical operations, the stack shouldn't put the radio to standby rather than +sleep before performing time critical operations. Mbed OS LoRaWAN stack handles this automatically which means +that the user can safely use sleep mode with cold start. \ No newline at end of file diff --git a/SX126X/mbed_lib.json b/SX126X/mbed_lib.json new file mode 100644 index 0000000000..b524a9f4ce --- /dev/null +++ b/SX126X/mbed_lib.json @@ -0,0 +1,29 @@ +{ + "name": "SX126X-lora-driver", + "config": { + "spi-frequency": { + "help": "SPI frequency, Default: 16 MHz", + "value": 16000000 + }, + "buffer-size": { + "help": "Max. buffer size the radio can handle, Default: 255 B", + "value": 255 + }, + "boost-rx": { + "help": "Increases sensitivity at the cost of power ~2mA for around ~3dB in sensitivity 0 = disabled, 1 = enabled", + "value": 0 + }, + "regulator-mode": { + "help": "Default: DCDC (low power, high BOM). Alternatively, LDO = 0. Check datasheet section 5.1 for more details", + "value": 1 + }, + "sleep-mode": { + "help": "Default: Cold start = 1, Warm start = 0. Check SleepMode.txt", + "value": 1 + }, + "standby-mode": { + "help": "Default: STDBY_RC = 0, STDBY_XOSC = 1", + "value": 0 + } + } +} diff --git a/SX126X/sx126x_ds.h b/SX126X/sx126x_ds.h new file mode 100644 index 0000000000..a15336adf4 --- /dev/null +++ b/SX126X/sx126x_ds.h @@ -0,0 +1,612 @@ +/* + * sx126x_ds.h + * + * Created on: Feb 20, 2019 + * Author: hasnain + */ + +#ifndef MBED_LORA_RADIO_DRV_SX126X_SX126X_DS_H_ +#define MBED_LORA_RADIO_DRV_SX126X_SX126X_DS_H_ + +#include "LoRaRadio.h" +/*! + * \brief Provides the frequency of the chip running on the radio and the frequency step + * + * \remark These defines are used for computing the frequency divider to set the RF frequency + */ +#define XTAL_FREQ 32000000 +#define FREQ_DIV 33554432 +#define FREQ_STEP 0.95367431640625 // ((double)(XTAL_FREQ / (double)FREQ_DIV)) +#define FREQ_ERR 0.47683715820312 + + +/*! + * \brief List of devices supported by this driver + */ +#define SX1261 0 +#define SX1262 1 +#define SX1268 2 + +/*! + * \brief List of matching supported by the sx126x + */ +#define MATCHING_FREQ_915 0 +#define MATCHING_FREQ_780 1 +#define MATCHING_FREQ_490 2 +#define MATCHING_FREQ_434 3 +#define MATCHING_FREQ_280 4 +#define MATCHING_FREQ_169 5 +#define MATCHING_FREQ_868 6 + +/*! + * \brief Compensation delay for SetAutoTx/Rx functions in 15.625 microseconds + */ +#define AUTO_RX_TX_OFFSET 2 + +/*! + * \brief LFSR initial value to compute IBM type CRC + */ +#define CRC_IBM_SEED 0xFFFF + +/*! + * \brief LFSR initial value to compute CCIT type CRC + */ +#define CRC_CCITT_SEED 0x1D0F + +/*! + * \brief Polynomial used to compute IBM CRC + */ +#define CRC_POLYNOMIAL_IBM 0x8005 + +/*! + * \brief Polynomial used to compute CCIT CRC + */ +#define CRC_POLYNOMIAL_CCITT 0x1021 + +/*! + * \brief The address of the register holding the first byte defining the CRC seed + * + */ +#define REG_LR_CRCSEEDBASEADDR 0x06BC + +/*! + * \brief The address of the register holding the first byte defining the CRC polynomial + */ +#define REG_LR_CRCPOLYBASEADDR 0x06BE + +/*! + * \brief The address of the register holding the first byte defining the whitening seed + */ +#define REG_LR_WHITSEEDBASEADDR_MSB 0x06B8 +#define REG_LR_WHITSEEDBASEADDR_LSB 0x06B9 + +/*! + * \brief The address of the register holding the packet configuration + */ +#define REG_LR_PACKETPARAMS 0x0704 + +/*! + * \brief The address of the register holding the payload size + */ +#define REG_LR_PAYLOADLENGTH 0x0702 + +/*! + * \brief The addresses of the registers holding SyncWords values + */ +#define REG_LR_SYNCWORDBASEADDRESS 0x06C0 + +/*! + * \brief The addresses of the register holding LoRa Modem SyncWord value + */ +#define REG_LR_SYNCWORD 0x0740 + +/*! + * Syncword for Private LoRa networks + */ +#define LORA_MAC_PRIVATE_SYNCWORD 0x1424 + +/*! + * Syncword for Public LoRa networks + */ +#define LORA_MAC_PUBLIC_SYNCWORD 0x3444 + +/*! + * The address of the register giving a 4 bytes random number + */ +#define RANDOM_NUMBER_GENERATORBASEADDR 0x0819 + +/*! + * The address of the register holding RX Gain value (0x94: power saving, 0x96: rx boosted) + */ +#define REG_RX_GAIN 0x08AC + +/*! + * The address of the register holding frequency error indication + */ +#define REG_FREQUENCY_ERRORBASEADDR 0x076B + +/*! + * Change the value on the device internal trimming capacitor + */ +#define REG_XTA_TRIM 0x0911 + +/*! + * Set the current max value in the over current protection + */ +#define REG_OCP 0x08E7 + + +/*! + * \brief Represents the Rx internal counters values when GFSK or LoRa packet type is used + */ +typedef struct { + radio_modems_t modem_type; //!< Packet to which the packet status are referring to. + uint16_t packet_received; + uint16_t crc_ok; + uint16_t length_error; +} rx_counter_t; + +/*! + * \brief Represents a calibration configuration + */ +typedef union { + struct { + uint8_t rc64k_enable : 1; //!< Calibrate RC64K clock + uint8_t rc13m_enable : 1; //!< Calibrate RC13M clock + uint8_t pll_enable : 1; //!< Calibrate PLL + uint8_t adc_pulse_enable : 1; //!< Calibrate ADC Pulse + uint8_t adc_bulkN_enable : 1; //!< Calibrate ADC bulkN + uint8_t adc_bulkP_enable : 1; //!< Calibrate ADC bulkP + uint8_t img_enable : 1; + uint8_t pad : 1; + } fields; + + uint8_t value; + +} caliberation_params_t; + +/*! + * \brief Represents the possible radio system error states + */ +typedef union { + struct { + uint8_t rc64k_calib : 1; //!< RC 64kHz oscillator calibration failed + uint8_t rc13m_calib : 1; //!< RC 13MHz oscillator calibration failed + uint8_t pll_calib : 1; //!< PLL calibration failed + uint8_t adc_calib : 1; //!< ADC calibration failed + uint8_t img_calib : 1; //!< Image calibration failed + uint8_t xosc_start : 1; //!< XOSC oscillator failed to start + uint8_t pll_lock : 1; //!< PLL lock failed + uint8_t buck_start : 1; //!< Buck converter failed to start + uint8_t pa_ramp : 1; //!< PA ramp failed + uint8_t reserved : 7; //!< reserved + } fields; + + uint16_t value; + +} radio_error_t; + +/*! + * \brief Represents the operating mode the radio is actually running + */ +typedef enum { + MODE_SLEEP = 0x00, //! The radio is in sleep mode + MODE_DEEP_SLEEP, //! The radio is in deep-sleep mode + MODE_STDBY_RC, //! The radio is in standby mode with RC oscillator + MODE_STDBY_XOSC, //! The radio is in standby mode with XOSC oscillator + MODE_FS, //! The radio is in frequency synthesis mode + MODE_TX, //! The radio is in transmit mode + MODE_RX, //! The radio is in receive mode + MODE_RX_DC, //! The radio is in receive duty cycle mode + MODE_CAD //! The radio is in channel activity detection mode +} radio_operating_mode_t; + +/*! + * \brief Declares the oscillator in use while in standby mode + * + * Using the STDBY_RC standby mode allow to reduce the energy consumption + * STDBY_XOSC should be used for time critical applications + */ +typedef enum { + STDBY_RC = 0x00, + STDBY_XOSC = 0x01, +} radio_standby_mode_t; + +/*! + * \brief Declares the power regulation used to power the device + * + * This command allows the user to specify if DC-DC or LDO is used for power regulation. + * Using only LDO implies that the Rx or Tx current is doubled + */ +typedef enum { + USE_LDO = 0x00, // default + USE_DCDC = 0x01, +} radio_regulator_mode_t; + +/*! + * \brief Represents the ramping time for power amplifier + */ +typedef enum { + RADIO_RAMP_10_US = 0x00, + RADIO_RAMP_20_US = 0x01, + RADIO_RAMP_40_US = 0x02, + RADIO_RAMP_80_US = 0x03, + RADIO_RAMP_200_US = 0x04, + RADIO_RAMP_800_US = 0x05, + RADIO_RAMP_1700_US = 0x06, + RADIO_RAMP_3400_US = 0x07, +} radio_ramp_time_t; + +/*! + * \brief Represents the number of symbols to be used for channel activity detection operation + */ +typedef enum { + LORA_CAD_01_SYMBOL = 0x00, + LORA_CAD_02_SYMBOL = 0x01, + LORA_CAD_04_SYMBOL = 0x02, + LORA_CAD_08_SYMBOL = 0x03, + LORA_CAD_16_SYMBOL = 0x04, +} lora_cad_symbols_t; + +/*! + * \brief Represents the Channel Activity Detection actions after the CAD operation is finished + */ +typedef enum { + LORA_CAD_ONLY = 0x00, + LORA_CAD_RX = 0x01, + LORA_CAD_LBT = 0x10, +} cad_exit_modes_t; + +/*! + * \brief Represents the modulation shaping parameter + */ +typedef enum { + MOD_SHAPING_OFF = 0x00, + MOD_SHAPING_G_BT_03 = 0x08, + MOD_SHAPING_G_BT_05 = 0x09, + MOD_SHAPING_G_BT_07 = 0x0A, + MOD_SHAPING_G_BT_1 = 0x0B, +} radio_mod_shaping_t; + +/*! + * \brief Represents the modulation shaping parameter + */ +typedef enum { + RX_BW_4800 = 0x1F, + RX_BW_5800 = 0x17, + RX_BW_7300 = 0x0F, + RX_BW_9700 = 0x1E, + RX_BW_11700 = 0x16, + RX_BW_14600 = 0x0E, + RX_BW_19500 = 0x1D, + RX_BW_23400 = 0x15, + RX_BW_29300 = 0x0D, + RX_BW_39000 = 0x1C, + RX_BW_46900 = 0x14, + RX_BW_58600 = 0x0C, + RX_BW_78200 = 0x1B, + RX_BW_93800 = 0x13, + RX_BW_117300 = 0x0B, + RX_BW_156200 = 0x1A, + RX_BW_187200 = 0x12, + RX_BW_234300 = 0x0A, + RX_BW_312000 = 0x19, + RX_BW_373600 = 0x11, + RX_BW_467000 = 0x09, +} radio_rx_bandwidth_t; + +/*! + * \brief Represents the possible spreading factor values in LoRa packet types + */ +typedef enum { + LORA_SF5 = 0x05, + LORA_SF6 = 0x06, + LORA_SF7 = 0x07, + LORA_SF8 = 0x08, + LORA_SF9 = 0x09, + LORA_SF10 = 0x0A, + LORA_SF11 = 0x0B, + LORA_SF12 = 0x0C, +} lora_spread_factors_t; + +/*! + * \brief Represents the bandwidth values for LoRa packet type + */ +typedef enum { + LORA_BW_500 = 6, + LORA_BW_250 = 5, + LORA_BW_125 = 4, + LORA_BW_062 = 3, + LORA_BW_041 = 10, + LORA_BW_031 = 2, + LORA_BW_020 = 9, + LORA_BW_015 = 1, + LORA_BW_010 = 8, + LORA_BW_007 = 0, +} lora_bandwidths_t; + +const uint8_t lora_bandwidhts [] = {LORA_BW_125, LORA_BW_250, LORA_BW_500}; + +/*! + * \brief Represents the coding rate values for LoRa packet type + */ +typedef enum { + LORA_CR_4_5 = 0x01, + LORA_CR_4_6 = 0x02, + LORA_CR_4_7 = 0x03, + LORA_CR_4_8 = 0x04, +} lora_coding_tates_t; + +/*! + * \brief Represents the preamble length used to detect the packet on Rx side + */ +typedef enum { + RADIO_PREAMBLE_DETECTOR_OFF = 0x00, //!< Preamble detection length off + RADIO_PREAMBLE_DETECTOR_08_BITS = 0x04, //!< Preamble detection length 8 bits + RADIO_PREAMBLE_DETECTOR_16_BITS = 0x05, //!< Preamble detection length 16 bits + RADIO_PREAMBLE_DETECTOR_24_BITS = 0x06, //!< Preamble detection length 24 bits + RADIO_PREAMBLE_DETECTOR_32_BITS = 0x07, //!< Preamble detection length 32 bit +} radio_preamble_detection_t; + +/*! + * \brief Represents the possible combinations of SyncWord correlators activated + */ +typedef enum { + RADIO_ADDRESSCOMP_FILT_OFF = 0x00, //!< No correlator turned on, i.e. do not search for SyncWord + RADIO_ADDRESSCOMP_FILT_NODE = 0x01, + RADIO_ADDRESSCOMP_FILT_NODE_BROAD = 0x02, +} radio_address_filter_t; + +/*! + * \brief Radio packet length mode + */ +typedef enum { + RADIO_PACKET_VARIABLE_LENGTH = 0x00, //!< The packet is on variable size, header included + RADIO_PACKET_FIXED_LENGTH = 0x01, //!< The packet is known on both sides, no header included in the packet +} radio_pkt_length_t; + +/*! + * \brief Represents the CRC length + */ +typedef enum radio_crc_types_e{ + RADIO_CRC_OFF = 0x01, //!< No CRC in use + RADIO_CRC_1_BYTES = 0x00, + RADIO_CRC_2_BYTES = 0x02, + RADIO_CRC_1_BYTES_INV = 0x04, + RADIO_CRC_2_BYTES_INV = 0x06, + RADIO_CRC_2_BYTES_IBM = 0xF1, + RADIO_CRC_2_BYTES_CCIT = 0xF2, +} radio_crc_types_t; + +/*! + * \brief Radio whitening mode activated or deactivated + */ +typedef enum { + RADIO_DC_FREE_OFF = 0x00, + RADIO_DC_FREEWHITENING = 0x01, +} radio_whitening_mode_t; + +/*! + * \brief Holds the lengths mode of a LoRa packet type + */ +typedef enum { + LORA_PACKET_VARIABLE_LENGTH = 0x00, //!< The packet is on variable size, header included + LORA_PACKET_FIXED_LENGTH = 0x01, //!< The packet is known on both sides, no header included in the packet + LORA_PACKET_EXPLICIT = LORA_PACKET_VARIABLE_LENGTH, + LORA_PACKET_IMPLICIT = LORA_PACKET_FIXED_LENGTH, +} lora_pkt_length_t; + +/*! + * \brief Represents the CRC mode for LoRa packet type + */ +typedef enum { + LORA_CRC_ON = 0x01, //!< CRC activated + LORA_CRC_OFF = 0x00, //!< CRC not used +} lora_crc_mode_t; + +/*! + * \brief Represents the IQ mode for LoRa packet type + */ +typedef enum { + LORA_IQ_NORMAL = 0x00, + LORA_IQ_INVERTED = 0x01, +} lora_IQ_mode_t; + +/*! + * \brief Represents the volatge used to control the TCXO on/off from DIO3 + */ +typedef enum { + TCXO_CTRL_1_6V = 0x00, + TCXO_CTRL_1_7V = 0x01, + TCXO_CTRL_1_8V = 0x02, + TCXO_CTRL_2_2V = 0x03, + TCXO_CTRL_2_4V = 0x04, + TCXO_CTRL_2_7V = 0x05, + TCXO_CTRL_3_0V = 0x06, + TCXO_CTRL_3_3V = 0x07, +} radio_TCXO_ctrl_voltage_t; + +/*! + * \brief Represents the interruption masks available for the radio + * + * \remark Note that not all these interruptions are available for all packet types + */ +typedef enum { + IRQ_RADIO_NONE = 0x0000, + IRQ_TX_DONE = 0x0001, + IRQ_RX_DONE = 0x0002, + IRQ_PREAMBLE_DETECTED = 0x0004, + IRQ_SYNCWORD_VALID = 0x0008, + IRQ_HEADER_VALID = 0x0010, + IRQ_HEADER_ERROR = 0x0020, + IRQ_CRC_ERROR = 0x0040, + IRQ_CAD_DONE = 0x0080, + IRQ_CAD_ACTIVITY_DETECTED = 0x0100, + IRQ_RX_TX_TIMEOUT = 0x0200, + IRQ_RADIO_ALL = 0xFFFF, +} radio_irq_masks_t; + +typedef enum { + RADIO_GET_STATUS = 0xC0, + RADIO_WRITE_REGISTER = 0x0D, + RADIO_READ_REGISTER = 0x1D, + RADIO_WRITE_BUFFER = 0x0E, + RADIO_READ_BUFFER = 0x1E, + RADIO_SET_SLEEP = 0x84, + RADIO_SET_STANDBY = 0x80, + RADIO_SET_FS = 0xC1, + RADIO_SET_TX = 0x83, + RADIO_SET_RX = 0x82, + RADIO_SET_RXDUTYCYCLE = 0x94, + RADIO_SET_CAD = 0xC5, + RADIO_SET_TXCONTINUOUSWAVE = 0xD1, + RADIO_SET_TXCONTINUOUSPREAMBLE = 0xD2, + RADIO_SET_PACKETTYPE = 0x8A, + RADIO_GET_PACKETTYPE = 0x11, + RADIO_SET_RFFREQUENCY = 0x86, + RADIO_SET_TXPARAMS = 0x8E, + RADIO_SET_PACONFIG = 0x95, + RADIO_SET_CADPARAMS = 0x88, + RADIO_SET_BUFFERBASEADDRESS = 0x8F, + RADIO_SET_MODULATIONPARAMS = 0x8B, + RADIO_SET_PACKETPARAMS = 0x8C, + RADIO_GET_RXBUFFERSTATUS = 0x13, + RADIO_GET_PACKETSTATUS = 0x14, + RADIO_GET_RSSIINST = 0x15, + RADIO_GET_STATS = 0x10, + RADIO_RESET_STATS = 0x00, + RADIO_CFG_DIOIRQ = 0x08, + RADIO_GET_IRQSTATUS = 0x12, + RADIO_CLR_IRQSTATUS = 0x02, + RADIO_CALIBRATE = 0x89, + RADIO_CALIBRATEIMAGE = 0x98, + RADIO_SET_REGULATORMODE = 0x96, + RADIO_GET_ERROR = 0x17, + RADIO_CLR_ERROR = 0x07, + RADIO_SET_TCXOMODE = 0x97, + RADIO_SET_TXFALLBACKMODE = 0x93, + RADIO_SET_RFSWITCHMODE = 0x9D, + RADIO_SET_STOPRXTIMERONPREAMBLE = 0x9F, + RADIO_SET_LORASYMBTIMEOUT = 0xA0, +} opmode_commands_t; + +/*! + * \brief Structure describing the radio status + */ +typedef union { + uint8_t value; + struct { + //bit order is lsb -> msb + uint8_t reserved : 1; //!< Reserved + uint8_t cmd_status : 3; //!< Command status + uint8_t chip_mode : 3; //!< Chip mode + uint8_t cpu_busy : 1; //!< Flag for CPU radio busy + } fields; +} radio_status_t; + +/*! + * \brief Structure describing the error codes for callback functions + */ +typedef enum { + IRQ_HEADER_ERROR_CODE = 0x01, + IRQ_SYNCWORD_ERROR_CODE = 0x02, + IRQ_CRC_ERROR_CODE = 0x04, +} irq_error_t; + + +typedef enum { + IRQ_PBL_DETECT_CODE = 0x01, + IRQ_SYNCWORD_VALID_CODE = 0x02, + IRQ_HEADER_VALID_CODE = 0x04, +} irq_valid_codes_t; + +typedef enum { + IRQ_RX_TIMEOUT = 0x00, + IRQ_TX_TIMEOUT = 0x01, +} irq_timeout_t; + +typedef enum { + RECEPTION_MODE_SINGLE = 0, + RECEPTION_MODE_CONTINUOUS, + RECEPTION_MODE_OTHER +} reception_mode_t; + +/*! + * \brief The type describing the modulation parameters for every packet types + */ +typedef struct { + radio_modems_t modem_type; //!< Packet to which the modulation parameters are referring to. + struct { + struct { + uint32_t bit_rate; + uint32_t fdev; + radio_mod_shaping_t modulation_shaping; + uint8_t bandwidth; + uint32_t operational_frequency; + } gfsk; + + struct { + lora_spread_factors_t spreading_factor; //!< Spreading Factor for the LoRa modulation + lora_bandwidths_t bandwidth; //!< Bandwidth for the LoRa modulation + lora_coding_tates_t coding_rate; //!< Coding rate for the LoRa modulation + uint8_t low_datarate_optimization; //!< Indicates if the modem uses the low datarate optimization + uint32_t operational_frequency; + } lora; + } params; //!< Holds the modulation parameters structure +} modulation_params_t; + +/*! + * \brief The type describing the packet parameters for every packet types + */ +typedef struct packet_params { + radio_modems_t modem_type; //!< Packet to which the packet parameters are referring to. + struct { + /*! + * \brief Holds the GFSK packet parameters + */ + struct { + uint16_t preamble_length; //!< The preamble Tx length for GFSK packet type in bit + radio_preamble_detection_t preamble_min_detect; //!< The preamble Rx length minimal for GFSK packet type + uint8_t syncword_length; //!< The synchronization word length for GFSK packet type + radio_address_filter_t addr_comp; //!< Activated SyncWord correlators + radio_pkt_length_t header_type; //!< If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted + uint8_t payload_length; //!< Size of the payload in the GFSK packet + radio_crc_types_t crc_length; //!< Size of the CRC block in the GFSK packet + radio_whitening_mode_t whitening_mode; + } gfsk; + /*! + * \brief Holds the LoRa packet parameters + */ + struct { + uint16_t preamble_length; //!< The preamble length is the number of LoRa symbols in the preamble + lora_pkt_length_t header_type; //!< If the header is explicit, it will be transmitted in the LoRa packet. If the header is implicit, it will not be transmitted + uint8_t payload_length; //!< Size of the payload in the LoRa packet + lora_crc_mode_t crc_mode; //!< Size of CRC block in LoRa packet + lora_IQ_mode_t invert_IQ; //!< Allows to swap IQ for LoRa packet + } lora; + } params; //!< Holds the packet parameters structure +} packet_params_t; + +/*! + * \brief Represents the packet status for every packet type + */ +typedef struct { + radio_modems_t modem_type; //!< Packet to which the packet status are referring to. + struct { + struct { + uint8_t rx_status; + int8_t rssi_avg; //!< The averaged RSSI + int8_t rssi_sync; //!< The RSSI measured on last packet + uint32_t freq_error; + } gfsk; + struct { + int8_t rssi_pkt; //!< The RSSI of the last packet + int8_t snr_pkt; //!< The SNR of the last packet + int8_t signal_rssi_pkt; + uint32_t freq_error; + } lora; + } params; +} packet_status_t; + + +#endif /* MBED_LORA_RADIO_DRV_SX126X_SX126X_DS_H_ */ From aed22776ef73ff31083be6a2264bec45dfb59c20 Mon Sep 17 00:00:00 2001 From: Antti Kauppila Date: Tue, 10 Mar 2020 10:21:22 +0200 Subject: [PATCH 34/42] Corrected copyright for sx126x_ds.h --- SX126X/sx126x_ds.h | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/SX126X/sx126x_ds.h b/SX126X/sx126x_ds.h index a15336adf4..ba07485bd7 100644 --- a/SX126X/sx126x_ds.h +++ b/SX126X/sx126x_ds.h @@ -1,8 +1,28 @@ -/* - * sx126x_ds.h +/*! + * \file sx126x.h * - * Created on: Feb 20, 2019 - * Author: hasnain + * \brief SX126x driver implementation + * + * \copyright Revised BSD License, see section \ref LICENSE. + * + * \code + * ______ _ + * / _____) _ | | + * ( (____ _____ ____ _| |_ _____ ____| |__ + * \____ \| ___ | (_ _) ___ |/ ___) _ \ + * _____) ) ____| | | || |_| ____( (___| | | | + * (______/|_____)_|_|_| \__)_____)\____)_| |_| + * (C)2013-2017 Semtech + * + * \endcode + * + * \author Miguel Luis ( Semtech ) + * + * \author Gregory Cristian ( Semtech ) + * + * Copyright (c) 2019, Arm Limited and affiliates. + * + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef MBED_LORA_RADIO_DRV_SX126X_SX126X_DS_H_ From 68beebfd11f629ba34c4656d2e1d3183a4539301 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Mon, 23 Mar 2020 10:15:59 +0200 Subject: [PATCH 35/42] Fix SPI flags for SX1272 and SX1276 --- SX1272/SX1272_LoRaRadio.cpp | 4 ++-- SX1276/SX1276_LoRaRadio.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 47750c3ed8..07c190f24b 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -32,8 +32,8 @@ SPDX-License-Identifier: BSD-3-Clause #include "sx1272Regs-Fsk.h" #include "sx1272Regs-LoRa.h" -#ifdef MBED_SX1272_LORA_RADIO_SPI_FREQUENCY -#define SPI_FREQUENCY MBED_SX1272_LORA_RADIO_SPI_FREQUENCY +#ifdef MBED_CONF_SX1272_LORA_DRIVER_SPI_FREQUENCY +#define SPI_FREQUENCY MBED_CONF_SX1272_LORA_DRIVER_SPI_FREQUENCY #else #define SPI_FREQUENCY 8000000 #endif diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 2f533fbf8d..94e7fb51be 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -154,8 +154,8 @@ enum RadioVariant { SX1276MB1MAS }; -#ifdef MBED_SX1276_LORA_RADIO_SPI_FREQUENCY -#define SPI_FREQUENCY MBED_SX1276_LORA_RADIO_SPI_FREQUENCY +#ifdef MBED_CONF_SX1276_LORA_DRIVER_SPI_FREQUENCY +#define SPI_FREQUENCY MBED_CONF_SX1276_LORA_DRIVER_SPI_FREQUENCY #else #define SPI_FREQUENCY 8000000 #endif From 2867b1878aa6fb67107ff8a9e5e7d2eb22c14449 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Wed, 25 Mar 2020 12:47:30 +0200 Subject: [PATCH 36/42] Lora: Replace deprecated methods with new ones in Semtech drivers --- SX126X/SX126X_LoRaRadio.cpp | 14 ++++++++------ SX1272/SX1272_LoRaRadio.cpp | 34 ++++++++++++++++++++-------------- SX1276/SX1276_LoRaRadio.cpp | 37 +++++++++++++++++++------------------ 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/SX126X/SX126X_LoRaRadio.cpp b/SX126X/SX126X_LoRaRadio.cpp index 30cc5948bb..29497a50da 100644 --- a/SX126X/SX126X_LoRaRadio.cpp +++ b/SX126X/SX126X_LoRaRadio.cpp @@ -23,6 +23,7 @@ SPDX-License-Identifier: BSD-3-Clause */ #include +#include "ThisThread.h" #include "mbed_wait_api.h" #include "Timer.h" #include "SX126X_LoRaRadio.h" @@ -34,8 +35,9 @@ SPDX-License-Identifier: BSD-3-Clause #endif using namespace mbed; -#ifdef MBED_CONF_RTOS_PRESENT using namespace rtos; + +#ifdef MBED_CONF_RTOS_PRESENT /** * Signals */ @@ -202,7 +204,7 @@ bool SX126X_LoRaRadio::perform_carrier_sense(radio_modems_t modem, receive(); // hold on a bit, radio turn-around time - wait_ms(1); + ThisThread::sleep_for(1); Timer elapsed_time; elapsed_time.start(); @@ -503,10 +505,10 @@ void SX126X_LoRaRadio::radio_reset() _reset_ctl.output(); _reset_ctl = 0; // should be enough, required is 50-100 us - wait_ms(2); + ThisThread::sleep_for(2); _reset_ctl.input(); // give some time for automatic image calibration - wait_ms(6); + ThisThread::sleep_for(6); } void SX126X_LoRaRadio::wakeup() @@ -540,7 +542,7 @@ void SX126X_LoRaRadio::sleep(void) #endif write_opmode_command(RADIO_SET_SLEEP, &sleep_state, 1); - wait_ms(2); + ThisThread::sleep_for(2); } uint32_t SX126X_LoRaRadio::random(void) @@ -552,7 +554,7 @@ uint32_t SX126X_LoRaRadio::random(void) _reception_mode = RECEPTION_MODE_OTHER; _rx_timeout = 0xFFFFFFFF; receive(); - wait_ms(1); + ThisThread::sleep_for(1); read_register(RANDOM_NUMBER_GENERATORBASEADDR, buf, 4); standby(); diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 07c190f24b..872d982b44 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -23,15 +23,20 @@ Copyright (c) 2017, Arm Limited and affiliates. SPDX-License-Identifier: BSD-3-Clause */ -#include -#include //rint -#include -#include "mbed.h" - #include "SX1272_LoRaRadio.h" #include "sx1272Regs-Fsk.h" #include "sx1272Regs-LoRa.h" +#include "rtos/ThisThread.h" +#include "platform/Callback.h" +#include "drivers/Timer.h" +#include "platform/mbed_wait_api.h" + +#include //rint + +using namespace mbed; +using namespace rtos; + #ifdef MBED_CONF_SX1272_LORA_DRIVER_SPI_FREQUENCY #define SPI_FREQUENCY MBED_CONF_SX1272_LORA_DRIVER_SPI_FREQUENCY #else @@ -383,9 +388,9 @@ void SX1272_LoRaRadio::radio_reset() { _reset_ctl.output(); _reset_ctl = 0; - wait_ms(2); + ThisThread::sleep_for(2); _reset_ctl.input(); - wait_ms(6); + ThisThread::sleep_for(6); } /** @@ -720,7 +725,7 @@ void SX1272_LoRaRadio::send(uint8_t *buffer, uint8_t size) // FIFO operations can not take place in Sleep mode if ((read_register(REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) { standby(); - wait_ms(1); + ThisThread::sleep_for(1); } if (_rf_settings.fsk.fix_len == false) { @@ -770,7 +775,7 @@ void SX1272_LoRaRadio::send(uint8_t *buffer, uint8_t size) // FIFO operations can not take place in Sleep mode if ((read_register(REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) { standby(); - wait_ms(1); + ThisThread::sleep_for(1); } // write payload buffer write_fifo(buffer, size); @@ -1043,7 +1048,7 @@ bool SX1272_LoRaRadio::perform_carrier_sense(radio_modems_t modem, set_operation_mode(RF_OPMODE_RECEIVER); // hold on a bit, radio turn-around time - wait_ms(1); + ThisThread::sleep_for(1); Timer elapsed_time; elapsed_time.start(); @@ -1161,7 +1166,7 @@ uint32_t SX1272_LoRaRadio::random() set_operation_mode(RF_OPMODE_RECEIVER); for (i = 0; i < 32; i++) { - wait_ms(1); + ThisThread::sleep_for(1); // Unfiltered RSSI value reading. Only takes the LSB value rnd |= ((uint32_t) read_register(REG_LR_RSSIWIDEBAND) & 0x01) << i; } @@ -1454,14 +1459,14 @@ void SX1272_LoRaRadio::set_sx1272_variant_type() { if (_rf_ctrls.ant_switch != NC){ _ant_switch.input(); - wait_ms(1); + ThisThread::sleep_for(1); if (_ant_switch == 1) { radio_variant = SX1272MB1DCS; } else { radio_variant = SX1272MB2XAS; } _ant_switch.output(); - wait_ms(1); + ThisThread::sleep_for(1); } else { radio_variant = MBED_CONF_SX1272_LORA_DRIVER_RADIO_VARIANT; } @@ -1560,8 +1565,9 @@ void SX1272_LoRaRadio::setup_spi() // otherwise use default SPI frequency which is 8 MHz _spi.frequency(spi_freq); #endif + // 100 us wait to settle down - wait(0.1); + wait_us(100); } /** diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 94e7fb51be..155d266542 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -22,21 +22,21 @@ Copyright (c) 2017, Arm Limited and affiliates. SPDX-License-Identifier: BSD-3-Clause */ -#include -#include //rint -#include #include "PinNames.h" -#include "Callback.h" -#include "mbed_wait_api.h" -#include "Timer.h" -#ifdef MBED_CONF_RTOS_PRESENT -#include "ThisThread.h" -using namespace rtos; -#endif +#include "platform/Callback.h" +#include "platform/mbed_wait_api.h" +#include "drivers/Timer.h" +#include "rtos/ThisThread.h" + #include "SX1276_LoRaRadio.h" #include "sx1276Regs-Fsk.h" #include "sx1276Regs-LoRa.h" +#include //rint + +using namespace rtos; +using namespace mbed; + /*! * Sync word for Private LoRa networks */ @@ -289,9 +289,9 @@ void SX1276_LoRaRadio::radio_reset() { _reset_ctl.output(); _reset_ctl = 0; - wait_ms(2); + ThisThread::sleep_for(2); _reset_ctl.input(); - wait_ms(6); + ThisThread::sleep_for(6); } /** @@ -358,7 +358,7 @@ uint32_t SX1276_LoRaRadio::random( void ) set_operation_mode(RF_OPMODE_RECEIVER); for (i = 0; i < 32; i++) { - wait_ms(1); + ThisThread::sleep_for(1); // Unfiltered RSSI value reading. Only takes the LSB value rnd |= ((uint32_t) read_register( REG_LR_RSSIWIDEBAND) & 0x01) << i; } @@ -806,7 +806,7 @@ void SX1276_LoRaRadio::send(uint8_t *buffer, uint8_t size) // FIFO operations can not take place in Sleep mode if ((read_register( REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) { standby(); - wait_ms(1); + ThisThread::sleep_for(1); } // write_to_register payload buffer write_fifo(buffer, size); @@ -1026,7 +1026,7 @@ bool SX1276_LoRaRadio::perform_carrier_sense(radio_modems_t modem, set_operation_mode(RF_OPMODE_RECEIVER); // hold on a bit, radio turn-around time - wait_ms(1); + ThisThread::sleep_for(1); Timer elapsed_time; elapsed_time.start(); @@ -1329,14 +1329,14 @@ void SX1276_LoRaRadio::set_sx1276_variant_type() { if (_rf_ctrls.ant_switch != NC) { _ant_switch.input(); - wait_ms(1); + ThisThread::sleep_for(1); if (_ant_switch == 1) { radio_variant = SX1276MB1LAS; } else { radio_variant = SX1276MB1MAS; } _ant_switch.output(); - wait_ms(1); + ThisThread::sleep_for(1); } else { radio_variant = MBED_CONF_SX1276_LORA_DRIVER_RADIO_VARIANT; } @@ -1362,8 +1362,9 @@ void SX1276_LoRaRadio::setup_spi() // otherwise use default SPI frequency which is 8 MHz _spi.frequency(spi_freq); #endif + // 100 us wait to settle down - wait(0.1); + wait_us(100); } /** From 444e72561f51ba653a73060be4a41b81c273612d Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Wed, 25 Mar 2020 12:52:29 +0200 Subject: [PATCH 37/42] Astyle fixes --- SX126X/SX126X_LoRaRadio.cpp | 189 +++++---- SX126X/SX126X_LoRaRadio.h | 14 +- SX126X/sx126x_ds.h | 4 +- SX1272/SX1272_LoRaRadio.cpp | 760 +++++++++++++++++------------------- SX1272/SX1272_LoRaRadio.h | 12 +- SX1276/SX1276_LoRaRadio.cpp | 611 ++++++++++++++--------------- SX1276/SX1276_LoRaRadio.h | 12 +- 7 files changed, 780 insertions(+), 822 deletions(-) diff --git a/SX126X/SX126X_LoRaRadio.cpp b/SX126X/SX126X_LoRaRadio.cpp index 29497a50da..21fa4cfcdd 100644 --- a/SX126X/SX126X_LoRaRadio.cpp +++ b/SX126X/SX126X_LoRaRadio.cpp @@ -47,28 +47,26 @@ using namespace rtos; /*! * FSK bandwidth definition */ -typedef struct -{ +typedef struct { uint32_t bandwidth; uint8_t register_value; } fsk_bw_t; -static const fsk_bw_t fsk_bandwidths[] = -{ - { 4800 , 0x1F }, - { 5800 , 0x17 }, - { 7300 , 0x0F }, - { 9700 , 0x1E }, - { 11700 , 0x16 }, - { 14600 , 0x0E }, - { 19500 , 0x1D }, - { 23400 , 0x15 }, - { 29300 , 0x0D }, - { 39000 , 0x1C }, - { 46900 , 0x14 }, - { 58600 , 0x0C }, - { 78200 , 0x1B }, - { 93800 , 0x13 }, +static const fsk_bw_t fsk_bandwidths[] = { + { 4800, 0x1F }, + { 5800, 0x17 }, + { 7300, 0x0F }, + { 9700, 0x1E }, + { 11700, 0x16 }, + { 14600, 0x0E }, + { 19500, 0x1D }, + { 23400, 0x15 }, + { 29300, 0x0D }, + { 39000, 0x1C }, + { 46900, 0x14 }, + { 58600, 0x0C }, + { 78200, 0x1B }, + { 93800, 0x13 }, { 117300, 0x0B }, { 156200, 0x1A }, { 187200, 0x12 }, @@ -79,12 +77,13 @@ static const fsk_bw_t fsk_bandwidths[] = { 500000, 0x00 }, // Invalid Bandwidth }; -const uint8_t sync_word[] = {0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00,0x00}; +const uint8_t sync_word[] = {0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00}; // in ms SF12 SF11 SF10 SF9 SF8 SF7 const float lora_symbol_time[3][6] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024 }, // 125 KHz - { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512 }, // 250 KHz - { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256 }}; // 500 KHz + { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512 }, // 250 KHz + { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256 } +}; // 500 KHz SX126X_LoRaRadio::SX126X_LoRaRadio(PinName mosi, PinName miso, @@ -107,7 +106,7 @@ SX126X_LoRaRadio::SX126X_LoRaRadio(PinName mosi, _crystal_select(crystal_select, PullDown), _ant_switch(ant_switch, PIN_INPUT, PullUp, 0) #ifdef MBED_CONF_RTOS_PRESENT - , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX126X") + , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX126X") #endif { _radio_events = NULL; @@ -181,8 +180,8 @@ void SX126X_LoRaRadio::clear_irq_status(uint16_t irq) { uint8_t buf[2]; - buf[0] = (uint8_t) (((uint16_t) irq >> 8) & 0x00FF); - buf[1] = (uint8_t) ((uint16_t) irq & 0x00FF); + buf[0] = (uint8_t)(((uint16_t) irq >> 8) & 0x00FF); + buf[1] = (uint8_t)((uint16_t) irq & 0x00FF); write_opmode_command((uint8_t) RADIO_CLR_IRQSTATUS, buf, 2); } @@ -287,7 +286,7 @@ void SX126X_LoRaRadio::handle_dio1_irq() if ((irq_status & IRQ_CAD_DONE) == IRQ_CAD_DONE) { if (_radio_events->cad_done) { _radio_events->cad_done((irq_status & IRQ_CAD_ACTIVITY_DETECTED) - == IRQ_CAD_ACTIVITY_DETECTED); + == IRQ_CAD_ACTIVITY_DETECTED); } } @@ -344,16 +343,16 @@ void SX126X_LoRaRadio::set_channel(uint32_t frequency) uint8_t buf[4]; uint32_t freq = 0; - if ( _force_image_calibration || !_image_calibrated) { + if (_force_image_calibration || !_image_calibrated) { calibrate_image(frequency); _image_calibrated = true; } freq = (uint32_t) ceil(((float) frequency / (float) FREQ_STEP)); - buf[0] = (uint8_t) ((freq >> 24) & 0xFF); - buf[1] = (uint8_t) ((freq >> 16) & 0xFF); - buf[2] = (uint8_t) ((freq >> 8) & 0xFF); - buf[3] = (uint8_t) (freq & 0xFF); + buf[0] = (uint8_t)((freq >> 24) & 0xFF); + buf[1] = (uint8_t)((freq >> 16) & 0xFF); + buf[2] = (uint8_t)((freq >> 8) & 0xFF); + buf[3] = (uint8_t)(freq & 0xFF); write_opmode_command((uint8_t) RADIO_SET_RFFREQUENCY, buf, 4); } @@ -389,9 +388,9 @@ void SX126X_LoRaRadio::set_dio3_as_tcxo_ctrl(radio_TCXO_ctrl_voltage_t voltage, uint8_t buf[4]; buf[0] = voltage & 0x07; - buf[1] = (uint8_t) ((timeout >> 16) & 0xFF); - buf[2] = (uint8_t) ((timeout >> 8) & 0xFF); - buf[3] = (uint8_t) (timeout & 0xFF); + buf[1] = (uint8_t)((timeout >> 16) & 0xFF); + buf[2] = (uint8_t)((timeout >> 8) & 0xFF); + buf[3] = (uint8_t)(timeout & 0xFF); write_opmode_command(RADIO_SET_TCXOMODE, buf, 4); } @@ -468,25 +467,25 @@ uint32_t SX126X_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) switch (modem) { case MODEM_FSK: { air_time = rint((8 * (_packet_params.params.gfsk.preamble_length - + (_packet_params.params.gfsk.syncword_length >> 3) - + ((_packet_params.params.gfsk.header_type - == RADIO_PACKET_FIXED_LENGTH) ? 0.0f : 1.0f) + pkt_len - + ((_packet_params.params.gfsk.crc_length == RADIO_CRC_2_BYTES) ? 2.0f : 0.0f)) - / _mod_params.params.gfsk.bit_rate) * 1000); + + (_packet_params.params.gfsk.syncword_length >> 3) + + ((_packet_params.params.gfsk.header_type + == RADIO_PACKET_FIXED_LENGTH) ? 0.0f : 1.0f) + pkt_len + + ((_packet_params.params.gfsk.crc_length == RADIO_CRC_2_BYTES) ? 2.0f : 0.0f)) + / _mod_params.params.gfsk.bit_rate) * 1000); } - break; + break; case MODEM_LORA: { float ts = lora_symbol_time[_mod_params.params.lora.bandwidth - 4][12 - - _mod_params.params.lora.spreading_factor]; + - _mod_params.params.lora.spreading_factor]; // time of preamble float t_preamble = (_packet_params.params.lora.preamble_length + 4.25f) * ts; // Symbol length of payload and time float tmp = ceil((8 * pkt_len - 4 * _mod_params.params.lora.spreading_factor - + 28 + 16 * _packet_params.params.lora.crc_mode - - ((_packet_params.params.lora.header_type == LORA_PACKET_FIXED_LENGTH) ? 20 : 0)) - / (float) (4 * (_mod_params.params.lora.spreading_factor - - ((_mod_params.params.lora.low_datarate_optimization > 0) ? 2 : 0)))) - * ((_mod_params.params.lora.coding_rate % 4) + 4); + + 28 + 16 * _packet_params.params.lora.crc_mode + - ((_packet_params.params.lora.header_type == LORA_PACKET_FIXED_LENGTH) ? 20 : 0)) + / (float)(4 * (_mod_params.params.lora.spreading_factor + - ((_mod_params.params.lora.low_datarate_optimization > 0) ? 2 : 0)))) + * ((_mod_params.params.lora.coding_rate % 4) + 4); float n_payload = 8 + ((tmp > 0) ? tmp : 0); float t_payload = n_payload * ts; // Time on air @@ -494,7 +493,7 @@ uint32_t SX126X_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) // return milliseconds (as ts is in milliseconds) air_time = floor(tOnAir + 0.999); } - break; + break; } return air_time; @@ -709,19 +708,19 @@ uint8_t SX126X_LoRaRadio::get_frequency_support(void) val = _freq_select.read_u16(); if (val < 100) { - return ( MATCHING_FREQ_915); + return (MATCHING_FREQ_915); } else if (val <= 0x3000) { - return ( MATCHING_FREQ_780); + return (MATCHING_FREQ_780); } else if (val <= 0x4900) { // 0x4724 - return ( MATCHING_FREQ_490); + return (MATCHING_FREQ_490); } else if (val <= 1) { - return ( MATCHING_FREQ_434); + return (MATCHING_FREQ_434); } else if (val <= 1) { - return ( MATCHING_FREQ_280); + return (MATCHING_FREQ_280); } else if (val <= 0xF000) { - return ( MATCHING_FREQ_169); + return (MATCHING_FREQ_169); } else { - return ( MATCHING_FREQ_868); + return (MATCHING_FREQ_868); } } @@ -770,9 +769,9 @@ void SX126X_LoRaRadio::set_tx_config(radio_modems_t modem, _mod_params.modem_type = MODEM_FSK; _mod_params.params.gfsk.bit_rate = datarate; - _mod_params.params.gfsk.modulation_shaping = MOD_SHAPING_G_BT_1; - _mod_params.params.gfsk.bandwidth = get_fsk_bw_reg_val(bandwidth); - _mod_params.params.gfsk.fdev = fdev; + _mod_params.params.gfsk.modulation_shaping = MOD_SHAPING_G_BT_1; + _mod_params.params.gfsk.bandwidth = get_fsk_bw_reg_val(bandwidth); + _mod_params.params.gfsk.fdev = fdev; _packet_params.modem_type = MODEM_FSK; _packet_params.params.gfsk.preamble_length = (preamble_len << 3); // convert byte into bit @@ -780,8 +779,8 @@ void SX126X_LoRaRadio::set_tx_config(radio_modems_t modem, _packet_params.params.gfsk.syncword_length = 3 << 3; // convert byte into bit _packet_params.params.gfsk.addr_comp = RADIO_ADDRESSCOMP_FILT_OFF; _packet_params.params.gfsk.header_type = (fix_len == true) ? - RADIO_PACKET_FIXED_LENGTH : - RADIO_PACKET_VARIABLE_LENGTH; + RADIO_PACKET_FIXED_LENGTH : + RADIO_PACKET_VARIABLE_LENGTH; if (crc_on) { _packet_params.params.gfsk.crc_length = RADIO_CRC_2_BYTES_CCIT; @@ -809,7 +808,7 @@ void SX126X_LoRaRadio::set_tx_config(radio_modems_t modem, _mod_params.params.lora.low_datarate_optimization = 0x00; } - _packet_params.modem_type = MODEM_LORA; + _packet_params.modem_type = MODEM_LORA; if ((_mod_params.params.lora.spreading_factor == LORA_SF5) || (_mod_params.params.lora.spreading_factor == LORA_SF6)) { @@ -878,13 +877,13 @@ void SX126X_LoRaRadio::set_rx_config(radio_modems_t modem, _packet_params.modem_type = MODEM_FSK; _packet_params.params.gfsk.preamble_length = (preamble_len << 3); // convert byte into bit _packet_params.params.gfsk.preamble_min_detect = - RADIO_PREAMBLE_DETECTOR_08_BITS; + RADIO_PREAMBLE_DETECTOR_08_BITS; _packet_params.params.gfsk.syncword_length = 3 << 3; // convert byte into bit _packet_params.params.gfsk.addr_comp = RADIO_ADDRESSCOMP_FILT_OFF; _packet_params.params.gfsk.header_type = - (fix_len == true) ? - RADIO_PACKET_FIXED_LENGTH : - RADIO_PACKET_VARIABLE_LENGTH; + (fix_len == true) ? + RADIO_PACKET_FIXED_LENGTH : + RADIO_PACKET_VARIABLE_LENGTH; _packet_params.params.gfsk.payload_length = max_payload_len; if (crc_on) { @@ -900,8 +899,8 @@ void SX126X_LoRaRadio::set_rx_config(radio_modems_t modem, write_to_register(REG_LR_SYNCWORDBASEADDRESS, (uint8_t *) sync_word, 8); set_whitening_seed(0x01FF); - _rx_timeout = (uint32_t) (symb_timeout - * ((1.0 / (float) datarate) * 8.0) * 1000); + _rx_timeout = (uint32_t)(symb_timeout + * ((1.0 / (float) datarate) * 8.0) * 1000); break; } @@ -910,10 +909,10 @@ void SX126X_LoRaRadio::set_rx_config(radio_modems_t modem, _rx_timeout_in_symbols = symb_timeout; _mod_params.modem_type = MODEM_LORA; _mod_params.params.lora.spreading_factor = - (lora_spread_factors_t) datarate; + (lora_spread_factors_t) datarate; _mod_params.params.lora.bandwidth = (lora_bandwidths_t) lora_bandwidhts[bandwidth]; _mod_params.params.lora.coding_rate = - (lora_coding_tates_t) coderate; + (lora_coding_tates_t) coderate; if (((bandwidth == 0) && ((datarate == 11) || (datarate == 12))) || ((bandwidth == 1) && (datarate == 12))) { @@ -961,14 +960,14 @@ void SX126X_LoRaRadio::configure_dio_irq(uint16_t irq_mask, uint16_t dio1_mask, { uint8_t buf[8]; - buf[0] = (uint8_t) ((irq_mask >> 8) & 0x00FF); - buf[1] = (uint8_t) (irq_mask & 0x00FF); - buf[2] = (uint8_t) ((dio1_mask >> 8) & 0x00FF); - buf[3] = (uint8_t) (dio1_mask & 0x00FF); - buf[4] = (uint8_t) ((dio2_mask >> 8) & 0x00FF); - buf[5] = (uint8_t) (dio2_mask & 0x00FF); - buf[6] = (uint8_t) ((dio3_mask >> 8) & 0x00FF); - buf[7] = (uint8_t) (dio3_mask & 0x00FF); + buf[0] = (uint8_t)((irq_mask >> 8) & 0x00FF); + buf[1] = (uint8_t)(irq_mask & 0x00FF); + buf[2] = (uint8_t)((dio1_mask >> 8) & 0x00FF); + buf[3] = (uint8_t)(dio1_mask & 0x00FF); + buf[4] = (uint8_t)((dio2_mask >> 8) & 0x00FF); + buf[5] = (uint8_t)(dio2_mask & 0x00FF); + buf[6] = (uint8_t)((dio3_mask >> 8) & 0x00FF); + buf[7] = (uint8_t)(dio3_mask & 0x00FF); write_opmode_command((uint8_t) RADIO_CFG_DIOIRQ, buf, 8); } @@ -979,7 +978,7 @@ void SX126X_LoRaRadio::send(uint8_t *buffer, uint8_t size) configure_dio_irq(IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, IRQ_RADIO_NONE, - IRQ_RADIO_NONE ); + IRQ_RADIO_NONE); set_modulation_params(&_mod_params); set_packet_params(&_packet_params); @@ -991,9 +990,9 @@ void SX126X_LoRaRadio::send(uint8_t *buffer, uint8_t size) // 15.625 us. Check data-sheet 13.1.4 SetTX() section. uint32_t timeout_scalled = ceil((_tx_timeout * 1000) / 15.625); - buf[0] = (uint8_t) ((timeout_scalled >> 16) & 0xFF); - buf[1] = (uint8_t) ((timeout_scalled >> 8) & 0xFF); - buf[2] = (uint8_t) (timeout_scalled & 0xFF); + buf[0] = (uint8_t)((timeout_scalled >> 16) & 0xFF); + buf[1] = (uint8_t)((timeout_scalled >> 8) & 0xFF); + buf[2] = (uint8_t)(timeout_scalled & 0xFF); write_opmode_command(RADIO_SET_TX, buf, 3); @@ -1017,8 +1016,8 @@ void SX126X_LoRaRadio::receive(void) } if (_reception_mode != RECEPTION_MODE_OTHER) { - configure_dio_irq(IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR , - IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR , + configure_dio_irq(IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR, + IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_CRC_ERROR, IRQ_RADIO_NONE, IRQ_RADIO_NONE); set_modulation_params(&_mod_params); @@ -1031,9 +1030,9 @@ void SX126X_LoRaRadio::receive(void) write_to_register(REG_RX_GAIN, 0x96); #endif - buf[0] = (uint8_t) ((_rx_timeout >> 16) & 0xFF); - buf[1] = (uint8_t) ((_rx_timeout >> 8) & 0xFF); - buf[2] = (uint8_t) (_rx_timeout & 0xFF); + buf[0] = (uint8_t)((_rx_timeout >> 16) & 0xFF); + buf[1] = (uint8_t)((_rx_timeout >> 8) & 0xFF); + buf[2] = (uint8_t)(_rx_timeout & 0xFF); write_opmode_command(RADIO_SET_RX, buf, 3); @@ -1049,7 +1048,7 @@ void SX126X_LoRaRadio::set_tx_power(int8_t power) if (power >= 14) { set_pa_config(0x04, 0x00, 0x01, 0x01); power = 14; - } else if (power < 14){ + } else if (power < 14) { set_pa_config(0x01, 0x00, 0x01, 0x01); } @@ -1102,13 +1101,13 @@ void SX126X_LoRaRadio::set_modulation_params(modulation_params_t *params) switch (params->modem_type) { case MODEM_FSK: n = 8; - temp = (uint32_t) (32 * ((float) XTAL_FREQ / (float) params->params.gfsk.bit_rate)); + temp = (uint32_t)(32 * ((float) XTAL_FREQ / (float) params->params.gfsk.bit_rate)); buf[0] = (temp >> 16) & 0xFF; buf[1] = (temp >> 8) & 0xFF; buf[2] = temp & 0xFF; buf[3] = params->params.gfsk.modulation_shaping; buf[4] = params->params.gfsk.bandwidth; - temp = (uint32_t) ((float) params->params.gfsk.fdev / (float) FREQ_STEP); + temp = (uint32_t)((float) params->params.gfsk.fdev / (float) FREQ_STEP); buf[5] = (temp >> 16) & 0xFF; buf[6] = (temp >> 8) & 0xFF; buf[7] = (temp & 0xFF); @@ -1131,7 +1130,7 @@ void SX126X_LoRaRadio::set_modulation_params(modulation_params_t *params) } void SX126X_LoRaRadio::set_pa_config(uint8_t pa_DC, uint8_t hp_max, - uint8_t device_type, uint8_t pa_LUT ) + uint8_t device_type, uint8_t pa_LUT) { uint8_t buf[4]; @@ -1146,8 +1145,8 @@ void SX126X_LoRaRadio::set_crc_seed(uint16_t seed) { if (_active_modem == MODEM_FSK) { uint8_t buf[2]; - buf[0] = (uint8_t) ((seed >> 8) & 0xFF); - buf[1] = (uint8_t) (seed & 0xFF); + buf[0] = (uint8_t)((seed >> 8) & 0xFF); + buf[1] = (uint8_t)(seed & 0xFF); write_to_register(REG_LR_CRCSEEDBASEADDR, buf, 2); } } @@ -1156,8 +1155,8 @@ void SX126X_LoRaRadio::set_crc_polynomial(uint16_t polynomial) { if (_active_modem == MODEM_FSK) { uint8_t buf[2]; - buf[0] = (uint8_t) ((polynomial >> 8) & 0xFF); - buf[1] = (uint8_t) (polynomial & 0xFF); + buf[0] = (uint8_t)((polynomial >> 8) & 0xFF); + buf[1] = (uint8_t)(polynomial & 0xFF); write_to_register(REG_LR_CRCPOLYBASEADDR, buf, 2); } } @@ -1235,9 +1234,9 @@ void SX126X_LoRaRadio::set_cad_params(lora_cad_symbols_t nb_symbols, buf[1] = det_peak; buf[2] = det_min; buf[3] = (uint8_t) exit_mode; - buf[4] = (uint8_t) ((timeout >> 16) & 0xFF); - buf[5] = (uint8_t) ((timeout >> 8) & 0xFF); - buf[6] = (uint8_t) (timeout & 0xFF); + buf[4] = (uint8_t)((timeout >> 16) & 0xFF); + buf[5] = (uint8_t)((timeout >> 8) & 0xFF); + buf[6] = (uint8_t)(timeout & 0xFF); write_opmode_command((uint8_t) RADIO_SET_CADPARAMS, buf, 7); _operation_mode = MODE_CAD; diff --git a/SX126X/SX126X_LoRaRadio.h b/SX126X/SX126X_LoRaRadio.h index 3b2bc410a5..32355d263c 100644 --- a/SX126X/SX126X_LoRaRadio.h +++ b/SX126X/SX126X_LoRaRadio.h @@ -122,7 +122,7 @@ public: * @param rx_continuous Sets the reception in continuous mode * [false: single mode, true: continuous mode] */ - virtual void set_rx_config (radio_modems_t modem, uint32_t bandwidth, + virtual void set_rx_config(radio_modems_t modem, uint32_t bandwidth, uint32_t datarate, uint8_t coderate, uint32_t bandwidth_afc, uint16_t preamble_len, uint16_t symb_timeout, bool fix_len, @@ -160,10 +160,10 @@ public: * @param timeout Transmission timeout [ms] */ virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, - uint32_t bandwidth, uint32_t datarate, - uint8_t coderate, uint16_t preamble_len, - bool fix_len, bool crc_on, bool freq_hop_on, - uint8_t hop_period, bool iq_inverted, uint32_t timeout); + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preamble_len, + bool fix_len, bool crc_on, bool freq_hop_on, + uint8_t hop_period, bool iq_inverted, uint32_t timeout); /** * Sends the buffer of size @@ -374,8 +374,8 @@ private: void set_crc_seed(uint16_t seed); void set_crc_polynomial(uint16_t polynomial); void set_whitening_seed(uint16_t seed); - void set_pa_config( uint8_t pa_DC, uint8_t hp_max, uint8_t device_type, - uint8_t pa_LUT ); + void set_pa_config(uint8_t pa_DC, uint8_t hp_max, uint8_t device_type, + uint8_t pa_LUT); void set_tx_power(int8_t power); void calibrate_image(uint32_t freq); void configure_dio_irq(uint16_t irq_mask, uint16_t dio1_mask, diff --git a/SX126X/sx126x_ds.h b/SX126X/sx126x_ds.h index ba07485bd7..b50752517b 100644 --- a/SX126X/sx126x_ds.h +++ b/SX126X/sx126x_ds.h @@ -19,7 +19,7 @@ * \author Miguel Luis ( Semtech ) * * \author Gregory Cristian ( Semtech ) - * + * * Copyright (c) 2019, Arm Limited and affiliates. * * SPDX-License-Identifier: BSD-3-Clause @@ -388,7 +388,7 @@ typedef enum { /*! * \brief Represents the CRC length */ -typedef enum radio_crc_types_e{ +typedef enum radio_crc_types_e { RADIO_CRC_OFF = 0x01, //!< No CRC in use RADIO_CRC_1_BYTES = 0x00, RADIO_CRC_2_BYTES = 0x02, diff --git a/SX1272/SX1272_LoRaRadio.cpp b/SX1272/SX1272_LoRaRadio.cpp index 872d982b44..9e042668fe 100644 --- a/SX1272/SX1272_LoRaRadio.cpp +++ b/SX1272/SX1272_LoRaRadio.cpp @@ -63,8 +63,7 @@ enum RadioVariant { /*! * FSK bandwidth definition */ -typedef struct -{ +typedef struct { uint32_t bandwidth; uint8_t register_value; } fsk_bw_t; @@ -72,8 +71,7 @@ typedef struct /*! * Radio registers definition */ -typedef struct -{ +typedef struct { modem_type modem; uint8_t addr; uint8_t value; @@ -105,24 +103,23 @@ typedef struct { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\ } -const fsk_bw_t fsk_bandwidths[] = -{ - { 2600 , 0x17 }, - { 3100 , 0x0F }, - { 3900 , 0x07 }, - { 5200 , 0x16 }, - { 6300 , 0x0E }, - { 7800 , 0x06 }, - { 10400 , 0x15 }, - { 12500 , 0x0D }, - { 15600 , 0x05 }, - { 20800 , 0x14 }, - { 25000 , 0x0C }, - { 31300 , 0x04 }, - { 41700 , 0x13 }, - { 50000 , 0x0B }, - { 62500 , 0x03 }, - { 83333 , 0x12 }, +const fsk_bw_t fsk_bandwidths[] = { + { 2600, 0x17 }, + { 3100, 0x0F }, + { 3900, 0x07 }, + { 5200, 0x16 }, + { 6300, 0x0E }, + { 7800, 0x06 }, + { 10400, 0x15 }, + { 12500, 0x0D }, + { 15600, 0x05 }, + { 20800, 0x14 }, + { 25000, 0x0C }, + { 31300, 0x04 }, + { 41700, 0x13 }, + { 50000, 0x0B }, + { 62500, 0x03 }, + { 83333, 0x12 }, { 100000, 0x0A }, { 125000, 0x02 }, { 166700, 0x11 }, @@ -185,7 +182,7 @@ SX1272_LoRaRadio::SX1272_LoRaRadio(PinName spi_mosi, _tcxo(tcxo) #ifdef MBED_CONF_RTOS_PRESENT - , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX1272") + , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX1272") #endif { _rf_ctrls.ant_switch = antswitch; @@ -289,10 +286,10 @@ bool SX1272_LoRaRadio::check_rf_frequency(uint32_t frequency) void SX1272_LoRaRadio::set_channel(uint32_t freq) { _rf_settings.channel = freq; - freq = (uint32_t) ((float) freq / (float) FREQ_STEP); - write_to_register(REG_FRFMSB, (uint8_t) ((freq >> 16) & 0xFF)); - write_to_register(REG_FRFMID, (uint8_t) ((freq >> 8) & 0xFF)); - write_to_register(REG_FRFLSB, (uint8_t) (freq & 0xFF)); + freq = (uint32_t)((float) freq / (float) FREQ_STEP); + write_to_register(REG_FRFMSB, (uint8_t)((freq >> 16) & 0xFF)); + write_to_register(REG_FRFMID, (uint8_t)((freq >> 8) & 0xFF)); + write_to_register(REG_FRFLSB, (uint8_t)(freq & 0xFF)); } /** @@ -339,44 +336,43 @@ void SX1272_LoRaRadio::set_operation_mode(uint8_t mode) */ void SX1272_LoRaRadio::set_modem(uint8_t modem) { - if ((read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON) != 0 ) { + if ((read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON) != 0) { _rf_settings.modem = MODEM_LORA; } else { _rf_settings.modem = MODEM_FSK; } - if(_rf_settings.modem == modem ) { + if (_rf_settings.modem == modem) { // if the modem is already set return; } _rf_settings.modem = modem; - switch(_rf_settings.modem) - { - default: - case MODEM_FSK: - // before changing modem mode, put the module to sleep - sleep(); - write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) - | RFLR_OPMODE_LONGRANGEMODE_OFF); + switch (_rf_settings.modem) { + default: + case MODEM_FSK: + // before changing modem mode, put the module to sleep + sleep(); + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) + | RFLR_OPMODE_LONGRANGEMODE_OFF); - // Datasheet Tables 28, 29 DIO mapping - write_to_register(REG_DIOMAPPING1, 0x00); // sets DIO0-DI03 in default mode - write_to_register(REG_DIOMAPPING2, 0x30); // bits 4-5 are turned on i.e., - // DIO5 and DIO4=ModeReady - break; - case MODEM_LORA: - sleep(); - write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) - | RFLR_OPMODE_LONGRANGEMODE_ON); + // Datasheet Tables 28, 29 DIO mapping + write_to_register(REG_DIOMAPPING1, 0x00); // sets DIO0-DI03 in default mode + write_to_register(REG_DIOMAPPING2, 0x30); // bits 4-5 are turned on i.e., + // DIO5 and DIO4=ModeReady + break; + case MODEM_LORA: + sleep(); + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) + | RFLR_OPMODE_LONGRANGEMODE_ON); - // Datasheet Tables 17 DIO mapping for LoRa - // set to defaults - write_to_register(REG_DIOMAPPING1, 0x00); // DIO0 - DIO3 defaults - write_to_register(REG_DIOMAPPING2, 0x00); // DIO4 - DIO5 defaults + // Datasheet Tables 17 DIO mapping for LoRa + // set to defaults + write_to_register(REG_DIOMAPPING1, 0x00); // DIO0 - DIO3 defaults + write_to_register(REG_DIOMAPPING2, 0x00); // DIO4 - DIO5 defaults - break; + break; } } @@ -399,12 +395,12 @@ void SX1272_LoRaRadio::radio_reset() * Must be called before setting the radio in rx mode */ void SX1272_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, - uint32_t datarate, uint8_t coderate, - uint32_t bandwidth_afc, uint16_t preamble_len, - uint16_t symb_timeout, bool fix_len, - uint8_t payload_len, - bool crc_on, bool freq_hop_on, uint8_t hop_period, - bool iq_inverted, bool rx_continuous) + uint32_t datarate, uint8_t coderate, + uint32_t bandwidth_afc, uint16_t preamble_len, + uint16_t symb_timeout, bool fix_len, + uint8_t payload_len, + bool crc_on, bool freq_hop_on, uint8_t hop_period, + bool iq_inverted, bool rx_continuous) { set_modem(modem); @@ -421,15 +417,15 @@ void SX1272_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, _rf_settings.fsk.preamble_len = preamble_len; _rf_settings.fsk.rx_single_timeout = (symb_timeout + 1) / 2; // dividing by 2 as our detector size is 2 symbols (16 bytes) - datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate); - write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8)); - write_to_register(REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); + datarate = (uint16_t)((float) XTAL_FREQ / (float) datarate); + write_to_register(REG_BITRATEMSB, (uint8_t)(datarate >> 8)); + write_to_register(REG_BITRATELSB, (uint8_t)(datarate & 0xFF)); write_to_register(REG_RXBW, get_fsk_bw_reg_val(bandwidth)); write_to_register(REG_AFCBW, get_fsk_bw_reg_val(bandwidth_afc)); - write_to_register(REG_PREAMBLEMSB, (uint8_t) ((preamble_len >> 8) & 0xFF)); - write_to_register(REG_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF)); + write_to_register(REG_PREAMBLEMSB, (uint8_t)((preamble_len >> 8) & 0xFF)); + write_to_register(REG_PREAMBLELSB, (uint8_t)(preamble_len & 0xFF)); if (fix_len == 1) { write_to_register(REG_PAYLOADLENGTH, payload_len); @@ -438,11 +434,11 @@ void SX1272_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, } write_to_register(REG_PACKETCONFIG1, (read_register(REG_PACKETCONFIG1) & RF_PACKETCONFIG1_CRC_MASK - & RF_PACKETCONFIG1_PACKETFORMAT_MASK) - | ((fix_len == 1) ? - RF_PACKETCONFIG1_PACKETFORMAT_FIXED : - RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) - | (crc_on << 4)); + & RF_PACKETCONFIG1_PACKETFORMAT_MASK) + | ((fix_len == 1) ? + RF_PACKETCONFIG1_PACKETFORMAT_FIXED : + RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) + | (crc_on << 4)); // TODO why packet mode 2 ? write_to_register(REG_PACKETCONFIG2, (read_register(REG_PACKETCONFIG2) | RF_PACKETCONFIG2_DATAMODE_PACKET)); @@ -476,42 +472,42 @@ void SX1272_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, } write_to_register(REG_LR_MODEMCONFIG1, (read_register(REG_LR_MODEMCONFIG1) & RFLR_MODEMCONFIG1_BW_MASK - & RFLR_MODEMCONFIG1_CODINGRATE_MASK - & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK - & RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK & RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK) - | (bandwidth << 6) - | (coderate << 3) | (fix_len << 2) | (crc_on << 1) - | _rf_settings.lora.low_datarate_optimize); + & RFLR_MODEMCONFIG1_CODINGRATE_MASK + & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK + & RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK & RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK) + | (bandwidth << 6) + | (coderate << 3) | (fix_len << 2) | (crc_on << 1) + | _rf_settings.lora.low_datarate_optimize); write_to_register(REG_LR_MODEMCONFIG2, (read_register(REG_LR_MODEMCONFIG2) & RFLR_MODEMCONFIG2_SF_MASK - & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK) - | (datarate << 4) - | ((symb_timeout >> 8) - & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK)); + & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK) + | (datarate << 4) + | ((symb_timeout >> 8) + & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK)); - write_to_register(REG_LR_SYMBTIMEOUTLSB, (uint8_t) (symb_timeout & 0xFF)); + write_to_register(REG_LR_SYMBTIMEOUTLSB, (uint8_t)(symb_timeout & 0xFF)); - write_to_register(REG_LR_PREAMBLEMSB, (uint8_t) ((preamble_len >> 8) & 0xFF)); - write_to_register(REG_LR_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF)); + write_to_register(REG_LR_PREAMBLEMSB, (uint8_t)((preamble_len >> 8) & 0xFF)); + write_to_register(REG_LR_PREAMBLELSB, (uint8_t)(preamble_len & 0xFF)); if (fix_len == 1) { write_to_register(REG_LR_PAYLOADLENGTH, payload_len); } if (_rf_settings.lora.freq_hop_on == true) { - write_to_register( REG_LR_PLLHOP, (read_register(REG_LR_PLLHOP) & RFLR_PLLHOP_FASTHOP_MASK) - | RFLR_PLLHOP_FASTHOP_ON); - write_to_register( REG_LR_HOPPERIOD, _rf_settings.lora.hop_period); + write_to_register(REG_LR_PLLHOP, (read_register(REG_LR_PLLHOP) & RFLR_PLLHOP_FASTHOP_MASK) + | RFLR_PLLHOP_FASTHOP_ON); + write_to_register(REG_LR_HOPPERIOD, _rf_settings.lora.hop_period); } if (datarate == 6) { - write_to_register( REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) & RFLR_DETECTIONOPTIMIZE_MASK) - | RFLR_DETECTIONOPTIMIZE_SF6); - write_to_register( REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF6); + write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) & RFLR_DETECTIONOPTIMIZE_MASK) + | RFLR_DETECTIONOPTIMIZE_SF6); + write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF6); } else { write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) & RFLR_DETECTIONOPTIMIZE_MASK) - | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); - write_to_register( REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12); + | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); + write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12); } break; @@ -550,29 +546,29 @@ void SX1272_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power, _rf_settings.fsk.iq_inverted = iq_inverted; _rf_settings.fsk.tx_timeout = timeout; - fdev = (uint16_t) ((float) fdev / (float) FREQ_STEP); - write_to_register( REG_FDEVMSB, (uint8_t) (fdev >> 8)); - write_to_register( REG_FDEVLSB, (uint8_t) (fdev & 0xFF)); + fdev = (uint16_t)((float) fdev / (float) FREQ_STEP); + write_to_register(REG_FDEVMSB, (uint8_t)(fdev >> 8)); + write_to_register(REG_FDEVLSB, (uint8_t)(fdev & 0xFF)); - datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate); - write_to_register( REG_BITRATEMSB, (uint8_t) (datarate >> 8)); - write_to_register( REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); + datarate = (uint16_t)((float) XTAL_FREQ / (float) datarate); + write_to_register(REG_BITRATEMSB, (uint8_t)(datarate >> 8)); + write_to_register(REG_BITRATELSB, (uint8_t)(datarate & 0xFF)); - write_to_register( REG_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); - write_to_register( REG_PREAMBLELSB, preamble_len & 0xFF); + write_to_register(REG_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); + write_to_register(REG_PREAMBLELSB, preamble_len & 0xFF); write_to_register(REG_PACKETCONFIG1, (read_register(REG_PACKETCONFIG1) - & RF_PACKETCONFIG1_CRC_MASK - & RF_PACKETCONFIG1_PACKETFORMAT_MASK) + & RF_PACKETCONFIG1_CRC_MASK + & RF_PACKETCONFIG1_PACKETFORMAT_MASK) | ((fix_len == 1) ? - RF_PACKETCONFIG1_PACKETFORMAT_FIXED : - RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) + RF_PACKETCONFIG1_PACKETFORMAT_FIXED : + RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) | (crc_on << 4)); //cfg_mode = read_register(REG_PACKETCONFIG2); write_to_register(REG_PACKETCONFIG2, read_register(REG_PACKETCONFIG2) - | RF_PACKETCONFIG2_DATAMODE_PACKET); + | RF_PACKETCONFIG2_DATAMODE_PACKET); break; @@ -603,40 +599,40 @@ void SX1272_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power, if (_rf_settings.lora.freq_hop_on == true) { write_to_register(REG_LR_PLLHOP, (read_register(REG_LR_PLLHOP) - & RFLR_PLLHOP_FASTHOP_MASK) - | RFLR_PLLHOP_FASTHOP_ON); + & RFLR_PLLHOP_FASTHOP_MASK) + | RFLR_PLLHOP_FASTHOP_ON); write_to_register(REG_LR_HOPPERIOD, _rf_settings.lora.hop_period); } write_to_register(REG_LR_MODEMCONFIG1, (read_register(REG_LR_MODEMCONFIG1) & - RFLR_MODEMCONFIG1_BW_MASK & - RFLR_MODEMCONFIG1_CODINGRATE_MASK & - RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK & - RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK & - RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK) - | (bandwidth << 6) | (coderate << 3) - | (fix_len << 2) | (crc_on << 1) - | _rf_settings.lora.low_datarate_optimize); + RFLR_MODEMCONFIG1_BW_MASK & + RFLR_MODEMCONFIG1_CODINGRATE_MASK & + RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK & + RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK & + RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK) + | (bandwidth << 6) | (coderate << 3) + | (fix_len << 2) | (crc_on << 1) + | _rf_settings.lora.low_datarate_optimize); write_to_register(REG_LR_MODEMCONFIG2, (read_register(REG_LR_MODEMCONFIG2) & - RFLR_MODEMCONFIG2_SF_MASK) | (datarate << 4)); + RFLR_MODEMCONFIG2_SF_MASK) | (datarate << 4)); - write_to_register( REG_LR_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); - write_to_register( REG_LR_PREAMBLELSB, preamble_len & 0xFF); + write_to_register(REG_LR_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); + write_to_register(REG_LR_PREAMBLELSB, preamble_len & 0xFF); if (datarate == 6) { write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) & - RFLR_DETECTIONOPTIMIZE_MASK) | + RFLR_DETECTIONOPTIMIZE_MASK) | RFLR_DETECTIONOPTIMIZE_SF6); - write_to_register( REG_LR_DETECTIONTHRESHOLD, - RFLR_DETECTIONTHRESH_SF6); + write_to_register(REG_LR_DETECTIONTHRESHOLD, + RFLR_DETECTIONTHRESH_SF6); } else { write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) & - RFLR_DETECTIONOPTIMIZE_MASK) | - RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); + RFLR_DETECTIONOPTIMIZE_MASK) | + RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12); } @@ -658,18 +654,18 @@ uint32_t SX1272_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) switch (modem) { case MODEM_FSK: { airtime = rint((8 * (_rf_settings.fsk.preamble_len - + ((read_register( REG_SYNCCONFIG) - & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1) - + ((_rf_settings.fsk.fix_len == 0x01) ? - 0.0f : 1.0f) - + (((read_register( REG_PACKETCONFIG1) - & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK) - != 0x00) ? 1.0f : 0) + pkt_len - + ((_rf_settings.fsk.crc_on == 0x01) ? - 2.0f : 0)) + + ((read_register(REG_SYNCCONFIG) + & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1) + + ((_rf_settings.fsk.fix_len == 0x01) ? + 0.0f : 1.0f) + + (((read_register(REG_PACKETCONFIG1) + & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK) + != 0x00) ? 1.0f : 0) + pkt_len + + ((_rf_settings.fsk.crc_on == 0x01) ? + 2.0f : 0)) / _rf_settings.fsk.datarate) * 1000); } - break; + break; case MODEM_LORA: { float bw = 0.0f; switch (_rf_settings.lora.bandwidth) { @@ -691,12 +687,12 @@ uint32_t SX1272_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) float preamble_time = (_rf_settings.lora.preamble_len + 4.25f) * ts; // Symbol length of payload and time float tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28 - + 16 * _rf_settings.lora.crc_on - - (_rf_settings.lora.fix_len ? 20 : 0)) - / (float) (4 * (_rf_settings.lora.datarate - - ((_rf_settings.lora.low_datarate_optimize - > 0) ? 2 : 0)))) * - (_rf_settings.lora.coderate + 4); + + 16 * _rf_settings.lora.crc_on - + (_rf_settings.lora.fix_len ? 20 : 0)) + / (float)(4 * (_rf_settings.lora.datarate - + ((_rf_settings.lora.low_datarate_optimize + > 0) ? 2 : 0)))) * + (_rf_settings.lora.coderate + 4); float n_payload = 8 + ((tmp > 0) ? tmp : 0); float t_payload = n_payload * ts; // Time on air @@ -704,7 +700,7 @@ uint32_t SX1272_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) // return ms secs airtime = floor(t_onair * 1000 + 0.999f); } - break; + break; } return airtime; } @@ -744,23 +740,23 @@ void SX1272_LoRaRadio::send(uint8_t *buffer, uint8_t size) // write payload buffer write_fifo(buffer, _rf_settings.fsk_packet_handler.chunk_size); _rf_settings.fsk_packet_handler.nb_bytes += - _rf_settings.fsk_packet_handler.chunk_size; + _rf_settings.fsk_packet_handler.chunk_size; tx_timeout = _rf_settings.fsk.tx_timeout; break; case MODEM_LORA: if (_rf_settings.lora.iq_inverted == true) { write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) & - RFLR_INVERTIQ_TX_MASK & - RFLR_INVERTIQ_RX_MASK) | - RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON)); + RFLR_INVERTIQ_TX_MASK & + RFLR_INVERTIQ_RX_MASK) | + RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON)); write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); } else { write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) & - RFLR_INVERTIQ_TX_MASK & - RFLR_INVERTIQ_RX_MASK) | - RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF)); - write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); + RFLR_INVERTIQ_TX_MASK & + RFLR_INVERTIQ_RX_MASK) | + RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF)); + write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); } _rf_settings.lora_packet_handler.size = size; @@ -807,17 +803,17 @@ void SX1272_LoRaRadio::transmit(uint32_t timeout) // DIO3=FifoEmpty // DIO4=LowBat // DIO5=ModeReady - write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) & - RF_DIOMAPPING1_DIO0_MASK & - RF_DIOMAPPING1_DIO1_MASK & - RF_DIOMAPPING1_DIO2_MASK) | + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & + RF_DIOMAPPING1_DIO0_MASK & + RF_DIOMAPPING1_DIO1_MASK & + RF_DIOMAPPING1_DIO2_MASK) | RF_DIOMAPPING1_DIO1_01); write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) & - RF_DIOMAPPING2_DIO4_MASK & - RF_DIOMAPPING2_MAP_MASK)); + RF_DIOMAPPING2_DIO4_MASK & + RF_DIOMAPPING2_MAP_MASK)); _rf_settings.fsk_packet_handler.fifo_thresh = - read_register(REG_FIFOTHRESH) & 0x3F; + read_register(REG_FIFOTHRESH) & 0x3F; break; @@ -835,8 +831,8 @@ void SX1272_LoRaRadio::transmit(uint32_t timeout) // DIO0=tx_done, DIO2=fhss_change_channel write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & - RFLR_DIOMAPPING1_DIO0_MASK & - RFLR_DIOMAPPING1_DIO2_MASK) | + RFLR_DIOMAPPING1_DIO0_MASK & + RFLR_DIOMAPPING1_DIO2_MASK) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_01); } else { @@ -850,8 +846,8 @@ void SX1272_LoRaRadio::transmit(uint32_t timeout) RFLR_IRQFLAGS_CADDETECTED); // DIO0=tx_done - write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) & - RFLR_DIOMAPPING1_DIO0_MASK) | + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & + RFLR_DIOMAPPING1_DIO0_MASK) | RFLR_DIOMAPPING1_DIO0_01); } @@ -882,21 +878,21 @@ void SX1272_LoRaRadio::receive(void) // DIO4=Preamble // DIO5=ModeReady write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & - RF_DIOMAPPING1_DIO0_MASK & - RF_DIOMAPPING1_DIO1_MASK & - RF_DIOMAPPING1_DIO2_MASK) | + RF_DIOMAPPING1_DIO0_MASK & + RF_DIOMAPPING1_DIO1_MASK & + RF_DIOMAPPING1_DIO2_MASK) | RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_10); write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) & - RF_DIOMAPPING2_DIO4_MASK & - RF_DIOMAPPING2_MAP_MASK) | + RF_DIOMAPPING2_DIO4_MASK & + RF_DIOMAPPING2_MAP_MASK) | RF_DIOMAPPING2_DIO4_11 | RF_DIOMAPPING2_MAP_PREAMBLEDETECT); _rf_settings.fsk_packet_handler.fifo_thresh = - read_register(REG_FIFOTHRESH) & 0x3F; + read_register(REG_FIFOTHRESH) & 0x3F; write_to_register(REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON | @@ -923,18 +919,18 @@ void SX1272_LoRaRadio::receive(void) if (_rf_settings.lora.iq_inverted == true) { write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) & - RFLR_INVERTIQ_TX_MASK & - RFLR_INVERTIQ_RX_MASK) | - RFLR_INVERTIQ_RX_ON | - RFLR_INVERTIQ_TX_OFF)); + RFLR_INVERTIQ_TX_MASK & + RFLR_INVERTIQ_RX_MASK) | + RFLR_INVERTIQ_RX_ON | + RFLR_INVERTIQ_TX_OFF)); write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); } else { write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) & - RFLR_INVERTIQ_TX_MASK & - RFLR_INVERTIQ_RX_MASK) | - RFLR_INVERTIQ_RX_OFF | - RFLR_INVERTIQ_TX_OFF)); - write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); + RFLR_INVERTIQ_TX_MASK & + RFLR_INVERTIQ_RX_MASK) | + RFLR_INVERTIQ_RX_OFF | + RFLR_INVERTIQ_TX_OFF)); + write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); } if (_rf_settings.lora.freq_hop_on == true) { @@ -946,8 +942,8 @@ void SX1272_LoRaRadio::receive(void) // DIO0=rx_done, DIO2=fhss_change_channel write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & - RFLR_DIOMAPPING1_DIO0_MASK & - RFLR_DIOMAPPING1_DIO2_MASK) | + RFLR_DIOMAPPING1_DIO0_MASK & + RFLR_DIOMAPPING1_DIO2_MASK) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00); } else { @@ -960,7 +956,7 @@ void SX1272_LoRaRadio::receive(void) // DIO0=rx_done write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & - RFLR_DIOMAPPING1_DIO0_MASK) | + RFLR_DIOMAPPING1_DIO0_MASK) | RFLR_DIOMAPPING1_DIO0_00); } @@ -1036,9 +1032,9 @@ void SX1272_LoRaRadio::set_public_network(bool enable) * */ bool SX1272_LoRaRadio::perform_carrier_sense(radio_modems_t modem, - uint32_t freq, - int16_t rssi_threshold, - uint32_t max_carrier_sense_time) + uint32_t freq, + int16_t rssi_threshold, + uint32_t max_carrier_sense_time) { bool status = true; int16_t rssi = 0; @@ -1093,7 +1089,7 @@ void SX1272_LoRaRadio::start_cad() // DIO3=CADDone reg_val = read_register(REG_DIOMAPPING1); write_to_register(REG_DIOMAPPING1, (reg_val & - RFLR_DIOMAPPING1_DIO3_MASK) | + RFLR_DIOMAPPING1_DIO3_MASK) | RFLR_DIOMAPPING1_DIO3_00); set_operation_mode(RFLR_OPMODE_CAD); @@ -1118,10 +1114,10 @@ void SX1272_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, set_tx_config(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, time * 1000); reg_val = read_register(REG_PACKETCONFIG2); - write_to_register( REG_PACKETCONFIG2, (reg_val & RF_PACKETCONFIG2_DATAMODE_MASK ) ); + write_to_register(REG_PACKETCONFIG2, (reg_val & RF_PACKETCONFIG2_DATAMODE_MASK)); // Disable radio interrupts - write_to_register( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 ); - write_to_register( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 ); + write_to_register(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11); + write_to_register(REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10); _rf_settings.state = RF_TX_RUNNING; tx_timeout_timer.attach_us(callback(this, &SX1272_LoRaRadio::timeout_irq_isr), time * 1000000); @@ -1131,7 +1127,7 @@ void SX1272_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, /** * Put radio in Standby mode */ -void SX1272_LoRaRadio::standby( void ) +void SX1272_LoRaRadio::standby(void) { tx_timeout_timer.detach(); set_operation_mode(RF_OPMODE_STANDBY); @@ -1356,17 +1352,16 @@ int16_t SX1272_LoRaRadio::get_rssi(radio_modems_t modem) { int16_t rssi = 0; - switch( modem ) - { - case MODEM_FSK: - rssi = -(read_register(REG_RSSIVALUE) >> 1 ); - break; - case MODEM_LORA: - rssi = RSSI_OFFSET + read_register(REG_LR_RSSIVALUE); - break; - default: - rssi = -1; - break; + switch (modem) { + case MODEM_FSK: + rssi = -(read_register(REG_RSSIVALUE) >> 1); + break; + case MODEM_LORA: + rssi = RSSI_OFFSET + read_register(REG_LR_RSSIVALUE); + break; + default: + rssi = -1; + break; } return rssi; } @@ -1388,12 +1383,10 @@ void SX1272_LoRaRadio::set_rf_tx_power(int8_t power) pa_dac = read_register(REG_PADAC); #if defined ( TARGET_MOTE_L152RC ) - if(power > 19) { + if (power > 19) { pa_config = (pa_config & RF_PACONFIG_PASELECT_MASK) | RF_PACONFIG_PASELECT_RFO; pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) | RFO_table[power - 20]; - } - else - { + } else { pa_config = (pa_config & RF_PACONFIG_PASELECT_MASK) | RF_PACONFIG_PASELECT_PABOOST; pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) | pa_boost_table[power]; } @@ -1415,7 +1408,7 @@ void SX1272_LoRaRadio::set_rf_tx_power(int8_t power) power = 20; } pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) - | (uint8_t) ((uint16_t) (power - 5) & 0x0F); + | (uint8_t)((uint16_t)(power - 5) & 0x0F); } else { if (power < 2) { power = 2; @@ -1424,7 +1417,7 @@ void SX1272_LoRaRadio::set_rf_tx_power(int8_t power) power = 17; } pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) - | (uint8_t) ((uint16_t) (power - 2) & 0x0F); + | (uint8_t)((uint16_t)(power - 2) & 0x0F); } } else { if (power < -1) { @@ -1434,7 +1427,7 @@ void SX1272_LoRaRadio::set_rf_tx_power(int8_t power) power = 14; } pa_config = (pa_config & RFLR_PACONFIG_OUTPUTPOWER_MASK) - | (uint8_t) ((uint16_t) (power + 1) & 0x0F); + | (uint8_t)((uint16_t)(power + 1) & 0x0F); } #endif write_to_register(REG_PACONFIG, pa_config); @@ -1457,7 +1450,7 @@ void SX1272_LoRaRadio::setup_registers() */ void SX1272_LoRaRadio::set_sx1272_variant_type() { - if (_rf_ctrls.ant_switch != NC){ + if (_rf_ctrls.ant_switch != NC) { _ant_switch.input(); ThisThread::sleep_for(1); if (_ant_switch == 1) { @@ -1483,12 +1476,12 @@ void SX1272_LoRaRadio::set_antenna_switch(uint8_t mode) switch (mode) { case RFLR_OPMODE_TRANSMITTER: if (_rf_ctrls.rf_switch_ctl1 != NC - && _rf_ctrls.rf_switch_ctl2 != NC) { + && _rf_ctrls.rf_switch_ctl2 != NC) { // module is in transmit mode and RF latch switches // are connected. Check if power amplifier boost is // setup or not if ((read_register(REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST) - == RF_PACONFIG_PASELECT_PABOOST) { + == RF_PACONFIG_PASELECT_PABOOST) { _rf_switch_ctl1 = 1; _rf_switch_ctl2 = 0; } else { @@ -1501,7 +1494,7 @@ void SX1272_LoRaRadio::set_antenna_switch(uint8_t mode) // pins are connected _txctl = 1; _rxctl = 0; - } else if (_rf_ctrls.ant_switch != NC){ + } else if (_rf_ctrls.ant_switch != NC) { _ant_switch = 1; } else { // None of the control pins are connected. @@ -1511,7 +1504,7 @@ void SX1272_LoRaRadio::set_antenna_switch(uint8_t mode) case RFLR_OPMODE_RECEIVER_SINGLE: case RFLR_OPMODE_CAD: if (_rf_ctrls.rf_switch_ctl1 != NC - && _rf_ctrls.rf_switch_ctl2 != NC) { + && _rf_ctrls.rf_switch_ctl2 != NC) { // radio is in reception or CAD mode and RF latch switches // are connected _rf_switch_ctl1 = 1; @@ -1528,7 +1521,7 @@ void SX1272_LoRaRadio::set_antenna_switch(uint8_t mode) default: // Enforce default case when any connected control pin is kept low. if (_rf_ctrls.rf_switch_ctl1 != NC - && _rf_ctrls.rf_switch_ctl2 != NC) { + && _rf_ctrls.rf_switch_ctl2 != NC) { // radio is in reception or CAD mode and RF latch switches // are connected _rf_switch_ctl1 = 0; @@ -1631,9 +1624,9 @@ void SX1272_LoRaRadio::set_low_power_mode(bool status) void SX1272_LoRaRadio::dio0_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.flags_set(SIG_DIO0); + irq_thread.flags_set(SIG_DIO0); #else - handle_dio0_irq(); + handle_dio0_irq(); #endif } @@ -1745,27 +1738,27 @@ void SX1272_LoRaRadio::handle_dio0_irq() // should be more smoothed out. _rf_settings.fsk_packet_handler.rssi_value = -(read_register(REG_RSSIVALUE) >> 1); _rf_settings.fsk_packet_handler.afc_value = (int32_t)(float)(((uint16_t)read_register(REG_AFCMSB) << 8) | - (uint16_t)read_register(REG_AFCLSB)) * - (float)FREQ_STEP; + (uint16_t)read_register(REG_AFCLSB)) * + (float)FREQ_STEP; _rf_settings.fsk_packet_handler.rx_gain = (read_register(REG_LNA) >> 5) & 0x07; // Read received packet size if ((_rf_settings.fsk_packet_handler.size == 0) && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) { if (_rf_settings.fsk.fix_len == false) { - read_fifo((uint8_t*) &_rf_settings.fsk_packet_handler.size, 1); + read_fifo((uint8_t *) &_rf_settings.fsk_packet_handler.size, 1); } else { _rf_settings.fsk_packet_handler.size = read_register(REG_PAYLOADLENGTH); } read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, - _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); _rf_settings.fsk_packet_handler.nb_bytes += - (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); } else { read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, - _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); _rf_settings.fsk_packet_handler.nb_bytes += - (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); } if (_rf_settings.fsk.rx_continuous == false) { @@ -1773,14 +1766,14 @@ void SX1272_LoRaRadio::handle_dio0_irq() } else { // Continuous mode restart Rx chain write_to_register(REG_RXCONFIG, read_register(REG_RXCONFIG) - | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); } if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done( - _data_buffer, - _rf_settings.fsk_packet_handler.size, - _rf_settings.fsk_packet_handler.rssi_value, 0); + _data_buffer, + _rf_settings.fsk_packet_handler.size, + _rf_settings.fsk_packet_handler.rssi_value, 0); } _rf_settings.fsk_packet_handler.preamble_detected = 0; _rf_settings.fsk_packet_handler.sync_word_detected = 0; @@ -1812,23 +1805,22 @@ void SX1272_LoRaRadio::handle_dio0_irq() } _rf_settings.lora_packet_handler.snr_value = read_register(REG_LR_PKTSNRVALUE); - if (_rf_settings.lora_packet_handler.snr_value & 0x80) // The SNR sign bit is 1 - { + if (_rf_settings.lora_packet_handler.snr_value & 0x80) { // The SNR sign bit is 1 // Invert and divide by 4 snr = ((~_rf_settings.lora_packet_handler.snr_value + 1) & 0xFF) >> 2; snr = -snr; } else { // Divide by 4 - snr =(_rf_settings.lora_packet_handler.snr_value & 0xFF) >> 2; + snr = (_rf_settings.lora_packet_handler.snr_value & 0xFF) >> 2; } int16_t rssi = read_register(REG_LR_PKTRSSIVALUE); if (snr < 0) { _rf_settings.lora_packet_handler.rssi_value = - RSSI_OFFSET + rssi + (rssi >> 4) + snr; + RSSI_OFFSET + rssi + (rssi >> 4) + snr; } else { _rf_settings.lora_packet_handler.rssi_value = - RSSI_OFFSET + rssi + (rssi >> 4); + RSSI_OFFSET + rssi + (rssi >> 4); } _rf_settings.lora_packet_handler.size = read_register(REG_LR_RXNBBYTES); @@ -1841,13 +1833,13 @@ void SX1272_LoRaRadio::handle_dio0_irq() if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done( - _data_buffer, - _rf_settings.lora_packet_handler.size, - _rf_settings.lora_packet_handler.rssi_value, - _rf_settings.lora_packet_handler.snr_value); + _data_buffer, + _rf_settings.lora_packet_handler.size, + _rf_settings.lora_packet_handler.rssi_value, + _rf_settings.lora_packet_handler.snr_value); } } - break; + break; default: break; } @@ -1858,8 +1850,8 @@ void SX1272_LoRaRadio::handle_dio0_irq() switch (_rf_settings.modem) { case MODEM_LORA: // Clear Irq - write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE); - // Intentional fall through + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE); + // Intentional fall through case MODEM_FSK: default: _rf_settings.state = RF_IDLE; @@ -1878,146 +1870,56 @@ void SX1272_LoRaRadio::handle_dio0_irq() void SX1272_LoRaRadio::handle_dio1_irq() { - switch(_rf_settings.state ) - { - case RF_RX_RUNNING: - switch(_rf_settings.modem ) { - case MODEM_FSK: - // FifoLevel interrupt - // Read received packet size - if( ( _rf_settings.fsk_packet_handler.size == 0 ) && ( _rf_settings.fsk_packet_handler.nb_bytes == 0 ) ) - { - if( _rf_settings.fsk.fix_len == false ) - { - read_fifo( ( uint8_t* )&_rf_settings.fsk_packet_handler.size, 1 ); - } - else - { - _rf_settings.fsk_packet_handler.size = read_register(REG_PAYLOADLENGTH); - } - } + switch (_rf_settings.state) { + case RF_RX_RUNNING: + switch (_rf_settings.modem) { + case MODEM_FSK: + // FifoLevel interrupt + // Read received packet size + if ((_rf_settings.fsk_packet_handler.size == 0) && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) { + if (_rf_settings.fsk.fix_len == false) { + read_fifo((uint8_t *)&_rf_settings.fsk_packet_handler.size, 1); + } else { + _rf_settings.fsk_packet_handler.size = read_register(REG_PAYLOADLENGTH); + } + } - if( ( _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ) > _rf_settings.fsk_packet_handler.fifo_thresh ) - { - read_fifo( ( _data_buffer + _rf_settings.fsk_packet_handler.nb_bytes ), _rf_settings.fsk_packet_handler.fifo_thresh ); - _rf_settings.fsk_packet_handler.nb_bytes += _rf_settings.fsk_packet_handler.fifo_thresh; - } - else - { - read_fifo( ( _data_buffer + _rf_settings.fsk_packet_handler.nb_bytes ), _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ); - _rf_settings.fsk_packet_handler.nb_bytes += ( _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ); - } - break; - case MODEM_LORA: - // Sync time out - _rf_settings.state = RF_IDLE; - if ((_radio_events != NULL) && (_radio_events->rx_timeout)) { + if ((_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes) > _rf_settings.fsk_packet_handler.fifo_thresh) { + read_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes), _rf_settings.fsk_packet_handler.fifo_thresh); + _rf_settings.fsk_packet_handler.nb_bytes += _rf_settings.fsk_packet_handler.fifo_thresh; + } else { + read_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes), _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.nb_bytes += (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + } + break; + case MODEM_LORA: + // Sync time out + _rf_settings.state = RF_IDLE; + if ((_radio_events != NULL) && (_radio_events->rx_timeout)) { _radio_events->rx_timeout(); } - break; - default: - break; - } - break; - case RF_TX_RUNNING: - switch( _rf_settings.modem ) - { - case MODEM_FSK: - // FifoLevel interrupt - if( ( _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ) > _rf_settings.fsk_packet_handler.chunk_size ) - { - write_fifo(( _data_buffer + _rf_settings.fsk_packet_handler.nb_bytes ), _rf_settings.fsk_packet_handler.chunk_size ); - _rf_settings.fsk_packet_handler.nb_bytes += _rf_settings.fsk_packet_handler.chunk_size; - } - else - { - // Write the last chunk of data - write_fifo( _data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes ); - _rf_settings.fsk_packet_handler.nb_bytes += _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes; - } - break; - case MODEM_LORA: - break; - default: - break; - } - break; - default: - break; - } -} - -void SX1272_LoRaRadio::handle_dio2_irq(void) -{ - switch(_rf_settings.state ) - { - case RF_RX_RUNNING: - switch( _rf_settings.modem ) - { - case MODEM_FSK: - _rf_settings.fsk_packet_handler.preamble_detected = 0; - _rf_settings.fsk_packet_handler.sync_word_detected = 0; - _rf_settings.fsk_packet_handler.nb_bytes = 0; - _rf_settings.fsk_packet_handler.size = 0; - - // Clear Irqs - write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | - RF_IRQFLAGS1_PREAMBLEDETECT | - RF_IRQFLAGS1_SYNCADDRESSMATCH | - RF_IRQFLAGS1_TIMEOUT); - - write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); - - if (_rf_settings.fsk.rx_continuous == true) { - // Continuous mode restart Rx chain - write_to_register( REG_RXCONFIG, - read_register(REG_RXCONFIG) | - RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); - } else { - _rf_settings.state = RF_IDLE; - } - - if ((_radio_events != NULL) - && (_radio_events->rx_timeout)) { - _radio_events->rx_timeout(); - } - - break; - case MODEM_LORA: - if( _rf_settings.lora.freq_hop_on == true ) - { - // Clear Irq - write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); - - if( ( _radio_events != NULL ) && (_radio_events->fhss_change_channel ) ) - { - _radio_events->fhss_change_channel((read_register( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK )); - } - } - break; - default: - break; + break; + default: + break; } break; case RF_TX_RUNNING: - switch( _rf_settings.modem ) - { - case MODEM_FSK: - break; - case MODEM_LORA: - if( _rf_settings.lora.freq_hop_on == true ) - { - // Clear Irq - write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); - - if( (_radio_events != NULL ) && ( _radio_events->fhss_change_channel ) ) - { - _radio_events->fhss_change_channel((read_register( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK )); + switch (_rf_settings.modem) { + case MODEM_FSK: + // FifoLevel interrupt + if ((_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes) > _rf_settings.fsk_packet_handler.chunk_size) { + write_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes), _rf_settings.fsk_packet_handler.chunk_size); + _rf_settings.fsk_packet_handler.nb_bytes += _rf_settings.fsk_packet_handler.chunk_size; + } else { + // Write the last chunk of data + write_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.nb_bytes += _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes; } - } - break; - default: - break; + break; + case MODEM_LORA: + break; + default: + break; } break; default: @@ -2025,34 +1927,99 @@ void SX1272_LoRaRadio::handle_dio2_irq(void) } } -void SX1272_LoRaRadio::handle_dio3_irq( void ) +void SX1272_LoRaRadio::handle_dio2_irq(void) { - switch( _rf_settings.modem ) - { - case MODEM_FSK: - break; - case MODEM_LORA: - if( ( read_register( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED ) - { - // Clear Irq - write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE ); - if( ( _radio_events != NULL ) && ( _radio_events->cad_done ) ) - { - _radio_events->cad_done( true ); + switch (_rf_settings.state) { + case RF_RX_RUNNING: + switch (_rf_settings.modem) { + case MODEM_FSK: + _rf_settings.fsk_packet_handler.preamble_detected = 0; + _rf_settings.fsk_packet_handler.sync_word_detected = 0; + _rf_settings.fsk_packet_handler.nb_bytes = 0; + _rf_settings.fsk_packet_handler.size = 0; + + // Clear Irqs + write_to_register(REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI | + RF_IRQFLAGS1_PREAMBLEDETECT | + RF_IRQFLAGS1_SYNCADDRESSMATCH | + RF_IRQFLAGS1_TIMEOUT); + + write_to_register(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); + + if (_rf_settings.fsk.rx_continuous == true) { + // Continuous mode restart Rx chain + write_to_register(REG_RXCONFIG, + read_register(REG_RXCONFIG) | + RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + } else { + _rf_settings.state = RF_IDLE; + } + + if ((_radio_events != NULL) + && (_radio_events->rx_timeout)) { + _radio_events->rx_timeout(); + } + + break; + case MODEM_LORA: + if (_rf_settings.lora.freq_hop_on == true) { + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL); + + if ((_radio_events != NULL) && (_radio_events->fhss_change_channel)) { + _radio_events->fhss_change_channel((read_register(REG_LR_HOPCHANNEL) & RFLR_HOPCHANNEL_CHANNEL_MASK)); + } + } + break; + default: + break; } - } - else - { - // Clear Irq - write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE ); - if( ( _radio_events != NULL ) && ( _radio_events->cad_done ) ) - { - _radio_events->cad_done( false ); + break; + case RF_TX_RUNNING: + switch (_rf_settings.modem) { + case MODEM_FSK: + break; + case MODEM_LORA: + if (_rf_settings.lora.freq_hop_on == true) { + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL); + + if ((_radio_events != NULL) && (_radio_events->fhss_change_channel)) { + _radio_events->fhss_change_channel((read_register(REG_LR_HOPCHANNEL) & RFLR_HOPCHANNEL_CHANNEL_MASK)); + } + } + break; + default: + break; } - } - break; - default: - break; + break; + default: + break; + } +} + +void SX1272_LoRaRadio::handle_dio3_irq(void) +{ + switch (_rf_settings.modem) { + case MODEM_FSK: + break; + case MODEM_LORA: + if ((read_register(REG_LR_IRQFLAGS) & RFLR_IRQFLAGS_CADDETECTED) == RFLR_IRQFLAGS_CADDETECTED) { + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE); + if ((_radio_events != NULL) && (_radio_events->cad_done)) { + _radio_events->cad_done(true); + } + } else { + // Clear Irq + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE); + if ((_radio_events != NULL) && (_radio_events->cad_done)) { + _radio_events->cad_done(false); + } + } + break; + default: + break; } } @@ -2065,7 +2032,7 @@ void SX1272_LoRaRadio::handle_dio4_irq(void) _rf_settings.fsk_packet_handler.preamble_detected = 1; } } - break; + break; case MODEM_LORA: break; default: @@ -2075,14 +2042,13 @@ void SX1272_LoRaRadio::handle_dio4_irq(void) void SX1272_LoRaRadio::handle_dio5_irq() { - switch( _rf_settings.modem ) - { - case MODEM_FSK: - break; - case MODEM_LORA: - break; - default: - break; + switch (_rf_settings.modem) { + case MODEM_FSK: + break; + case MODEM_LORA: + break; + default: + break; } } diff --git a/SX1272/SX1272_LoRaRadio.h b/SX1272/SX1272_LoRaRadio.h index 485a08b2ad..3adcd6ae09 100644 --- a/SX1272/SX1272_LoRaRadio.h +++ b/SX1272/SX1272_LoRaRadio.h @@ -33,7 +33,7 @@ SPDX-License-Identifier: BSD-3-Clause #include "SPI.h" #include "platform/PlatformMutex.h" #ifdef MBED_CONF_RTOS_PRESENT - #include "rtos/Thread.h" +#include "rtos/Thread.h" #endif #include "lorawan/LoRaRadio.h" @@ -145,7 +145,7 @@ public: * @param rx_continuous Sets the reception in continuous mode * [false: single mode, true: continuous mode] */ - virtual void set_rx_config (radio_modems_t modem, uint32_t bandwidth, + virtual void set_rx_config(radio_modems_t modem, uint32_t bandwidth, uint32_t datarate, uint8_t coderate, uint32_t bandwidth_afc, uint16_t preamble_len, uint16_t symb_timeout, bool fix_len, @@ -183,10 +183,10 @@ public: * @param timeout Transmission timeout [ms] */ virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, - uint32_t bandwidth, uint32_t datarate, - uint8_t coderate, uint16_t preamble_len, - bool fix_len, bool crc_on, bool freq_hop_on, - uint8_t hop_period, bool iq_inverted, uint32_t timeout); + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preamble_len, + bool fix_len, bool crc_on, bool freq_hop_on, + uint8_t hop_period, bool iq_inverted, uint32_t timeout); /** * Sends the buffer of size diff --git a/SX1276/SX1276_LoRaRadio.cpp b/SX1276/SX1276_LoRaRadio.cpp index 155d266542..5deecf9948 100644 --- a/SX1276/SX1276_LoRaRadio.cpp +++ b/SX1276/SX1276_LoRaRadio.cpp @@ -64,8 +64,7 @@ using namespace mbed; /*! * FSK bandwidth definition */ -typedef struct -{ +typedef struct { uint32_t bandwidth; uint8_t register_value; } fsk_bw_t; @@ -73,8 +72,7 @@ typedef struct /*! * Radio registers definition */ -typedef struct -{ +typedef struct { uint8_t modem; uint8_t addr; uint8_t value; @@ -100,24 +98,23 @@ typedef struct { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\ } -static const fsk_bw_t fsk_bandwidths[] = -{ - { 2600 , 0x17 }, - { 3100 , 0x0F }, - { 3900 , 0x07 }, - { 5200 , 0x16 }, - { 6300 , 0x0E }, - { 7800 , 0x06 }, - { 10400 , 0x15 }, - { 12500 , 0x0D }, - { 15600 , 0x05 }, - { 20800 , 0x14 }, - { 25000 , 0x0C }, - { 31300 , 0x04 }, - { 41700 , 0x13 }, - { 50000 , 0x0B }, - { 62500 , 0x03 }, - { 83333 , 0x12 }, +static const fsk_bw_t fsk_bandwidths[] = { + { 2600, 0x17 }, + { 3100, 0x0F }, + { 3900, 0x07 }, + { 5200, 0x16 }, + { 6300, 0x0E }, + { 7800, 0x06 }, + { 10400, 0x15 }, + { 12500, 0x0D }, + { 15600, 0x05 }, + { 20800, 0x14 }, + { 25000, 0x0C }, + { 31300, 0x04 }, + { 41700, 0x13 }, + { 50000, 0x0B }, + { 62500, 0x03 }, + { 83333, 0x12 }, { 100000, 0x0A }, { 125000, 0x02 }, { 166700, 0x11 }, @@ -193,7 +190,7 @@ SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi, _tcxo(tcxo) #ifdef MBED_CONF_RTOS_PRESENT - , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX1276") + , irq_thread(osPriorityRealtime, 1024, NULL, "LR-SX1276") #endif { _rf_ctrls.ant_switch = antswitch; @@ -318,10 +315,10 @@ uint8_t SX1276_LoRaRadio::get_status(void) void SX1276_LoRaRadio::set_channel(uint32_t freq) { _rf_settings.channel = freq; - freq = (uint32_t) ((float) freq / (float) FREQ_STEP); - write_to_register(REG_FRFMSB, (uint8_t) ((freq >> 16) & 0xFF)); - write_to_register(REG_FRFMID, (uint8_t) ((freq >> 8) & 0xFF)); - write_to_register(REG_FRFLSB, (uint8_t) (freq & 0xFF)); + freq = (uint32_t)((float) freq / (float) FREQ_STEP); + write_to_register(REG_FRFMSB, (uint8_t)((freq >> 16) & 0xFF)); + write_to_register(REG_FRFMID, (uint8_t)((freq >> 8) & 0xFF)); + write_to_register(REG_FRFLSB, (uint8_t)(freq & 0xFF)); } /** @@ -334,7 +331,7 @@ void SX1276_LoRaRadio::set_channel(uint32_t freq) * In addition to that RX and TX configuration APIs should be called again in * order to have correct desires setup. */ -uint32_t SX1276_LoRaRadio::random( void ) +uint32_t SX1276_LoRaRadio::random(void) { uint8_t i; uint32_t rnd = 0; @@ -342,17 +339,17 @@ uint32_t SX1276_LoRaRadio::random( void ) /* * Radio setup for random number generation */ - set_modem( MODEM_LORA ); + set_modem(MODEM_LORA); // Disable LoRa modem interrupts write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | - RFLR_IRQFLAGS_RXDONE | - RFLR_IRQFLAGS_PAYLOADCRCERROR | - RFLR_IRQFLAGS_VALIDHEADER | - RFLR_IRQFLAGS_TXDONE | - RFLR_IRQFLAGS_CADDONE | - RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | - RFLR_IRQFLAGS_CADDETECTED ); + RFLR_IRQFLAGS_RXDONE | + RFLR_IRQFLAGS_PAYLOADCRCERROR | + RFLR_IRQFLAGS_VALIDHEADER | + RFLR_IRQFLAGS_TXDONE | + RFLR_IRQFLAGS_CADDONE | + RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | + RFLR_IRQFLAGS_CADDETECTED); // Set radio in continuous reception set_operation_mode(RF_OPMODE_RECEIVER); @@ -360,7 +357,7 @@ uint32_t SX1276_LoRaRadio::random( void ) for (i = 0; i < 32; i++) { ThisThread::sleep_for(1); // Unfiltered RSSI value reading. Only takes the LSB value - rnd |= ((uint32_t) read_register( REG_LR_RSSIWIDEBAND) & 0x01) << i; + rnd |= ((uint32_t) read_register(REG_LR_RSSIWIDEBAND) & 0x01) << i; } sleep(); @@ -397,15 +394,15 @@ void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, _rf_settings.fsk.preamble_len = preamble_len; _rf_settings.fsk.rx_single_timeout = (symb_timeout + 1) / 2; // dividing by 2 as our detector size is 2 symbols (16 bytes) - datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate); - write_to_register(REG_BITRATEMSB, (uint8_t) (datarate >> 8)); - write_to_register(REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); + datarate = (uint16_t)((float) XTAL_FREQ / (float) datarate); + write_to_register(REG_BITRATEMSB, (uint8_t)(datarate >> 8)); + write_to_register(REG_BITRATELSB, (uint8_t)(datarate & 0xFF)); write_to_register(REG_RXBW, get_fsk_bw_reg_val(bandwidth)); write_to_register(REG_AFCBW, get_fsk_bw_reg_val(bandwidth_afc)); - write_to_register(REG_PREAMBLEMSB, (uint8_t) ((preamble_len >> 8) & 0xFF)); - write_to_register(REG_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF)); + write_to_register(REG_PREAMBLEMSB, (uint8_t)((preamble_len >> 8) & 0xFF)); + write_to_register(REG_PREAMBLELSB, (uint8_t)(preamble_len & 0xFF)); if (fix_len == 1) { write_to_register(REG_PAYLOADLENGTH, payload_len); @@ -414,18 +411,18 @@ void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, } write_to_register( - REG_PACKETCONFIG1, - (read_register(REG_PACKETCONFIG1) - & RF_PACKETCONFIG1_CRC_MASK - & RF_PACKETCONFIG1_PACKETFORMAT_MASK) - | ((fix_len == 1) ? - RF_PACKETCONFIG1_PACKETFORMAT_FIXED : - RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) - | (crc_on << 4)); + REG_PACKETCONFIG1, + (read_register(REG_PACKETCONFIG1) + & RF_PACKETCONFIG1_CRC_MASK + & RF_PACKETCONFIG1_PACKETFORMAT_MASK) + | ((fix_len == 1) ? + RF_PACKETCONFIG1_PACKETFORMAT_FIXED : + RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) + | (crc_on << 4)); // TODO why packet mode 2 ? write_to_register(REG_PACKETCONFIG2, (read_register(REG_PACKETCONFIG2) - | RF_PACKETCONFIG2_DATAMODE_PACKET)); + | RF_PACKETCONFIG2_DATAMODE_PACKET)); break; @@ -439,7 +436,7 @@ void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, } // stupid hack. TODO think something better - bandwidth+=7; + bandwidth += 7; _rf_settings.lora.bandwidth = bandwidth; _rf_settings.lora.datarate = datarate; @@ -466,40 +463,40 @@ void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, _rf_settings.lora.low_datarate_optimize = 0x00; } - write_to_register(REG_LR_MODEMCONFIG1, (read_register( REG_LR_MODEMCONFIG1) - & RFLR_MODEMCONFIG1_BW_MASK - & RFLR_MODEMCONFIG1_CODINGRATE_MASK - & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK) - | (bandwidth << 4) - | (coderate << 1) | fix_len); + write_to_register(REG_LR_MODEMCONFIG1, (read_register(REG_LR_MODEMCONFIG1) + & RFLR_MODEMCONFIG1_BW_MASK + & RFLR_MODEMCONFIG1_CODINGRATE_MASK + & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK) + | (bandwidth << 4) + | (coderate << 1) | fix_len); - write_to_register(REG_LR_MODEMCONFIG2, (read_register( REG_LR_MODEMCONFIG2) - & RFLR_MODEMCONFIG2_SF_MASK - & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK - & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK) - | (datarate << 4) - | (crc_on << 2) - | ((symb_timeout >> 8) - & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK)); + write_to_register(REG_LR_MODEMCONFIG2, (read_register(REG_LR_MODEMCONFIG2) + & RFLR_MODEMCONFIG2_SF_MASK + & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK + & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK) + | (datarate << 4) + | (crc_on << 2) + | ((symb_timeout >> 8) + & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK)); - write_to_register(REG_LR_MODEMCONFIG3, (read_register( REG_LR_MODEMCONFIG3) - & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) - | (_rf_settings.lora.low_datarate_optimize << 3)); + write_to_register(REG_LR_MODEMCONFIG3, (read_register(REG_LR_MODEMCONFIG3) + & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) + | (_rf_settings.lora.low_datarate_optimize << 3)); - write_to_register(REG_LR_SYMBTIMEOUTLSB, (uint8_t) (symb_timeout & 0xFF)); + write_to_register(REG_LR_SYMBTIMEOUTLSB, (uint8_t)(symb_timeout & 0xFF)); - write_to_register(REG_LR_PREAMBLEMSB, (uint8_t) ((preamble_len >> 8) & 0xFF)); - write_to_register(REG_LR_PREAMBLELSB, (uint8_t) (preamble_len & 0xFF)); + write_to_register(REG_LR_PREAMBLEMSB, (uint8_t)((preamble_len >> 8) & 0xFF)); + write_to_register(REG_LR_PREAMBLELSB, (uint8_t)(preamble_len & 0xFF)); if (fix_len == 1) { write_to_register(REG_LR_PAYLOADLENGTH, payload_len); } if (_rf_settings.lora.freq_hop_on == true) { - write_to_register(REG_LR_PLLHOP, (read_register( REG_LR_PLLHOP) - & RFLR_PLLHOP_FASTHOP_MASK) - | RFLR_PLLHOP_FASTHOP_ON); - write_to_register(REG_LR_HOPPERIOD,_rf_settings.lora.hop_period); + write_to_register(REG_LR_PLLHOP, (read_register(REG_LR_PLLHOP) + & RFLR_PLLHOP_FASTHOP_MASK) + | RFLR_PLLHOP_FASTHOP_ON); + write_to_register(REG_LR_HOPPERIOD, _rf_settings.lora.hop_period); } if ((bandwidth == 9) && (_rf_settings.channel > RF_MID_BAND_THRESH)) { @@ -517,13 +514,13 @@ void SX1276_LoRaRadio::set_rx_config(radio_modems_t modem, uint32_t bandwidth, if (datarate == 6) { write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) - & RFLR_DETECTIONOPTIMIZE_MASK) - | RFLR_DETECTIONOPTIMIZE_SF6); + & RFLR_DETECTIONOPTIMIZE_MASK) + | RFLR_DETECTIONOPTIMIZE_SF6); write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF6); } else { write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) - & RFLR_DETECTIONOPTIMIZE_MASK) - | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); + & RFLR_DETECTIONOPTIMIZE_MASK) + | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12); } break; @@ -562,28 +559,28 @@ void SX1276_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power, _rf_settings.fsk.iq_inverted = iq_inverted; _rf_settings.fsk.tx_timeout = timeout; - fdev = (uint16_t) ((float) fdev / (float) FREQ_STEP); - write_to_register( REG_FDEVMSB, (uint8_t) (fdev >> 8)); - write_to_register( REG_FDEVLSB, (uint8_t) (fdev & 0xFF)); + fdev = (uint16_t)((float) fdev / (float) FREQ_STEP); + write_to_register(REG_FDEVMSB, (uint8_t)(fdev >> 8)); + write_to_register(REG_FDEVLSB, (uint8_t)(fdev & 0xFF)); - datarate = (uint16_t) ((float) XTAL_FREQ / (float) datarate); - write_to_register( REG_BITRATEMSB, (uint8_t) (datarate >> 8)); - write_to_register( REG_BITRATELSB, (uint8_t) (datarate & 0xFF)); + datarate = (uint16_t)((float) XTAL_FREQ / (float) datarate); + write_to_register(REG_BITRATEMSB, (uint8_t)(datarate >> 8)); + write_to_register(REG_BITRATELSB, (uint8_t)(datarate & 0xFF)); - write_to_register( REG_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); - write_to_register( REG_PREAMBLELSB, preamble_len & 0xFF); + write_to_register(REG_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); + write_to_register(REG_PREAMBLELSB, preamble_len & 0xFF); write_to_register(REG_PACKETCONFIG1, - (read_register( REG_PACKETCONFIG1) & - RF_PACKETCONFIG1_CRC_MASK & - RF_PACKETCONFIG1_PACKETFORMAT_MASK) - | ((fix_len == 1) ? - RF_PACKETCONFIG1_PACKETFORMAT_FIXED : - RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) - | (crc_on << 4)); + (read_register(REG_PACKETCONFIG1) & + RF_PACKETCONFIG1_CRC_MASK & + RF_PACKETCONFIG1_PACKETFORMAT_MASK) + | ((fix_len == 1) ? + RF_PACKETCONFIG1_PACKETFORMAT_FIXED : + RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE) + | (crc_on << 4)); write_to_register(REG_PACKETCONFIG2, - (read_register( REG_PACKETCONFIG2) - | RF_PACKETCONFIG2_DATAMODE_PACKET)); + (read_register(REG_PACKETCONFIG2) + | RF_PACKETCONFIG2_DATAMODE_PACKET)); break; @@ -617,38 +614,38 @@ void SX1276_LoRaRadio::set_tx_config(radio_modems_t modem, int8_t power, if (_rf_settings.lora.freq_hop_on == true) { write_to_register(REG_LR_PLLHOP, (read_register(REG_LR_PLLHOP) - & RFLR_PLLHOP_FASTHOP_MASK) - | RFLR_PLLHOP_FASTHOP_ON); - write_to_register( REG_LR_HOPPERIOD, _rf_settings.lora.hop_period); + & RFLR_PLLHOP_FASTHOP_MASK) + | RFLR_PLLHOP_FASTHOP_ON); + write_to_register(REG_LR_HOPPERIOD, _rf_settings.lora.hop_period); } - write_to_register(REG_LR_MODEMCONFIG1, (read_register( REG_LR_MODEMCONFIG1) - & RFLR_MODEMCONFIG1_BW_MASK - & RFLR_MODEMCONFIG1_CODINGRATE_MASK - & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK) | (bandwidth << 4) - | (coderate << 1) | fix_len); + write_to_register(REG_LR_MODEMCONFIG1, (read_register(REG_LR_MODEMCONFIG1) + & RFLR_MODEMCONFIG1_BW_MASK + & RFLR_MODEMCONFIG1_CODINGRATE_MASK + & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK) | (bandwidth << 4) + | (coderate << 1) | fix_len); - write_to_register(REG_LR_MODEMCONFIG2, (read_register( REG_LR_MODEMCONFIG2) - & RFLR_MODEMCONFIG2_SF_MASK - & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK) + write_to_register(REG_LR_MODEMCONFIG2, (read_register(REG_LR_MODEMCONFIG2) + & RFLR_MODEMCONFIG2_SF_MASK + & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK) | (datarate << 4) | (crc_on << 2)); write_to_register(REG_LR_MODEMCONFIG3, (read_register(REG_LR_MODEMCONFIG3) - & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) + & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK) | (_rf_settings.lora.low_datarate_optimize << 3)); write_to_register(REG_LR_PREAMBLEMSB, (preamble_len >> 8) & 0x00FF); write_to_register(REG_LR_PREAMBLELSB, preamble_len & 0xFF); if (datarate == 6) { - write_to_register(REG_LR_DETECTOPTIMIZE, (read_register( REG_LR_DETECTOPTIMIZE) - & RFLR_DETECTIONOPTIMIZE_MASK) | RFLR_DETECTIONOPTIMIZE_SF6); + write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) + & RFLR_DETECTIONOPTIMIZE_MASK) | RFLR_DETECTIONOPTIMIZE_SF6); write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF6); } else { - write_to_register(REG_LR_DETECTOPTIMIZE, (read_register( REG_LR_DETECTOPTIMIZE) - & RFLR_DETECTIONOPTIMIZE_MASK) | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); - write_to_register( REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12); + write_to_register(REG_LR_DETECTOPTIMIZE, (read_register(REG_LR_DETECTOPTIMIZE) + & RFLR_DETECTIONOPTIMIZE_MASK) | RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12); + write_to_register(REG_LR_DETECTIONTHRESHOLD, RFLR_DETECTIONTHRESH_SF7_TO_SF12); } break; @@ -668,17 +665,17 @@ uint32_t SX1276_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) switch (modem) { case MODEM_FSK: airTime = - rint((8 * (_rf_settings.fsk.preamble_len - + ((read_register( REG_SYNCCONFIG) - & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1) - + ((_rf_settings.fsk.fix_len == 0x01) ? - 0.0f : 1.0f) - + (((read_register( REG_PACKETCONFIG1) - & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK) - != 0x00) ? 1.0f : 0) + pkt_len - + ((_rf_settings.fsk.crc_on == 0x01) ? - 2.0 : 0)) - / _rf_settings.fsk.datarate) * 1000); + rint((8 * (_rf_settings.fsk.preamble_len + + ((read_register(REG_SYNCCONFIG) + & ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1) + + ((_rf_settings.fsk.fix_len == 0x01) ? + 0.0f : 1.0f) + + (((read_register(REG_PACKETCONFIG1) + & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK) + != 0x00) ? 1.0f : 0) + pkt_len + + ((_rf_settings.fsk.crc_on == 0x01) ? + 2.0 : 0)) + / _rf_settings.fsk.datarate) * 1000); break; case MODEM_LORA: @@ -724,13 +721,13 @@ uint32_t SX1276_LoRaRadio::time_on_air(radio_modems_t modem, uint8_t pkt_len) float tPreamble = (_rf_settings.lora.preamble_len + 4.25f) * ts; // Symbol length of payload and time float tmp = ceil((8 * pkt_len - 4 * _rf_settings.lora.datarate + 28 - + 16 * _rf_settings.lora.crc_on - - (_rf_settings.lora.fix_len ? 20 : 0)) - / (float) (4 - * (_rf_settings.lora.datarate - - ((_rf_settings.lora.low_datarate_optimize > 0) - ? 2 : 0)))) - * (_rf_settings.lora.coderate + 4); + + 16 * _rf_settings.lora.crc_on + - (_rf_settings.lora.fix_len ? 20 : 0)) + / (float)(4 + * (_rf_settings.lora.datarate + - ((_rf_settings.lora.low_datarate_optimize > 0) + ? 2 : 0)))) + * (_rf_settings.lora.coderate + 4); float nPayload = 8 + ((tmp > 0) ? tmp : 0); float tPayload = nPayload * ts; // Time on air @@ -757,7 +754,7 @@ void SX1276_LoRaRadio::send(uint8_t *buffer, uint8_t size) _rf_settings.fsk_packet_handler.size = size; if (_rf_settings.fsk.fix_len == false) { - write_fifo((uint8_t*) &size, 1); + write_fifo((uint8_t *) &size, 1); } else { write_to_register(REG_PAYLOADLENGTH, size); } @@ -772,7 +769,7 @@ void SX1276_LoRaRadio::send(uint8_t *buffer, uint8_t size) // Write payload buffer write_fifo(buffer, _rf_settings.fsk_packet_handler.chunk_size); _rf_settings.fsk_packet_handler.nb_bytes += - _rf_settings.fsk_packet_handler.chunk_size; + _rf_settings.fsk_packet_handler.chunk_size; tx_timeout = _rf_settings.fsk.tx_timeout; break; @@ -780,18 +777,18 @@ void SX1276_LoRaRadio::send(uint8_t *buffer, uint8_t size) case MODEM_LORA: if (_rf_settings.lora.iq_inverted == true) { write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) - & RFLR_INVERTIQ_TX_MASK - & RFLR_INVERTIQ_RX_MASK) - | RFLR_INVERTIQ_RX_OFF - | RFLR_INVERTIQ_TX_ON)); - write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); + & RFLR_INVERTIQ_TX_MASK + & RFLR_INVERTIQ_RX_MASK) + | RFLR_INVERTIQ_RX_OFF + | RFLR_INVERTIQ_TX_ON)); + write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); } else { - write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ) - & RFLR_INVERTIQ_TX_MASK - & RFLR_INVERTIQ_RX_MASK) - | RFLR_INVERTIQ_RX_OFF - | RFLR_INVERTIQ_TX_OFF)); - write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); + write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) + & RFLR_INVERTIQ_TX_MASK + & RFLR_INVERTIQ_RX_MASK) + | RFLR_INVERTIQ_RX_OFF + | RFLR_INVERTIQ_TX_OFF)); + write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); } _rf_settings.lora_packet_handler.size = size; @@ -804,7 +801,7 @@ void SX1276_LoRaRadio::send(uint8_t *buffer, uint8_t size) write_to_register(REG_LR_FIFOADDRPTR, 0); // FIFO operations can not take place in Sleep mode - if ((read_register( REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) { + if ((read_register(REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) { standby(); ThisThread::sleep_for(1); } @@ -834,7 +831,7 @@ void SX1276_LoRaRadio::sleep() /** * Put radio in Standby mode */ -void SX1276_LoRaRadio::standby( void ) +void SX1276_LoRaRadio::standby(void) { tx_timeout_timer.detach(); @@ -860,22 +857,22 @@ void SX1276_LoRaRadio::receive(void) // DIO3=FifoEmpty? // DIO4=PreambleDetect // DIO5=ModeReady? - write_to_register(REG_DIOMAPPING1, (read_register( REG_DIOMAPPING1) - & RF_DIOMAPPING1_DIO0_MASK - & RF_DIOMAPPING1_DIO1_MASK - & RF_DIOMAPPING1_DIO2_MASK) + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) + & RF_DIOMAPPING1_DIO0_MASK + & RF_DIOMAPPING1_DIO1_MASK + & RF_DIOMAPPING1_DIO2_MASK) | RF_DIOMAPPING1_DIO0_00 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_10); - write_to_register(REG_DIOMAPPING2, (read_register( REG_DIOMAPPING2) - & RF_DIOMAPPING2_DIO4_MASK - & RF_DIOMAPPING2_MAP_MASK) + write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) + & RF_DIOMAPPING2_DIO4_MASK + & RF_DIOMAPPING2_MAP_MASK) | RF_DIOMAPPING2_DIO4_11 | RF_DIOMAPPING2_MAP_PREAMBLEDETECT); _rf_settings.fsk_packet_handler.fifo_thresh = - read_register(REG_FIFOTHRESH) & 0x3F; + read_register(REG_FIFOTHRESH) & 0x3F; write_to_register(REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON @@ -901,15 +898,15 @@ void SX1276_LoRaRadio::receive(void) case MODEM_LORA: if (_rf_settings.lora.iq_inverted == true) { - write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ) - & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) - | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF)); - write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); + write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) + & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) + | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF)); + write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON); } else { - write_to_register(REG_LR_INVERTIQ, ((read_register( REG_LR_INVERTIQ) - & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) - | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF)); - write_to_register( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); + write_to_register(REG_LR_INVERTIQ, ((read_register(REG_LR_INVERTIQ) + & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK) + | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF)); + write_to_register(REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF); } // ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal @@ -919,42 +916,42 @@ void SX1276_LoRaRadio::receive(void) write_to_register(REG_LR_TEST30, 0x00); switch (_rf_settings.lora.bandwidth) { case 0: // 7.8 kHz - write_to_register( REG_LR_TEST2F, 0x48); + write_to_register(REG_LR_TEST2F, 0x48); set_channel(_rf_settings.channel + 7.81e3); break; case 1: // 10.4 kHz - write_to_register( REG_LR_TEST2F, 0x44); + write_to_register(REG_LR_TEST2F, 0x44); set_channel(_rf_settings.channel + 10.42e3); break; case 2: // 15.6 kHz - write_to_register( REG_LR_TEST2F, 0x44); + write_to_register(REG_LR_TEST2F, 0x44); set_channel(_rf_settings.channel + 15.62e3); break; case 3: // 20.8 kHz - write_to_register( REG_LR_TEST2F, 0x44); + write_to_register(REG_LR_TEST2F, 0x44); set_channel(_rf_settings.channel + 20.83e3); break; case 4: // 31.2 kHz - write_to_register( REG_LR_TEST2F, 0x44); + write_to_register(REG_LR_TEST2F, 0x44); set_channel(_rf_settings.channel + 31.25e3); break; case 5: // 41.4 kHz - write_to_register( REG_LR_TEST2F, 0x44); + write_to_register(REG_LR_TEST2F, 0x44); set_channel(_rf_settings.channel + 41.67e3); break; case 6: // 62.5 kHz - write_to_register( REG_LR_TEST2F, 0x40); + write_to_register(REG_LR_TEST2F, 0x40); break; case 7: // 125 kHz - write_to_register( REG_LR_TEST2F, 0x40); + write_to_register(REG_LR_TEST2F, 0x40); break; case 8: // 250 kHz - write_to_register( REG_LR_TEST2F, 0x40); + write_to_register(REG_LR_TEST2F, 0x40); break; } } else { - write_to_register( REG_LR_DETECTOPTIMIZE, - read_register( REG_LR_DETECTOPTIMIZE) | 0x80); + write_to_register(REG_LR_DETECTOPTIMIZE, + read_register(REG_LR_DETECTOPTIMIZE) | 0x80); } if (_rf_settings.lora.freq_hop_on == true) { @@ -965,20 +962,20 @@ void SX1276_LoRaRadio::receive(void) // DIO0=RxDone, DIO2=FhssChangeChannel write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) - & RFLR_DIOMAPPING1_DIO0_MASK - & RFLR_DIOMAPPING1_DIO2_MASK) - | RFLR_DIOMAPPING1_DIO0_00 - | RFLR_DIOMAPPING1_DIO2_00); + & RFLR_DIOMAPPING1_DIO0_MASK + & RFLR_DIOMAPPING1_DIO2_MASK) + | RFLR_DIOMAPPING1_DIO0_00 + | RFLR_DIOMAPPING1_DIO2_00); } else { write_to_register(REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_VALIDHEADER - | RFLR_IRQFLAGS_TXDONE - | RFLR_IRQFLAGS_CADDONE - | RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL - | RFLR_IRQFLAGS_CADDETECTED); + | RFLR_IRQFLAGS_TXDONE + | RFLR_IRQFLAGS_CADDONE + | RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL + | RFLR_IRQFLAGS_CADDETECTED); // DIO0=RxDone - write_to_register(REG_DIOMAPPING1, (read_register( REG_DIOMAPPING1) - & RFLR_DIOMAPPING1_DIO0_MASK) + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) + & RFLR_DIOMAPPING1_DIO0_MASK) | RFLR_DIOMAPPING1_DIO0_00); } write_to_register(REG_LR_FIFORXBASEADDR, 0); @@ -1014,9 +1011,9 @@ void SX1276_LoRaRadio::receive(void) * */ bool SX1276_LoRaRadio::perform_carrier_sense(radio_modems_t modem, - uint32_t freq, - int16_t rssi_threshold, - uint32_t max_carrier_sense_time) + uint32_t freq, + int16_t rssi_threshold, + uint32_t max_carrier_sense_time) { bool status = true; int16_t rssi = 0; @@ -1110,7 +1107,7 @@ void SX1276_LoRaRadio::start_cad() // DIO3=CADDone reg_val = read_register(REG_DIOMAPPING1); write_to_register(REG_DIOMAPPING1, (reg_val & - RFLR_DIOMAPPING1_DIO3_MASK) | + RFLR_DIOMAPPING1_DIO3_MASK) | RFLR_DIOMAPPING1_DIO3_00); set_operation_mode(RFLR_OPMODE_CAD); @@ -1135,10 +1132,10 @@ void SX1276_LoRaRadio::set_tx_continuous_wave(uint32_t freq, int8_t power, set_tx_config(MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, time * 1000); reg_val = read_register(REG_PACKETCONFIG2); - write_to_register( REG_PACKETCONFIG2, (reg_val & RF_PACKETCONFIG2_DATAMODE_MASK ) ); + write_to_register(REG_PACKETCONFIG2, (reg_val & RF_PACKETCONFIG2_DATAMODE_MASK)); // Disable radio interrupts - write_to_register( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 ); - write_to_register( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 ); + write_to_register(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11); + write_to_register(REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10); _rf_settings.state = RF_TX_RUNNING; tx_timeout_timer.attach_us(callback(this, &SX1276_LoRaRadio::timeout_irq_isr), time * 1000000); @@ -1279,46 +1276,45 @@ void SX1276_LoRaRadio::set_operation_mode(uint8_t mode) * At initialization FSK is chosen. Later stack or application * can choose to change. */ -void SX1276_LoRaRadio::set_modem(uint8_t modem ) +void SX1276_LoRaRadio::set_modem(uint8_t modem) { - if ((read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON) != 0 ) { + if ((read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON) != 0) { _rf_settings.modem = MODEM_LORA; } else { _rf_settings.modem = MODEM_FSK; } - if(_rf_settings.modem == modem ) { + if (_rf_settings.modem == modem) { // if the modem is already set return; } _rf_settings.modem = modem; - switch(_rf_settings.modem) - { - default: - case MODEM_FSK: - // before changing modem mode, put the module to sleep - sleep(); - write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) - | RFLR_OPMODE_LONGRANGEMODE_OFF); + switch (_rf_settings.modem) { + default: + case MODEM_FSK: + // before changing modem mode, put the module to sleep + sleep(); + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) + | RFLR_OPMODE_LONGRANGEMODE_OFF); - // Datasheet Tables 28, 29 DIO mapping - write_to_register(REG_DIOMAPPING1, 0x00); // sets DIO0-DI03 in default mode - write_to_register(REG_DIOMAPPING2, 0x30); // bits 4-5 are turned on i.e., - // DIO5 and DIO4=ModeReady - break; - case MODEM_LORA: - sleep(); - write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) - | RFLR_OPMODE_LONGRANGEMODE_ON); + // Datasheet Tables 28, 29 DIO mapping + write_to_register(REG_DIOMAPPING1, 0x00); // sets DIO0-DI03 in default mode + write_to_register(REG_DIOMAPPING2, 0x30); // bits 4-5 are turned on i.e., + // DIO5 and DIO4=ModeReady + break; + case MODEM_LORA: + sleep(); + write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_MASK) + | RFLR_OPMODE_LONGRANGEMODE_ON); - // Datasheet Tables 17 DIO mapping for LoRa - // set to defaults - write_to_register(REG_DIOMAPPING1, 0x00); // DIO0 - DIO3 defaults - write_to_register(REG_DIOMAPPING2, 0x00); // DIO4 - DIO5 defaults + // Datasheet Tables 17 DIO mapping for LoRa + // set to defaults + write_to_register(REG_DIOMAPPING1, 0x00); // DIO0 - DIO3 defaults + write_to_register(REG_DIOMAPPING2, 0x00); // DIO4 - DIO5 defaults - break; + break; } } @@ -1390,38 +1386,36 @@ void SX1276_LoRaRadio::rx_chain_calibration(void) uint32_t initialFreq; // Save context - regPaConfigInitVal = read_register( REG_PACONFIG ); - initialFreq = (float) (((uint32_t) this->read_register(REG_FRFMSB) << 16) | - ((uint32_t) this->read_register(REG_FRFMID) << 8 ) | - ((uint32_t)this->read_register(REG_FRFLSB))) * (float) FREQ_STEP; + regPaConfigInitVal = read_register(REG_PACONFIG); + initialFreq = (float)(((uint32_t) this->read_register(REG_FRFMSB) << 16) | + ((uint32_t) this->read_register(REG_FRFMID) << 8) | + ((uint32_t)this->read_register(REG_FRFLSB))) * (float) FREQ_STEP; // Cut the PA just in case, RFO output, power = -1 dBm write_to_register(REG_PACONFIG, 0x00); // Launch Rx chain calibration for LF band - write_to_register (REG_IMAGECAL, (read_register(REG_IMAGECAL) - & RF_IMAGECAL_IMAGECAL_MASK) - | RF_IMAGECAL_IMAGECAL_START); - while((read_register(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING ) - == RF_IMAGECAL_IMAGECAL_RUNNING ) - { + write_to_register(REG_IMAGECAL, (read_register(REG_IMAGECAL) + & RF_IMAGECAL_IMAGECAL_MASK) + | RF_IMAGECAL_IMAGECAL_START); + while ((read_register(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING) + == RF_IMAGECAL_IMAGECAL_RUNNING) { } // Sets a Frequency in HF band set_channel(868000000); // Launch Rx chain calibration for HF band - write_to_register (REG_IMAGECAL, (read_register(REG_IMAGECAL) - & RF_IMAGECAL_IMAGECAL_MASK ) - | RF_IMAGECAL_IMAGECAL_START ); - while((read_register(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING ) - == RF_IMAGECAL_IMAGECAL_RUNNING ) - { + write_to_register(REG_IMAGECAL, (read_register(REG_IMAGECAL) + & RF_IMAGECAL_IMAGECAL_MASK) + | RF_IMAGECAL_IMAGECAL_START); + while ((read_register(REG_IMAGECAL) & RF_IMAGECAL_IMAGECAL_RUNNING) + == RF_IMAGECAL_IMAGECAL_RUNNING) { // do nothing, just wait while rf image frequency calibration is done } // Restore context - write_to_register( REG_PACONFIG, regPaConfigInitVal ); + write_to_register(REG_PACONFIG, regPaConfigInitVal); set_channel(initialFreq); } @@ -1490,7 +1484,7 @@ void SX1276_LoRaRadio::set_rf_tx_power(int8_t power) power = 20; } paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK) - | (uint8_t) ((uint16_t) (power - 5) & 0x0F); + | (uint8_t)((uint16_t)(power - 5) & 0x0F); } else { if (power < 2) { power = 2; @@ -1499,7 +1493,7 @@ void SX1276_LoRaRadio::set_rf_tx_power(int8_t power) power = 17; } paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK) - | (uint8_t) ((uint16_t) (power - 2) & 0x0F); + | (uint8_t)((uint16_t)(power - 2) & 0x0F); } } else { if (power < -1) { @@ -1509,10 +1503,10 @@ void SX1276_LoRaRadio::set_rf_tx_power(int8_t power) power = 14; } paConfig = (paConfig & RF_PACONFIG_OUTPUTPOWER_MASK) - | (uint8_t) ((uint16_t) (power + 1) & 0x0F); + | (uint8_t)((uint16_t)(power + 1) & 0x0F); } - write_to_register( REG_PACONFIG, paConfig); - write_to_register( REG_PADAC, paDac); + write_to_register(REG_PACONFIG, paConfig); + write_to_register(REG_PADAC, paDac); } /** @@ -1534,17 +1528,17 @@ void SX1276_LoRaRadio::transmit(uint32_t timeout) // DIO3=FifoEmpty // DIO4=LowBat // DIO5=ModeReady - write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) & - RF_DIOMAPPING1_DIO0_MASK & - RF_DIOMAPPING1_DIO1_MASK & - RF_DIOMAPPING1_DIO2_MASK) | + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & + RF_DIOMAPPING1_DIO0_MASK & + RF_DIOMAPPING1_DIO1_MASK & + RF_DIOMAPPING1_DIO2_MASK) | RF_DIOMAPPING1_DIO1_01); write_to_register(REG_DIOMAPPING2, (read_register(REG_DIOMAPPING2) & - RF_DIOMAPPING2_DIO4_MASK & - RF_DIOMAPPING2_MAP_MASK)); + RF_DIOMAPPING2_DIO4_MASK & + RF_DIOMAPPING2_MAP_MASK)); _rf_settings.fsk_packet_handler.fifo_thresh = - read_register(REG_FIFOTHRESH) & 0x3F; + read_register(REG_FIFOTHRESH) & 0x3F; break; @@ -1562,8 +1556,8 @@ void SX1276_LoRaRadio::transmit(uint32_t timeout) // DIO0=tx_done, DIO2=fhss_change_channel write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & - RFLR_DIOMAPPING1_DIO0_MASK & - RFLR_DIOMAPPING1_DIO2_MASK) | + RFLR_DIOMAPPING1_DIO0_MASK & + RFLR_DIOMAPPING1_DIO2_MASK) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_01); } else { @@ -1577,8 +1571,8 @@ void SX1276_LoRaRadio::transmit(uint32_t timeout) RFLR_IRQFLAGS_CADDETECTED); // DIO0=tx_done - write_to_register(REG_DIOMAPPING1,(read_register(REG_DIOMAPPING1) & - RFLR_DIOMAPPING1_DIO0_MASK) | + write_to_register(REG_DIOMAPPING1, (read_register(REG_DIOMAPPING1) & + RFLR_DIOMAPPING1_DIO0_MASK) | RFLR_DIOMAPPING1_DIO0_01); } @@ -1588,7 +1582,7 @@ void SX1276_LoRaRadio::transmit(uint32_t timeout) _rf_settings.state = RF_TX_RUNNING; tx_timeout_timer.attach_us(callback(this, - &SX1276_LoRaRadio::timeout_irq_isr), timeout * 1000); + &SX1276_LoRaRadio::timeout_irq_isr), timeout * 1000); set_operation_mode(RF_OPMODE_TRANSMITTER); } @@ -1678,12 +1672,12 @@ void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode) switch (mode) { case RFLR_OPMODE_TRANSMITTER: if (_rf_ctrls.rf_switch_ctl1 != NC - && _rf_ctrls.rf_switch_ctl2 != NC) { + && _rf_ctrls.rf_switch_ctl2 != NC) { // module is in transmit mode and RF latch switches // are connected. Check if power amplifier boost is // setup or not if ((read_register(REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST) - == RF_PACONFIG_PASELECT_PABOOST) { + == RF_PACONFIG_PASELECT_PABOOST) { _rf_switch_ctl1 = 1; _rf_switch_ctl2 = 0; } else { @@ -1708,7 +1702,7 @@ void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode) } _rxctl = 0; } - if (_rf_ctrls.ant_switch != NC){ + if (_rf_ctrls.ant_switch != NC) { _ant_switch = 1; } break; @@ -1716,7 +1710,7 @@ void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode) case RFLR_OPMODE_RECEIVER_SINGLE: case RFLR_OPMODE_CAD: if (_rf_ctrls.rf_switch_ctl1 != NC - && _rf_ctrls.rf_switch_ctl2 != NC) { + && _rf_ctrls.rf_switch_ctl2 != NC) { // radio is in reception or CAD mode and RF latch switches // are connected _rf_switch_ctl1 = 1; @@ -1736,7 +1730,7 @@ void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode) default: // Enforce default case when any connected control pin is kept low. if (_rf_ctrls.rf_switch_ctl1 != NC - && _rf_ctrls.rf_switch_ctl2 != NC) { + && _rf_ctrls.rf_switch_ctl2 != NC) { // radio is in reception or CAD mode and RF latch switches // are connected _rf_switch_ctl1 = 0; @@ -1762,9 +1756,9 @@ void SX1276_LoRaRadio::set_antenna_switch(uint8_t mode) void SX1276_LoRaRadio::dio0_irq_isr() { #ifdef MBED_CONF_RTOS_PRESENT - irq_thread.flags_set(SIG_DIO0); + irq_thread.flags_set(SIG_DIO0); #else - handle_dio0_irq(); + handle_dio0_irq(); #endif } @@ -1874,32 +1868,32 @@ void SX1276_LoRaRadio::handle_dio0_irq() // We can have a snapshot of RSSI here as at this point it // should be more smoothed out. _rf_settings.fsk_packet_handler.rssi_value = - -(read_register(REG_RSSIVALUE) >> 1); + -(read_register(REG_RSSIVALUE) >> 1); _rf_settings.fsk_packet_handler.afc_value = - (int32_t) (float) (((uint16_t) read_register(REG_AFCMSB) << 8) - | (uint16_t) read_register( REG_AFCLSB)) - * (float) FREQ_STEP; + (int32_t)(float)(((uint16_t) read_register(REG_AFCMSB) << 8) + | (uint16_t) read_register(REG_AFCLSB)) + * (float) FREQ_STEP; _rf_settings.fsk_packet_handler.rx_gain = - (read_register( REG_LNA) >> 5) & 0x07; + (read_register(REG_LNA) >> 5) & 0x07; // Read received packet size if ((_rf_settings.fsk_packet_handler.size == 0) && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) { if (_rf_settings.fsk.fix_len == false) { - read_fifo((uint8_t*) &_rf_settings.fsk_packet_handler.size, 1); + read_fifo((uint8_t *) &_rf_settings.fsk_packet_handler.size, 1); } else { _rf_settings.fsk_packet_handler.size = read_register(REG_PAYLOADLENGTH); } read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, - _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); _rf_settings.fsk_packet_handler.nb_bytes += - (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); } else { read_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, - _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); _rf_settings.fsk_packet_handler.nb_bytes += - (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); + (_rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes); } if (_rf_settings.fsk.rx_continuous == false) { @@ -1907,14 +1901,14 @@ void SX1276_LoRaRadio::handle_dio0_irq() } else { // Continuous mode restart Rx chain write_to_register(REG_RXCONFIG, read_register(REG_RXCONFIG) - | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); + | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); } if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done( - _data_buffer, - _rf_settings.fsk_packet_handler.size, - _rf_settings.fsk_packet_handler.rssi_value, 0); + _data_buffer, + _rf_settings.fsk_packet_handler.size, + _rf_settings.fsk_packet_handler.rssi_value, 0); } _rf_settings.fsk_packet_handler.preamble_detected = 0; _rf_settings.fsk_packet_handler.sync_word_detected = 0; @@ -1932,7 +1926,7 @@ void SX1276_LoRaRadio::handle_dio0_irq() if ((irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK) == RFLR_IRQFLAGS_PAYLOADCRCERROR) { // Clear Irq - write_to_register( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR); + write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR); if (_rf_settings.lora.rx_continuous == false) { _rf_settings.state = RF_IDLE; @@ -1946,36 +1940,35 @@ void SX1276_LoRaRadio::handle_dio0_irq() } _rf_settings.lora_packet_handler.snr_value = read_register( - REG_LR_PKTSNRVALUE); - if (_rf_settings.lora_packet_handler.snr_value & 0x80) // The SNR sign bit is 1 - { + REG_LR_PKTSNRVALUE); + if (_rf_settings.lora_packet_handler.snr_value & 0x80) { // The SNR sign bit is 1 // Invert and divide by 4 snr = ((~_rf_settings.lora_packet_handler.snr_value + 1) - & 0xFF) >> 2; + & 0xFF) >> 2; snr = -snr; } else { // Divide by 4 snr = - (_rf_settings.lora_packet_handler.snr_value - & 0xFF) >> 2; + (_rf_settings.lora_packet_handler.snr_value + & 0xFF) >> 2; } - int16_t rssi = read_register( REG_LR_PKTRSSIVALUE); + int16_t rssi = read_register(REG_LR_PKTRSSIVALUE); if (snr < 0) { if (_rf_settings.channel > RF_MID_BAND_THRESH) { _rf_settings.lora_packet_handler.rssi_value = - RSSI_OFFSET_HF + rssi + (rssi >> 4) + snr; + RSSI_OFFSET_HF + rssi + (rssi >> 4) + snr; } else { _rf_settings.lora_packet_handler.rssi_value = - RSSI_OFFSET_LF + rssi + (rssi >> 4) + snr; + RSSI_OFFSET_LF + rssi + (rssi >> 4) + snr; } } else { if (_rf_settings.channel > RF_MID_BAND_THRESH) { _rf_settings.lora_packet_handler.rssi_value = - RSSI_OFFSET_HF + rssi + (rssi >> 4); + RSSI_OFFSET_HF + rssi + (rssi >> 4); } else { _rf_settings.lora_packet_handler.rssi_value = - RSSI_OFFSET_LF + rssi + (rssi >> 4); + RSSI_OFFSET_LF + rssi + (rssi >> 4); } } @@ -1988,12 +1981,12 @@ void SX1276_LoRaRadio::handle_dio0_irq() if ((_radio_events != NULL) && (_radio_events->rx_done)) { _radio_events->rx_done(_data_buffer, - _rf_settings.lora_packet_handler.size, - _rf_settings.lora_packet_handler.rssi_value, - _rf_settings.lora_packet_handler.snr_value); + _rf_settings.lora_packet_handler.size, + _rf_settings.lora_packet_handler.rssi_value, + _rf_settings.lora_packet_handler.snr_value); } } - break; + break; default: break; } @@ -2005,7 +1998,7 @@ void SX1276_LoRaRadio::handle_dio0_irq() case MODEM_LORA: // Clear Irq write_to_register(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE); - // Intentional fall through + // Intentional fall through case MODEM_FSK: default: _rf_settings.state = RF_IDLE; @@ -2032,10 +2025,10 @@ void SX1276_LoRaRadio::handle_dio1_irq() if ((_rf_settings.fsk_packet_handler.size == 0) && (_rf_settings.fsk_packet_handler.nb_bytes == 0)) { if (_rf_settings.fsk.fix_len == false) { - read_fifo((uint8_t*) &_rf_settings.fsk_packet_handler.size, 1); + read_fifo((uint8_t *) &_rf_settings.fsk_packet_handler.size, 1); } else { _rf_settings.fsk_packet_handler.size = - read_register(REG_PAYLOADLENGTH); + read_register(REG_PAYLOADLENGTH); } } @@ -2043,16 +2036,16 @@ void SX1276_LoRaRadio::handle_dio1_irq() - _rf_settings.fsk_packet_handler.nb_bytes) > _rf_settings.fsk_packet_handler.fifo_thresh) { read_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes), - _rf_settings.fsk_packet_handler.fifo_thresh); + _rf_settings.fsk_packet_handler.fifo_thresh); _rf_settings.fsk_packet_handler.nb_bytes += - _rf_settings.fsk_packet_handler.fifo_thresh; + _rf_settings.fsk_packet_handler.fifo_thresh; } else { read_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes), - _rf_settings.fsk_packet_handler.size - - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.size + - _rf_settings.fsk_packet_handler.nb_bytes); _rf_settings.fsk_packet_handler.nb_bytes += - (_rf_settings.fsk_packet_handler.size - - _rf_settings.fsk_packet_handler.nb_bytes); + (_rf_settings.fsk_packet_handler.size + - _rf_settings.fsk_packet_handler.nb_bytes); } break; @@ -2080,16 +2073,16 @@ void SX1276_LoRaRadio::handle_dio1_irq() - _rf_settings.fsk_packet_handler.nb_bytes) > _rf_settings.fsk_packet_handler.chunk_size) { write_fifo((_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes), - _rf_settings.fsk_packet_handler.chunk_size); + _rf_settings.fsk_packet_handler.chunk_size); _rf_settings.fsk_packet_handler.nb_bytes += - _rf_settings.fsk_packet_handler.chunk_size; + _rf_settings.fsk_packet_handler.chunk_size; } else { // Write the last chunk of data write_fifo(_data_buffer + _rf_settings.fsk_packet_handler.nb_bytes, - _rf_settings.fsk_packet_handler.size - - _rf_settings.fsk_packet_handler.nb_bytes); + _rf_settings.fsk_packet_handler.size + - _rf_settings.fsk_packet_handler.nb_bytes); _rf_settings.fsk_packet_handler.nb_bytes += - _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes; + _rf_settings.fsk_packet_handler.size - _rf_settings.fsk_packet_handler.nb_bytes; } break; @@ -2122,11 +2115,11 @@ void SX1276_LoRaRadio::handle_dio2_irq(void) RF_IRQFLAGS1_SYNCADDRESSMATCH | RF_IRQFLAGS1_TIMEOUT); - write_to_register( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); + write_to_register(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN); if (_rf_settings.fsk.rx_continuous == true) { // Continuous mode restart Rx chain - write_to_register( REG_RXCONFIG, + write_to_register(REG_RXCONFIG, read_register(REG_RXCONFIG) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK); } else { @@ -2149,8 +2142,8 @@ void SX1276_LoRaRadio::handle_dio2_irq(void) if ((_radio_events != NULL) && (_radio_events->fhss_change_channel)) { _radio_events->fhss_change_channel( - (read_register(REG_LR_HOPCHANNEL) - & RFLR_HOPCHANNEL_CHANNEL_MASK)); + (read_register(REG_LR_HOPCHANNEL) + & RFLR_HOPCHANNEL_CHANNEL_MASK)); } } @@ -2175,8 +2168,8 @@ void SX1276_LoRaRadio::handle_dio2_irq(void) if ((_radio_events != NULL) && (_radio_events->fhss_change_channel)) { _radio_events->fhss_change_channel( - (read_register(REG_LR_HOPCHANNEL) - & RFLR_HOPCHANNEL_CHANNEL_MASK)); + (read_register(REG_LR_HOPCHANNEL) + & RFLR_HOPCHANNEL_CHANNEL_MASK)); } } break; @@ -2199,7 +2192,7 @@ void SX1276_LoRaRadio::handle_dio3_irq(void) == RFLR_IRQFLAGS_CADDETECTED) { // Clear Irq write_to_register(REG_LR_IRQFLAGS, - RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE); + RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE); if ((_radio_events != NULL) && (_radio_events->cad_done)) { _radio_events->cad_done(true); @@ -2227,7 +2220,7 @@ void SX1276_LoRaRadio::handle_dio4_irq(void) _rf_settings.fsk_packet_handler.preamble_detected = 1; } } - break; + break; case MODEM_LORA: break; default: diff --git a/SX1276/SX1276_LoRaRadio.h b/SX1276/SX1276_LoRaRadio.h index aaf946f7fd..47be6bcc6b 100644 --- a/SX1276/SX1276_LoRaRadio.h +++ b/SX1276/SX1276_LoRaRadio.h @@ -33,7 +33,7 @@ SPDX-License-Identifier: BSD-3-Clause #include "SPI.h" #include "platform/PlatformMutex.h" #ifdef MBED_CONF_RTOS_PRESENT - #include "rtos/Thread.h" +#include "rtos/Thread.h" #endif #include "lorawan/LoRaRadio.h" @@ -160,7 +160,7 @@ public: * @param rx_continuous Sets the reception in continuous mode * [false: single mode, true: continuous mode] */ - virtual void set_rx_config (radio_modems_t modem, uint32_t bandwidth, + virtual void set_rx_config(radio_modems_t modem, uint32_t bandwidth, uint32_t datarate, uint8_t coderate, uint32_t bandwidth_afc, uint16_t preamble_len, uint16_t symb_timeout, bool fix_len, @@ -198,10 +198,10 @@ public: * @param timeout Transmission timeout [ms] */ virtual void set_tx_config(radio_modems_t modem, int8_t power, uint32_t fdev, - uint32_t bandwidth, uint32_t datarate, - uint8_t coderate, uint16_t preamble_len, - bool fix_len, bool crc_on, bool freq_hop_on, - uint8_t hop_period, bool iq_inverted, uint32_t timeout); + uint32_t bandwidth, uint32_t datarate, + uint8_t coderate, uint16_t preamble_len, + bool fix_len, bool crc_on, bool freq_hop_on, + uint8_t hop_period, bool iq_inverted, uint32_t timeout); /** * Sends the buffer of size From fd6f9bf134d2282234101331e81e43c2832f44c5 Mon Sep 17 00:00:00 2001 From: Travis Hendrickson Date: Thu, 26 Mar 2020 16:22:11 -0600 Subject: [PATCH 38/42] BUGFIX: MODEM_LORA rx continuous was timing out --- SX126X/SX126X_LoRaRadio.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/SX126X/SX126X_LoRaRadio.cpp b/SX126X/SX126X_LoRaRadio.cpp index 21fa4cfcdd..0ad4e5d45e 100644 --- a/SX126X/SX126X_LoRaRadio.cpp +++ b/SX126X/SX126X_LoRaRadio.cpp @@ -906,7 +906,7 @@ void SX126X_LoRaRadio::set_rx_config(radio_modems_t modem, } case MODEM_LORA: { - _rx_timeout_in_symbols = symb_timeout; + _rx_timeout_in_symbols = rx_continuous ? 0 : symb_timeout; _mod_params.modem_type = MODEM_LORA; _mod_params.params.lora.spreading_factor = (lora_spread_factors_t) datarate; @@ -1002,15 +1002,18 @@ void SX126X_LoRaRadio::send(uint8_t *buffer, uint8_t size) void SX126X_LoRaRadio::receive(void) { - if (get_modem() == MODEM_LORA && _reception_mode != RECEPTION_MODE_CONTINUOUS) { - // Data-sheet Table 13-11: StopOnPreambParam - // We will use radio's internal timer to mark no reception. This behaviour - // is different from SX1272/SX1276 where we are relying on radio to stop - // at preamble detection. - // 0x00 means Timer will be stopped on SyncWord(FSK) or Header (LoRa) detection - // 0x01 means Timer is stopped on preamble detection - uint8_t stop_at_preamble = 0x01; - write_opmode_command(RADIO_SET_STOPRXTIMERONPREAMBLE, &stop_at_preamble, 1); + if (get_modem() == MODEM_LORA) { + if (_reception_mode != RECEPTION_MODE_CONTINUOUS) { + // Data-sheet Table 13-11: StopOnPreambParam + // We will use radio's internal timer to mark no reception. This behaviour + // is different from SX1272/SX1276 where we are relying on radio to stop + // at preamble detection. + // 0x00 means Timer will be stopped on SyncWord(FSK) or Header (LoRa) detection + // 0x01 means Timer is stopped on preamble detection + uint8_t stop_at_preamble = 0x01; + write_opmode_command(RADIO_SET_STOPRXTIMERONPREAMBLE, &stop_at_preamble, 1); + } + // Data-sheet 13.4.9 SetLoRaSymbNumTimeout write_opmode_command(RADIO_SET_LORASYMBTIMEOUT, &_rx_timeout_in_symbols, 1); } From 0f7efe3ad17c6c619843b8391b3035149f358260 Mon Sep 17 00:00:00 2001 From: Travis Hendrickson Date: Fri, 27 Mar 2020 19:48:22 -0600 Subject: [PATCH 39/42] set symb_timeout to 0 also in FSK mode --- SX126X/SX126X_LoRaRadio.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SX126X/SX126X_LoRaRadio.cpp b/SX126X/SX126X_LoRaRadio.cpp index 0ad4e5d45e..071185d029 100644 --- a/SX126X/SX126X_LoRaRadio.cpp +++ b/SX126X/SX126X_LoRaRadio.cpp @@ -855,6 +855,7 @@ void SX126X_LoRaRadio::set_rx_config(radio_modems_t modem, if (rx_continuous) { _reception_mode = RECEPTION_MODE_CONTINUOUS; + symb_timeout = 0; } else { _reception_mode = RECEPTION_MODE_SINGLE; } @@ -906,7 +907,7 @@ void SX126X_LoRaRadio::set_rx_config(radio_modems_t modem, } case MODEM_LORA: { - _rx_timeout_in_symbols = rx_continuous ? 0 : symb_timeout; + _rx_timeout_in_symbols = symb_timeout; _mod_params.modem_type = MODEM_LORA; _mod_params.params.lora.spreading_factor = (lora_spread_factors_t) datarate; From 6ca66e23df1cee42cfd41e43631c904d6e79e54a Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Wed, 1 Apr 2020 12:50:24 +0300 Subject: [PATCH 40/42] Lora: Fix line endings --- .../lora/SX1276/registers/sx1276Regs-Fsk.h | 2276 ++++++++--------- .../lora/SX1276/registers/sx1276Regs-LoRa.h | 1138 ++++----- 2 files changed, 1707 insertions(+), 1707 deletions(-) diff --git a/components/lora/SX1276/registers/sx1276Regs-Fsk.h b/components/lora/SX1276/registers/sx1276Regs-Fsk.h index 40472a399a..d3b39b66a5 100644 --- a/components/lora/SX1276/registers/sx1276Regs-Fsk.h +++ b/components/lora/SX1276/registers/sx1276Regs-Fsk.h @@ -1,1138 +1,1138 @@ -/** - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C) 2014 Semtech - -Description: SX1276 FSK modem registers and bits definitions - -License: Revised BSD License, see LICENSE.TXT file include in the project - -Maintainer: Miguel Luis and Gregory Cristian - -Copyright (c) 2017, Arm Limited and affiliates. - -SPDX-License-Identifier: BSD-3-Clause -*/ -#ifndef __SX1276_REGS_FSK_H__ -#define __SX1276_REGS_FSK_H__ - -/*! - * ============================================================================ - * SX1276 Internal registers Address - * ============================================================================ - */ -#define REG_FIFO 0x00 -// Common settings -#define REG_OPMODE 0x01 -#define REG_BITRATEMSB 0x02 -#define REG_BITRATELSB 0x03 -#define REG_FDEVMSB 0x04 -#define REG_FDEVLSB 0x05 -#define REG_FRFMSB 0x06 -#define REG_FRFMID 0x07 -#define REG_FRFLSB 0x08 -// Tx settings -#define REG_PACONFIG 0x09 -#define REG_PARAMP 0x0A -#define REG_OCP 0x0B -// Rx settings -#define REG_LNA 0x0C -#define REG_RXCONFIG 0x0D -#define REG_RSSICONFIG 0x0E -#define REG_RSSICOLLISION 0x0F -#define REG_RSSITHRESH 0x10 -#define REG_RSSIVALUE 0x11 -#define REG_RXBW 0x12 -#define REG_AFCBW 0x13 -#define REG_OOKPEAK 0x14 -#define REG_OOKFIX 0x15 -#define REG_OOKAVG 0x16 -#define REG_RES17 0x17 -#define REG_RES18 0x18 -#define REG_RES19 0x19 -#define REG_AFCFEI 0x1A -#define REG_AFCMSB 0x1B -#define REG_AFCLSB 0x1C -#define REG_FEIMSB 0x1D -#define REG_FEILSB 0x1E -#define REG_PREAMBLEDETECT 0x1F -#define REG_RXTIMEOUT1 0x20 -#define REG_RXTIMEOUT2 0x21 -#define REG_RXTIMEOUT3 0x22 -#define REG_RXDELAY 0x23 -// Oscillator settings -#define REG_OSC 0x24 -// Packet handler settings -#define REG_PREAMBLEMSB 0x25 -#define REG_PREAMBLELSB 0x26 -#define REG_SYNCCONFIG 0x27 -#define REG_SYNCVALUE1 0x28 -#define REG_SYNCVALUE2 0x29 -#define REG_SYNCVALUE3 0x2A -#define REG_SYNCVALUE4 0x2B -#define REG_SYNCVALUE5 0x2C -#define REG_SYNCVALUE6 0x2D -#define REG_SYNCVALUE7 0x2E -#define REG_SYNCVALUE8 0x2F -#define REG_PACKETCONFIG1 0x30 -#define REG_PACKETCONFIG2 0x31 -#define REG_PAYLOADLENGTH 0x32 -#define REG_NODEADRS 0x33 -#define REG_BROADCASTADRS 0x34 -#define REG_FIFOTHRESH 0x35 -// SM settings -#define REG_SEQCONFIG1 0x36 -#define REG_SEQCONFIG2 0x37 -#define REG_TIMERRESOL 0x38 -#define REG_TIMER1COEF 0x39 -#define REG_TIMER2COEF 0x3A -// Service settings -#define REG_IMAGECAL 0x3B -#define REG_TEMP 0x3C -#define REG_LOWBAT 0x3D -// Status -#define REG_IRQFLAGS1 0x3E -#define REG_IRQFLAGS2 0x3F -// I/O settings -#define REG_DIOMAPPING1 0x40 -#define REG_DIOMAPPING2 0x41 -// Version -#define REG_VERSION 0x42 -// Additional settings -#define REG_PLLHOP 0x44 -#define REG_TCXO 0x4B -#define REG_PADAC 0x4D -#define REG_FORMERTEMP 0x5B -#define REG_BITRATEFRAC 0x5D -#define REG_AGCREF 0x61 -#define REG_AGCTHRESH1 0x62 -#define REG_AGCTHRESH2 0x63 -#define REG_AGCTHRESH3 0x64 -#define REG_PLL 0x70 - -/*! - * ============================================================================ - * SX1276 FSK bits control definition - * ============================================================================ - */ - -/*! - * RegFifo - */ - -/*! - * RegOpMode - */ -#define RF_OPMODE_LONGRANGEMODE_MASK 0x7F -#define RF_OPMODE_LONGRANGEMODE_OFF 0x00 -#define RF_OPMODE_LONGRANGEMODE_ON 0x80 - -#define RF_OPMODE_MODULATIONTYPE_MASK 0x9F -#define RF_OPMODE_MODULATIONTYPE_FSK 0x00 // Default -#define RF_OPMODE_MODULATIONTYPE_OOK 0x20 - -#define RF_OPMODE_MODULATIONSHAPING_MASK 0xE7 -#define RF_OPMODE_MODULATIONSHAPING_00 0x00 // Default -#define RF_OPMODE_MODULATIONSHAPING_01 0x08 -#define RF_OPMODE_MODULATIONSHAPING_10 0x10 -#define RF_OPMODE_MODULATIONSHAPING_11 0x18 - -#define RF_OPMODE_MASK 0xF8 -#define RF_OPMODE_SLEEP 0x00 -#define RF_OPMODE_STANDBY 0x01 // Default -#define RF_OPMODE_SYNTHESIZER_TX 0x02 -#define RF_OPMODE_TRANSMITTER 0x03 -#define RF_OPMODE_SYNTHESIZER_RX 0x04 -#define RF_OPMODE_RECEIVER 0x05 - -/*! - * RegBitRate (bits/sec) - */ -#define RF_BITRATEMSB_1200_BPS 0x68 -#define RF_BITRATELSB_1200_BPS 0x2B -#define RF_BITRATEMSB_2400_BPS 0x34 -#define RF_BITRATELSB_2400_BPS 0x15 -#define RF_BITRATEMSB_4800_BPS 0x1A // Default -#define RF_BITRATELSB_4800_BPS 0x0B // Default -#define RF_BITRATEMSB_9600_BPS 0x0D -#define RF_BITRATELSB_9600_BPS 0x05 -#define RF_BITRATEMSB_15000_BPS 0x08 -#define RF_BITRATELSB_15000_BPS 0x55 -#define RF_BITRATEMSB_19200_BPS 0x06 -#define RF_BITRATELSB_19200_BPS 0x83 -#define RF_BITRATEMSB_38400_BPS 0x03 -#define RF_BITRATELSB_38400_BPS 0x41 -#define RF_BITRATEMSB_76800_BPS 0x01 -#define RF_BITRATELSB_76800_BPS 0xA1 -#define RF_BITRATEMSB_153600_BPS 0x00 -#define RF_BITRATELSB_153600_BPS 0xD0 -#define RF_BITRATEMSB_57600_BPS 0x02 -#define RF_BITRATELSB_57600_BPS 0x2C -#define RF_BITRATEMSB_115200_BPS 0x01 -#define RF_BITRATELSB_115200_BPS 0x16 -#define RF_BITRATEMSB_12500_BPS 0x0A -#define RF_BITRATELSB_12500_BPS 0x00 -#define RF_BITRATEMSB_25000_BPS 0x05 -#define RF_BITRATELSB_25000_BPS 0x00 -#define RF_BITRATEMSB_50000_BPS 0x02 -#define RF_BITRATELSB_50000_BPS 0x80 -#define RF_BITRATEMSB_100000_BPS 0x01 -#define RF_BITRATELSB_100000_BPS 0x40 -#define RF_BITRATEMSB_150000_BPS 0x00 -#define RF_BITRATELSB_150000_BPS 0xD5 -#define RF_BITRATEMSB_200000_BPS 0x00 -#define RF_BITRATELSB_200000_BPS 0xA0 -#define RF_BITRATEMSB_250000_BPS 0x00 -#define RF_BITRATELSB_250000_BPS 0x80 -#define RF_BITRATEMSB_32768_BPS 0x03 -#define RF_BITRATELSB_32768_BPS 0xD1 - -/*! - * RegFdev (Hz) - */ -#define RF_FDEVMSB_2000_HZ 0x00 -#define RF_FDEVLSB_2000_HZ 0x21 -#define RF_FDEVMSB_5000_HZ 0x00 // Default -#define RF_FDEVLSB_5000_HZ 0x52 // Default -#define RF_FDEVMSB_10000_HZ 0x00 -#define RF_FDEVLSB_10000_HZ 0xA4 -#define RF_FDEVMSB_15000_HZ 0x00 -#define RF_FDEVLSB_15000_HZ 0xF6 -#define RF_FDEVMSB_20000_HZ 0x01 -#define RF_FDEVLSB_20000_HZ 0x48 -#define RF_FDEVMSB_25000_HZ 0x01 -#define RF_FDEVLSB_25000_HZ 0x9A -#define RF_FDEVMSB_30000_HZ 0x01 -#define RF_FDEVLSB_30000_HZ 0xEC -#define RF_FDEVMSB_35000_HZ 0x02 -#define RF_FDEVLSB_35000_HZ 0x3D -#define RF_FDEVMSB_40000_HZ 0x02 -#define RF_FDEVLSB_40000_HZ 0x8F -#define RF_FDEVMSB_45000_HZ 0x02 -#define RF_FDEVLSB_45000_HZ 0xE1 -#define RF_FDEVMSB_50000_HZ 0x03 -#define RF_FDEVLSB_50000_HZ 0x33 -#define RF_FDEVMSB_55000_HZ 0x03 -#define RF_FDEVLSB_55000_HZ 0x85 -#define RF_FDEVMSB_60000_HZ 0x03 -#define RF_FDEVLSB_60000_HZ 0xD7 -#define RF_FDEVMSB_65000_HZ 0x04 -#define RF_FDEVLSB_65000_HZ 0x29 -#define RF_FDEVMSB_70000_HZ 0x04 -#define RF_FDEVLSB_70000_HZ 0x7B -#define RF_FDEVMSB_75000_HZ 0x04 -#define RF_FDEVLSB_75000_HZ 0xCD -#define RF_FDEVMSB_80000_HZ 0x05 -#define RF_FDEVLSB_80000_HZ 0x1F -#define RF_FDEVMSB_85000_HZ 0x05 -#define RF_FDEVLSB_85000_HZ 0x71 -#define RF_FDEVMSB_90000_HZ 0x05 -#define RF_FDEVLSB_90000_HZ 0xC3 -#define RF_FDEVMSB_95000_HZ 0x06 -#define RF_FDEVLSB_95000_HZ 0x14 -#define RF_FDEVMSB_100000_HZ 0x06 -#define RF_FDEVLSB_100000_HZ 0x66 -#define RF_FDEVMSB_110000_HZ 0x07 -#define RF_FDEVLSB_110000_HZ 0x0A -#define RF_FDEVMSB_120000_HZ 0x07 -#define RF_FDEVLSB_120000_HZ 0xAE -#define RF_FDEVMSB_130000_HZ 0x08 -#define RF_FDEVLSB_130000_HZ 0x52 -#define RF_FDEVMSB_140000_HZ 0x08 -#define RF_FDEVLSB_140000_HZ 0xF6 -#define RF_FDEVMSB_150000_HZ 0x09 -#define RF_FDEVLSB_150000_HZ 0x9A -#define RF_FDEVMSB_160000_HZ 0x0A -#define RF_FDEVLSB_160000_HZ 0x3D -#define RF_FDEVMSB_170000_HZ 0x0A -#define RF_FDEVLSB_170000_HZ 0xE1 -#define RF_FDEVMSB_180000_HZ 0x0B -#define RF_FDEVLSB_180000_HZ 0x85 -#define RF_FDEVMSB_190000_HZ 0x0C -#define RF_FDEVLSB_190000_HZ 0x29 -#define RF_FDEVMSB_200000_HZ 0x0C -#define RF_FDEVLSB_200000_HZ 0xCD - -/*! - * RegFrf (MHz) - */ -#define RF_FRFMSB_863_MHZ 0xD7 -#define RF_FRFMID_863_MHZ 0xC0 -#define RF_FRFLSB_863_MHZ 0x00 -#define RF_FRFMSB_864_MHZ 0xD8 -#define RF_FRFMID_864_MHZ 0x00 -#define RF_FRFLSB_864_MHZ 0x00 -#define RF_FRFMSB_865_MHZ 0xD8 -#define RF_FRFMID_865_MHZ 0x40 -#define RF_FRFLSB_865_MHZ 0x00 -#define RF_FRFMSB_866_MHZ 0xD8 -#define RF_FRFMID_866_MHZ 0x80 -#define RF_FRFLSB_866_MHZ 0x00 -#define RF_FRFMSB_867_MHZ 0xD8 -#define RF_FRFMID_867_MHZ 0xC0 -#define RF_FRFLSB_867_MHZ 0x00 -#define RF_FRFMSB_868_MHZ 0xD9 -#define RF_FRFMID_868_MHZ 0x00 -#define RF_FRFLSB_868_MHZ 0x00 -#define RF_FRFMSB_869_MHZ 0xD9 -#define RF_FRFMID_869_MHZ 0x40 -#define RF_FRFLSB_869_MHZ 0x00 -#define RF_FRFMSB_870_MHZ 0xD9 -#define RF_FRFMID_870_MHZ 0x80 -#define RF_FRFLSB_870_MHZ 0x00 - -#define RF_FRFMSB_902_MHZ 0xE1 -#define RF_FRFMID_902_MHZ 0x80 -#define RF_FRFLSB_902_MHZ 0x00 -#define RF_FRFMSB_903_MHZ 0xE1 -#define RF_FRFMID_903_MHZ 0xC0 -#define RF_FRFLSB_903_MHZ 0x00 -#define RF_FRFMSB_904_MHZ 0xE2 -#define RF_FRFMID_904_MHZ 0x00 -#define RF_FRFLSB_904_MHZ 0x00 -#define RF_FRFMSB_905_MHZ 0xE2 -#define RF_FRFMID_905_MHZ 0x40 -#define RF_FRFLSB_905_MHZ 0x00 -#define RF_FRFMSB_906_MHZ 0xE2 -#define RF_FRFMID_906_MHZ 0x80 -#define RF_FRFLSB_906_MHZ 0x00 -#define RF_FRFMSB_907_MHZ 0xE2 -#define RF_FRFMID_907_MHZ 0xC0 -#define RF_FRFLSB_907_MHZ 0x00 -#define RF_FRFMSB_908_MHZ 0xE3 -#define RF_FRFMID_908_MHZ 0x00 -#define RF_FRFLSB_908_MHZ 0x00 -#define RF_FRFMSB_909_MHZ 0xE3 -#define RF_FRFMID_909_MHZ 0x40 -#define RF_FRFLSB_909_MHZ 0x00 -#define RF_FRFMSB_910_MHZ 0xE3 -#define RF_FRFMID_910_MHZ 0x80 -#define RF_FRFLSB_910_MHZ 0x00 -#define RF_FRFMSB_911_MHZ 0xE3 -#define RF_FRFMID_911_MHZ 0xC0 -#define RF_FRFLSB_911_MHZ 0x00 -#define RF_FRFMSB_912_MHZ 0xE4 -#define RF_FRFMID_912_MHZ 0x00 -#define RF_FRFLSB_912_MHZ 0x00 -#define RF_FRFMSB_913_MHZ 0xE4 -#define RF_FRFMID_913_MHZ 0x40 -#define RF_FRFLSB_913_MHZ 0x00 -#define RF_FRFMSB_914_MHZ 0xE4 -#define RF_FRFMID_914_MHZ 0x80 -#define RF_FRFLSB_914_MHZ 0x00 -#define RF_FRFMSB_915_MHZ 0xE4 // Default -#define RF_FRFMID_915_MHZ 0xC0 // Default -#define RF_FRFLSB_915_MHZ 0x00 // Default -#define RF_FRFMSB_916_MHZ 0xE5 -#define RF_FRFMID_916_MHZ 0x00 -#define RF_FRFLSB_916_MHZ 0x00 -#define RF_FRFMSB_917_MHZ 0xE5 -#define RF_FRFMID_917_MHZ 0x40 -#define RF_FRFLSB_917_MHZ 0x00 -#define RF_FRFMSB_918_MHZ 0xE5 -#define RF_FRFMID_918_MHZ 0x80 -#define RF_FRFLSB_918_MHZ 0x00 -#define RF_FRFMSB_919_MHZ 0xE5 -#define RF_FRFMID_919_MHZ 0xC0 -#define RF_FRFLSB_919_MHZ 0x00 -#define RF_FRFMSB_920_MHZ 0xE6 -#define RF_FRFMID_920_MHZ 0x00 -#define RF_FRFLSB_920_MHZ 0x00 -#define RF_FRFMSB_921_MHZ 0xE6 -#define RF_FRFMID_921_MHZ 0x40 -#define RF_FRFLSB_921_MHZ 0x00 -#define RF_FRFMSB_922_MHZ 0xE6 -#define RF_FRFMID_922_MHZ 0x80 -#define RF_FRFLSB_922_MHZ 0x00 -#define RF_FRFMSB_923_MHZ 0xE6 -#define RF_FRFMID_923_MHZ 0xC0 -#define RF_FRFLSB_923_MHZ 0x00 -#define RF_FRFMSB_924_MHZ 0xE7 -#define RF_FRFMID_924_MHZ 0x00 -#define RF_FRFLSB_924_MHZ 0x00 -#define RF_FRFMSB_925_MHZ 0xE7 -#define RF_FRFMID_925_MHZ 0x40 -#define RF_FRFLSB_925_MHZ 0x00 -#define RF_FRFMSB_926_MHZ 0xE7 -#define RF_FRFMID_926_MHZ 0x80 -#define RF_FRFLSB_926_MHZ 0x00 -#define RF_FRFMSB_927_MHZ 0xE7 -#define RF_FRFMID_927_MHZ 0xC0 -#define RF_FRFLSB_927_MHZ 0x00 -#define RF_FRFMSB_928_MHZ 0xE8 -#define RF_FRFMID_928_MHZ 0x00 -#define RF_FRFLSB_928_MHZ 0x00 - -/*! - * RegPaConfig - */ -#define RF_PACONFIG_PASELECT_MASK 0x7F -#define RF_PACONFIG_PASELECT_PABOOST 0x80 -#define RF_PACONFIG_PASELECT_RFO 0x00 // Default - -#define RF_PACONFIG_MAX_POWER_MASK 0x8F - -#define RF_PACONFIG_OUTPUTPOWER_MASK 0xF0 - -/*! - * RegPaRamp - */ -#define RF_PARAMP_MODULATIONSHAPING_MASK 0x9F -#define RF_PARAMP_MODULATIONSHAPING_00 0x00 // Default -#define RF_PARAMP_MODULATIONSHAPING_01 0x20 -#define RF_PARAMP_MODULATIONSHAPING_10 0x40 -#define RF_PARAMP_MODULATIONSHAPING_11 0x60 - -#define RF_PARAMP_LOWPNTXPLL_MASK 0xEF -#define RF_PARAMP_LOWPNTXPLL_OFF 0x10 -#define RF_PARAMP_LOWPNTXPLL_ON 0x00 // Default - -#define RF_PARAMP_MASK 0xF0 -#define RF_PARAMP_3400_US 0x00 -#define RF_PARAMP_2000_US 0x01 -#define RF_PARAMP_1000_US 0x02 -#define RF_PARAMP_0500_US 0x03 -#define RF_PARAMP_0250_US 0x04 -#define RF_PARAMP_0125_US 0x05 -#define RF_PARAMP_0100_US 0x06 -#define RF_PARAMP_0062_US 0x07 -#define RF_PARAMP_0050_US 0x08 -#define RF_PARAMP_0040_US 0x09 // Default -#define RF_PARAMP_0031_US 0x0A -#define RF_PARAMP_0025_US 0x0B -#define RF_PARAMP_0020_US 0x0C -#define RF_PARAMP_0015_US 0x0D -#define RF_PARAMP_0012_US 0x0E -#define RF_PARAMP_0010_US 0x0F - -/*! - * RegOcp - */ -#define RF_OCP_MASK 0xDF -#define RF_OCP_ON 0x20 // Default -#define RF_OCP_OFF 0x00 - -#define RF_OCP_TRIM_MASK 0xE0 -#define RF_OCP_TRIM_045_MA 0x00 -#define RF_OCP_TRIM_050_MA 0x01 -#define RF_OCP_TRIM_055_MA 0x02 -#define RF_OCP_TRIM_060_MA 0x03 -#define RF_OCP_TRIM_065_MA 0x04 -#define RF_OCP_TRIM_070_MA 0x05 -#define RF_OCP_TRIM_075_MA 0x06 -#define RF_OCP_TRIM_080_MA 0x07 -#define RF_OCP_TRIM_085_MA 0x08 -#define RF_OCP_TRIM_090_MA 0x09 -#define RF_OCP_TRIM_095_MA 0x0A -#define RF_OCP_TRIM_100_MA 0x0B // Default -#define RF_OCP_TRIM_105_MA 0x0C -#define RF_OCP_TRIM_110_MA 0x0D -#define RF_OCP_TRIM_115_MA 0x0E -#define RF_OCP_TRIM_120_MA 0x0F -#define RF_OCP_TRIM_130_MA 0x10 -#define RF_OCP_TRIM_140_MA 0x11 -#define RF_OCP_TRIM_150_MA 0x12 -#define RF_OCP_TRIM_160_MA 0x13 -#define RF_OCP_TRIM_170_MA 0x14 -#define RF_OCP_TRIM_180_MA 0x15 -#define RF_OCP_TRIM_190_MA 0x16 -#define RF_OCP_TRIM_200_MA 0x17 -#define RF_OCP_TRIM_210_MA 0x18 -#define RF_OCP_TRIM_220_MA 0x19 -#define RF_OCP_TRIM_230_MA 0x1A -#define RF_OCP_TRIM_240_MA 0x1B - -/*! - * RegLna - */ -#define RF_LNA_GAIN_MASK 0x1F -#define RF_LNA_GAIN_G1 0x20 // Default -#define RF_LNA_GAIN_G2 0x40 -#define RF_LNA_GAIN_G3 0x60 -#define RF_LNA_GAIN_G4 0x80 -#define RF_LNA_GAIN_G5 0xA0 -#define RF_LNA_GAIN_G6 0xC0 - -#define RF_LNA_BOOST_MASK 0xFC -#define RF_LNA_BOOST_OFF 0x00 // Default -#define RF_LNA_BOOST_ON 0x03 - -/*! - * RegRxConfig - */ -#define RF_RXCONFIG_RESTARTRXONCOLLISION_MASK 0x7F -#define RF_RXCONFIG_RESTARTRXONCOLLISION_ON 0x80 -#define RF_RXCONFIG_RESTARTRXONCOLLISION_OFF 0x00 // Default - -#define RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK 0x40 // Write only - -#define RF_RXCONFIG_RESTARTRXWITHPLLLOCK 0x20 // Write only - -#define RF_RXCONFIG_AFCAUTO_MASK 0xEF -#define RF_RXCONFIG_AFCAUTO_ON 0x10 -#define RF_RXCONFIG_AFCAUTO_OFF 0x00 // Default - -#define RF_RXCONFIG_AGCAUTO_MASK 0xF7 -#define RF_RXCONFIG_AGCAUTO_ON 0x08 // Default -#define RF_RXCONFIG_AGCAUTO_OFF 0x00 - -#define RF_RXCONFIG_RXTRIGER_MASK 0xF8 -#define RF_RXCONFIG_RXTRIGER_OFF 0x00 -#define RF_RXCONFIG_RXTRIGER_RSSI 0x01 -#define RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT 0x06 // Default -#define RF_RXCONFIG_RXTRIGER_RSSI_PREAMBLEDETECT 0x07 - -/*! - * RegRssiConfig - */ -#define RF_RSSICONFIG_OFFSET_MASK 0x07 -#define RF_RSSICONFIG_OFFSET_P_00_DB 0x00 // Default -#define RF_RSSICONFIG_OFFSET_P_01_DB 0x08 -#define RF_RSSICONFIG_OFFSET_P_02_DB 0x10 -#define RF_RSSICONFIG_OFFSET_P_03_DB 0x18 -#define RF_RSSICONFIG_OFFSET_P_04_DB 0x20 -#define RF_RSSICONFIG_OFFSET_P_05_DB 0x28 -#define RF_RSSICONFIG_OFFSET_P_06_DB 0x30 -#define RF_RSSICONFIG_OFFSET_P_07_DB 0x38 -#define RF_RSSICONFIG_OFFSET_P_08_DB 0x40 -#define RF_RSSICONFIG_OFFSET_P_09_DB 0x48 -#define RF_RSSICONFIG_OFFSET_P_10_DB 0x50 -#define RF_RSSICONFIG_OFFSET_P_11_DB 0x58 -#define RF_RSSICONFIG_OFFSET_P_12_DB 0x60 -#define RF_RSSICONFIG_OFFSET_P_13_DB 0x68 -#define RF_RSSICONFIG_OFFSET_P_14_DB 0x70 -#define RF_RSSICONFIG_OFFSET_P_15_DB 0x78 -#define RF_RSSICONFIG_OFFSET_M_16_DB 0x80 -#define RF_RSSICONFIG_OFFSET_M_15_DB 0x88 -#define RF_RSSICONFIG_OFFSET_M_14_DB 0x90 -#define RF_RSSICONFIG_OFFSET_M_13_DB 0x98 -#define RF_RSSICONFIG_OFFSET_M_12_DB 0xA0 -#define RF_RSSICONFIG_OFFSET_M_11_DB 0xA8 -#define RF_RSSICONFIG_OFFSET_M_10_DB 0xB0 -#define RF_RSSICONFIG_OFFSET_M_09_DB 0xB8 -#define RF_RSSICONFIG_OFFSET_M_08_DB 0xC0 -#define RF_RSSICONFIG_OFFSET_M_07_DB 0xC8 -#define RF_RSSICONFIG_OFFSET_M_06_DB 0xD0 -#define RF_RSSICONFIG_OFFSET_M_05_DB 0xD8 -#define RF_RSSICONFIG_OFFSET_M_04_DB 0xE0 -#define RF_RSSICONFIG_OFFSET_M_03_DB 0xE8 -#define RF_RSSICONFIG_OFFSET_M_02_DB 0xF0 -#define RF_RSSICONFIG_OFFSET_M_01_DB 0xF8 - -#define RF_RSSICONFIG_SMOOTHING_MASK 0xF8 -#define RF_RSSICONFIG_SMOOTHING_2 0x00 -#define RF_RSSICONFIG_SMOOTHING_4 0x01 -#define RF_RSSICONFIG_SMOOTHING_8 0x02 // Default -#define RF_RSSICONFIG_SMOOTHING_16 0x03 -#define RF_RSSICONFIG_SMOOTHING_32 0x04 -#define RF_RSSICONFIG_SMOOTHING_64 0x05 -#define RF_RSSICONFIG_SMOOTHING_128 0x06 -#define RF_RSSICONFIG_SMOOTHING_256 0x07 - -/*! - * RegRssiCollision - */ -#define RF_RSSICOLISION_THRESHOLD 0x0A // Default - -/*! - * RegRssiThresh - */ -#define RF_RSSITHRESH_THRESHOLD 0xFF // Default - -/*! - * RegRssiValue (Read Only) - */ - -/*! - * RegRxBw - */ -#define RF_RXBW_MANT_MASK 0xE7 -#define RF_RXBW_MANT_16 0x00 -#define RF_RXBW_MANT_20 0x08 -#define RF_RXBW_MANT_24 0x10 // Default - -#define RF_RXBW_EXP_MASK 0xF8 -#define RF_RXBW_EXP_0 0x00 -#define RF_RXBW_EXP_1 0x01 -#define RF_RXBW_EXP_2 0x02 -#define RF_RXBW_EXP_3 0x03 -#define RF_RXBW_EXP_4 0x04 -#define RF_RXBW_EXP_5 0x05 // Default -#define RF_RXBW_EXP_6 0x06 -#define RF_RXBW_EXP_7 0x07 - -/*! - * RegAfcBw - */ -#define RF_AFCBW_MANTAFC_MASK 0xE7 -#define RF_AFCBW_MANTAFC_16 0x00 -#define RF_AFCBW_MANTAFC_20 0x08 // Default -#define RF_AFCBW_MANTAFC_24 0x10 - -#define RF_AFCBW_EXPAFC_MASK 0xF8 -#define RF_AFCBW_EXPAFC_0 0x00 -#define RF_AFCBW_EXPAFC_1 0x01 -#define RF_AFCBW_EXPAFC_2 0x02 -#define RF_AFCBW_EXPAFC_3 0x03 // Default -#define RF_AFCBW_EXPAFC_4 0x04 -#define RF_AFCBW_EXPAFC_5 0x05 -#define RF_AFCBW_EXPAFC_6 0x06 -#define RF_AFCBW_EXPAFC_7 0x07 - -/*! - * RegOokPeak - */ -#define RF_OOKPEAK_BITSYNC_MASK 0xDF // Default -#define RF_OOKPEAK_BITSYNC_ON 0x20 // Default -#define RF_OOKPEAK_BITSYNC_OFF 0x00 - -#define RF_OOKPEAK_OOKTHRESHTYPE_MASK 0xE7 -#define RF_OOKPEAK_OOKTHRESHTYPE_FIXED 0x00 -#define RF_OOKPEAK_OOKTHRESHTYPE_PEAK 0x08 // Default -#define RF_OOKPEAK_OOKTHRESHTYPE_AVERAGE 0x10 - -#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_MASK 0xF8 -#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_0_5_DB 0x00 // Default -#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_0_DB 0x01 -#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_5_DB 0x02 -#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_2_0_DB 0x03 -#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_3_0_DB 0x04 -#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_4_0_DB 0x05 -#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_5_0_DB 0x06 -#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_6_0_DB 0x07 - -/*! - * RegOokFix - */ -#define RF_OOKFIX_OOKFIXEDTHRESHOLD 0x0C // Default - -/*! - * RegOokAvg - */ -#define RF_OOKAVG_OOKPEAKTHRESHDEC_MASK 0x1F -#define RF_OOKAVG_OOKPEAKTHRESHDEC_000 0x00 // Default -#define RF_OOKAVG_OOKPEAKTHRESHDEC_001 0x20 -#define RF_OOKAVG_OOKPEAKTHRESHDEC_010 0x40 -#define RF_OOKAVG_OOKPEAKTHRESHDEC_011 0x60 -#define RF_OOKAVG_OOKPEAKTHRESHDEC_100 0x80 -#define RF_OOKAVG_OOKPEAKTHRESHDEC_101 0xA0 -#define RF_OOKAVG_OOKPEAKTHRESHDEC_110 0xC0 -#define RF_OOKAVG_OOKPEAKTHRESHDEC_111 0xE0 - -#define RF_OOKAVG_AVERAGEOFFSET_MASK 0xF3 -#define RF_OOKAVG_AVERAGEOFFSET_0_DB 0x00 // Default -#define RF_OOKAVG_AVERAGEOFFSET_2_DB 0x04 -#define RF_OOKAVG_AVERAGEOFFSET_4_DB 0x08 -#define RF_OOKAVG_AVERAGEOFFSET_6_DB 0x0C - -#define RF_OOKAVG_OOKAVERAGETHRESHFILT_MASK 0xFC -#define RF_OOKAVG_OOKAVERAGETHRESHFILT_00 0x00 -#define RF_OOKAVG_OOKAVERAGETHRESHFILT_01 0x01 -#define RF_OOKAVG_OOKAVERAGETHRESHFILT_10 0x02 // Default -#define RF_OOKAVG_OOKAVERAGETHRESHFILT_11 0x03 - -/*! - * RegAfcFei - */ -#define RF_AFCFEI_AGCSTART 0x10 - -#define RF_AFCFEI_AFCCLEAR 0x02 - -#define RF_AFCFEI_AFCAUTOCLEAR_MASK 0xFE -#define RF_AFCFEI_AFCAUTOCLEAR_ON 0x01 -#define RF_AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default - -/*! - * RegAfcMsb (Read Only) - */ - -/*! - * RegAfcLsb (Read Only) - */ - -/*! - * RegFeiMsb (Read Only) - */ - -/*! - * RegFeiLsb (Read Only) - */ - -/*! - * RegPreambleDetect - */ -#define RF_PREAMBLEDETECT_DETECTOR_MASK 0x7F -#define RF_PREAMBLEDETECT_DETECTOR_ON 0x80 // Default -#define RF_PREAMBLEDETECT_DETECTOR_OFF 0x00 - -#define RF_PREAMBLEDETECT_DETECTORSIZE_MASK 0x9F -#define RF_PREAMBLEDETECT_DETECTORSIZE_1 0x00 -#define RF_PREAMBLEDETECT_DETECTORSIZE_2 0x20 // Default -#define RF_PREAMBLEDETECT_DETECTORSIZE_3 0x40 -#define RF_PREAMBLEDETECT_DETECTORSIZE_4 0x60 - -#define RF_PREAMBLEDETECT_DETECTORTOL_MASK 0xE0 -#define RF_PREAMBLEDETECT_DETECTORTOL_0 0x00 -#define RF_PREAMBLEDETECT_DETECTORTOL_1 0x01 -#define RF_PREAMBLEDETECT_DETECTORTOL_2 0x02 -#define RF_PREAMBLEDETECT_DETECTORTOL_3 0x03 -#define RF_PREAMBLEDETECT_DETECTORTOL_4 0x04 -#define RF_PREAMBLEDETECT_DETECTORTOL_5 0x05 -#define RF_PREAMBLEDETECT_DETECTORTOL_6 0x06 -#define RF_PREAMBLEDETECT_DETECTORTOL_7 0x07 -#define RF_PREAMBLEDETECT_DETECTORTOL_8 0x08 -#define RF_PREAMBLEDETECT_DETECTORTOL_9 0x09 -#define RF_PREAMBLEDETECT_DETECTORTOL_10 0x0A // Default -#define RF_PREAMBLEDETECT_DETECTORTOL_11 0x0B -#define RF_PREAMBLEDETECT_DETECTORTOL_12 0x0C -#define RF_PREAMBLEDETECT_DETECTORTOL_13 0x0D -#define RF_PREAMBLEDETECT_DETECTORTOL_14 0x0E -#define RF_PREAMBLEDETECT_DETECTORTOL_15 0x0F -#define RF_PREAMBLEDETECT_DETECTORTOL_16 0x10 -#define RF_PREAMBLEDETECT_DETECTORTOL_17 0x11 -#define RF_PREAMBLEDETECT_DETECTORTOL_18 0x12 -#define RF_PREAMBLEDETECT_DETECTORTOL_19 0x13 -#define RF_PREAMBLEDETECT_DETECTORTOL_20 0x14 -#define RF_PREAMBLEDETECT_DETECTORTOL_21 0x15 -#define RF_PREAMBLEDETECT_DETECTORTOL_22 0x16 -#define RF_PREAMBLEDETECT_DETECTORTOL_23 0x17 -#define RF_PREAMBLEDETECT_DETECTORTOL_24 0x18 -#define RF_PREAMBLEDETECT_DETECTORTOL_25 0x19 -#define RF_PREAMBLEDETECT_DETECTORTOL_26 0x1A -#define RF_PREAMBLEDETECT_DETECTORTOL_27 0x1B -#define RF_PREAMBLEDETECT_DETECTORTOL_28 0x1C -#define RF_PREAMBLEDETECT_DETECTORTOL_29 0x1D -#define RF_PREAMBLEDETECT_DETECTORTOL_30 0x1E -#define RF_PREAMBLEDETECT_DETECTORTOL_31 0x1F - -/*! - * RegRxTimeout1 - */ -#define RF_RXTIMEOUT1_TIMEOUTRXRSSI 0x00 // Default - -/*! - * RegRxTimeout2 - */ -#define RF_RXTIMEOUT2_TIMEOUTRXPREAMBLE 0x00 // Default - -/*! - * RegRxTimeout3 - */ -#define RF_RXTIMEOUT3_TIMEOUTSIGNALSYNC 0x00 // Default - -/*! - * RegRxDelay - */ -#define RF_RXDELAY_INTERPACKETRXDELAY 0x00 // Default - -/*! - * RegOsc - */ -#define RF_OSC_RCCALSTART 0x08 - -#define RF_OSC_CLKOUT_MASK 0xF8 -#define RF_OSC_CLKOUT_32_MHZ 0x00 -#define RF_OSC_CLKOUT_16_MHZ 0x01 -#define RF_OSC_CLKOUT_8_MHZ 0x02 -#define RF_OSC_CLKOUT_4_MHZ 0x03 -#define RF_OSC_CLKOUT_2_MHZ 0x04 -#define RF_OSC_CLKOUT_1_MHZ 0x05 // Default -#define RF_OSC_CLKOUT_RC 0x06 -#define RF_OSC_CLKOUT_OFF 0x07 - -/*! - * RegPreambleMsb/RegPreambleLsb - */ -#define RF_PREAMBLEMSB_SIZE 0x00 // Default -#define RF_PREAMBLELSB_SIZE 0x03 // Default - -/*! - * RegSyncConfig - */ -#define RF_SYNCCONFIG_AUTORESTARTRXMODE_MASK 0x3F -#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON 0x80 // Default -#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_OFF 0x40 -#define RF_SYNCCONFIG_AUTORESTARTRXMODE_OFF 0x00 - - -#define RF_SYNCCONFIG_PREAMBLEPOLARITY_MASK 0xDF -#define RF_SYNCCONFIG_PREAMBLEPOLARITY_55 0x20 -#define RF_SYNCCONFIG_PREAMBLEPOLARITY_AA 0x00 // Default - -#define RF_SYNCCONFIG_SYNC_MASK 0xEF -#define RF_SYNCCONFIG_SYNC_ON 0x10 // Default -#define RF_SYNCCONFIG_SYNC_OFF 0x00 - - -#define RF_SYNCCONFIG_SYNCSIZE_MASK 0xF8 -#define RF_SYNCCONFIG_SYNCSIZE_1 0x00 -#define RF_SYNCCONFIG_SYNCSIZE_2 0x01 -#define RF_SYNCCONFIG_SYNCSIZE_3 0x02 -#define RF_SYNCCONFIG_SYNCSIZE_4 0x03 // Default -#define RF_SYNCCONFIG_SYNCSIZE_5 0x04 -#define RF_SYNCCONFIG_SYNCSIZE_6 0x05 -#define RF_SYNCCONFIG_SYNCSIZE_7 0x06 -#define RF_SYNCCONFIG_SYNCSIZE_8 0x07 - -/*! - * RegSyncValue1-8 - */ -#define RF_SYNCVALUE1_SYNCVALUE 0x01 // Default -#define RF_SYNCVALUE2_SYNCVALUE 0x01 // Default -#define RF_SYNCVALUE3_SYNCVALUE 0x01 // Default -#define RF_SYNCVALUE4_SYNCVALUE 0x01 // Default -#define RF_SYNCVALUE5_SYNCVALUE 0x01 // Default -#define RF_SYNCVALUE6_SYNCVALUE 0x01 // Default -#define RF_SYNCVALUE7_SYNCVALUE 0x01 // Default -#define RF_SYNCVALUE8_SYNCVALUE 0x01 // Default - -/*! - * RegPacketConfig1 - */ -#define RF_PACKETCONFIG1_PACKETFORMAT_MASK 0x7F -#define RF_PACKETCONFIG1_PACKETFORMAT_FIXED 0x00 -#define RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE 0x80 // Default - -#define RF_PACKETCONFIG1_DCFREE_MASK 0x9F -#define RF_PACKETCONFIG1_DCFREE_OFF 0x00 // Default -#define RF_PACKETCONFIG1_DCFREE_MANCHESTER 0x20 -#define RF_PACKETCONFIG1_DCFREE_WHITENING 0x40 - -#define RF_PACKETCONFIG1_CRC_MASK 0xEF -#define RF_PACKETCONFIG1_CRC_ON 0x10 // Default -#define RF_PACKETCONFIG1_CRC_OFF 0x00 - -#define RF_PACKETCONFIG1_CRCAUTOCLEAR_MASK 0xF7 -#define RF_PACKETCONFIG1_CRCAUTOCLEAR_ON 0x00 // Default -#define RF_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08 - -#define RF_PACKETCONFIG1_ADDRSFILTERING_MASK 0xF9 -#define RF_PACKETCONFIG1_ADDRSFILTERING_OFF 0x00 // Default -#define RF_PACKETCONFIG1_ADDRSFILTERING_NODE 0x02 -#define RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST 0x04 - -#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_MASK 0xFE -#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT 0x00 // Default -#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_IBM 0x01 - -/*! - * RegPacketConfig2 - */ - -#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE_MASK 0x7F -#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE 0x80 -#define RF_PACKETCONFIG2_WMBUS_CRC_DISABLE 0x00 // Default - -#define RF_PACKETCONFIG2_DATAMODE_MASK 0xBF -#define RF_PACKETCONFIG2_DATAMODE_CONTINUOUS 0x00 -#define RF_PACKETCONFIG2_DATAMODE_PACKET 0x40 // Default - -#define RF_PACKETCONFIG2_IOHOME_MASK 0xDF -#define RF_PACKETCONFIG2_IOHOME_ON 0x20 -#define RF_PACKETCONFIG2_IOHOME_OFF 0x00 // Default - -#define RF_PACKETCONFIG2_BEACON_MASK 0xF7 -#define RF_PACKETCONFIG2_BEACON_ON 0x08 -#define RF_PACKETCONFIG2_BEACON_OFF 0x00 // Default - -#define RF_PACKETCONFIG2_PAYLOADLENGTH_MSB_MASK 0xF8 - -/*! - * RegPayloadLength - */ -#define RF_PAYLOADLENGTH_LENGTH 0x40 // Default - -/*! - * RegNodeAdrs - */ -#define RF_NODEADDRESS_ADDRESS 0x00 - -/*! - * RegBroadcastAdrs - */ -#define RF_BROADCASTADDRESS_ADDRESS 0x00 - -/*! - * RegFifoThresh - */ -#define RF_FIFOTHRESH_TXSTARTCONDITION_MASK 0x7F -#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFOTHRESH 0x00 // Default -#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY 0x80 - -#define RF_FIFOTHRESH_FIFOTHRESHOLD_MASK 0xC0 -#define RF_FIFOTHRESH_FIFOTHRESHOLD_THRESHOLD 0x0F // Default - -/*! - * RegSeqConfig1 - */ -#define RF_SEQCONFIG1_SEQUENCER_START 0x80 - -#define RF_SEQCONFIG1_SEQUENCER_STOP 0x40 - -#define RF_SEQCONFIG1_IDLEMODE_MASK 0xDF -#define RF_SEQCONFIG1_IDLEMODE_SLEEP 0x20 -#define RF_SEQCONFIG1_IDLEMODE_STANDBY 0x00 // Default - -#define RF_SEQCONFIG1_FROMSTART_MASK 0xE7 -#define RF_SEQCONFIG1_FROMSTART_TOLPS 0x00 // Default -#define RF_SEQCONFIG1_FROMSTART_TORX 0x08 -#define RF_SEQCONFIG1_FROMSTART_TOTX 0x10 -#define RF_SEQCONFIG1_FROMSTART_TOTX_ONFIFOLEVEL 0x18 - -#define RF_SEQCONFIG1_LPS_MASK 0xFB -#define RF_SEQCONFIG1_LPS_SEQUENCER_OFF 0x00 // Default -#define RF_SEQCONFIG1_LPS_IDLE 0x04 - -#define RF_SEQCONFIG1_FROMIDLE_MASK 0xFD -#define RF_SEQCONFIG1_FROMIDLE_TOTX 0x00 // Default -#define RF_SEQCONFIG1_FROMIDLE_TORX 0x02 - -#define RF_SEQCONFIG1_FROMTX_MASK 0xFE -#define RF_SEQCONFIG1_FROMTX_TOLPS 0x00 // Default -#define RF_SEQCONFIG1_FROMTX_TORX 0x01 - -/*! - * RegSeqConfig2 - */ -#define RF_SEQCONFIG2_FROMRX_MASK 0x1F -#define RF_SEQCONFIG2_FROMRX_TOUNUSED_000 0x00 // Default -#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONPLDRDY 0x20 -#define RF_SEQCONFIG2_FROMRX_TOLPS_ONPLDRDY 0x40 -#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONCRCOK 0x60 -#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONRSSI 0x80 -#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONSYNC 0xA0 -#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONPREAMBLE 0xC0 -#define RF_SEQCONFIG2_FROMRX_TOUNUSED_111 0xE0 - -#define RF_SEQCONFIG2_FROMRXTIMEOUT_MASK 0xE7 -#define RF_SEQCONFIG2_FROMRXTIMEOUT_TORXRESTART 0x00 // Default -#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOTX 0x08 -#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOLPS 0x10 -#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOSEQUENCEROFF 0x18 - -#define RF_SEQCONFIG2_FROMRXPKT_MASK 0xF8 -#define RF_SEQCONFIG2_FROMRXPKT_TOSEQUENCEROFF 0x00 // Default -#define RF_SEQCONFIG2_FROMRXPKT_TOTX_ONFIFOEMPTY 0x01 -#define RF_SEQCONFIG2_FROMRXPKT_TOLPS 0x02 -#define RF_SEQCONFIG2_FROMRXPKT_TOSYNTHESIZERRX 0x03 -#define RF_SEQCONFIG2_FROMRXPKT_TORX 0x04 - -/*! - * RegTimerResol - */ -#define RF_TIMERRESOL_TIMER1RESOL_MASK 0xF3 -#define RF_TIMERRESOL_TIMER1RESOL_OFF 0x00 // Default -#define RF_TIMERRESOL_TIMER1RESOL_000064_US 0x04 -#define RF_TIMERRESOL_TIMER1RESOL_004100_US 0x08 -#define RF_TIMERRESOL_TIMER1RESOL_262000_US 0x0C - -#define RF_TIMERRESOL_TIMER2RESOL_MASK 0xFC -#define RF_TIMERRESOL_TIMER2RESOL_OFF 0x00 // Default -#define RF_TIMERRESOL_TIMER2RESOL_000064_US 0x01 -#define RF_TIMERRESOL_TIMER2RESOL_004100_US 0x02 -#define RF_TIMERRESOL_TIMER2RESOL_262000_US 0x03 - -/*! - * RegTimer1Coef - */ -#define RF_TIMER1COEF_TIMER1COEFFICIENT 0xF5 // Default - -/*! - * RegTimer2Coef - */ -#define RF_TIMER2COEF_TIMER2COEFFICIENT 0x20 // Default - -/*! - * RegImageCal - */ -#define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F -#define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 -#define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default - -#define RF_IMAGECAL_IMAGECAL_MASK 0xBF -#define RF_IMAGECAL_IMAGECAL_START 0x40 - -#define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 -#define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default - -#define RF_IMAGECAL_TEMPCHANGE_HIGHER 0x08 -#define RF_IMAGECAL_TEMPCHANGE_LOWER 0x00 - -#define RF_IMAGECAL_TEMPTHRESHOLD_MASK 0xF9 -#define RF_IMAGECAL_TEMPTHRESHOLD_05 0x00 -#define RF_IMAGECAL_TEMPTHRESHOLD_10 0x02 // Default -#define RF_IMAGECAL_TEMPTHRESHOLD_15 0x04 -#define RF_IMAGECAL_TEMPTHRESHOLD_20 0x06 - -#define RF_IMAGECAL_TEMPMONITOR_MASK 0xFE -#define RF_IMAGECAL_TEMPMONITOR_ON 0x00 // Default -#define RF_IMAGECAL_TEMPMONITOR_OFF 0x01 - -/*! - * RegTemp (Read Only) - */ - -/*! - * RegLowBat - */ -#define RF_LOWBAT_MASK 0xF7 -#define RF_LOWBAT_ON 0x08 -#define RF_LOWBAT_OFF 0x00 // Default - -#define RF_LOWBAT_TRIM_MASK 0xF8 -#define RF_LOWBAT_TRIM_1695 0x00 -#define RF_LOWBAT_TRIM_1764 0x01 -#define RF_LOWBAT_TRIM_1835 0x02 // Default -#define RF_LOWBAT_TRIM_1905 0x03 -#define RF_LOWBAT_TRIM_1976 0x04 -#define RF_LOWBAT_TRIM_2045 0x05 -#define RF_LOWBAT_TRIM_2116 0x06 -#define RF_LOWBAT_TRIM_2185 0x07 - -/*! - * RegIrqFlags1 - */ -#define RF_IRQFLAGS1_MODEREADY 0x80 - -#define RF_IRQFLAGS1_RXREADY 0x40 - -#define RF_IRQFLAGS1_TXREADY 0x20 - -#define RF_IRQFLAGS1_PLLLOCK 0x10 - -#define RF_IRQFLAGS1_RSSI 0x08 - -#define RF_IRQFLAGS1_TIMEOUT 0x04 - -#define RF_IRQFLAGS1_PREAMBLEDETECT 0x02 - -#define RF_IRQFLAGS1_SYNCADDRESSMATCH 0x01 - -/*! - * RegIrqFlags2 - */ -#define RF_IRQFLAGS2_FIFOFULL 0x80 - -#define RF_IRQFLAGS2_FIFOEMPTY 0x40 - -#define RF_IRQFLAGS2_FIFOLEVEL 0x20 - -#define RF_IRQFLAGS2_FIFOOVERRUN 0x10 - -#define RF_IRQFLAGS2_PACKETSENT 0x08 - -#define RF_IRQFLAGS2_PAYLOADREADY 0x04 - -#define RF_IRQFLAGS2_CRCOK 0x02 - -#define RF_IRQFLAGS2_LOWBAT 0x01 - -/*! - * RegDioMapping1 - */ -#define RF_DIOMAPPING1_DIO0_MASK 0x3F -#define RF_DIOMAPPING1_DIO0_00 0x00 // Default -#define RF_DIOMAPPING1_DIO0_01 0x40 -#define RF_DIOMAPPING1_DIO0_10 0x80 -#define RF_DIOMAPPING1_DIO0_11 0xC0 - -#define RF_DIOMAPPING1_DIO1_MASK 0xCF -#define RF_DIOMAPPING1_DIO1_00 0x00 // Default -#define RF_DIOMAPPING1_DIO1_01 0x10 -#define RF_DIOMAPPING1_DIO1_10 0x20 -#define RF_DIOMAPPING1_DIO1_11 0x30 - -#define RF_DIOMAPPING1_DIO2_MASK 0xF3 -#define RF_DIOMAPPING1_DIO2_00 0x00 // Default -#define RF_DIOMAPPING1_DIO2_01 0x04 -#define RF_DIOMAPPING1_DIO2_10 0x08 -#define RF_DIOMAPPING1_DIO2_11 0x0C - -#define RF_DIOMAPPING1_DIO3_MASK 0xFC -#define RF_DIOMAPPING1_DIO3_00 0x00 // Default -#define RF_DIOMAPPING1_DIO3_01 0x01 -#define RF_DIOMAPPING1_DIO3_10 0x02 -#define RF_DIOMAPPING1_DIO3_11 0x03 - -/*! - * RegDioMapping2 - */ -#define RF_DIOMAPPING2_DIO4_MASK 0x3F -#define RF_DIOMAPPING2_DIO4_00 0x00 // Default -#define RF_DIOMAPPING2_DIO4_01 0x40 -#define RF_DIOMAPPING2_DIO4_10 0x80 -#define RF_DIOMAPPING2_DIO4_11 0xC0 - -#define RF_DIOMAPPING2_DIO5_MASK 0xCF -#define RF_DIOMAPPING2_DIO5_00 0x00 // Default -#define RF_DIOMAPPING2_DIO5_01 0x10 -#define RF_DIOMAPPING2_DIO5_10 0x20 -#define RF_DIOMAPPING2_DIO5_11 0x30 - -#define RF_DIOMAPPING2_MAP_MASK 0xFE -#define RF_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 -#define RF_DIOMAPPING2_MAP_RSSI 0x00 // Default - -/*! - * RegVersion (Read Only) - */ - -/*! - * RegPllHop - */ -#define RF_PLLHOP_FASTHOP_MASK 0x7F -#define RF_PLLHOP_FASTHOP_ON 0x80 -#define RF_PLLHOP_FASTHOP_OFF 0x00 // Default - -/*! - * RegTcxo - */ -#define RF_TCXO_TCXOINPUT_MASK 0xEF -#define RF_TCXO_TCXOINPUT_ON 0x10 -#define RF_TCXO_TCXOINPUT_OFF 0x00 // Default - -/*! - * RegPaDac - */ -#define RF_PADAC_20DBM_MASK 0xF8 -#define RF_PADAC_20DBM_ON 0x07 -#define RF_PADAC_20DBM_OFF 0x04 // Default - -/*! - * RegFormerTemp - */ - -/*! - * RegBitrateFrac - */ -#define RF_BITRATEFRAC_MASK 0xF0 - -/*! - * RegAgcRef - */ - -/*! - * RegAgcThresh1 - */ - -/*! - * RegAgcThresh2 - */ - -/*! - * RegAgcThresh3 - */ - -/*! - * RegPll - */ -#define RF_PLL_BANDWIDTH_MASK 0x3F -#define RF_PLL_BANDWIDTH_75 0x00 -#define RF_PLL_BANDWIDTH_150 0x40 -#define RF_PLL_BANDWIDTH_225 0x80 -#define RF_PLL_BANDWIDTH_300 0xC0 // Default - -#endif // __SX1276_REGS_FSK_H__ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C) 2014 Semtech + +Description: SX1276 FSK modem registers and bits definitions + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ +#ifndef __SX1276_REGS_FSK_H__ +#define __SX1276_REGS_FSK_H__ + +/*! + * ============================================================================ + * SX1276 Internal registers Address + * ============================================================================ + */ +#define REG_FIFO 0x00 +// Common settings +#define REG_OPMODE 0x01 +#define REG_BITRATEMSB 0x02 +#define REG_BITRATELSB 0x03 +#define REG_FDEVMSB 0x04 +#define REG_FDEVLSB 0x05 +#define REG_FRFMSB 0x06 +#define REG_FRFMID 0x07 +#define REG_FRFLSB 0x08 +// Tx settings +#define REG_PACONFIG 0x09 +#define REG_PARAMP 0x0A +#define REG_OCP 0x0B +// Rx settings +#define REG_LNA 0x0C +#define REG_RXCONFIG 0x0D +#define REG_RSSICONFIG 0x0E +#define REG_RSSICOLLISION 0x0F +#define REG_RSSITHRESH 0x10 +#define REG_RSSIVALUE 0x11 +#define REG_RXBW 0x12 +#define REG_AFCBW 0x13 +#define REG_OOKPEAK 0x14 +#define REG_OOKFIX 0x15 +#define REG_OOKAVG 0x16 +#define REG_RES17 0x17 +#define REG_RES18 0x18 +#define REG_RES19 0x19 +#define REG_AFCFEI 0x1A +#define REG_AFCMSB 0x1B +#define REG_AFCLSB 0x1C +#define REG_FEIMSB 0x1D +#define REG_FEILSB 0x1E +#define REG_PREAMBLEDETECT 0x1F +#define REG_RXTIMEOUT1 0x20 +#define REG_RXTIMEOUT2 0x21 +#define REG_RXTIMEOUT3 0x22 +#define REG_RXDELAY 0x23 +// Oscillator settings +#define REG_OSC 0x24 +// Packet handler settings +#define REG_PREAMBLEMSB 0x25 +#define REG_PREAMBLELSB 0x26 +#define REG_SYNCCONFIG 0x27 +#define REG_SYNCVALUE1 0x28 +#define REG_SYNCVALUE2 0x29 +#define REG_SYNCVALUE3 0x2A +#define REG_SYNCVALUE4 0x2B +#define REG_SYNCVALUE5 0x2C +#define REG_SYNCVALUE6 0x2D +#define REG_SYNCVALUE7 0x2E +#define REG_SYNCVALUE8 0x2F +#define REG_PACKETCONFIG1 0x30 +#define REG_PACKETCONFIG2 0x31 +#define REG_PAYLOADLENGTH 0x32 +#define REG_NODEADRS 0x33 +#define REG_BROADCASTADRS 0x34 +#define REG_FIFOTHRESH 0x35 +// SM settings +#define REG_SEQCONFIG1 0x36 +#define REG_SEQCONFIG2 0x37 +#define REG_TIMERRESOL 0x38 +#define REG_TIMER1COEF 0x39 +#define REG_TIMER2COEF 0x3A +// Service settings +#define REG_IMAGECAL 0x3B +#define REG_TEMP 0x3C +#define REG_LOWBAT 0x3D +// Status +#define REG_IRQFLAGS1 0x3E +#define REG_IRQFLAGS2 0x3F +// I/O settings +#define REG_DIOMAPPING1 0x40 +#define REG_DIOMAPPING2 0x41 +// Version +#define REG_VERSION 0x42 +// Additional settings +#define REG_PLLHOP 0x44 +#define REG_TCXO 0x4B +#define REG_PADAC 0x4D +#define REG_FORMERTEMP 0x5B +#define REG_BITRATEFRAC 0x5D +#define REG_AGCREF 0x61 +#define REG_AGCTHRESH1 0x62 +#define REG_AGCTHRESH2 0x63 +#define REG_AGCTHRESH3 0x64 +#define REG_PLL 0x70 + +/*! + * ============================================================================ + * SX1276 FSK bits control definition + * ============================================================================ + */ + +/*! + * RegFifo + */ + +/*! + * RegOpMode + */ +#define RF_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RF_OPMODE_LONGRANGEMODE_OFF 0x00 +#define RF_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RF_OPMODE_MODULATIONTYPE_MASK 0x9F +#define RF_OPMODE_MODULATIONTYPE_FSK 0x00 // Default +#define RF_OPMODE_MODULATIONTYPE_OOK 0x20 + +#define RF_OPMODE_MODULATIONSHAPING_MASK 0xE7 +#define RF_OPMODE_MODULATIONSHAPING_00 0x00 // Default +#define RF_OPMODE_MODULATIONSHAPING_01 0x08 +#define RF_OPMODE_MODULATIONSHAPING_10 0x10 +#define RF_OPMODE_MODULATIONSHAPING_11 0x18 + +#define RF_OPMODE_MASK 0xF8 +#define RF_OPMODE_SLEEP 0x00 +#define RF_OPMODE_STANDBY 0x01 // Default +#define RF_OPMODE_SYNTHESIZER_TX 0x02 +#define RF_OPMODE_TRANSMITTER 0x03 +#define RF_OPMODE_SYNTHESIZER_RX 0x04 +#define RF_OPMODE_RECEIVER 0x05 + +/*! + * RegBitRate (bits/sec) + */ +#define RF_BITRATEMSB_1200_BPS 0x68 +#define RF_BITRATELSB_1200_BPS 0x2B +#define RF_BITRATEMSB_2400_BPS 0x34 +#define RF_BITRATELSB_2400_BPS 0x15 +#define RF_BITRATEMSB_4800_BPS 0x1A // Default +#define RF_BITRATELSB_4800_BPS 0x0B // Default +#define RF_BITRATEMSB_9600_BPS 0x0D +#define RF_BITRATELSB_9600_BPS 0x05 +#define RF_BITRATEMSB_15000_BPS 0x08 +#define RF_BITRATELSB_15000_BPS 0x55 +#define RF_BITRATEMSB_19200_BPS 0x06 +#define RF_BITRATELSB_19200_BPS 0x83 +#define RF_BITRATEMSB_38400_BPS 0x03 +#define RF_BITRATELSB_38400_BPS 0x41 +#define RF_BITRATEMSB_76800_BPS 0x01 +#define RF_BITRATELSB_76800_BPS 0xA1 +#define RF_BITRATEMSB_153600_BPS 0x00 +#define RF_BITRATELSB_153600_BPS 0xD0 +#define RF_BITRATEMSB_57600_BPS 0x02 +#define RF_BITRATELSB_57600_BPS 0x2C +#define RF_BITRATEMSB_115200_BPS 0x01 +#define RF_BITRATELSB_115200_BPS 0x16 +#define RF_BITRATEMSB_12500_BPS 0x0A +#define RF_BITRATELSB_12500_BPS 0x00 +#define RF_BITRATEMSB_25000_BPS 0x05 +#define RF_BITRATELSB_25000_BPS 0x00 +#define RF_BITRATEMSB_50000_BPS 0x02 +#define RF_BITRATELSB_50000_BPS 0x80 +#define RF_BITRATEMSB_100000_BPS 0x01 +#define RF_BITRATELSB_100000_BPS 0x40 +#define RF_BITRATEMSB_150000_BPS 0x00 +#define RF_BITRATELSB_150000_BPS 0xD5 +#define RF_BITRATEMSB_200000_BPS 0x00 +#define RF_BITRATELSB_200000_BPS 0xA0 +#define RF_BITRATEMSB_250000_BPS 0x00 +#define RF_BITRATELSB_250000_BPS 0x80 +#define RF_BITRATEMSB_32768_BPS 0x03 +#define RF_BITRATELSB_32768_BPS 0xD1 + +/*! + * RegFdev (Hz) + */ +#define RF_FDEVMSB_2000_HZ 0x00 +#define RF_FDEVLSB_2000_HZ 0x21 +#define RF_FDEVMSB_5000_HZ 0x00 // Default +#define RF_FDEVLSB_5000_HZ 0x52 // Default +#define RF_FDEVMSB_10000_HZ 0x00 +#define RF_FDEVLSB_10000_HZ 0xA4 +#define RF_FDEVMSB_15000_HZ 0x00 +#define RF_FDEVLSB_15000_HZ 0xF6 +#define RF_FDEVMSB_20000_HZ 0x01 +#define RF_FDEVLSB_20000_HZ 0x48 +#define RF_FDEVMSB_25000_HZ 0x01 +#define RF_FDEVLSB_25000_HZ 0x9A +#define RF_FDEVMSB_30000_HZ 0x01 +#define RF_FDEVLSB_30000_HZ 0xEC +#define RF_FDEVMSB_35000_HZ 0x02 +#define RF_FDEVLSB_35000_HZ 0x3D +#define RF_FDEVMSB_40000_HZ 0x02 +#define RF_FDEVLSB_40000_HZ 0x8F +#define RF_FDEVMSB_45000_HZ 0x02 +#define RF_FDEVLSB_45000_HZ 0xE1 +#define RF_FDEVMSB_50000_HZ 0x03 +#define RF_FDEVLSB_50000_HZ 0x33 +#define RF_FDEVMSB_55000_HZ 0x03 +#define RF_FDEVLSB_55000_HZ 0x85 +#define RF_FDEVMSB_60000_HZ 0x03 +#define RF_FDEVLSB_60000_HZ 0xD7 +#define RF_FDEVMSB_65000_HZ 0x04 +#define RF_FDEVLSB_65000_HZ 0x29 +#define RF_FDEVMSB_70000_HZ 0x04 +#define RF_FDEVLSB_70000_HZ 0x7B +#define RF_FDEVMSB_75000_HZ 0x04 +#define RF_FDEVLSB_75000_HZ 0xCD +#define RF_FDEVMSB_80000_HZ 0x05 +#define RF_FDEVLSB_80000_HZ 0x1F +#define RF_FDEVMSB_85000_HZ 0x05 +#define RF_FDEVLSB_85000_HZ 0x71 +#define RF_FDEVMSB_90000_HZ 0x05 +#define RF_FDEVLSB_90000_HZ 0xC3 +#define RF_FDEVMSB_95000_HZ 0x06 +#define RF_FDEVLSB_95000_HZ 0x14 +#define RF_FDEVMSB_100000_HZ 0x06 +#define RF_FDEVLSB_100000_HZ 0x66 +#define RF_FDEVMSB_110000_HZ 0x07 +#define RF_FDEVLSB_110000_HZ 0x0A +#define RF_FDEVMSB_120000_HZ 0x07 +#define RF_FDEVLSB_120000_HZ 0xAE +#define RF_FDEVMSB_130000_HZ 0x08 +#define RF_FDEVLSB_130000_HZ 0x52 +#define RF_FDEVMSB_140000_HZ 0x08 +#define RF_FDEVLSB_140000_HZ 0xF6 +#define RF_FDEVMSB_150000_HZ 0x09 +#define RF_FDEVLSB_150000_HZ 0x9A +#define RF_FDEVMSB_160000_HZ 0x0A +#define RF_FDEVLSB_160000_HZ 0x3D +#define RF_FDEVMSB_170000_HZ 0x0A +#define RF_FDEVLSB_170000_HZ 0xE1 +#define RF_FDEVMSB_180000_HZ 0x0B +#define RF_FDEVLSB_180000_HZ 0x85 +#define RF_FDEVMSB_190000_HZ 0x0C +#define RF_FDEVLSB_190000_HZ 0x29 +#define RF_FDEVMSB_200000_HZ 0x0C +#define RF_FDEVLSB_200000_HZ 0xCD + +/*! + * RegFrf (MHz) + */ +#define RF_FRFMSB_863_MHZ 0xD7 +#define RF_FRFMID_863_MHZ 0xC0 +#define RF_FRFLSB_863_MHZ 0x00 +#define RF_FRFMSB_864_MHZ 0xD8 +#define RF_FRFMID_864_MHZ 0x00 +#define RF_FRFLSB_864_MHZ 0x00 +#define RF_FRFMSB_865_MHZ 0xD8 +#define RF_FRFMID_865_MHZ 0x40 +#define RF_FRFLSB_865_MHZ 0x00 +#define RF_FRFMSB_866_MHZ 0xD8 +#define RF_FRFMID_866_MHZ 0x80 +#define RF_FRFLSB_866_MHZ 0x00 +#define RF_FRFMSB_867_MHZ 0xD8 +#define RF_FRFMID_867_MHZ 0xC0 +#define RF_FRFLSB_867_MHZ 0x00 +#define RF_FRFMSB_868_MHZ 0xD9 +#define RF_FRFMID_868_MHZ 0x00 +#define RF_FRFLSB_868_MHZ 0x00 +#define RF_FRFMSB_869_MHZ 0xD9 +#define RF_FRFMID_869_MHZ 0x40 +#define RF_FRFLSB_869_MHZ 0x00 +#define RF_FRFMSB_870_MHZ 0xD9 +#define RF_FRFMID_870_MHZ 0x80 +#define RF_FRFLSB_870_MHZ 0x00 + +#define RF_FRFMSB_902_MHZ 0xE1 +#define RF_FRFMID_902_MHZ 0x80 +#define RF_FRFLSB_902_MHZ 0x00 +#define RF_FRFMSB_903_MHZ 0xE1 +#define RF_FRFMID_903_MHZ 0xC0 +#define RF_FRFLSB_903_MHZ 0x00 +#define RF_FRFMSB_904_MHZ 0xE2 +#define RF_FRFMID_904_MHZ 0x00 +#define RF_FRFLSB_904_MHZ 0x00 +#define RF_FRFMSB_905_MHZ 0xE2 +#define RF_FRFMID_905_MHZ 0x40 +#define RF_FRFLSB_905_MHZ 0x00 +#define RF_FRFMSB_906_MHZ 0xE2 +#define RF_FRFMID_906_MHZ 0x80 +#define RF_FRFLSB_906_MHZ 0x00 +#define RF_FRFMSB_907_MHZ 0xE2 +#define RF_FRFMID_907_MHZ 0xC0 +#define RF_FRFLSB_907_MHZ 0x00 +#define RF_FRFMSB_908_MHZ 0xE3 +#define RF_FRFMID_908_MHZ 0x00 +#define RF_FRFLSB_908_MHZ 0x00 +#define RF_FRFMSB_909_MHZ 0xE3 +#define RF_FRFMID_909_MHZ 0x40 +#define RF_FRFLSB_909_MHZ 0x00 +#define RF_FRFMSB_910_MHZ 0xE3 +#define RF_FRFMID_910_MHZ 0x80 +#define RF_FRFLSB_910_MHZ 0x00 +#define RF_FRFMSB_911_MHZ 0xE3 +#define RF_FRFMID_911_MHZ 0xC0 +#define RF_FRFLSB_911_MHZ 0x00 +#define RF_FRFMSB_912_MHZ 0xE4 +#define RF_FRFMID_912_MHZ 0x00 +#define RF_FRFLSB_912_MHZ 0x00 +#define RF_FRFMSB_913_MHZ 0xE4 +#define RF_FRFMID_913_MHZ 0x40 +#define RF_FRFLSB_913_MHZ 0x00 +#define RF_FRFMSB_914_MHZ 0xE4 +#define RF_FRFMID_914_MHZ 0x80 +#define RF_FRFLSB_914_MHZ 0x00 +#define RF_FRFMSB_915_MHZ 0xE4 // Default +#define RF_FRFMID_915_MHZ 0xC0 // Default +#define RF_FRFLSB_915_MHZ 0x00 // Default +#define RF_FRFMSB_916_MHZ 0xE5 +#define RF_FRFMID_916_MHZ 0x00 +#define RF_FRFLSB_916_MHZ 0x00 +#define RF_FRFMSB_917_MHZ 0xE5 +#define RF_FRFMID_917_MHZ 0x40 +#define RF_FRFLSB_917_MHZ 0x00 +#define RF_FRFMSB_918_MHZ 0xE5 +#define RF_FRFMID_918_MHZ 0x80 +#define RF_FRFLSB_918_MHZ 0x00 +#define RF_FRFMSB_919_MHZ 0xE5 +#define RF_FRFMID_919_MHZ 0xC0 +#define RF_FRFLSB_919_MHZ 0x00 +#define RF_FRFMSB_920_MHZ 0xE6 +#define RF_FRFMID_920_MHZ 0x00 +#define RF_FRFLSB_920_MHZ 0x00 +#define RF_FRFMSB_921_MHZ 0xE6 +#define RF_FRFMID_921_MHZ 0x40 +#define RF_FRFLSB_921_MHZ 0x00 +#define RF_FRFMSB_922_MHZ 0xE6 +#define RF_FRFMID_922_MHZ 0x80 +#define RF_FRFLSB_922_MHZ 0x00 +#define RF_FRFMSB_923_MHZ 0xE6 +#define RF_FRFMID_923_MHZ 0xC0 +#define RF_FRFLSB_923_MHZ 0x00 +#define RF_FRFMSB_924_MHZ 0xE7 +#define RF_FRFMID_924_MHZ 0x00 +#define RF_FRFLSB_924_MHZ 0x00 +#define RF_FRFMSB_925_MHZ 0xE7 +#define RF_FRFMID_925_MHZ 0x40 +#define RF_FRFLSB_925_MHZ 0x00 +#define RF_FRFMSB_926_MHZ 0xE7 +#define RF_FRFMID_926_MHZ 0x80 +#define RF_FRFLSB_926_MHZ 0x00 +#define RF_FRFMSB_927_MHZ 0xE7 +#define RF_FRFMID_927_MHZ 0xC0 +#define RF_FRFLSB_927_MHZ 0x00 +#define RF_FRFMSB_928_MHZ 0xE8 +#define RF_FRFMID_928_MHZ 0x00 +#define RF_FRFLSB_928_MHZ 0x00 + +/*! + * RegPaConfig + */ +#define RF_PACONFIG_PASELECT_MASK 0x7F +#define RF_PACONFIG_PASELECT_PABOOST 0x80 +#define RF_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RF_PACONFIG_MAX_POWER_MASK 0x8F + +#define RF_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +/*! + * RegPaRamp + */ +#define RF_PARAMP_MODULATIONSHAPING_MASK 0x9F +#define RF_PARAMP_MODULATIONSHAPING_00 0x00 // Default +#define RF_PARAMP_MODULATIONSHAPING_01 0x20 +#define RF_PARAMP_MODULATIONSHAPING_10 0x40 +#define RF_PARAMP_MODULATIONSHAPING_11 0x60 + +#define RF_PARAMP_LOWPNTXPLL_MASK 0xEF +#define RF_PARAMP_LOWPNTXPLL_OFF 0x10 +#define RF_PARAMP_LOWPNTXPLL_ON 0x00 // Default + +#define RF_PARAMP_MASK 0xF0 +#define RF_PARAMP_3400_US 0x00 +#define RF_PARAMP_2000_US 0x01 +#define RF_PARAMP_1000_US 0x02 +#define RF_PARAMP_0500_US 0x03 +#define RF_PARAMP_0250_US 0x04 +#define RF_PARAMP_0125_US 0x05 +#define RF_PARAMP_0100_US 0x06 +#define RF_PARAMP_0062_US 0x07 +#define RF_PARAMP_0050_US 0x08 +#define RF_PARAMP_0040_US 0x09 // Default +#define RF_PARAMP_0031_US 0x0A +#define RF_PARAMP_0025_US 0x0B +#define RF_PARAMP_0020_US 0x0C +#define RF_PARAMP_0015_US 0x0D +#define RF_PARAMP_0012_US 0x0E +#define RF_PARAMP_0010_US 0x0F + +/*! + * RegOcp + */ +#define RF_OCP_MASK 0xDF +#define RF_OCP_ON 0x20 // Default +#define RF_OCP_OFF 0x00 + +#define RF_OCP_TRIM_MASK 0xE0 +#define RF_OCP_TRIM_045_MA 0x00 +#define RF_OCP_TRIM_050_MA 0x01 +#define RF_OCP_TRIM_055_MA 0x02 +#define RF_OCP_TRIM_060_MA 0x03 +#define RF_OCP_TRIM_065_MA 0x04 +#define RF_OCP_TRIM_070_MA 0x05 +#define RF_OCP_TRIM_075_MA 0x06 +#define RF_OCP_TRIM_080_MA 0x07 +#define RF_OCP_TRIM_085_MA 0x08 +#define RF_OCP_TRIM_090_MA 0x09 +#define RF_OCP_TRIM_095_MA 0x0A +#define RF_OCP_TRIM_100_MA 0x0B // Default +#define RF_OCP_TRIM_105_MA 0x0C +#define RF_OCP_TRIM_110_MA 0x0D +#define RF_OCP_TRIM_115_MA 0x0E +#define RF_OCP_TRIM_120_MA 0x0F +#define RF_OCP_TRIM_130_MA 0x10 +#define RF_OCP_TRIM_140_MA 0x11 +#define RF_OCP_TRIM_150_MA 0x12 +#define RF_OCP_TRIM_160_MA 0x13 +#define RF_OCP_TRIM_170_MA 0x14 +#define RF_OCP_TRIM_180_MA 0x15 +#define RF_OCP_TRIM_190_MA 0x16 +#define RF_OCP_TRIM_200_MA 0x17 +#define RF_OCP_TRIM_210_MA 0x18 +#define RF_OCP_TRIM_220_MA 0x19 +#define RF_OCP_TRIM_230_MA 0x1A +#define RF_OCP_TRIM_240_MA 0x1B + +/*! + * RegLna + */ +#define RF_LNA_GAIN_MASK 0x1F +#define RF_LNA_GAIN_G1 0x20 // Default +#define RF_LNA_GAIN_G2 0x40 +#define RF_LNA_GAIN_G3 0x60 +#define RF_LNA_GAIN_G4 0x80 +#define RF_LNA_GAIN_G5 0xA0 +#define RF_LNA_GAIN_G6 0xC0 + +#define RF_LNA_BOOST_MASK 0xFC +#define RF_LNA_BOOST_OFF 0x00 // Default +#define RF_LNA_BOOST_ON 0x03 + +/*! + * RegRxConfig + */ +#define RF_RXCONFIG_RESTARTRXONCOLLISION_MASK 0x7F +#define RF_RXCONFIG_RESTARTRXONCOLLISION_ON 0x80 +#define RF_RXCONFIG_RESTARTRXONCOLLISION_OFF 0x00 // Default + +#define RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK 0x40 // Write only + +#define RF_RXCONFIG_RESTARTRXWITHPLLLOCK 0x20 // Write only + +#define RF_RXCONFIG_AFCAUTO_MASK 0xEF +#define RF_RXCONFIG_AFCAUTO_ON 0x10 +#define RF_RXCONFIG_AFCAUTO_OFF 0x00 // Default + +#define RF_RXCONFIG_AGCAUTO_MASK 0xF7 +#define RF_RXCONFIG_AGCAUTO_ON 0x08 // Default +#define RF_RXCONFIG_AGCAUTO_OFF 0x00 + +#define RF_RXCONFIG_RXTRIGER_MASK 0xF8 +#define RF_RXCONFIG_RXTRIGER_OFF 0x00 +#define RF_RXCONFIG_RXTRIGER_RSSI 0x01 +#define RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT 0x06 // Default +#define RF_RXCONFIG_RXTRIGER_RSSI_PREAMBLEDETECT 0x07 + +/*! + * RegRssiConfig + */ +#define RF_RSSICONFIG_OFFSET_MASK 0x07 +#define RF_RSSICONFIG_OFFSET_P_00_DB 0x00 // Default +#define RF_RSSICONFIG_OFFSET_P_01_DB 0x08 +#define RF_RSSICONFIG_OFFSET_P_02_DB 0x10 +#define RF_RSSICONFIG_OFFSET_P_03_DB 0x18 +#define RF_RSSICONFIG_OFFSET_P_04_DB 0x20 +#define RF_RSSICONFIG_OFFSET_P_05_DB 0x28 +#define RF_RSSICONFIG_OFFSET_P_06_DB 0x30 +#define RF_RSSICONFIG_OFFSET_P_07_DB 0x38 +#define RF_RSSICONFIG_OFFSET_P_08_DB 0x40 +#define RF_RSSICONFIG_OFFSET_P_09_DB 0x48 +#define RF_RSSICONFIG_OFFSET_P_10_DB 0x50 +#define RF_RSSICONFIG_OFFSET_P_11_DB 0x58 +#define RF_RSSICONFIG_OFFSET_P_12_DB 0x60 +#define RF_RSSICONFIG_OFFSET_P_13_DB 0x68 +#define RF_RSSICONFIG_OFFSET_P_14_DB 0x70 +#define RF_RSSICONFIG_OFFSET_P_15_DB 0x78 +#define RF_RSSICONFIG_OFFSET_M_16_DB 0x80 +#define RF_RSSICONFIG_OFFSET_M_15_DB 0x88 +#define RF_RSSICONFIG_OFFSET_M_14_DB 0x90 +#define RF_RSSICONFIG_OFFSET_M_13_DB 0x98 +#define RF_RSSICONFIG_OFFSET_M_12_DB 0xA0 +#define RF_RSSICONFIG_OFFSET_M_11_DB 0xA8 +#define RF_RSSICONFIG_OFFSET_M_10_DB 0xB0 +#define RF_RSSICONFIG_OFFSET_M_09_DB 0xB8 +#define RF_RSSICONFIG_OFFSET_M_08_DB 0xC0 +#define RF_RSSICONFIG_OFFSET_M_07_DB 0xC8 +#define RF_RSSICONFIG_OFFSET_M_06_DB 0xD0 +#define RF_RSSICONFIG_OFFSET_M_05_DB 0xD8 +#define RF_RSSICONFIG_OFFSET_M_04_DB 0xE0 +#define RF_RSSICONFIG_OFFSET_M_03_DB 0xE8 +#define RF_RSSICONFIG_OFFSET_M_02_DB 0xF0 +#define RF_RSSICONFIG_OFFSET_M_01_DB 0xF8 + +#define RF_RSSICONFIG_SMOOTHING_MASK 0xF8 +#define RF_RSSICONFIG_SMOOTHING_2 0x00 +#define RF_RSSICONFIG_SMOOTHING_4 0x01 +#define RF_RSSICONFIG_SMOOTHING_8 0x02 // Default +#define RF_RSSICONFIG_SMOOTHING_16 0x03 +#define RF_RSSICONFIG_SMOOTHING_32 0x04 +#define RF_RSSICONFIG_SMOOTHING_64 0x05 +#define RF_RSSICONFIG_SMOOTHING_128 0x06 +#define RF_RSSICONFIG_SMOOTHING_256 0x07 + +/*! + * RegRssiCollision + */ +#define RF_RSSICOLISION_THRESHOLD 0x0A // Default + +/*! + * RegRssiThresh + */ +#define RF_RSSITHRESH_THRESHOLD 0xFF // Default + +/*! + * RegRssiValue (Read Only) + */ + +/*! + * RegRxBw + */ +#define RF_RXBW_MANT_MASK 0xE7 +#define RF_RXBW_MANT_16 0x00 +#define RF_RXBW_MANT_20 0x08 +#define RF_RXBW_MANT_24 0x10 // Default + +#define RF_RXBW_EXP_MASK 0xF8 +#define RF_RXBW_EXP_0 0x00 +#define RF_RXBW_EXP_1 0x01 +#define RF_RXBW_EXP_2 0x02 +#define RF_RXBW_EXP_3 0x03 +#define RF_RXBW_EXP_4 0x04 +#define RF_RXBW_EXP_5 0x05 // Default +#define RF_RXBW_EXP_6 0x06 +#define RF_RXBW_EXP_7 0x07 + +/*! + * RegAfcBw + */ +#define RF_AFCBW_MANTAFC_MASK 0xE7 +#define RF_AFCBW_MANTAFC_16 0x00 +#define RF_AFCBW_MANTAFC_20 0x08 // Default +#define RF_AFCBW_MANTAFC_24 0x10 + +#define RF_AFCBW_EXPAFC_MASK 0xF8 +#define RF_AFCBW_EXPAFC_0 0x00 +#define RF_AFCBW_EXPAFC_1 0x01 +#define RF_AFCBW_EXPAFC_2 0x02 +#define RF_AFCBW_EXPAFC_3 0x03 // Default +#define RF_AFCBW_EXPAFC_4 0x04 +#define RF_AFCBW_EXPAFC_5 0x05 +#define RF_AFCBW_EXPAFC_6 0x06 +#define RF_AFCBW_EXPAFC_7 0x07 + +/*! + * RegOokPeak + */ +#define RF_OOKPEAK_BITSYNC_MASK 0xDF // Default +#define RF_OOKPEAK_BITSYNC_ON 0x20 // Default +#define RF_OOKPEAK_BITSYNC_OFF 0x00 + +#define RF_OOKPEAK_OOKTHRESHTYPE_MASK 0xE7 +#define RF_OOKPEAK_OOKTHRESHTYPE_FIXED 0x00 +#define RF_OOKPEAK_OOKTHRESHTYPE_PEAK 0x08 // Default +#define RF_OOKPEAK_OOKTHRESHTYPE_AVERAGE 0x10 + +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_MASK 0xF8 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_0_5_DB 0x00 // Default +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_0_DB 0x01 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_5_DB 0x02 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_2_0_DB 0x03 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_3_0_DB 0x04 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_4_0_DB 0x05 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_5_0_DB 0x06 +#define RF_OOKPEAK_OOKPEAKTHRESHSTEP_6_0_DB 0x07 + +/*! + * RegOokFix + */ +#define RF_OOKFIX_OOKFIXEDTHRESHOLD 0x0C // Default + +/*! + * RegOokAvg + */ +#define RF_OOKAVG_OOKPEAKTHRESHDEC_MASK 0x1F +#define RF_OOKAVG_OOKPEAKTHRESHDEC_000 0x00 // Default +#define RF_OOKAVG_OOKPEAKTHRESHDEC_001 0x20 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_010 0x40 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_011 0x60 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_100 0x80 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_101 0xA0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_110 0xC0 +#define RF_OOKAVG_OOKPEAKTHRESHDEC_111 0xE0 + +#define RF_OOKAVG_AVERAGEOFFSET_MASK 0xF3 +#define RF_OOKAVG_AVERAGEOFFSET_0_DB 0x00 // Default +#define RF_OOKAVG_AVERAGEOFFSET_2_DB 0x04 +#define RF_OOKAVG_AVERAGEOFFSET_4_DB 0x08 +#define RF_OOKAVG_AVERAGEOFFSET_6_DB 0x0C + +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_MASK 0xFC +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_00 0x00 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_01 0x01 +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_10 0x02 // Default +#define RF_OOKAVG_OOKAVERAGETHRESHFILT_11 0x03 + +/*! + * RegAfcFei + */ +#define RF_AFCFEI_AGCSTART 0x10 + +#define RF_AFCFEI_AFCCLEAR 0x02 + +#define RF_AFCFEI_AFCAUTOCLEAR_MASK 0xFE +#define RF_AFCFEI_AFCAUTOCLEAR_ON 0x01 +#define RF_AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default + +/*! + * RegAfcMsb (Read Only) + */ + +/*! + * RegAfcLsb (Read Only) + */ + +/*! + * RegFeiMsb (Read Only) + */ + +/*! + * RegFeiLsb (Read Only) + */ + +/*! + * RegPreambleDetect + */ +#define RF_PREAMBLEDETECT_DETECTOR_MASK 0x7F +#define RF_PREAMBLEDETECT_DETECTOR_ON 0x80 // Default +#define RF_PREAMBLEDETECT_DETECTOR_OFF 0x00 + +#define RF_PREAMBLEDETECT_DETECTORSIZE_MASK 0x9F +#define RF_PREAMBLEDETECT_DETECTORSIZE_1 0x00 +#define RF_PREAMBLEDETECT_DETECTORSIZE_2 0x20 // Default +#define RF_PREAMBLEDETECT_DETECTORSIZE_3 0x40 +#define RF_PREAMBLEDETECT_DETECTORSIZE_4 0x60 + +#define RF_PREAMBLEDETECT_DETECTORTOL_MASK 0xE0 +#define RF_PREAMBLEDETECT_DETECTORTOL_0 0x00 +#define RF_PREAMBLEDETECT_DETECTORTOL_1 0x01 +#define RF_PREAMBLEDETECT_DETECTORTOL_2 0x02 +#define RF_PREAMBLEDETECT_DETECTORTOL_3 0x03 +#define RF_PREAMBLEDETECT_DETECTORTOL_4 0x04 +#define RF_PREAMBLEDETECT_DETECTORTOL_5 0x05 +#define RF_PREAMBLEDETECT_DETECTORTOL_6 0x06 +#define RF_PREAMBLEDETECT_DETECTORTOL_7 0x07 +#define RF_PREAMBLEDETECT_DETECTORTOL_8 0x08 +#define RF_PREAMBLEDETECT_DETECTORTOL_9 0x09 +#define RF_PREAMBLEDETECT_DETECTORTOL_10 0x0A // Default +#define RF_PREAMBLEDETECT_DETECTORTOL_11 0x0B +#define RF_PREAMBLEDETECT_DETECTORTOL_12 0x0C +#define RF_PREAMBLEDETECT_DETECTORTOL_13 0x0D +#define RF_PREAMBLEDETECT_DETECTORTOL_14 0x0E +#define RF_PREAMBLEDETECT_DETECTORTOL_15 0x0F +#define RF_PREAMBLEDETECT_DETECTORTOL_16 0x10 +#define RF_PREAMBLEDETECT_DETECTORTOL_17 0x11 +#define RF_PREAMBLEDETECT_DETECTORTOL_18 0x12 +#define RF_PREAMBLEDETECT_DETECTORTOL_19 0x13 +#define RF_PREAMBLEDETECT_DETECTORTOL_20 0x14 +#define RF_PREAMBLEDETECT_DETECTORTOL_21 0x15 +#define RF_PREAMBLEDETECT_DETECTORTOL_22 0x16 +#define RF_PREAMBLEDETECT_DETECTORTOL_23 0x17 +#define RF_PREAMBLEDETECT_DETECTORTOL_24 0x18 +#define RF_PREAMBLEDETECT_DETECTORTOL_25 0x19 +#define RF_PREAMBLEDETECT_DETECTORTOL_26 0x1A +#define RF_PREAMBLEDETECT_DETECTORTOL_27 0x1B +#define RF_PREAMBLEDETECT_DETECTORTOL_28 0x1C +#define RF_PREAMBLEDETECT_DETECTORTOL_29 0x1D +#define RF_PREAMBLEDETECT_DETECTORTOL_30 0x1E +#define RF_PREAMBLEDETECT_DETECTORTOL_31 0x1F + +/*! + * RegRxTimeout1 + */ +#define RF_RXTIMEOUT1_TIMEOUTRXRSSI 0x00 // Default + +/*! + * RegRxTimeout2 + */ +#define RF_RXTIMEOUT2_TIMEOUTRXPREAMBLE 0x00 // Default + +/*! + * RegRxTimeout3 + */ +#define RF_RXTIMEOUT3_TIMEOUTSIGNALSYNC 0x00 // Default + +/*! + * RegRxDelay + */ +#define RF_RXDELAY_INTERPACKETRXDELAY 0x00 // Default + +/*! + * RegOsc + */ +#define RF_OSC_RCCALSTART 0x08 + +#define RF_OSC_CLKOUT_MASK 0xF8 +#define RF_OSC_CLKOUT_32_MHZ 0x00 +#define RF_OSC_CLKOUT_16_MHZ 0x01 +#define RF_OSC_CLKOUT_8_MHZ 0x02 +#define RF_OSC_CLKOUT_4_MHZ 0x03 +#define RF_OSC_CLKOUT_2_MHZ 0x04 +#define RF_OSC_CLKOUT_1_MHZ 0x05 // Default +#define RF_OSC_CLKOUT_RC 0x06 +#define RF_OSC_CLKOUT_OFF 0x07 + +/*! + * RegPreambleMsb/RegPreambleLsb + */ +#define RF_PREAMBLEMSB_SIZE 0x00 // Default +#define RF_PREAMBLELSB_SIZE 0x03 // Default + +/*! + * RegSyncConfig + */ +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_MASK 0x3F +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON 0x80 // Default +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_OFF 0x40 +#define RF_SYNCCONFIG_AUTORESTARTRXMODE_OFF 0x00 + + +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_MASK 0xDF +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_55 0x20 +#define RF_SYNCCONFIG_PREAMBLEPOLARITY_AA 0x00 // Default + +#define RF_SYNCCONFIG_SYNC_MASK 0xEF +#define RF_SYNCCONFIG_SYNC_ON 0x10 // Default +#define RF_SYNCCONFIG_SYNC_OFF 0x00 + + +#define RF_SYNCCONFIG_SYNCSIZE_MASK 0xF8 +#define RF_SYNCCONFIG_SYNCSIZE_1 0x00 +#define RF_SYNCCONFIG_SYNCSIZE_2 0x01 +#define RF_SYNCCONFIG_SYNCSIZE_3 0x02 +#define RF_SYNCCONFIG_SYNCSIZE_4 0x03 // Default +#define RF_SYNCCONFIG_SYNCSIZE_5 0x04 +#define RF_SYNCCONFIG_SYNCSIZE_6 0x05 +#define RF_SYNCCONFIG_SYNCSIZE_7 0x06 +#define RF_SYNCCONFIG_SYNCSIZE_8 0x07 + +/*! + * RegSyncValue1-8 + */ +#define RF_SYNCVALUE1_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE2_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE3_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE4_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE5_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE6_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE7_SYNCVALUE 0x01 // Default +#define RF_SYNCVALUE8_SYNCVALUE 0x01 // Default + +/*! + * RegPacketConfig1 + */ +#define RF_PACKETCONFIG1_PACKETFORMAT_MASK 0x7F +#define RF_PACKETCONFIG1_PACKETFORMAT_FIXED 0x00 +#define RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE 0x80 // Default + +#define RF_PACKETCONFIG1_DCFREE_MASK 0x9F +#define RF_PACKETCONFIG1_DCFREE_OFF 0x00 // Default +#define RF_PACKETCONFIG1_DCFREE_MANCHESTER 0x20 +#define RF_PACKETCONFIG1_DCFREE_WHITENING 0x40 + +#define RF_PACKETCONFIG1_CRC_MASK 0xEF +#define RF_PACKETCONFIG1_CRC_ON 0x10 // Default +#define RF_PACKETCONFIG1_CRC_OFF 0x00 + +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_MASK 0xF7 +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_ON 0x00 // Default +#define RF_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08 + +#define RF_PACKETCONFIG1_ADDRSFILTERING_MASK 0xF9 +#define RF_PACKETCONFIG1_ADDRSFILTERING_OFF 0x00 // Default +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODE 0x02 +#define RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST 0x04 + +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_MASK 0xFE +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT 0x00 // Default +#define RF_PACKETCONFIG1_CRCWHITENINGTYPE_IBM 0x01 + +/*! + * RegPacketConfig2 + */ + +#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE_MASK 0x7F +#define RF_PACKETCONFIG2_WMBUS_CRC_ENABLE 0x80 +#define RF_PACKETCONFIG2_WMBUS_CRC_DISABLE 0x00 // Default + +#define RF_PACKETCONFIG2_DATAMODE_MASK 0xBF +#define RF_PACKETCONFIG2_DATAMODE_CONTINUOUS 0x00 +#define RF_PACKETCONFIG2_DATAMODE_PACKET 0x40 // Default + +#define RF_PACKETCONFIG2_IOHOME_MASK 0xDF +#define RF_PACKETCONFIG2_IOHOME_ON 0x20 +#define RF_PACKETCONFIG2_IOHOME_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_BEACON_MASK 0xF7 +#define RF_PACKETCONFIG2_BEACON_ON 0x08 +#define RF_PACKETCONFIG2_BEACON_OFF 0x00 // Default + +#define RF_PACKETCONFIG2_PAYLOADLENGTH_MSB_MASK 0xF8 + +/*! + * RegPayloadLength + */ +#define RF_PAYLOADLENGTH_LENGTH 0x40 // Default + +/*! + * RegNodeAdrs + */ +#define RF_NODEADDRESS_ADDRESS 0x00 + +/*! + * RegBroadcastAdrs + */ +#define RF_BROADCASTADDRESS_ADDRESS 0x00 + +/*! + * RegFifoThresh + */ +#define RF_FIFOTHRESH_TXSTARTCONDITION_MASK 0x7F +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFOTHRESH 0x00 // Default +#define RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY 0x80 + +#define RF_FIFOTHRESH_FIFOTHRESHOLD_MASK 0xC0 +#define RF_FIFOTHRESH_FIFOTHRESHOLD_THRESHOLD 0x0F // Default + +/*! + * RegSeqConfig1 + */ +#define RF_SEQCONFIG1_SEQUENCER_START 0x80 + +#define RF_SEQCONFIG1_SEQUENCER_STOP 0x40 + +#define RF_SEQCONFIG1_IDLEMODE_MASK 0xDF +#define RF_SEQCONFIG1_IDLEMODE_SLEEP 0x20 +#define RF_SEQCONFIG1_IDLEMODE_STANDBY 0x00 // Default + +#define RF_SEQCONFIG1_FROMSTART_MASK 0xE7 +#define RF_SEQCONFIG1_FROMSTART_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMSTART_TORX 0x08 +#define RF_SEQCONFIG1_FROMSTART_TOTX 0x10 +#define RF_SEQCONFIG1_FROMSTART_TOTX_ONFIFOLEVEL 0x18 + +#define RF_SEQCONFIG1_LPS_MASK 0xFB +#define RF_SEQCONFIG1_LPS_SEQUENCER_OFF 0x00 // Default +#define RF_SEQCONFIG1_LPS_IDLE 0x04 + +#define RF_SEQCONFIG1_FROMIDLE_MASK 0xFD +#define RF_SEQCONFIG1_FROMIDLE_TOTX 0x00 // Default +#define RF_SEQCONFIG1_FROMIDLE_TORX 0x02 + +#define RF_SEQCONFIG1_FROMTX_MASK 0xFE +#define RF_SEQCONFIG1_FROMTX_TOLPS 0x00 // Default +#define RF_SEQCONFIG1_FROMTX_TORX 0x01 + +/*! + * RegSeqConfig2 + */ +#define RF_SEQCONFIG2_FROMRX_MASK 0x1F +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_000 0x00 // Default +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONPLDRDY 0x20 +#define RF_SEQCONFIG2_FROMRX_TOLPS_ONPLDRDY 0x40 +#define RF_SEQCONFIG2_FROMRX_TORXPKT_ONCRCOK 0x60 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONRSSI 0x80 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONSYNC 0xA0 +#define RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONPREAMBLE 0xC0 +#define RF_SEQCONFIG2_FROMRX_TOUNUSED_111 0xE0 + +#define RF_SEQCONFIG2_FROMRXTIMEOUT_MASK 0xE7 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TORXRESTART 0x00 // Default +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOTX 0x08 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOLPS 0x10 +#define RF_SEQCONFIG2_FROMRXTIMEOUT_TOSEQUENCEROFF 0x18 + +#define RF_SEQCONFIG2_FROMRXPKT_MASK 0xF8 +#define RF_SEQCONFIG2_FROMRXPKT_TOSEQUENCEROFF 0x00 // Default +#define RF_SEQCONFIG2_FROMRXPKT_TOTX_ONFIFOEMPTY 0x01 +#define RF_SEQCONFIG2_FROMRXPKT_TOLPS 0x02 +#define RF_SEQCONFIG2_FROMRXPKT_TOSYNTHESIZERRX 0x03 +#define RF_SEQCONFIG2_FROMRXPKT_TORX 0x04 + +/*! + * RegTimerResol + */ +#define RF_TIMERRESOL_TIMER1RESOL_MASK 0xF3 +#define RF_TIMERRESOL_TIMER1RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER1RESOL_000064_US 0x04 +#define RF_TIMERRESOL_TIMER1RESOL_004100_US 0x08 +#define RF_TIMERRESOL_TIMER1RESOL_262000_US 0x0C + +#define RF_TIMERRESOL_TIMER2RESOL_MASK 0xFC +#define RF_TIMERRESOL_TIMER2RESOL_OFF 0x00 // Default +#define RF_TIMERRESOL_TIMER2RESOL_000064_US 0x01 +#define RF_TIMERRESOL_TIMER2RESOL_004100_US 0x02 +#define RF_TIMERRESOL_TIMER2RESOL_262000_US 0x03 + +/*! + * RegTimer1Coef + */ +#define RF_TIMER1COEF_TIMER1COEFFICIENT 0xF5 // Default + +/*! + * RegTimer2Coef + */ +#define RF_TIMER2COEF_TIMER2COEFFICIENT 0x20 // Default + +/*! + * RegImageCal + */ +#define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F +#define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 +#define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default + +#define RF_IMAGECAL_IMAGECAL_MASK 0xBF +#define RF_IMAGECAL_IMAGECAL_START 0x40 + +#define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 +#define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default + +#define RF_IMAGECAL_TEMPCHANGE_HIGHER 0x08 +#define RF_IMAGECAL_TEMPCHANGE_LOWER 0x00 + +#define RF_IMAGECAL_TEMPTHRESHOLD_MASK 0xF9 +#define RF_IMAGECAL_TEMPTHRESHOLD_05 0x00 +#define RF_IMAGECAL_TEMPTHRESHOLD_10 0x02 // Default +#define RF_IMAGECAL_TEMPTHRESHOLD_15 0x04 +#define RF_IMAGECAL_TEMPTHRESHOLD_20 0x06 + +#define RF_IMAGECAL_TEMPMONITOR_MASK 0xFE +#define RF_IMAGECAL_TEMPMONITOR_ON 0x00 // Default +#define RF_IMAGECAL_TEMPMONITOR_OFF 0x01 + +/*! + * RegTemp (Read Only) + */ + +/*! + * RegLowBat + */ +#define RF_LOWBAT_MASK 0xF7 +#define RF_LOWBAT_ON 0x08 +#define RF_LOWBAT_OFF 0x00 // Default + +#define RF_LOWBAT_TRIM_MASK 0xF8 +#define RF_LOWBAT_TRIM_1695 0x00 +#define RF_LOWBAT_TRIM_1764 0x01 +#define RF_LOWBAT_TRIM_1835 0x02 // Default +#define RF_LOWBAT_TRIM_1905 0x03 +#define RF_LOWBAT_TRIM_1976 0x04 +#define RF_LOWBAT_TRIM_2045 0x05 +#define RF_LOWBAT_TRIM_2116 0x06 +#define RF_LOWBAT_TRIM_2185 0x07 + +/*! + * RegIrqFlags1 + */ +#define RF_IRQFLAGS1_MODEREADY 0x80 + +#define RF_IRQFLAGS1_RXREADY 0x40 + +#define RF_IRQFLAGS1_TXREADY 0x20 + +#define RF_IRQFLAGS1_PLLLOCK 0x10 + +#define RF_IRQFLAGS1_RSSI 0x08 + +#define RF_IRQFLAGS1_TIMEOUT 0x04 + +#define RF_IRQFLAGS1_PREAMBLEDETECT 0x02 + +#define RF_IRQFLAGS1_SYNCADDRESSMATCH 0x01 + +/*! + * RegIrqFlags2 + */ +#define RF_IRQFLAGS2_FIFOFULL 0x80 + +#define RF_IRQFLAGS2_FIFOEMPTY 0x40 + +#define RF_IRQFLAGS2_FIFOLEVEL 0x20 + +#define RF_IRQFLAGS2_FIFOOVERRUN 0x10 + +#define RF_IRQFLAGS2_PACKETSENT 0x08 + +#define RF_IRQFLAGS2_PAYLOADREADY 0x04 + +#define RF_IRQFLAGS2_CRCOK 0x02 + +#define RF_IRQFLAGS2_LOWBAT 0x01 + +/*! + * RegDioMapping1 + */ +#define RF_DIOMAPPING1_DIO0_MASK 0x3F +#define RF_DIOMAPPING1_DIO0_00 0x00 // Default +#define RF_DIOMAPPING1_DIO0_01 0x40 +#define RF_DIOMAPPING1_DIO0_10 0x80 +#define RF_DIOMAPPING1_DIO0_11 0xC0 + +#define RF_DIOMAPPING1_DIO1_MASK 0xCF +#define RF_DIOMAPPING1_DIO1_00 0x00 // Default +#define RF_DIOMAPPING1_DIO1_01 0x10 +#define RF_DIOMAPPING1_DIO1_10 0x20 +#define RF_DIOMAPPING1_DIO1_11 0x30 + +#define RF_DIOMAPPING1_DIO2_MASK 0xF3 +#define RF_DIOMAPPING1_DIO2_00 0x00 // Default +#define RF_DIOMAPPING1_DIO2_01 0x04 +#define RF_DIOMAPPING1_DIO2_10 0x08 +#define RF_DIOMAPPING1_DIO2_11 0x0C + +#define RF_DIOMAPPING1_DIO3_MASK 0xFC +#define RF_DIOMAPPING1_DIO3_00 0x00 // Default +#define RF_DIOMAPPING1_DIO3_01 0x01 +#define RF_DIOMAPPING1_DIO3_10 0x02 +#define RF_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RF_DIOMAPPING2_DIO4_MASK 0x3F +#define RF_DIOMAPPING2_DIO4_00 0x00 // Default +#define RF_DIOMAPPING2_DIO4_01 0x40 +#define RF_DIOMAPPING2_DIO4_10 0x80 +#define RF_DIOMAPPING2_DIO4_11 0xC0 + +#define RF_DIOMAPPING2_DIO5_MASK 0xCF +#define RF_DIOMAPPING2_DIO5_00 0x00 // Default +#define RF_DIOMAPPING2_DIO5_01 0x10 +#define RF_DIOMAPPING2_DIO5_10 0x20 +#define RF_DIOMAPPING2_DIO5_11 0x30 + +#define RF_DIOMAPPING2_MAP_MASK 0xFE +#define RF_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RF_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegPllHop + */ +#define RF_PLLHOP_FASTHOP_MASK 0x7F +#define RF_PLLHOP_FASTHOP_ON 0x80 +#define RF_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RF_TCXO_TCXOINPUT_MASK 0xEF +#define RF_TCXO_TCXOINPUT_ON 0x10 +#define RF_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RF_PADAC_20DBM_MASK 0xF8 +#define RF_PADAC_20DBM_ON 0x07 +#define RF_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegFormerTemp + */ + +/*! + * RegBitrateFrac + */ +#define RF_BITRATEFRAC_MASK 0xF0 + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegPll + */ +#define RF_PLL_BANDWIDTH_MASK 0x3F +#define RF_PLL_BANDWIDTH_75 0x00 +#define RF_PLL_BANDWIDTH_150 0x40 +#define RF_PLL_BANDWIDTH_225 0x80 +#define RF_PLL_BANDWIDTH_300 0xC0 // Default + +#endif // __SX1276_REGS_FSK_H__ diff --git a/components/lora/SX1276/registers/sx1276Regs-LoRa.h b/components/lora/SX1276/registers/sx1276Regs-LoRa.h index ca501c1496..c97eae2037 100644 --- a/components/lora/SX1276/registers/sx1276Regs-LoRa.h +++ b/components/lora/SX1276/registers/sx1276Regs-LoRa.h @@ -1,569 +1,569 @@ -/** - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C) 2014 Semtech - -Description: SX1276 LoRa modem registers and bits definitions - -License: Revised BSD License, see LICENSE.TXT file include in the project - -Maintainer: Miguel Luis and Gregory Cristian - -Copyright (c) 2017, Arm Limited and affiliates. - -SPDX-License-Identifier: BSD-3-Clause -*/ -#ifndef __SX1276_REGS_LORA_H__ -#define __SX1276_REGS_LORA_H__ - -/*! - * ============================================================================ - * SX1276 Internal registers Address - * ============================================================================ - */ -#define REG_LR_FIFO 0x00 -// Common settings -#define REG_LR_OPMODE 0x01 -#define REG_LR_FRFMSB 0x06 -#define REG_LR_FRFMID 0x07 -#define REG_LR_FRFLSB 0x08 -// Tx settings -#define REG_LR_PACONFIG 0x09 -#define REG_LR_PARAMP 0x0A -#define REG_LR_OCP 0x0B -// Rx settings -#define REG_LR_LNA 0x0C -// LoRa registers -#define REG_LR_FIFOADDRPTR 0x0D -#define REG_LR_FIFOTXBASEADDR 0x0E -#define REG_LR_FIFORXBASEADDR 0x0F -#define REG_LR_FIFORXCURRENTADDR 0x10 -#define REG_LR_IRQFLAGSMASK 0x11 -#define REG_LR_IRQFLAGS 0x12 -#define REG_LR_RXNBBYTES 0x13 -#define REG_LR_RXHEADERCNTVALUEMSB 0x14 -#define REG_LR_RXHEADERCNTVALUELSB 0x15 -#define REG_LR_RXPACKETCNTVALUEMSB 0x16 -#define REG_LR_RXPACKETCNTVALUELSB 0x17 -#define REG_LR_MODEMSTAT 0x18 -#define REG_LR_PKTSNRVALUE 0x19 -#define REG_LR_PKTRSSIVALUE 0x1A -#define REG_LR_RSSIVALUE 0x1B -#define REG_LR_HOPCHANNEL 0x1C -#define REG_LR_MODEMCONFIG1 0x1D -#define REG_LR_MODEMCONFIG2 0x1E -#define REG_LR_SYMBTIMEOUTLSB 0x1F -#define REG_LR_PREAMBLEMSB 0x20 -#define REG_LR_PREAMBLELSB 0x21 -#define REG_LR_PAYLOADLENGTH 0x22 -#define REG_LR_PAYLOADMAXLENGTH 0x23 -#define REG_LR_HOPPERIOD 0x24 -#define REG_LR_FIFORXBYTEADDR 0x25 -#define REG_LR_MODEMCONFIG3 0x26 -#define REG_LR_FEIMSB 0x28 -#define REG_LR_FEIMID 0x29 -#define REG_LR_FEILSB 0x2A -#define REG_LR_RSSIWIDEBAND 0x2C -#define REG_LR_TEST2F 0x2F -#define REG_LR_TEST30 0x30 -#define REG_LR_DETECTOPTIMIZE 0x31 -#define REG_LR_INVERTIQ 0x33 -#define REG_LR_TEST36 0x36 -#define REG_LR_DETECTIONTHRESHOLD 0x37 -#define REG_LR_SYNCWORD 0x39 -#define REG_LR_TEST3A 0x3A -#define REG_LR_INVERTIQ2 0x3B - -// end of documented register in datasheet -// I/O settings -#define REG_LR_DIOMAPPING1 0x40 -#define REG_LR_DIOMAPPING2 0x41 -// Version -#define REG_LR_VERSION 0x42 -// Additional settings -#define REG_LR_PLLHOP 0x44 -#define REG_LR_TCXO 0x4B -#define REG_LR_PADAC 0x4D -#define REG_LR_FORMERTEMP 0x5B -#define REG_LR_BITRATEFRAC 0x5D -#define REG_LR_AGCREF 0x61 -#define REG_LR_AGCTHRESH1 0x62 -#define REG_LR_AGCTHRESH2 0x63 -#define REG_LR_AGCTHRESH3 0x64 -#define REG_LR_PLL 0x70 - -/*! - * ============================================================================ - * SX1276 LoRa bits control definition - * ============================================================================ - */ - -/*! - * RegFifo - */ - -/*! - * RegOpMode - */ -#define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F -#define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default -#define RFLR_OPMODE_LONGRANGEMODE_ON 0x80 - -#define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF -#define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40 -#define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default - -#define RFLR_OPMODE_FREQMODE_ACCESS_MASK 0xF7 -#define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default -#define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00 - -#define RFLR_OPMODE_MASK 0xF8 -#define RFLR_OPMODE_SLEEP 0x00 -#define RFLR_OPMODE_STANDBY 0x01 // Default -#define RFLR_OPMODE_SYNTHESIZER_TX 0x02 -#define RFLR_OPMODE_TRANSMITTER 0x03 -#define RFLR_OPMODE_SYNTHESIZER_RX 0x04 -#define RFLR_OPMODE_RECEIVER 0x05 -// LoRa specific modes -#define RFLR_OPMODE_RECEIVER_SINGLE 0x06 -#define RFLR_OPMODE_CAD 0x07 - -/*! - * RegFrf (MHz) - */ -#define RFLR_FRFMSB_434_MHZ 0x6C // Default -#define RFLR_FRFMID_434_MHZ 0x80 // Default -#define RFLR_FRFLSB_434_MHZ 0x00 // Default - -/*! - * RegPaConfig - */ -#define RFLR_PACONFIG_PASELECT_MASK 0x7F -#define RFLR_PACONFIG_PASELECT_PABOOST 0x80 -#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default - -#define RFLR_PACONFIG_MAX_POWER_MASK 0x8F - -#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0 - -/*! - * RegPaRamp - */ -#define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF -#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10 -#define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default - -#define RFLR_PARAMP_MASK 0xF0 -#define RFLR_PARAMP_3400_US 0x00 -#define RFLR_PARAMP_2000_US 0x01 -#define RFLR_PARAMP_1000_US 0x02 -#define RFLR_PARAMP_0500_US 0x03 -#define RFLR_PARAMP_0250_US 0x04 -#define RFLR_PARAMP_0125_US 0x05 -#define RFLR_PARAMP_0100_US 0x06 -#define RFLR_PARAMP_0062_US 0x07 -#define RFLR_PARAMP_0050_US 0x08 -#define RFLR_PARAMP_0040_US 0x09 // Default -#define RFLR_PARAMP_0031_US 0x0A -#define RFLR_PARAMP_0025_US 0x0B -#define RFLR_PARAMP_0020_US 0x0C -#define RFLR_PARAMP_0015_US 0x0D -#define RFLR_PARAMP_0012_US 0x0E -#define RFLR_PARAMP_0010_US 0x0F - -/*! - * RegOcp - */ -#define RFLR_OCP_MASK 0xDF -#define RFLR_OCP_ON 0x20 // Default -#define RFLR_OCP_OFF 0x00 - -#define RFLR_OCP_TRIM_MASK 0xE0 -#define RFLR_OCP_TRIM_045_MA 0x00 -#define RFLR_OCP_TRIM_050_MA 0x01 -#define RFLR_OCP_TRIM_055_MA 0x02 -#define RFLR_OCP_TRIM_060_MA 0x03 -#define RFLR_OCP_TRIM_065_MA 0x04 -#define RFLR_OCP_TRIM_070_MA 0x05 -#define RFLR_OCP_TRIM_075_MA 0x06 -#define RFLR_OCP_TRIM_080_MA 0x07 -#define RFLR_OCP_TRIM_085_MA 0x08 -#define RFLR_OCP_TRIM_090_MA 0x09 -#define RFLR_OCP_TRIM_095_MA 0x0A -#define RFLR_OCP_TRIM_100_MA 0x0B // Default -#define RFLR_OCP_TRIM_105_MA 0x0C -#define RFLR_OCP_TRIM_110_MA 0x0D -#define RFLR_OCP_TRIM_115_MA 0x0E -#define RFLR_OCP_TRIM_120_MA 0x0F -#define RFLR_OCP_TRIM_130_MA 0x10 -#define RFLR_OCP_TRIM_140_MA 0x11 -#define RFLR_OCP_TRIM_150_MA 0x12 -#define RFLR_OCP_TRIM_160_MA 0x13 -#define RFLR_OCP_TRIM_170_MA 0x14 -#define RFLR_OCP_TRIM_180_MA 0x15 -#define RFLR_OCP_TRIM_190_MA 0x16 -#define RFLR_OCP_TRIM_200_MA 0x17 -#define RFLR_OCP_TRIM_210_MA 0x18 -#define RFLR_OCP_TRIM_220_MA 0x19 -#define RFLR_OCP_TRIM_230_MA 0x1A -#define RFLR_OCP_TRIM_240_MA 0x1B - -/*! - * RegLna - */ -#define RFLR_LNA_GAIN_MASK 0x1F -#define RFLR_LNA_GAIN_G1 0x20 // Default -#define RFLR_LNA_GAIN_G2 0x40 -#define RFLR_LNA_GAIN_G3 0x60 -#define RFLR_LNA_GAIN_G4 0x80 -#define RFLR_LNA_GAIN_G5 0xA0 -#define RFLR_LNA_GAIN_G6 0xC0 - -#define RFLR_LNA_BOOST_LF_MASK 0xE7 -#define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default - -#define RFLR_LNA_BOOST_HF_MASK 0xFC -#define RFLR_LNA_BOOST_HF_OFF 0x00 // Default -#define RFLR_LNA_BOOST_HF_ON 0x03 - -/*! - * RegFifoAddrPtr - */ -#define RFLR_FIFOADDRPTR 0x00 // Default - -/*! - * RegFifoTxBaseAddr - */ -#define RFLR_FIFOTXBASEADDR 0x80 // Default - -/*! - * RegFifoTxBaseAddr - */ -#define RFLR_FIFORXBASEADDR 0x00 // Default - -/*! - * RegFifoRxCurrentAddr (Read Only) - */ - -/*! - * RegIrqFlagsMask - */ -#define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80 -#define RFLR_IRQFLAGS_RXDONE_MASK 0x40 -#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20 -#define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10 -#define RFLR_IRQFLAGS_TXDONE_MASK 0x08 -#define RFLR_IRQFLAGS_CADDONE_MASK 0x04 -#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02 -#define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01 - -/*! - * RegIrqFlags - */ -#define RFLR_IRQFLAGS_RXTIMEOUT 0x80 -#define RFLR_IRQFLAGS_RXDONE 0x40 -#define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20 -#define RFLR_IRQFLAGS_VALIDHEADER 0x10 -#define RFLR_IRQFLAGS_TXDONE 0x08 -#define RFLR_IRQFLAGS_CADDONE 0x04 -#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02 -#define RFLR_IRQFLAGS_CADDETECTED 0x01 - -/*! - * RegFifoRxNbBytes (Read Only) - */ - -/*! - * RegRxHeaderCntValueMsb (Read Only) - */ - -/*! - * RegRxHeaderCntValueLsb (Read Only) - */ - -/*! - * RegRxPacketCntValueMsb (Read Only) - */ - -/*! - * RegRxPacketCntValueLsb (Read Only) - */ - -/*! - * RegModemStat (Read Only) - */ -#define RFLR_MODEMSTAT_RX_CR_MASK 0x1F -#define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0 - -/*! - * RegPktSnrValue (Read Only) - */ - -/*! - * RegPktRssiValue (Read Only) - */ - -/*! - * RegRssiValue (Read Only) - */ - -/*! - * RegHopChannel (Read Only) - */ -#define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F -#define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80 -#define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default - -#define RFLR_HOPCHANNEL_CRCONPAYLOAD_MASK 0xBF -#define RFLR_HOPCHANNEL_CRCONPAYLOAD_ON 0x40 -#define RFLR_HOPCHANNEL_CRCONPAYLOAD_OFF 0x00 // Default - -#define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F - -/*! - * RegModemConfig1 - */ -#define RFLR_MODEMCONFIG1_BW_MASK 0x0F -#define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00 -#define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10 -#define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20 -#define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30 -#define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40 -#define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50 -#define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60 -#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default -#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80 -#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90 - -#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1 -#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02 -#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default -#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06 -#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08 - -#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE -#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01 -#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default - -/*! - * RegModemConfig2 - */ -#define RFLR_MODEMCONFIG2_SF_MASK 0x0F -#define RFLR_MODEMCONFIG2_SF_6 0x60 -#define RFLR_MODEMCONFIG2_SF_7 0x70 // Default -#define RFLR_MODEMCONFIG2_SF_8 0x80 -#define RFLR_MODEMCONFIG2_SF_9 0x90 -#define RFLR_MODEMCONFIG2_SF_10 0xA0 -#define RFLR_MODEMCONFIG2_SF_11 0xB0 -#define RFLR_MODEMCONFIG2_SF_12 0xC0 - -#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7 -#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08 -#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00 - -#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK 0xFB -#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04 -#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default - -#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC -#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default - -/*! - * RegSymbTimeoutLsb - */ -#define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default - -/*! - * RegPreambleLengthMsb - */ -#define RFLR_PREAMBLELENGTHMSB 0x00 // Default - -/*! - * RegPreambleLengthLsb - */ -#define RFLR_PREAMBLELENGTHLSB 0x08 // Default - -/*! - * RegPayloadLength - */ -#define RFLR_PAYLOADLENGTH 0x0E // Default - -/*! - * RegPayloadMaxLength - */ -#define RFLR_PAYLOADMAXLENGTH 0xFF // Default - -/*! - * RegHopPeriod - */ -#define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default - -/*! - * RegFifoRxByteAddr (Read Only) - */ - -/*! - * RegModemConfig3 - */ -#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK 0xF7 -#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON 0x08 -#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF 0x00 // Default - -#define RFLR_MODEMCONFIG3_AGCAUTO_MASK 0xFB -#define RFLR_MODEMCONFIG3_AGCAUTO_ON 0x04 // Default -#define RFLR_MODEMCONFIG3_AGCAUTO_OFF 0x00 - -/*! - * RegFeiMsb (Read Only) - */ - -/*! - * RegFeiMid (Read Only) - */ - -/*! - * RegFeiLsb (Read Only) - */ - -/*! - * RegRssiWideband (Read Only) - */ - -/*! - * RegDetectOptimize - */ -#define RFLR_DETECTIONOPTIMIZE_MASK 0xF8 -#define RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 0x03 // Default -#define RFLR_DETECTIONOPTIMIZE_SF6 0x05 - -/*! - * RegInvertIQ - */ -#define RFLR_INVERTIQ_RX_MASK 0xBF -#define RFLR_INVERTIQ_RX_OFF 0x00 -#define RFLR_INVERTIQ_RX_ON 0x40 -#define RFLR_INVERTIQ_TX_MASK 0xFE -#define RFLR_INVERTIQ_TX_OFF 0x01 -#define RFLR_INVERTIQ_TX_ON 0x00 - -/*! - * RegDetectionThreshold - */ -#define RFLR_DETECTIONTHRESH_SF7_TO_SF12 0x0A // Default -#define RFLR_DETECTIONTHRESH_SF6 0x0C - -/*! - * RegInvertIQ2 - */ -#define RFLR_INVERTIQ2_ON 0x19 -#define RFLR_INVERTIQ2_OFF 0x1D - -/*! - * RegDioMapping1 - */ -#define RFLR_DIOMAPPING1_DIO0_MASK 0x3F -#define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default -#define RFLR_DIOMAPPING1_DIO0_01 0x40 -#define RFLR_DIOMAPPING1_DIO0_10 0x80 -#define RFLR_DIOMAPPING1_DIO0_11 0xC0 - -#define RFLR_DIOMAPPING1_DIO1_MASK 0xCF -#define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default -#define RFLR_DIOMAPPING1_DIO1_01 0x10 -#define RFLR_DIOMAPPING1_DIO1_10 0x20 -#define RFLR_DIOMAPPING1_DIO1_11 0x30 - -#define RFLR_DIOMAPPING1_DIO2_MASK 0xF3 -#define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default -#define RFLR_DIOMAPPING1_DIO2_01 0x04 -#define RFLR_DIOMAPPING1_DIO2_10 0x08 -#define RFLR_DIOMAPPING1_DIO2_11 0x0C - -#define RFLR_DIOMAPPING1_DIO3_MASK 0xFC -#define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default -#define RFLR_DIOMAPPING1_DIO3_01 0x01 -#define RFLR_DIOMAPPING1_DIO3_10 0x02 -#define RFLR_DIOMAPPING1_DIO3_11 0x03 - -/*! - * RegDioMapping2 - */ -#define RFLR_DIOMAPPING2_DIO4_MASK 0x3F -#define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default -#define RFLR_DIOMAPPING2_DIO4_01 0x40 -#define RFLR_DIOMAPPING2_DIO4_10 0x80 -#define RFLR_DIOMAPPING2_DIO4_11 0xC0 - -#define RFLR_DIOMAPPING2_DIO5_MASK 0xCF -#define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default -#define RFLR_DIOMAPPING2_DIO5_01 0x10 -#define RFLR_DIOMAPPING2_DIO5_10 0x20 -#define RFLR_DIOMAPPING2_DIO5_11 0x30 - -#define RFLR_DIOMAPPING2_MAP_MASK 0xFE -#define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 -#define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default - -/*! - * RegVersion (Read Only) - */ - -/*! - * RegPllHop - */ -#define RFLR_PLLHOP_FASTHOP_MASK 0x7F -#define RFLR_PLLHOP_FASTHOP_ON 0x80 -#define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default - -/*! - * RegTcxo - */ -#define RFLR_TCXO_TCXOINPUT_MASK 0xEF -#define RFLR_TCXO_TCXOINPUT_ON 0x10 -#define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default - -/*! - * RegPaDac - */ -#define RFLR_PADAC_20DBM_MASK 0xF8 -#define RFLR_PADAC_20DBM_ON 0x07 -#define RFLR_PADAC_20DBM_OFF 0x04 // Default - -/*! - * RegFormerTemp - */ - -/*! - * RegBitrateFrac - */ -#define RF_BITRATEFRAC_MASK 0xF0 - -/*! - * RegAgcRef - */ - -/*! - * RegAgcThresh1 - */ - -/*! - * RegAgcThresh2 - */ - -/*! - * RegAgcThresh3 - */ - -/*! - * RegPll - */ -#define RF_PLL_BANDWIDTH_MASK 0x3F -#define RF_PLL_BANDWIDTH_75 0x00 -#define RF_PLL_BANDWIDTH_150 0x40 -#define RF_PLL_BANDWIDTH_225 0x80 -#define RF_PLL_BANDWIDTH_300 0xC0 // Default - -#endif // __SX1276_REGS_LORA_H__ +/** + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C) 2014 Semtech + +Description: SX1276 LoRa modem registers and bits definitions + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian + +Copyright (c) 2017, Arm Limited and affiliates. + +SPDX-License-Identifier: BSD-3-Clause +*/ +#ifndef __SX1276_REGS_LORA_H__ +#define __SX1276_REGS_LORA_H__ + +/*! + * ============================================================================ + * SX1276 Internal registers Address + * ============================================================================ + */ +#define REG_LR_FIFO 0x00 +// Common settings +#define REG_LR_OPMODE 0x01 +#define REG_LR_FRFMSB 0x06 +#define REG_LR_FRFMID 0x07 +#define REG_LR_FRFLSB 0x08 +// Tx settings +#define REG_LR_PACONFIG 0x09 +#define REG_LR_PARAMP 0x0A +#define REG_LR_OCP 0x0B +// Rx settings +#define REG_LR_LNA 0x0C +// LoRa registers +#define REG_LR_FIFOADDRPTR 0x0D +#define REG_LR_FIFOTXBASEADDR 0x0E +#define REG_LR_FIFORXBASEADDR 0x0F +#define REG_LR_FIFORXCURRENTADDR 0x10 +#define REG_LR_IRQFLAGSMASK 0x11 +#define REG_LR_IRQFLAGS 0x12 +#define REG_LR_RXNBBYTES 0x13 +#define REG_LR_RXHEADERCNTVALUEMSB 0x14 +#define REG_LR_RXHEADERCNTVALUELSB 0x15 +#define REG_LR_RXPACKETCNTVALUEMSB 0x16 +#define REG_LR_RXPACKETCNTVALUELSB 0x17 +#define REG_LR_MODEMSTAT 0x18 +#define REG_LR_PKTSNRVALUE 0x19 +#define REG_LR_PKTRSSIVALUE 0x1A +#define REG_LR_RSSIVALUE 0x1B +#define REG_LR_HOPCHANNEL 0x1C +#define REG_LR_MODEMCONFIG1 0x1D +#define REG_LR_MODEMCONFIG2 0x1E +#define REG_LR_SYMBTIMEOUTLSB 0x1F +#define REG_LR_PREAMBLEMSB 0x20 +#define REG_LR_PREAMBLELSB 0x21 +#define REG_LR_PAYLOADLENGTH 0x22 +#define REG_LR_PAYLOADMAXLENGTH 0x23 +#define REG_LR_HOPPERIOD 0x24 +#define REG_LR_FIFORXBYTEADDR 0x25 +#define REG_LR_MODEMCONFIG3 0x26 +#define REG_LR_FEIMSB 0x28 +#define REG_LR_FEIMID 0x29 +#define REG_LR_FEILSB 0x2A +#define REG_LR_RSSIWIDEBAND 0x2C +#define REG_LR_TEST2F 0x2F +#define REG_LR_TEST30 0x30 +#define REG_LR_DETECTOPTIMIZE 0x31 +#define REG_LR_INVERTIQ 0x33 +#define REG_LR_TEST36 0x36 +#define REG_LR_DETECTIONTHRESHOLD 0x37 +#define REG_LR_SYNCWORD 0x39 +#define REG_LR_TEST3A 0x3A +#define REG_LR_INVERTIQ2 0x3B + +// end of documented register in datasheet +// I/O settings +#define REG_LR_DIOMAPPING1 0x40 +#define REG_LR_DIOMAPPING2 0x41 +// Version +#define REG_LR_VERSION 0x42 +// Additional settings +#define REG_LR_PLLHOP 0x44 +#define REG_LR_TCXO 0x4B +#define REG_LR_PADAC 0x4D +#define REG_LR_FORMERTEMP 0x5B +#define REG_LR_BITRATEFRAC 0x5D +#define REG_LR_AGCREF 0x61 +#define REG_LR_AGCTHRESH1 0x62 +#define REG_LR_AGCTHRESH2 0x63 +#define REG_LR_AGCTHRESH3 0x64 +#define REG_LR_PLL 0x70 + +/*! + * ============================================================================ + * SX1276 LoRa bits control definition + * ============================================================================ + */ + +/*! + * RegFifo + */ + +/*! + * RegOpMode + */ +#define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F +#define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default +#define RFLR_OPMODE_LONGRANGEMODE_ON 0x80 + +#define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF +#define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40 +#define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default + +#define RFLR_OPMODE_FREQMODE_ACCESS_MASK 0xF7 +#define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default +#define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00 + +#define RFLR_OPMODE_MASK 0xF8 +#define RFLR_OPMODE_SLEEP 0x00 +#define RFLR_OPMODE_STANDBY 0x01 // Default +#define RFLR_OPMODE_SYNTHESIZER_TX 0x02 +#define RFLR_OPMODE_TRANSMITTER 0x03 +#define RFLR_OPMODE_SYNTHESIZER_RX 0x04 +#define RFLR_OPMODE_RECEIVER 0x05 +// LoRa specific modes +#define RFLR_OPMODE_RECEIVER_SINGLE 0x06 +#define RFLR_OPMODE_CAD 0x07 + +/*! + * RegFrf (MHz) + */ +#define RFLR_FRFMSB_434_MHZ 0x6C // Default +#define RFLR_FRFMID_434_MHZ 0x80 // Default +#define RFLR_FRFLSB_434_MHZ 0x00 // Default + +/*! + * RegPaConfig + */ +#define RFLR_PACONFIG_PASELECT_MASK 0x7F +#define RFLR_PACONFIG_PASELECT_PABOOST 0x80 +#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default + +#define RFLR_PACONFIG_MAX_POWER_MASK 0x8F + +#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0 + +/*! + * RegPaRamp + */ +#define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF +#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10 +#define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default + +#define RFLR_PARAMP_MASK 0xF0 +#define RFLR_PARAMP_3400_US 0x00 +#define RFLR_PARAMP_2000_US 0x01 +#define RFLR_PARAMP_1000_US 0x02 +#define RFLR_PARAMP_0500_US 0x03 +#define RFLR_PARAMP_0250_US 0x04 +#define RFLR_PARAMP_0125_US 0x05 +#define RFLR_PARAMP_0100_US 0x06 +#define RFLR_PARAMP_0062_US 0x07 +#define RFLR_PARAMP_0050_US 0x08 +#define RFLR_PARAMP_0040_US 0x09 // Default +#define RFLR_PARAMP_0031_US 0x0A +#define RFLR_PARAMP_0025_US 0x0B +#define RFLR_PARAMP_0020_US 0x0C +#define RFLR_PARAMP_0015_US 0x0D +#define RFLR_PARAMP_0012_US 0x0E +#define RFLR_PARAMP_0010_US 0x0F + +/*! + * RegOcp + */ +#define RFLR_OCP_MASK 0xDF +#define RFLR_OCP_ON 0x20 // Default +#define RFLR_OCP_OFF 0x00 + +#define RFLR_OCP_TRIM_MASK 0xE0 +#define RFLR_OCP_TRIM_045_MA 0x00 +#define RFLR_OCP_TRIM_050_MA 0x01 +#define RFLR_OCP_TRIM_055_MA 0x02 +#define RFLR_OCP_TRIM_060_MA 0x03 +#define RFLR_OCP_TRIM_065_MA 0x04 +#define RFLR_OCP_TRIM_070_MA 0x05 +#define RFLR_OCP_TRIM_075_MA 0x06 +#define RFLR_OCP_TRIM_080_MA 0x07 +#define RFLR_OCP_TRIM_085_MA 0x08 +#define RFLR_OCP_TRIM_090_MA 0x09 +#define RFLR_OCP_TRIM_095_MA 0x0A +#define RFLR_OCP_TRIM_100_MA 0x0B // Default +#define RFLR_OCP_TRIM_105_MA 0x0C +#define RFLR_OCP_TRIM_110_MA 0x0D +#define RFLR_OCP_TRIM_115_MA 0x0E +#define RFLR_OCP_TRIM_120_MA 0x0F +#define RFLR_OCP_TRIM_130_MA 0x10 +#define RFLR_OCP_TRIM_140_MA 0x11 +#define RFLR_OCP_TRIM_150_MA 0x12 +#define RFLR_OCP_TRIM_160_MA 0x13 +#define RFLR_OCP_TRIM_170_MA 0x14 +#define RFLR_OCP_TRIM_180_MA 0x15 +#define RFLR_OCP_TRIM_190_MA 0x16 +#define RFLR_OCP_TRIM_200_MA 0x17 +#define RFLR_OCP_TRIM_210_MA 0x18 +#define RFLR_OCP_TRIM_220_MA 0x19 +#define RFLR_OCP_TRIM_230_MA 0x1A +#define RFLR_OCP_TRIM_240_MA 0x1B + +/*! + * RegLna + */ +#define RFLR_LNA_GAIN_MASK 0x1F +#define RFLR_LNA_GAIN_G1 0x20 // Default +#define RFLR_LNA_GAIN_G2 0x40 +#define RFLR_LNA_GAIN_G3 0x60 +#define RFLR_LNA_GAIN_G4 0x80 +#define RFLR_LNA_GAIN_G5 0xA0 +#define RFLR_LNA_GAIN_G6 0xC0 + +#define RFLR_LNA_BOOST_LF_MASK 0xE7 +#define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default + +#define RFLR_LNA_BOOST_HF_MASK 0xFC +#define RFLR_LNA_BOOST_HF_OFF 0x00 // Default +#define RFLR_LNA_BOOST_HF_ON 0x03 + +/*! + * RegFifoAddrPtr + */ +#define RFLR_FIFOADDRPTR 0x00 // Default + +/*! + * RegFifoTxBaseAddr + */ +#define RFLR_FIFOTXBASEADDR 0x80 // Default + +/*! + * RegFifoTxBaseAddr + */ +#define RFLR_FIFORXBASEADDR 0x00 // Default + +/*! + * RegFifoRxCurrentAddr (Read Only) + */ + +/*! + * RegIrqFlagsMask + */ +#define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80 +#define RFLR_IRQFLAGS_RXDONE_MASK 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10 +#define RFLR_IRQFLAGS_TXDONE_MASK 0x08 +#define RFLR_IRQFLAGS_CADDONE_MASK 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02 +#define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01 + +/*! + * RegIrqFlags + */ +#define RFLR_IRQFLAGS_RXTIMEOUT 0x80 +#define RFLR_IRQFLAGS_RXDONE 0x40 +#define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20 +#define RFLR_IRQFLAGS_VALIDHEADER 0x10 +#define RFLR_IRQFLAGS_TXDONE 0x08 +#define RFLR_IRQFLAGS_CADDONE 0x04 +#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02 +#define RFLR_IRQFLAGS_CADDETECTED 0x01 + +/*! + * RegFifoRxNbBytes (Read Only) + */ + +/*! + * RegRxHeaderCntValueMsb (Read Only) + */ + +/*! + * RegRxHeaderCntValueLsb (Read Only) + */ + +/*! + * RegRxPacketCntValueMsb (Read Only) + */ + +/*! + * RegRxPacketCntValueLsb (Read Only) + */ + +/*! + * RegModemStat (Read Only) + */ +#define RFLR_MODEMSTAT_RX_CR_MASK 0x1F +#define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0 + +/*! + * RegPktSnrValue (Read Only) + */ + +/*! + * RegPktRssiValue (Read Only) + */ + +/*! + * RegRssiValue (Read Only) + */ + +/*! + * RegHopChannel (Read Only) + */ +#define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F +#define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80 +#define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default + +#define RFLR_HOPCHANNEL_CRCONPAYLOAD_MASK 0xBF +#define RFLR_HOPCHANNEL_CRCONPAYLOAD_ON 0x40 +#define RFLR_HOPCHANNEL_CRCONPAYLOAD_OFF 0x00 // Default + +#define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F + +/*! + * RegModemConfig1 + */ +#define RFLR_MODEMCONFIG1_BW_MASK 0x0F +#define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00 +#define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10 +#define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20 +#define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30 +#define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40 +#define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50 +#define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60 +#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default +#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80 +#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90 + +#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default +#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06 +#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08 + +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01 +#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default + +/*! + * RegModemConfig2 + */ +#define RFLR_MODEMCONFIG2_SF_MASK 0x0F +#define RFLR_MODEMCONFIG2_SF_6 0x60 +#define RFLR_MODEMCONFIG2_SF_7 0x70 // Default +#define RFLR_MODEMCONFIG2_SF_8 0x80 +#define RFLR_MODEMCONFIG2_SF_9 0x90 +#define RFLR_MODEMCONFIG2_SF_10 0xA0 +#define RFLR_MODEMCONFIG2_SF_11 0xB0 +#define RFLR_MODEMCONFIG2_SF_12 0xC0 + +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08 +#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00 + +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK 0xFB +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04 +#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC +#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default + +/*! + * RegSymbTimeoutLsb + */ +#define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default + +/*! + * RegPreambleLengthMsb + */ +#define RFLR_PREAMBLELENGTHMSB 0x00 // Default + +/*! + * RegPreambleLengthLsb + */ +#define RFLR_PREAMBLELENGTHLSB 0x08 // Default + +/*! + * RegPayloadLength + */ +#define RFLR_PAYLOADLENGTH 0x0E // Default + +/*! + * RegPayloadMaxLength + */ +#define RFLR_PAYLOADMAXLENGTH 0xFF // Default + +/*! + * RegHopPeriod + */ +#define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default + +/*! + * RegFifoRxByteAddr (Read Only) + */ + +/*! + * RegModemConfig3 + */ +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK 0xF7 +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON 0x08 +#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF 0x00 // Default + +#define RFLR_MODEMCONFIG3_AGCAUTO_MASK 0xFB +#define RFLR_MODEMCONFIG3_AGCAUTO_ON 0x04 // Default +#define RFLR_MODEMCONFIG3_AGCAUTO_OFF 0x00 + +/*! + * RegFeiMsb (Read Only) + */ + +/*! + * RegFeiMid (Read Only) + */ + +/*! + * RegFeiLsb (Read Only) + */ + +/*! + * RegRssiWideband (Read Only) + */ + +/*! + * RegDetectOptimize + */ +#define RFLR_DETECTIONOPTIMIZE_MASK 0xF8 +#define RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 0x03 // Default +#define RFLR_DETECTIONOPTIMIZE_SF6 0x05 + +/*! + * RegInvertIQ + */ +#define RFLR_INVERTIQ_RX_MASK 0xBF +#define RFLR_INVERTIQ_RX_OFF 0x00 +#define RFLR_INVERTIQ_RX_ON 0x40 +#define RFLR_INVERTIQ_TX_MASK 0xFE +#define RFLR_INVERTIQ_TX_OFF 0x01 +#define RFLR_INVERTIQ_TX_ON 0x00 + +/*! + * RegDetectionThreshold + */ +#define RFLR_DETECTIONTHRESH_SF7_TO_SF12 0x0A // Default +#define RFLR_DETECTIONTHRESH_SF6 0x0C + +/*! + * RegInvertIQ2 + */ +#define RFLR_INVERTIQ2_ON 0x19 +#define RFLR_INVERTIQ2_OFF 0x1D + +/*! + * RegDioMapping1 + */ +#define RFLR_DIOMAPPING1_DIO0_MASK 0x3F +#define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO0_01 0x40 +#define RFLR_DIOMAPPING1_DIO0_10 0x80 +#define RFLR_DIOMAPPING1_DIO0_11 0xC0 + +#define RFLR_DIOMAPPING1_DIO1_MASK 0xCF +#define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO1_01 0x10 +#define RFLR_DIOMAPPING1_DIO1_10 0x20 +#define RFLR_DIOMAPPING1_DIO1_11 0x30 + +#define RFLR_DIOMAPPING1_DIO2_MASK 0xF3 +#define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO2_01 0x04 +#define RFLR_DIOMAPPING1_DIO2_10 0x08 +#define RFLR_DIOMAPPING1_DIO2_11 0x0C + +#define RFLR_DIOMAPPING1_DIO3_MASK 0xFC +#define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default +#define RFLR_DIOMAPPING1_DIO3_01 0x01 +#define RFLR_DIOMAPPING1_DIO3_10 0x02 +#define RFLR_DIOMAPPING1_DIO3_11 0x03 + +/*! + * RegDioMapping2 + */ +#define RFLR_DIOMAPPING2_DIO4_MASK 0x3F +#define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO4_01 0x40 +#define RFLR_DIOMAPPING2_DIO4_10 0x80 +#define RFLR_DIOMAPPING2_DIO4_11 0xC0 + +#define RFLR_DIOMAPPING2_DIO5_MASK 0xCF +#define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default +#define RFLR_DIOMAPPING2_DIO5_01 0x10 +#define RFLR_DIOMAPPING2_DIO5_10 0x20 +#define RFLR_DIOMAPPING2_DIO5_11 0x30 + +#define RFLR_DIOMAPPING2_MAP_MASK 0xFE +#define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01 +#define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default + +/*! + * RegVersion (Read Only) + */ + +/*! + * RegPllHop + */ +#define RFLR_PLLHOP_FASTHOP_MASK 0x7F +#define RFLR_PLLHOP_FASTHOP_ON 0x80 +#define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default + +/*! + * RegTcxo + */ +#define RFLR_TCXO_TCXOINPUT_MASK 0xEF +#define RFLR_TCXO_TCXOINPUT_ON 0x10 +#define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default + +/*! + * RegPaDac + */ +#define RFLR_PADAC_20DBM_MASK 0xF8 +#define RFLR_PADAC_20DBM_ON 0x07 +#define RFLR_PADAC_20DBM_OFF 0x04 // Default + +/*! + * RegFormerTemp + */ + +/*! + * RegBitrateFrac + */ +#define RF_BITRATEFRAC_MASK 0xF0 + +/*! + * RegAgcRef + */ + +/*! + * RegAgcThresh1 + */ + +/*! + * RegAgcThresh2 + */ + +/*! + * RegAgcThresh3 + */ + +/*! + * RegPll + */ +#define RF_PLL_BANDWIDTH_MASK 0x3F +#define RF_PLL_BANDWIDTH_75 0x00 +#define RF_PLL_BANDWIDTH_150 0x40 +#define RF_PLL_BANDWIDTH_225 0x80 +#define RF_PLL_BANDWIDTH_300 0xC0 // Default + +#endif // __SX1276_REGS_LORA_H__ From a16a35246b0b0d03457c32bf8d45f731db320c1f Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Mon, 6 Apr 2020 08:26:29 +0300 Subject: [PATCH 41/42] Lora: Add driver implementation inside DEVICE_SPI flag These drivers uses SPI to communicate with radio so SPI must be present when compiling these. --- components/lora/SX126X/SX126X_LoRaRadio.cpp | 3 +++ components/lora/SX126X/SX126X_LoRaRadio.h | 4 ++++ components/lora/SX1272/SX1272_LoRaRadio.cpp | 4 ++++ components/lora/SX1272/SX1272_LoRaRadio.h | 4 ++++ components/lora/SX1276/SX1276_LoRaRadio.cpp | 5 +++++ components/lora/SX1276/SX1276_LoRaRadio.h | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/components/lora/SX126X/SX126X_LoRaRadio.cpp b/components/lora/SX126X/SX126X_LoRaRadio.cpp index 071185d029..041761c219 100644 --- a/components/lora/SX126X/SX126X_LoRaRadio.cpp +++ b/components/lora/SX126X/SX126X_LoRaRadio.cpp @@ -22,6 +22,8 @@ Copyright (c) 2019, Arm Limited and affiliates. SPDX-License-Identifier: BSD-3-Clause */ +#if DEVICE_SPI + #include #include "ThisThread.h" #include "mbed_wait_api.h" @@ -1337,3 +1339,4 @@ void SX126X_LoRaRadio::clear_device_errors(void) write_opmode_command((uint8_t) RADIO_CLR_ERROR, buf, 2); } +#endif // DEVICE_SPI diff --git a/components/lora/SX126X/SX126X_LoRaRadio.h b/components/lora/SX126X/SX126X_LoRaRadio.h index 32355d263c..b4fb7486ae 100644 --- a/components/lora/SX126X/SX126X_LoRaRadio.h +++ b/components/lora/SX126X/SX126X_LoRaRadio.h @@ -25,6 +25,8 @@ SPDX-License-Identifier: BSD-3-Clause #ifndef MBED_LORA_RADIO_DRV_SX126X_LORARADIO_H_ #define MBED_LORA_RADIO_DRV_SX126X_LORARADIO_H_ +#if DEVICE_SPI + #include "mbed_critical.h" #include "PinNames.h" #include "InterruptIn.h" @@ -401,4 +403,6 @@ private: packet_params_t _packet_params; }; +#endif // DEVICE_SPI + #endif /* MBED_LORA_RADIO_DRV_SX126X_LORARADIO_H_ */ diff --git a/components/lora/SX1272/SX1272_LoRaRadio.cpp b/components/lora/SX1272/SX1272_LoRaRadio.cpp index 9e042668fe..6826c123f5 100644 --- a/components/lora/SX1272/SX1272_LoRaRadio.cpp +++ b/components/lora/SX1272/SX1272_LoRaRadio.cpp @@ -23,6 +23,8 @@ Copyright (c) 2017, Arm Limited and affiliates. SPDX-License-Identifier: BSD-3-Clause */ +#if DEVICE_SPI + #include "SX1272_LoRaRadio.h" #include "sx1272Regs-Fsk.h" #include "sx1272Regs-LoRa.h" @@ -2080,3 +2082,5 @@ void SX1272_LoRaRadio::handle_timeout_irq() } } } + +#endif // DEVICE_SPI diff --git a/components/lora/SX1272/SX1272_LoRaRadio.h b/components/lora/SX1272/SX1272_LoRaRadio.h index 3adcd6ae09..711f1a571f 100644 --- a/components/lora/SX1272/SX1272_LoRaRadio.h +++ b/components/lora/SX1272/SX1272_LoRaRadio.h @@ -26,6 +26,8 @@ SPDX-License-Identifier: BSD-3-Clause #ifndef SX1272_LORARADIO_H_ #define SX1272_LORARADIO_H_ +#if DEVICE_SPI + #include "PinNames.h" #include "InterruptIn.h" #include "DigitalOut.h" @@ -435,4 +437,6 @@ private: void handle_timeout_irq(); }; +#endif // DEVICE_SPI + #endif /* SX1272_LORARADIO_H_ */ diff --git a/components/lora/SX1276/SX1276_LoRaRadio.cpp b/components/lora/SX1276/SX1276_LoRaRadio.cpp index 5deecf9948..8edd0ab430 100644 --- a/components/lora/SX1276/SX1276_LoRaRadio.cpp +++ b/components/lora/SX1276/SX1276_LoRaRadio.cpp @@ -22,6 +22,8 @@ Copyright (c) 2017, Arm Limited and affiliates. SPDX-License-Identifier: BSD-3-Clause */ +#if DEVICE_SPI + #include "PinNames.h" #include "platform/Callback.h" #include "platform/mbed_wait_api.h" @@ -2268,4 +2270,7 @@ void SX1276_LoRaRadio::handle_timeout_irq() } } } + +#endif // DEVICE_SPI + // EOF diff --git a/components/lora/SX1276/SX1276_LoRaRadio.h b/components/lora/SX1276/SX1276_LoRaRadio.h index 47be6bcc6b..e1ed1e7ad3 100644 --- a/components/lora/SX1276/SX1276_LoRaRadio.h +++ b/components/lora/SX1276/SX1276_LoRaRadio.h @@ -26,6 +26,8 @@ SPDX-License-Identifier: BSD-3-Clause #ifndef SX1276_LORARADIO_H_ #define SX1276_LORARADIO_H_ +#if DEVICE_SPI + #include "PinNames.h" #include "InterruptIn.h" #include "DigitalOut.h" @@ -446,4 +448,6 @@ private: void handle_timeout_irq(); }; +#endif // DEVICE_SPI + #endif // SX1276_LORARADIO_H_ From a1a98ab5273c4d900876a223de9921ab5c690ef4 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Mon, 6 Apr 2020 11:47:42 +0300 Subject: [PATCH 42/42] Lora: Move drivers to own COMPONENT -directories To enable building only when driver is enabled with components_add -setting in json configuration. --- components/lora/{SX126X => COMPONENT_SX126X}/SX126X_LoRaRadio.cpp | 0 components/lora/{SX126X => COMPONENT_SX126X}/SX126X_LoRaRadio.h | 0 components/lora/{SX126X => COMPONENT_SX126X}/SleepMode.txt | 0 components/lora/{SX126X => COMPONENT_SX126X}/mbed_lib.json | 0 components/lora/{SX126X => COMPONENT_SX126X}/sx126x_ds.h | 0 components/lora/{SX1272 => COMPONENT_SX1272}/README.md | 0 components/lora/{SX1272 => COMPONENT_SX1272}/SX1272_LoRaRadio.cpp | 0 components/lora/{SX1272 => COMPONENT_SX1272}/SX1272_LoRaRadio.h | 0 components/lora/{SX1272 => COMPONENT_SX1272}/mbed_lib.json | 0 .../lora/{SX1272 => COMPONENT_SX1272}/registers/sx1272Regs-Fsk.h | 0 .../lora/{SX1272 => COMPONENT_SX1272}/registers/sx1272Regs-LoRa.h | 0 components/lora/{SX1276 => COMPONENT_SX1276}/README.md | 0 components/lora/{SX1276 => COMPONENT_SX1276}/SX1276_LoRaRadio.cpp | 0 components/lora/{SX1276 => COMPONENT_SX1276}/SX1276_LoRaRadio.h | 0 components/lora/{SX1276 => COMPONENT_SX1276}/mbed_lib.json | 0 .../lora/{SX1276 => COMPONENT_SX1276}/registers/sx1276Regs-Fsk.h | 0 .../lora/{SX1276 => COMPONENT_SX1276}/registers/sx1276Regs-LoRa.h | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename components/lora/{SX126X => COMPONENT_SX126X}/SX126X_LoRaRadio.cpp (100%) rename components/lora/{SX126X => COMPONENT_SX126X}/SX126X_LoRaRadio.h (100%) rename components/lora/{SX126X => COMPONENT_SX126X}/SleepMode.txt (100%) rename components/lora/{SX126X => COMPONENT_SX126X}/mbed_lib.json (100%) rename components/lora/{SX126X => COMPONENT_SX126X}/sx126x_ds.h (100%) rename components/lora/{SX1272 => COMPONENT_SX1272}/README.md (100%) rename components/lora/{SX1272 => COMPONENT_SX1272}/SX1272_LoRaRadio.cpp (100%) rename components/lora/{SX1272 => COMPONENT_SX1272}/SX1272_LoRaRadio.h (100%) rename components/lora/{SX1272 => COMPONENT_SX1272}/mbed_lib.json (100%) rename components/lora/{SX1272 => COMPONENT_SX1272}/registers/sx1272Regs-Fsk.h (100%) rename components/lora/{SX1272 => COMPONENT_SX1272}/registers/sx1272Regs-LoRa.h (100%) rename components/lora/{SX1276 => COMPONENT_SX1276}/README.md (100%) rename components/lora/{SX1276 => COMPONENT_SX1276}/SX1276_LoRaRadio.cpp (100%) rename components/lora/{SX1276 => COMPONENT_SX1276}/SX1276_LoRaRadio.h (100%) rename components/lora/{SX1276 => COMPONENT_SX1276}/mbed_lib.json (100%) rename components/lora/{SX1276 => COMPONENT_SX1276}/registers/sx1276Regs-Fsk.h (100%) rename components/lora/{SX1276 => COMPONENT_SX1276}/registers/sx1276Regs-LoRa.h (100%) diff --git a/components/lora/SX126X/SX126X_LoRaRadio.cpp b/components/lora/COMPONENT_SX126X/SX126X_LoRaRadio.cpp similarity index 100% rename from components/lora/SX126X/SX126X_LoRaRadio.cpp rename to components/lora/COMPONENT_SX126X/SX126X_LoRaRadio.cpp diff --git a/components/lora/SX126X/SX126X_LoRaRadio.h b/components/lora/COMPONENT_SX126X/SX126X_LoRaRadio.h similarity index 100% rename from components/lora/SX126X/SX126X_LoRaRadio.h rename to components/lora/COMPONENT_SX126X/SX126X_LoRaRadio.h diff --git a/components/lora/SX126X/SleepMode.txt b/components/lora/COMPONENT_SX126X/SleepMode.txt similarity index 100% rename from components/lora/SX126X/SleepMode.txt rename to components/lora/COMPONENT_SX126X/SleepMode.txt diff --git a/components/lora/SX126X/mbed_lib.json b/components/lora/COMPONENT_SX126X/mbed_lib.json similarity index 100% rename from components/lora/SX126X/mbed_lib.json rename to components/lora/COMPONENT_SX126X/mbed_lib.json diff --git a/components/lora/SX126X/sx126x_ds.h b/components/lora/COMPONENT_SX126X/sx126x_ds.h similarity index 100% rename from components/lora/SX126X/sx126x_ds.h rename to components/lora/COMPONENT_SX126X/sx126x_ds.h diff --git a/components/lora/SX1272/README.md b/components/lora/COMPONENT_SX1272/README.md similarity index 100% rename from components/lora/SX1272/README.md rename to components/lora/COMPONENT_SX1272/README.md diff --git a/components/lora/SX1272/SX1272_LoRaRadio.cpp b/components/lora/COMPONENT_SX1272/SX1272_LoRaRadio.cpp similarity index 100% rename from components/lora/SX1272/SX1272_LoRaRadio.cpp rename to components/lora/COMPONENT_SX1272/SX1272_LoRaRadio.cpp diff --git a/components/lora/SX1272/SX1272_LoRaRadio.h b/components/lora/COMPONENT_SX1272/SX1272_LoRaRadio.h similarity index 100% rename from components/lora/SX1272/SX1272_LoRaRadio.h rename to components/lora/COMPONENT_SX1272/SX1272_LoRaRadio.h diff --git a/components/lora/SX1272/mbed_lib.json b/components/lora/COMPONENT_SX1272/mbed_lib.json similarity index 100% rename from components/lora/SX1272/mbed_lib.json rename to components/lora/COMPONENT_SX1272/mbed_lib.json diff --git a/components/lora/SX1272/registers/sx1272Regs-Fsk.h b/components/lora/COMPONENT_SX1272/registers/sx1272Regs-Fsk.h similarity index 100% rename from components/lora/SX1272/registers/sx1272Regs-Fsk.h rename to components/lora/COMPONENT_SX1272/registers/sx1272Regs-Fsk.h diff --git a/components/lora/SX1272/registers/sx1272Regs-LoRa.h b/components/lora/COMPONENT_SX1272/registers/sx1272Regs-LoRa.h similarity index 100% rename from components/lora/SX1272/registers/sx1272Regs-LoRa.h rename to components/lora/COMPONENT_SX1272/registers/sx1272Regs-LoRa.h diff --git a/components/lora/SX1276/README.md b/components/lora/COMPONENT_SX1276/README.md similarity index 100% rename from components/lora/SX1276/README.md rename to components/lora/COMPONENT_SX1276/README.md diff --git a/components/lora/SX1276/SX1276_LoRaRadio.cpp b/components/lora/COMPONENT_SX1276/SX1276_LoRaRadio.cpp similarity index 100% rename from components/lora/SX1276/SX1276_LoRaRadio.cpp rename to components/lora/COMPONENT_SX1276/SX1276_LoRaRadio.cpp diff --git a/components/lora/SX1276/SX1276_LoRaRadio.h b/components/lora/COMPONENT_SX1276/SX1276_LoRaRadio.h similarity index 100% rename from components/lora/SX1276/SX1276_LoRaRadio.h rename to components/lora/COMPONENT_SX1276/SX1276_LoRaRadio.h diff --git a/components/lora/SX1276/mbed_lib.json b/components/lora/COMPONENT_SX1276/mbed_lib.json similarity index 100% rename from components/lora/SX1276/mbed_lib.json rename to components/lora/COMPONENT_SX1276/mbed_lib.json diff --git a/components/lora/SX1276/registers/sx1276Regs-Fsk.h b/components/lora/COMPONENT_SX1276/registers/sx1276Regs-Fsk.h similarity index 100% rename from components/lora/SX1276/registers/sx1276Regs-Fsk.h rename to components/lora/COMPONENT_SX1276/registers/sx1276Regs-Fsk.h diff --git a/components/lora/SX1276/registers/sx1276Regs-LoRa.h b/components/lora/COMPONENT_SX1276/registers/sx1276Regs-LoRa.h similarity index 100% rename from components/lora/SX1276/registers/sx1276Regs-LoRa.h rename to components/lora/COMPONENT_SX1276/registers/sx1276Regs-LoRa.h