You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/02/15 17:12:02 UTC
[GitHub] wes3 closed pull request #813: lora: Initial version of sx1272 driver
wes3 closed pull request #813: lora: Initial version of sx1272 driver
URL: https://github.com/apache/mynewt-core/pull/813
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/hw/drivers/lora/sx1272/LICENSE.txt b/hw/drivers/lora/sx1272/LICENSE.txt
new file mode 100644
index 000000000..82695a7c2
--- /dev/null
+++ b/hw/drivers/lora/sx1272/LICENSE.txt
@@ -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.
\ No newline at end of file
diff --git a/hw/drivers/lora/sx1272/include/radio/radio.h b/hw/drivers/lora/sx1272/include/radio/radio.h
new file mode 100644
index 000000000..ccc0ffc98
--- /dev/null
+++ b/hw/drivers/lora/sx1272/include/radio/radio.h
@@ -0,0 +1,337 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: Generic radio driver definition
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __RADIO_H__
+#define __RADIO_H__
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+/*!
+ * Radio driver supported modems
+ */
+typedef enum
+{
+ MODEM_FSK = 0,
+ MODEM_LORA,
+}RadioModems_t;
+
+/*!
+ * Radio driver internal state machine states definition
+ */
+typedef enum
+{
+ RF_IDLE = 0,
+ RF_RX_RUNNING,
+ RF_TX_RUNNING,
+ RF_CAD,
+}RadioState_t;
+
+/*!
+ * \brief Radio driver callback functions
+ */
+typedef struct
+{
+ /*!
+ * \brief Tx Done callback prototype.
+ */
+ void ( *TxDone )( void );
+ /*!
+ * \brief Tx Timeout callback prototype.
+ */
+ void ( *TxTimeout )( void );
+ /*!
+ * \brief Rx Done callback prototype.
+ *
+ * \param [IN] payload Received buffer pointer
+ * \param [IN] size Received buffer size
+ * \param [IN] rssi RSSI value computed while receiving the frame [dBm]
+ * \param [IN] snr Raw SNR value given by the radio hardware
+ * FSK : N/A ( set to 0 )
+ * LoRa: SNR value in dB
+ */
+ void ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
+ /*!
+ * \brief Rx Timeout callback prototype.
+ */
+ void ( *RxTimeout )( void );
+ /*!
+ * \brief Rx Error callback prototype.
+ */
+ void ( *RxError )( void );
+ /*!
+ * \brief FHSS Change Channel callback prototype.
+ *
+ * \param [IN] currentChannel Index number of the current channel
+ */
+ void ( *FhssChangeChannel )( uint8_t currentChannel );
+
+ /*!
+ * \brief CAD Done callback prototype.
+ *
+ * \param [IN] channelDetected Channel Activity detected during the CAD
+ */
+ void ( *CadDone ) ( bool channelActivityDetected );
+}RadioEvents_t;
+
+/*!
+ * \brief Radio driver definition
+ */
+struct Radio_s
+{
+ /*!
+ * \brief Initializes the radio
+ *
+ * \param [IN] events Structure containing the driver callback functions
+ */
+ void ( *Init )( RadioEvents_t *events );
+ /*!
+ * Return current radio status
+ *
+ * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING]
+ */
+ RadioState_t ( *GetStatus )( void );
+ /*!
+ * \brief Configures the radio with the given modem
+ *
+ * \param [IN] modem Modem to be used [0: FSK, 1: LoRa]
+ */
+ void ( *SetModem )( RadioModems_t modem );
+ /*!
+ * \brief Sets the channel frequency
+ *
+ * \param [IN] freq Channel RF frequency
+ */
+ void ( *SetChannel )( uint32_t freq );
+ /*!
+ * \brief Sets the channels configuration
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] freq Channel RF frequency
+ * \param [IN] rssiThresh RSSI threshold
+ *
+ * \retval isFree [true: Channel is free, false: Channel is not free]
+ */
+ bool ( *IsChannelFree )( RadioModems_t modem, uint32_t freq, int16_t rssiThresh );
+ /*!
+ * \brief 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.
+ *
+ * \retval randomValue 32 bits random value
+ */
+ uint32_t ( *Random )( void );
+ /*!
+ * \brief Sets the reception parameters
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] bandwidth Sets the bandwidth
+ * FSK : >= 2600 and <= 250000 Hz
+ * LoRa: [0: 125 kHz, 1: 250 kHz,
+ * 2: 500 kHz, 3: Reserved]
+ * \param [IN] 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 [IN] 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 [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only)
+ * FSK : >= 2600 and <= 250000 Hz
+ * LoRa: N/A ( set to 0 )
+ * \param [IN] preambleLen Sets the Preamble length
+ * FSK : Number of bytes
+ * LoRa: Length in symbols (the hardware adds 4 more symbols)
+ * \param [IN] symbTimeout Sets the RxSingle timeout value (LoRa only)
+ * FSK : N/A ( set to 0 )
+ * LoRa: timeout in symbols
+ * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed]
+ * \param [IN] payloadLen Sets payload length when fixed length is used
+ * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON]
+ * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping
+ * FSK : N/A ( set to 0 )
+ * LoRa: [0: OFF, 1: ON]
+ * \param [IN] HopPeriod Number of symbols between each hop
+ * FSK : N/A ( set to 0 )
+ * LoRa: Number of symbols
+ * \param [IN] iqInverted Inverts IQ signals (LoRa only)
+ * FSK : N/A ( set to 0 )
+ * LoRa: [0: not inverted, 1: inverted]
+ * \param [IN] rxContinuous Sets the reception in continuous mode
+ * [false: single mode, true: continuous mode]
+ */
+ void ( *SetRxConfig )( RadioModems_t modem, uint32_t bandwidth,
+ uint32_t datarate, uint8_t coderate,
+ uint32_t bandwidthAfc, uint16_t preambleLen,
+ uint16_t symbTimeout, bool fixLen,
+ uint8_t payloadLen,
+ bool crcOn, bool FreqHopOn, uint8_t HopPeriod,
+ bool iqInverted, bool rxContinuous );
+ /*!
+ * \brief Sets the transmission parameters
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] power Sets the output power [dBm]
+ * \param [IN] fdev Sets the frequency deviation (FSK only)
+ * FSK : [Hz]
+ * LoRa: 0
+ * \param [IN] bandwidth Sets the bandwidth (LoRa only)
+ * FSK : 0
+ * LoRa: [0: 125 kHz, 1: 250 kHz,
+ * 2: 500 kHz, 3: Reserved]
+ * \param [IN] 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 [IN] 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 [IN] preambleLen Sets the preamble length
+ * FSK : Number of bytes
+ * LoRa: Length in symbols (the hardware adds 4 more symbols)
+ * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed]
+ * \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON]
+ * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping
+ * FSK : N/A ( set to 0 )
+ * LoRa: [0: OFF, 1: ON]
+ * \param [IN] HopPeriod Number of symbols between each hop
+ * FSK : N/A ( set to 0 )
+ * LoRa: Number of symbols
+ * \param [IN] iqInverted Inverts IQ signals (LoRa only)
+ * FSK : N/A ( set to 0 )
+ * LoRa: [0: not inverted, 1: inverted]
+ * \param [IN] timeout Transmission timeout [ms]
+ */
+ void ( *SetTxConfig )( RadioModems_t modem, int8_t power, uint32_t fdev,
+ uint32_t bandwidth, uint32_t datarate,
+ uint8_t coderate, uint16_t preambleLen,
+ bool fixLen, bool crcOn, bool FreqHopOn,
+ uint8_t HopPeriod, bool iqInverted, uint32_t timeout );
+ /*!
+ * \brief Checks if the given RF frequency is supported by the hardware
+ *
+ * \param [IN] frequency RF frequency to be checked
+ * \retval isSupported [true: supported, false: unsupported]
+ */
+ bool ( *CheckRfFrequency )( uint32_t frequency );
+ /*!
+ * \brief Computes the packet time on air in ms for the given payload
+ *
+ * \Remark Can only be called once SetRxConfig or SetTxConfig have been called
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] pktLen Packet payload length
+ *
+ * \retval airTime Computed airTime (ms) for the given packet payload length
+ */
+ uint32_t ( *TimeOnAir )( RadioModems_t modem, uint8_t pktLen );
+ /*!
+ * \brief Sends the buffer of size. Prepares the packet to be sent and sets
+ * the radio in transmission
+ *
+ * \param [IN]: buffer Buffer pointer
+ * \param [IN]: size Buffer size
+ */
+ void ( *Send )( uint8_t *buffer, uint8_t size );
+ /*!
+ * \brief Sets the radio in sleep mode
+ */
+ void ( *Sleep )( void );
+ /*!
+ * \brief Sets the radio in standby mode
+ */
+ void ( *Standby )( void );
+ /*!
+ * \brief Sets the radio in reception mode for the given time
+ * \param [IN] timeout Reception timeout [ms]
+ * [0: continuous, others timeout]
+ */
+ void ( *Rx )( uint32_t timeout );
+ /*!
+ * \brief Start a Channel Activity Detection
+ */
+ void ( *StartCad )( void );
+ /*!
+ * \brief Sets the radio in continuous wave transmission mode
+ *
+ * \param [IN]: freq Channel RF frequency
+ * \param [IN]: power Sets the output power [dBm]
+ * \param [IN]: time Transmission mode timeout [s]
+ */
+ void ( *SetTxContinuousWave )( uint32_t freq, int8_t power, uint16_t time );
+ /*!
+ * \brief Reads the current RSSI value
+ *
+ * \retval rssiValue Current RSSI value in [dBm]
+ */
+ int16_t ( *Rssi )( RadioModems_t modem );
+ /*!
+ * \brief Writes the radio register at the specified address
+ *
+ * \param [IN]: addr Register address
+ * \param [IN]: data New register value
+ */
+ void ( *Write )( uint8_t addr, uint8_t data );
+ /*!
+ * \brief Reads the radio register at the specified address
+ *
+ * \param [IN]: addr Register address
+ * \retval data Register value
+ */
+ uint8_t ( *Read )( uint8_t addr );
+ /*!
+ * \brief Writes multiple radio registers starting at address
+ *
+ * \param [IN] addr First Radio register address
+ * \param [IN] buffer Buffer containing the new register's values
+ * \param [IN] size Number of registers to be written
+ */
+ void ( *WriteBuffer )( uint8_t addr, uint8_t *buffer, uint8_t size );
+ /*!
+ * \brief Reads multiple radio registers starting at address
+ *
+ * \param [IN] addr First Radio register address
+ * \param [OUT] buffer Buffer where to copy the registers data
+ * \param [IN] size Number of registers to be read
+ */
+ void ( *ReadBuffer )( uint8_t addr, uint8_t *buffer, uint8_t size );
+ /*!
+ * \brief Sets the maximum payload length.
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] max Maximum payload length in bytes
+ */
+ void ( *SetMaxPayloadLength )( RadioModems_t modem, uint8_t max );
+ /*!
+ * \brief Sets the network to public or private. Updates the sync byte.
+ *
+ * \remark Applies to LoRa modem only
+ *
+ * \param [IN] enable if true, it enables a public network
+ */
+ void ( *SetPublicNetwork )( bool enable );
+};
+
+/*!
+ * \brief Radio driver
+ *
+ * \remark This variable is defined and initialized in the specific radio
+ * board implementation
+ */
+extern const struct Radio_s Radio;
+
+#endif // __RADIO_H__
diff --git a/hw/drivers/lora/sx1272/pkg.yml b/hw/drivers/lora/sx1272/pkg.yml
new file mode 100644
index 000000000..f1bfdc6b8
--- /dev/null
+++ b/hw/drivers/lora/sx1272/pkg.yml
@@ -0,0 +1,32 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/drivers/lora/sx1272
+pkg.description: LoRaMac-node radio driver for the SX1272 modem.
+pkg.author: "Semtech"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+ - lora
+ - sx1272
+
+pkg.deps:
+ - "@apache-mynewt-core/kernel/os"
+
+pkg.apis:
+ - lora_node_driver
diff --git a/hw/drivers/lora/sx1272/src/sx1272-board.c b/hw/drivers/lora/sx1272/src/sx1272-board.c
new file mode 100644
index 000000000..af8c37867
--- /dev/null
+++ b/hw/drivers/lora/sx1272/src/sx1272-board.c
@@ -0,0 +1,278 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: SX1272 driver specific target board functions implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#include <assert.h>
+#include "os/os.h"
+#include "hal/hal_spi.h"
+#include "hal/hal_gpio.h"
+#include "bsp/bsp.h"
+#include "radio/radio.h"
+#include "sx1272.h"
+#include "sx1272-board.h"
+
+#if (MYNEWT_VAL(SX1272_HAS_ANT_SW) && MYNEWT_VAL(SX1272_HAS_COMP_ANT_SW))
+#error "Cannot have both SX1272_HAS_ANT_SW and SX1272_HAS_COMP_ANT_SW set true"
+#endif
+
+#if MYNEWT_VAL(SX1272_HAS_ANT_SW)
+#error "Currently not supported"
+#endif
+
+/*!
+ * Flag used to set the RF switch control pins in low power mode when the radio is not active.
+ */
+#if (MYNEWT_VAL(SX1272_HAS_ANT_SW) || MYNEWT_VAL(SX1272_HAS_COMP_ANT_SW))
+static bool RadioIsActive = false;
+#endif
+
+/*!
+ * Radio driver structure initialization
+ */
+const struct Radio_s Radio =
+{
+ SX1272Init,
+ SX1272GetStatus,
+ SX1272SetModem,
+ SX1272SetChannel,
+ SX1272IsChannelFree,
+ SX1272Random,
+ SX1272SetRxConfig,
+ SX1272SetTxConfig,
+ SX1272CheckRfFrequency,
+ SX1272GetTimeOnAir,
+ SX1272Send,
+ SX1272SetSleep,
+ SX1272SetStby,
+ SX1272SetRx,
+ SX1272StartCad,
+ SX1272SetTxContinuousWave,
+ SX1272ReadRssi,
+ SX1272Write,
+ SX1272Read,
+ SX1272WriteBuffer,
+ SX1272ReadBuffer,
+ SX1272SetMaxPayloadLength,
+ SX1272SetPublicNetwork
+};
+
+void SX1272IoInit( void )
+{
+ struct hal_spi_settings spi_settings;
+ int rc;
+
+#if MYNEWT_VAL(SX1272_HAS_ANT_SW)
+ rc = hal_gpio_init_out(SX1272_RXTX, 1);
+ assert(rc == 0);
+#endif
+
+ /*
+ * XXX: This should really be in the BSP! On the schematic the pins are
+ * labeled LORA_FEM_CTX and nLORA_FEM_CTX but here they are RXTX and N_RXTX
+ *
+ * RXTX high, N_RXTX low = RX
+ * RXTX low, N_RXTX high = TX
+ *
+ * By default, put in RX
+ */
+#if MYNEWT_VAL(SX1272_HAS_COMP_ANT_SW)
+ rc = hal_gpio_init_out(SX1272_RXTX, 1);
+ assert(rc == 0);
+ rc = hal_gpio_init_out(SX1272_N_RXTX, 0);
+ assert(rc == 0);
+#endif
+
+ rc = hal_gpio_init_out(RADIO_NSS, 1);
+ assert(rc == 0);
+
+ hal_spi_disable(RADIO_SPI_IDX);
+
+ spi_settings.data_order = HAL_SPI_MSB_FIRST;
+ spi_settings.data_mode = HAL_SPI_MODE0;
+ spi_settings.baudrate = MYNEWT_VAL(SX1272_SPI_BAUDRATE);
+ spi_settings.word_size = HAL_SPI_WORD_SIZE_8BIT;
+
+ rc = hal_spi_config(RADIO_SPI_IDX, &spi_settings);
+ assert(rc == 0);
+
+ rc = hal_spi_enable(RADIO_SPI_IDX);
+ assert(rc == 0);
+}
+
+void SX1272IoIrqInit( DioIrqHandler **irqHandlers )
+{
+ int rc;
+
+ rc = hal_gpio_irq_init(SX1272_DIO0, irqHandlers[0], NULL,
+ HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+ assert(rc == 0);
+ hal_gpio_irq_enable(SX1272_DIO0);
+
+ rc = hal_gpio_irq_init(SX1272_DIO1, irqHandlers[1], NULL,
+ HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+ assert(rc == 0);
+ hal_gpio_irq_enable(SX1272_DIO1);
+
+ rc = hal_gpio_irq_init(SX1272_DIO2, irqHandlers[2], NULL,
+ HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+ assert(rc == 0);
+ hal_gpio_irq_enable(SX1272_DIO2);
+
+ rc = hal_gpio_irq_init(SX1272_DIO3, irqHandlers[3], NULL,
+ HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+ assert(rc == 0);
+ hal_gpio_irq_enable(SX1272_DIO3);
+
+ rc = hal_gpio_irq_init(SX1272_DIO4, irqHandlers[4], NULL,
+ HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+ assert(rc == 0);
+ hal_gpio_irq_enable(SX1272_DIO4);
+}
+
+void SX1272IoDeInit( void )
+{
+ hal_gpio_irq_release(SX1272_DIO0);
+ hal_gpio_irq_release(SX1272_DIO1);
+ hal_gpio_irq_release(SX1272_DIO2);
+ hal_gpio_irq_release(SX1272_DIO3);
+ hal_gpio_irq_release(SX1272_DIO4);
+}
+
+void SX1272SetRfTxPower( int8_t power )
+{
+ uint8_t paConfig = 0;
+ uint8_t paDac = 0;
+
+ paConfig = SX1272Read( REG_PACONFIG );
+ paDac = SX1272Read( REG_PADAC );
+
+ paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | SX1272GetPaSelect( SX1272.Settings.Channel );
+
+ 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 & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
+ }
+ else
+ {
+ if( power < 2 )
+ {
+ power = 2;
+ }
+ if( power > 17 )
+ {
+ power = 17;
+ }
+ paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
+ }
+ }
+ else
+ {
+ if( power < -1 )
+ {
+ power = -1;
+ }
+ if( power > 14 )
+ {
+ power = 14;
+ }
+ paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
+ }
+ SX1272Write( REG_PACONFIG, paConfig );
+ SX1272Write( REG_PADAC, paDac );
+}
+
+uint8_t SX1272GetPaSelect( uint32_t channel )
+{
+ return RF_PACONFIG_PASELECT_PABOOST;
+}
+
+#if (MYNEWT_VAL(SX1272_HAS_ANT_SW) || MYNEWT_VAL(SX1272_HAS_COMP_ANT_SW))
+void SX1272SetAntSwLowPower( bool status )
+{
+ if( RadioIsActive != status )
+ {
+ RadioIsActive = status;
+
+ if( status == false )
+ {
+ SX1272AntSwInit( );
+ }
+ else
+ {
+ SX1272AntSwDeInit( );
+ }
+ }
+}
+
+void SX1272AntSwInit( void )
+{
+ /*
+ * XXX: consider doing this to save power. Currently the gpio are
+ * set to rx mode automatically in the IO init function.
+ */
+}
+
+void SX1272AntSwDeInit( void )
+{
+ /*
+ * XXX: consider doing this to save power. Currently the gpio are
+ * set to rx mode automatically in the IO init function.
+ */
+}
+
+void SX1272SetAntSw( uint8_t opMode )
+{
+ os_sr_t sr;
+
+ OS_ENTER_CRITICAL(sr);
+ switch( opMode )
+ {
+ case RFLR_OPMODE_TRANSMITTER:
+ hal_gpio_write(SX1272_RXTX, 0);
+ hal_gpio_write(SX1272_N_RXTX, 1);
+ break;
+ case RFLR_OPMODE_RECEIVER:
+ case RFLR_OPMODE_RECEIVER_SINGLE:
+ case RFLR_OPMODE_CAD:
+ default:
+ hal_gpio_write(SX1272_RXTX, 1);
+ hal_gpio_write(SX1272_N_RXTX, 0);
+ break;
+ }
+ OS_EXIT_CRITICAL(sr);
+}
+#endif
+
+bool SX1272CheckRfFrequency( uint32_t frequency )
+{
+ // Implement check. Currently all frequencies are supported
+ return true;
+}
diff --git a/hw/drivers/lora/sx1272/src/sx1272-board.h b/hw/drivers/lora/sx1272/src/sx1272-board.h
new file mode 100644
index 000000000..a4110e948
--- /dev/null
+++ b/hw/drivers/lora/sx1272/src/sx1272-board.h
@@ -0,0 +1,127 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: SX1272 driver specific target board functions implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __SX1272_ARCH_H__
+#define __SX1272_ARCH_H__
+
+#define RADIO_SPI_IDX MYNEWT_VAL(SX1272_SPI_IDX)
+
+#if RADIO_SPI_IDX == 0
+#define RADIO_NSS MYNEWT_VAL(SX1272_SPI_CS_PIN)
+#else
+#error "Invalid SX1272_SPI_IDX value"
+#endif
+
+/*!
+ * \brief Radio hardware registers initialization definition
+ *
+ * \remark Can be automatically generated by the SX1272 GUI (not yet implemented)
+ */
+#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 },\
+} \
+
+/*!
+ * \brief Initializes the radio I/Os pins interface
+ */
+void SX1272IoInit( void );
+
+/*!
+ * \brief Initializes DIO IRQ handlers
+ *
+ * \param [IN] irqHandlers Array containing the IRQ callback functions
+ */
+void SX1272IoIrqInit( DioIrqHandler **irqHandlers );
+
+/*!
+ * \brief De-initializes the radio I/Os pins interface.
+ *
+ * \remark Useful when going in MCU low power modes
+ */
+void SX1272IoDeInit( void );
+
+/*!
+ * \brief Sets the radio output power.
+ *
+ * \param [IN] power Sets the RF output power
+ */
+void SX1272SetRfTxPower( int8_t power );
+
+/*!
+ * \brief Gets the board PA selection configuration
+ *
+ * \param [IN] channel Channel frequency in Hz
+ * \retval PaSelect RegPaConfig PaSelect value
+ */
+uint8_t SX1272GetPaSelect( uint32_t channel );
+
+/*!
+ * \brief Set the RF Switch I/Os pins in Low Power mode
+ *
+ * \param [IN] status enable or disable
+ */
+void SX1272SetAntSwLowPower( bool status );
+
+/*!
+ * \brief Initializes the RF Switch I/Os pins interface
+ */
+void SX1272AntSwInit( void );
+
+/*!
+ * \brief De-initializes the RF Switch I/Os pins interface
+ *
+ * \remark Needed to decrease the power consumption in MCU low power modes
+ */
+void SX1272AntSwDeInit( void );
+
+/*!
+ * \brief Controls the antenna switch if necessary.
+ *
+ * \remark see errata note
+ *
+ * \param [IN] opMode Current radio operating mode
+ */
+void SX1272SetAntSw( uint8_t opMode );
+
+/*!
+ * \brief Checks if the given RF frequency is supported by the hardware
+ *
+ * \param [IN] frequency RF frequency to be checked
+ * \retval isSupported [true: supported, false: unsupported]
+ */
+bool SX1272CheckRfFrequency( uint32_t frequency );
+
+/*!
+ * Radio hardware and global parameters
+ */
+extern SX1272_t SX1272;
+
+#endif // __SX1272_ARCH_H__
diff --git a/hw/drivers/lora/sx1272/src/sx1272.c b/hw/drivers/lora/sx1272/src/sx1272.c
new file mode 100644
index 000000000..2c6074c59
--- /dev/null
+++ b/hw/drivers/lora/sx1272/src/sx1272.c
@@ -0,0 +1,1660 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: Generic SX1272 driver implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#include <math.h>
+#include <string.h>
+#include "sysinit/sysinit.h"
+#include "syscfg/syscfg.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_spi.h"
+#include "hal/hal_timer.h"
+#include "bsp/bsp.h"
+#include "os/os.h"
+#include "radio/radio.h"
+#include "sx1272.h"
+#include "sx1272-board.h"
+
+#if MYNEWT_VAL(LORA_MAC_TIMER_NUM) == -1
+#error "Must define a Lora MAC timer number"
+#else
+#define SX1272_TIMER_NUM MYNEWT_VAL(LORA_MAC_TIMER_NUM)
+#endif
+
+/*
+ * Local types definition
+ */
+
+/*!
+ * Radio registers definition
+ */
+typedef struct
+{
+ RadioModems_t Modem;
+ uint8_t Addr;
+ uint8_t Value;
+}RadioRegisters_t;
+
+/*!
+ * FSK bandwidth definition
+ */
+typedef struct
+{
+ uint32_t bandwidth;
+ uint8_t RegValue;
+}FskBandwidth_t;
+
+
+/*
+ * Private functions prototypes
+ */
+
+
+/*!
+ * \brief Resets the SX1272
+ */
+void SX1272Reset( void );
+
+/*!
+ * \brief Sets the SX1272 in transmission mode for the given time
+ * \param [IN] timeout Transmission timeout [ms] [0: continuous, others timeout]
+ */
+void SX1272SetTx( uint32_t timeout );
+
+/*!
+ * \brief Writes the buffer contents to the SX1272 FIFO
+ *
+ * \param [IN] buffer Buffer containing data to be put on the FIFO.
+ * \param [IN] size Number of bytes to be written to the FIFO
+ */
+void SX1272WriteFifo( uint8_t *buffer, uint8_t size );
+
+/*!
+ * \brief Reads the contents of the SX1272 FIFO
+ *
+ * \param [OUT] buffer Buffer where to copy the FIFO read data.
+ * \param [IN] size Number of bytes to be read from the FIFO
+ */
+void SX1272ReadFifo( uint8_t *buffer, uint8_t size );
+
+/*!
+ * \brief Sets the SX1272 operating mode
+ *
+ * \param [IN] opMode New operating mode
+ */
+void SX1272SetOpMode( uint8_t opMode );
+
+/*
+ * SX1272 DIO IRQ callback functions prototype
+ */
+
+/*!
+ * \brief DIO 0 IRQ callback
+ */
+void SX1272OnDio0Irq(void *unused);
+
+/*!
+ * \brief DIO 1 IRQ callback
+ */
+void SX1272OnDio1Irq(void *unused);
+
+/*!
+ * \brief DIO 2 IRQ callback
+ */
+void SX1272OnDio2Irq(void *unused);
+
+/*!
+ * \brief DIO 3 IRQ callback
+ */
+void SX1272OnDio3Irq(void *unused);
+
+/*!
+ * \brief DIO 4 IRQ callback
+ */
+void SX1272OnDio4Irq(void *unused);
+
+/*!
+ * \brief DIO 5 IRQ callback
+ */
+void SX1272OnDio5Irq(void *unused);
+
+/*!
+ * \brief Tx & Rx timeout timer callback
+ */
+void SX1272OnTimeoutIrq(void *unused);
+
+/*
+ * Private global constants
+ */
+
+/*!
+ * Radio hardware registers initialization
+ *
+ * \remark RADIO_INIT_REGISTERS_VALUE is defined in sx1272-board.h file
+ */
+const RadioRegisters_t RadioRegsInit[] = RADIO_INIT_REGISTERS_VALUE;
+
+/*!
+ * Constant values need to compute the RSSI value
+ */
+#define RSSI_OFFSET -139
+
+/*!
+ * Precomputed FSK bandwidth registers values
+ */
+const FskBandwidth_t FskBandwidths[] =
+{
+ { 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
+};
+
+/*
+ * Private global variables
+ */
+
+/*!
+ * Radio callbacks variable
+ */
+static RadioEvents_t *RadioEvents;
+
+/*!
+ * Reception buffer
+ */
+static uint8_t RxTxBuffer[RX_BUFFER_SIZE];
+
+/*
+ * Public global variables
+ */
+
+/*!
+ * Radio hardware and global parameters
+ */
+SX1272_t SX1272;
+
+/*!
+ * Hardware DIO IRQ callback initialization
+ */
+DioIrqHandler *DioIrq[] = { SX1272OnDio0Irq, SX1272OnDio1Irq,
+ SX1272OnDio2Irq, SX1272OnDio3Irq,
+ SX1272OnDio4Irq, NULL };
+
+/*!
+ * Tx and Rx timers
+ */
+struct hal_timer TxTimeoutTimer;
+struct hal_timer RxTimeoutTimer;
+struct hal_timer RxTimeoutSyncWord;
+
+double
+ceil(double d)
+{
+ int64_t i;
+
+ i = d;
+ if (d == i) {
+ return i;
+ }
+ return i + 1;
+}
+
+double
+floor(double d)
+{
+ return (int64_t)d;
+}
+
+double
+round(double d)
+{
+ return (int64_t)(d + 0.5);
+}
+
+/*
+ * Radio driver functions implementation
+ */
+
+void SX1272Init( RadioEvents_t *events )
+{
+ uint8_t i;
+
+ RadioEvents = events;
+
+ // Initialize driver timeout timers
+ hal_timer_set_cb(SX1272_TIMER_NUM, &TxTimeoutTimer, SX1272OnTimeoutIrq, NULL);
+ hal_timer_set_cb(SX1272_TIMER_NUM, &RxTimeoutTimer, SX1272OnTimeoutIrq, NULL);
+ hal_timer_set_cb(SX1272_TIMER_NUM, &RxTimeoutSyncWord, SX1272OnTimeoutIrq, NULL);
+
+ SX1272Reset( );
+
+ SX1272SetOpMode( RF_OPMODE_SLEEP );
+
+ SX1272IoIrqInit( DioIrq );
+
+ for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
+ {
+ SX1272SetModem( RadioRegsInit[i].Modem );
+ SX1272Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
+ }
+
+ SX1272SetModem( MODEM_FSK );
+
+ SX1272.Settings.State = RF_IDLE;
+}
+
+RadioState_t SX1272GetStatus( void )
+{
+ return SX1272.Settings.State;
+}
+
+void SX1272SetChannel( uint32_t freq )
+{
+ SX1272.Settings.Channel = freq;
+ freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
+ SX1272Write( REG_FRFMSB, ( uint8_t )( ( freq >> 16 ) & 0xFF ) );
+ SX1272Write( REG_FRFMID, ( uint8_t )( ( freq >> 8 ) & 0xFF ) );
+ SX1272Write( REG_FRFLSB, ( uint8_t )( freq & 0xFF ) );
+}
+
+bool SX1272IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh )
+{
+ int16_t rssi = 0;
+
+ SX1272SetModem( modem );
+
+ SX1272SetChannel( freq );
+
+ SX1272SetOpMode( RF_OPMODE_RECEIVER );
+
+ /* Delay for 1 msec */
+ hal_timer_delay(SX1272_TIMER_NUM, 1000);
+
+ rssi = SX1272ReadRssi( modem );
+
+ SX1272SetSleep( );
+
+ if( rssi > rssiThresh )
+ {
+ return false;
+ }
+ return true;
+}
+
+uint32_t SX1272Random( void )
+{
+ uint8_t i;
+ uint32_t rnd = 0;
+
+ /*
+ * Radio setup for random number generation
+ */
+ // Set LoRa modem ON
+ SX1272SetModem( MODEM_LORA );
+
+ // Disable LoRa modem interrupts
+ SX1272Write( 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
+ SX1272SetOpMode( RF_OPMODE_RECEIVER );
+
+ for( i = 0; i < 32; i++ )
+ {
+ hal_timer_delay(SX1272_TIMER_NUM, 1000);
+ // Unfiltered RSSI value reading. Only takes the LSB value
+ rnd |= ( ( uint32_t )SX1272Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) << i;
+ }
+
+ SX1272SetSleep( );
+
+ return rnd;
+}
+
+/*!
+ * Returns the known FSK bandwidth registers value
+ *
+ * \param [IN] bandwidth Bandwidth value in Hz
+ * \retval regValue Bandwidth register value.
+ */
+static uint8_t GetFskBandwidthRegValue( uint32_t bandwidth )
+{
+ uint8_t i;
+
+ for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ )
+ {
+ if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) )
+ {
+ return FskBandwidths[i].RegValue;
+ }
+ }
+ // ERROR: Value not found
+ while( 1 );
+}
+
+void SX1272SetRxConfig( RadioModems_t modem, uint32_t bandwidth,
+ uint32_t datarate, uint8_t coderate,
+ uint32_t bandwidthAfc, uint16_t preambleLen,
+ uint16_t symbTimeout, bool fixLen,
+ uint8_t payloadLen,
+ bool crcOn, bool freqHopOn, uint8_t hopPeriod,
+ bool iqInverted, bool rxContinuous )
+{
+ SX1272SetModem( modem );
+
+ switch( modem )
+ {
+ case MODEM_FSK:
+ {
+ SX1272.Settings.Fsk.Bandwidth = bandwidth;
+ SX1272.Settings.Fsk.Datarate = datarate;
+ SX1272.Settings.Fsk.BandwidthAfc = bandwidthAfc;
+ SX1272.Settings.Fsk.FixLen = fixLen;
+ SX1272.Settings.Fsk.PayloadLen = payloadLen;
+ SX1272.Settings.Fsk.CrcOn = crcOn;
+ SX1272.Settings.Fsk.IqInverted = iqInverted;
+ SX1272.Settings.Fsk.RxContinuous = rxContinuous;
+ SX1272.Settings.Fsk.PreambleLen = preambleLen;
+ SX1272.Settings.Fsk.RxSingleTimeout = symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1e3;
+
+ datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
+ SX1272Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
+ SX1272Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
+
+ SX1272Write( REG_RXBW, GetFskBandwidthRegValue( bandwidth ) );
+ SX1272Write( REG_AFCBW, GetFskBandwidthRegValue( bandwidthAfc ) );
+
+ SX1272Write( REG_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
+ SX1272Write( REG_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
+
+ if( fixLen == 1 )
+ {
+ SX1272Write( REG_PAYLOADLENGTH, payloadLen );
+ }
+ else
+ {
+ SX1272Write( REG_PAYLOADLENGTH, 0xFF ); // Set payload length to the maximum
+ }
+
+ SX1272Write( REG_PACKETCONFIG1,
+ ( SX1272Read( REG_PACKETCONFIG1 ) &
+ RF_PACKETCONFIG1_CRC_MASK &
+ RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
+ ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
+ ( crcOn << 4 ) );
+ SX1272Write( REG_PACKETCONFIG2, ( SX1272Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
+ }
+ break;
+ case MODEM_LORA:
+ {
+ SX1272.Settings.LoRa.Bandwidth = bandwidth;
+ SX1272.Settings.LoRa.Datarate = datarate;
+ SX1272.Settings.LoRa.Coderate = coderate;
+ SX1272.Settings.LoRa.PreambleLen = preambleLen;
+ SX1272.Settings.LoRa.FixLen = fixLen;
+ SX1272.Settings.LoRa.PayloadLen = payloadLen;
+ SX1272.Settings.LoRa.CrcOn = crcOn;
+ SX1272.Settings.LoRa.FreqHopOn = freqHopOn;
+ SX1272.Settings.LoRa.HopPeriod = hopPeriod;
+ SX1272.Settings.LoRa.IqInverted = iqInverted;
+ SX1272.Settings.LoRa.RxContinuous = rxContinuous;
+
+ if( datarate > 12 )
+ {
+ datarate = 12;
+ }
+ else if( datarate < 6 )
+ {
+ datarate = 6;
+ }
+
+ if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
+ ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
+ {
+ SX1272.Settings.LoRa.LowDatarateOptimize = 0x01;
+ }
+ else
+ {
+ SX1272.Settings.LoRa.LowDatarateOptimize = 0x00;
+ }
+
+ SX1272Write( REG_LR_MODEMCONFIG1,
+ ( SX1272Read( 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 ) |
+ ( fixLen << 2 ) | ( crcOn << 1 ) |
+ SX1272.Settings.LoRa.LowDatarateOptimize );
+
+ SX1272Write( REG_LR_MODEMCONFIG2,
+ ( SX1272Read( REG_LR_MODEMCONFIG2 ) &
+ RFLR_MODEMCONFIG2_SF_MASK &
+ RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) |
+ ( datarate << 4 ) |
+ ( ( symbTimeout >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) );
+
+ SX1272Write( REG_LR_SYMBTIMEOUTLSB, ( uint8_t )( symbTimeout & 0xFF ) );
+
+ SX1272Write( REG_LR_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
+ SX1272Write( REG_LR_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
+
+ if( fixLen == 1 )
+ {
+ SX1272Write( REG_LR_PAYLOADLENGTH, payloadLen );
+ }
+
+ if( SX1272.Settings.LoRa.FreqHopOn == true )
+ {
+ SX1272Write( REG_LR_PLLHOP, ( SX1272Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
+ SX1272Write( REG_LR_HOPPERIOD, SX1272.Settings.LoRa.HopPeriod );
+ }
+
+ if( datarate == 6 )
+ {
+ SX1272Write( REG_LR_DETECTOPTIMIZE,
+ ( SX1272Read( REG_LR_DETECTOPTIMIZE ) &
+ RFLR_DETECTIONOPTIMIZE_MASK ) |
+ RFLR_DETECTIONOPTIMIZE_SF6 );
+ SX1272Write( REG_LR_DETECTIONTHRESHOLD,
+ RFLR_DETECTIONTHRESH_SF6 );
+ }
+ else
+ {
+ SX1272Write( REG_LR_DETECTOPTIMIZE,
+ ( SX1272Read( REG_LR_DETECTOPTIMIZE ) &
+ RFLR_DETECTIONOPTIMIZE_MASK ) |
+ RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
+ SX1272Write( REG_LR_DETECTIONTHRESHOLD,
+ RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
+ }
+ }
+ break;
+ }
+}
+
+void SX1272SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
+ uint32_t bandwidth, uint32_t datarate,
+ uint8_t coderate, uint16_t preambleLen,
+ bool fixLen, bool crcOn, bool freqHopOn,
+ uint8_t hopPeriod, bool iqInverted, uint32_t timeout )
+{
+ SX1272SetModem( modem );
+
+ SX1272SetRfTxPower( power );
+
+ switch( modem )
+ {
+ case MODEM_FSK:
+ {
+ SX1272.Settings.Fsk.Power = power;
+ SX1272.Settings.Fsk.Fdev = fdev;
+ SX1272.Settings.Fsk.Bandwidth = bandwidth;
+ SX1272.Settings.Fsk.Datarate = datarate;
+ SX1272.Settings.Fsk.PreambleLen = preambleLen;
+ SX1272.Settings.Fsk.FixLen = fixLen;
+ SX1272.Settings.Fsk.CrcOn = crcOn;
+ SX1272.Settings.Fsk.IqInverted = iqInverted;
+ SX1272.Settings.Fsk.TxTimeout = timeout;
+
+ fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
+ SX1272Write( REG_FDEVMSB, ( uint8_t )( fdev >> 8 ) );
+ SX1272Write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) );
+
+ datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
+ SX1272Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
+ SX1272Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
+
+ SX1272Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
+ SX1272Write( REG_PREAMBLELSB, preambleLen & 0xFF );
+
+ SX1272Write( REG_PACKETCONFIG1,
+ ( SX1272Read( REG_PACKETCONFIG1 ) &
+ RF_PACKETCONFIG1_CRC_MASK &
+ RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
+ ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
+ ( crcOn << 4 ) );
+ SX1272Write( REG_PACKETCONFIG2, ( SX1272Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
+ }
+ break;
+ case MODEM_LORA:
+ {
+ SX1272.Settings.LoRa.Power = power;
+ SX1272.Settings.LoRa.Bandwidth = bandwidth;
+ SX1272.Settings.LoRa.Datarate = datarate;
+ SX1272.Settings.LoRa.Coderate = coderate;
+ SX1272.Settings.LoRa.PreambleLen = preambleLen;
+ SX1272.Settings.LoRa.FixLen = fixLen;
+ SX1272.Settings.LoRa.FreqHopOn = freqHopOn;
+ SX1272.Settings.LoRa.HopPeriod = hopPeriod;
+ SX1272.Settings.LoRa.CrcOn = crcOn;
+ SX1272.Settings.LoRa.IqInverted = iqInverted;
+ SX1272.Settings.LoRa.TxTimeout = timeout;
+
+ if( datarate > 12 )
+ {
+ datarate = 12;
+ }
+ else if( datarate < 6 )
+ {
+ datarate = 6;
+ }
+ if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
+ ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
+ {
+ SX1272.Settings.LoRa.LowDatarateOptimize = 0x01;
+ }
+ else
+ {
+ SX1272.Settings.LoRa.LowDatarateOptimize = 0x00;
+ }
+
+ if( SX1272.Settings.LoRa.FreqHopOn == true )
+ {
+ SX1272Write( REG_LR_PLLHOP, ( SX1272Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
+ SX1272Write( REG_LR_HOPPERIOD, SX1272.Settings.LoRa.HopPeriod );
+ }
+
+ SX1272Write( REG_LR_MODEMCONFIG1,
+ ( SX1272Read( 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 ) |
+ ( fixLen << 2 ) | ( crcOn << 1 ) |
+ SX1272.Settings.LoRa.LowDatarateOptimize );
+
+ SX1272Write( REG_LR_MODEMCONFIG2,
+ ( SX1272Read( REG_LR_MODEMCONFIG2 ) &
+ RFLR_MODEMCONFIG2_SF_MASK ) |
+ ( datarate << 4 ) );
+
+
+ SX1272Write( REG_LR_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
+ SX1272Write( REG_LR_PREAMBLELSB, preambleLen & 0xFF );
+
+ if( datarate == 6 )
+ {
+ SX1272Write( REG_LR_DETECTOPTIMIZE,
+ ( SX1272Read( REG_LR_DETECTOPTIMIZE ) &
+ RFLR_DETECTIONOPTIMIZE_MASK ) |
+ RFLR_DETECTIONOPTIMIZE_SF6 );
+ SX1272Write( REG_LR_DETECTIONTHRESHOLD,
+ RFLR_DETECTIONTHRESH_SF6 );
+ }
+ else
+ {
+ SX1272Write( REG_LR_DETECTOPTIMIZE,
+ ( SX1272Read( REG_LR_DETECTOPTIMIZE ) &
+ RFLR_DETECTIONOPTIMIZE_MASK ) |
+ RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
+ SX1272Write( REG_LR_DETECTIONTHRESHOLD,
+ RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
+ }
+ }
+ break;
+ }
+}
+
+uint32_t SX1272GetTimeOnAir( RadioModems_t modem, uint8_t pktLen )
+{
+ uint32_t airTime = 0;
+
+ switch( modem )
+ {
+ case MODEM_FSK:
+ {
+ airTime = round( ( 8 * ( SX1272.Settings.Fsk.PreambleLen +
+ ( ( SX1272Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
+ ( ( SX1272.Settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
+ ( ( ( SX1272Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
+ pktLen +
+ ( ( SX1272.Settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) /
+ SX1272.Settings.Fsk.Datarate ) * 1e3 );
+ }
+ break;
+ case MODEM_LORA:
+ {
+ double bw = 0.0;
+ switch( SX1272.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 << SX1272.Settings.LoRa.Datarate );
+ double ts = 1 / rs;
+ // time of preamble
+ double tPreamble = ( SX1272.Settings.LoRa.PreambleLen + 4.25 ) * ts;
+ // Symbol length of payload and time
+ double tmp = ceil( ( 8 * pktLen - 4 * SX1272.Settings.LoRa.Datarate +
+ 28 + 16 * SX1272.Settings.LoRa.CrcOn -
+ ( SX1272.Settings.LoRa.FixLen ? 20 : 0 ) ) /
+ ( double )( 4 * ( SX1272.Settings.LoRa.Datarate -
+ ( ( SX1272.Settings.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
+ ( SX1272.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;
+}
+
+void SX1272Send( uint8_t *buffer, uint8_t size )
+{
+ uint32_t txTimeout = 0;
+
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ {
+ SX1272.Settings.FskPacketHandler.NbBytes = 0;
+ SX1272.Settings.FskPacketHandler.Size = size;
+
+ if( SX1272.Settings.Fsk.FixLen == false )
+ {
+ SX1272WriteFifo( ( uint8_t* )&size, 1 );
+ }
+ else
+ {
+ SX1272Write( REG_PAYLOADLENGTH, size );
+ }
+
+ if( ( size > 0 ) && ( size <= 64 ) )
+ {
+ SX1272.Settings.FskPacketHandler.ChunkSize = size;
+ }
+ else
+ {
+ memcpy( RxTxBuffer, buffer, size );
+ SX1272.Settings.FskPacketHandler.ChunkSize = 32;
+ }
+
+ // Write payload buffer
+ SX1272WriteFifo( buffer, SX1272.Settings.FskPacketHandler.ChunkSize );
+ SX1272.Settings.FskPacketHandler.NbBytes += SX1272.Settings.FskPacketHandler.ChunkSize;
+ txTimeout = SX1272.Settings.Fsk.TxTimeout;
+ }
+ break;
+ case MODEM_LORA:
+ {
+ if( SX1272.Settings.LoRa.IqInverted == true )
+ {
+ SX1272Write( REG_LR_INVERTIQ, ( ( SX1272Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) );
+ SX1272Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
+ }
+ else
+ {
+ SX1272Write( REG_LR_INVERTIQ, ( ( SX1272Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
+ SX1272Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
+ }
+
+ SX1272.Settings.LoRaPacketHandler.Size = size;
+
+ // Initializes the payload size
+ SX1272Write( REG_LR_PAYLOADLENGTH, size );
+
+ // Full buffer used for Tx
+ SX1272Write( REG_LR_FIFOTXBASEADDR, 0 );
+ SX1272Write( REG_LR_FIFOADDRPTR, 0 );
+
+ // FIFO operations can not take place in Sleep mode
+ if( ( SX1272Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP )
+ {
+ SX1272SetStby( );
+ hal_timer_delay(SX1272_TIMER_NUM, 1000);
+ }
+ // Write payload buffer
+ SX1272WriteFifo( buffer, size );
+ txTimeout = SX1272.Settings.LoRa.TxTimeout;
+ }
+ break;
+ }
+
+ SX1272SetTx( txTimeout );
+}
+
+void SX1272SetSleep( void )
+{
+ hal_timer_stop(&RxTimeoutTimer);
+ hal_timer_stop(&TxTimeoutTimer);
+
+ SX1272SetOpMode( RF_OPMODE_SLEEP );
+ SX1272.Settings.State = RF_IDLE;
+}
+
+void SX1272SetStby( void )
+{
+ hal_timer_stop(&RxTimeoutTimer);
+ hal_timer_stop(&TxTimeoutTimer);
+
+ SX1272SetOpMode( RF_OPMODE_STANDBY );
+ SX1272.Settings.State = RF_IDLE;
+}
+
+void SX1272SetRx( uint32_t timeout )
+{
+ bool rxContinuous = false;
+
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ {
+ rxContinuous = SX1272.Settings.Fsk.RxContinuous;
+
+ // DIO0=PayloadReady
+ // DIO1=FifoLevel
+ // DIO2=SyncAddr
+ // DIO3=FifoEmpty
+ // DIO4=Preamble
+ // DIO5=ModeReady
+ SX1272Write( REG_DIOMAPPING1, ( SX1272Read( 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 );
+
+ SX1272Write( REG_DIOMAPPING2, ( SX1272Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
+ RF_DIOMAPPING2_MAP_MASK ) |
+ RF_DIOMAPPING2_DIO4_11 |
+ RF_DIOMAPPING2_MAP_PREAMBLEDETECT );
+
+ SX1272.Settings.FskPacketHandler.FifoThresh = SX1272Read( REG_FIFOTHRESH ) & 0x3F;
+
+ SX1272Write( REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT );
+
+ SX1272.Settings.FskPacketHandler.PreambleDetected = false;
+ SX1272.Settings.FskPacketHandler.SyncWordDetected = false;
+ SX1272.Settings.FskPacketHandler.NbBytes = 0;
+ SX1272.Settings.FskPacketHandler.Size = 0;
+ }
+ break;
+ case MODEM_LORA:
+ {
+ if( SX1272.Settings.LoRa.IqInverted == true )
+ {
+ SX1272Write( REG_LR_INVERTIQ, ( ( SX1272Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF ) );
+ SX1272Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
+ }
+ else
+ {
+ SX1272Write( REG_LR_INVERTIQ, ( ( SX1272Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
+ SX1272Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
+ }
+
+ rxContinuous = SX1272.Settings.LoRa.RxContinuous;
+
+ if( SX1272.Settings.LoRa.FreqHopOn == true )
+ {
+ SX1272Write( 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 );
+
+ // DIO0=RxDone, DIO2=FhssChangeChannel
+ SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00 );
+ }
+ else
+ {
+ SX1272Write( 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 );
+
+ // DIO0=RxDone
+ SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
+ }
+ SX1272Write( REG_LR_FIFORXBASEADDR, 0 );
+ SX1272Write( REG_LR_FIFOADDRPTR, 0 );
+ }
+ break;
+ }
+
+ memset( RxTxBuffer, 0, ( size_t )RX_BUFFER_SIZE );
+
+ SX1272.Settings.State = RF_RX_RUNNING;
+ if( timeout != 0 )
+ {
+ hal_timer_stop(&RxTimeoutTimer);
+ hal_timer_start(&RxTimeoutTimer, timeout * 1000);
+ }
+
+ if( SX1272.Settings.Modem == MODEM_FSK )
+ {
+ SX1272SetOpMode( RF_OPMODE_RECEIVER );
+
+ if( rxContinuous == false )
+ {
+ hal_timer_stop(&RxTimeoutSyncWord);
+ hal_timer_start(&RxTimeoutSyncWord,
+ SX1272.Settings.Fsk.RxSingleTimeout * 1000);
+
+ }
+ }
+ else
+ {
+ if( rxContinuous == true )
+ {
+ SX1272SetOpMode( RFLR_OPMODE_RECEIVER );
+ }
+ else
+ {
+ SX1272SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
+ }
+ }
+}
+
+void SX1272SetTx( uint32_t timeout )
+{
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ {
+ // DIO0=PacketSent
+ // DIO1=FifoEmpty
+ // DIO2=FifoFull
+ // DIO3=FifoEmpty
+ // DIO4=LowBat
+ // DIO5=ModeReady
+ SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
+ RF_DIOMAPPING1_DIO1_MASK &
+ RF_DIOMAPPING1_DIO2_MASK ) |
+ RF_DIOMAPPING1_DIO1_01 );
+
+ SX1272Write( REG_DIOMAPPING2, ( SX1272Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
+ RF_DIOMAPPING2_MAP_MASK ) );
+ SX1272.Settings.FskPacketHandler.FifoThresh = SX1272Read( REG_FIFOTHRESH ) & 0x3F;
+ }
+ break;
+ case MODEM_LORA:
+ {
+ if( SX1272.Settings.LoRa.FreqHopOn == true )
+ {
+ SX1272Write( 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 );
+
+ // DIO0=TxDone, DIO2=FhssChangeChannel
+ SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_00 );
+ }
+ else
+ {
+ SX1272Write( 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 );
+
+ // DIO0=TxDone
+ SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
+ }
+ }
+ break;
+ }
+
+ SX1272.Settings.State = RF_TX_RUNNING;
+ hal_timer_stop(&TxTimeoutTimer);
+ hal_timer_start(&TxTimeoutTimer, timeout * 1000);
+ SX1272SetOpMode( RF_OPMODE_TRANSMITTER );
+}
+
+void SX1272StartCad( void )
+{
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ {
+
+ }
+ break;
+ case MODEM_LORA:
+ {
+ SX1272Write( 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
+ );
+
+ // DIO3=CADDone
+ SX1272Write( REG_DIOMAPPING1, ( SX1272Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO3_MASK ) | RFLR_DIOMAPPING1_DIO3_00 );
+
+ SX1272.Settings.State = RF_CAD;
+ SX1272SetOpMode( RFLR_OPMODE_CAD );
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SX1272SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
+{
+ uint32_t timeout = ( uint32_t )( time * 1e3 );
+
+ SX1272SetChannel( freq );
+
+ SX1272SetTxConfig( MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, timeout );
+
+ SX1272Write( REG_PACKETCONFIG2, ( SX1272Read( REG_PACKETCONFIG2 ) & RF_PACKETCONFIG2_DATAMODE_MASK ) );
+ // Disable radio interrupts
+ SX1272Write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 );
+ SX1272Write( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 );
+
+ hal_timer_stop(&TxTimeoutTimer);
+
+ SX1272.Settings.State = RF_TX_RUNNING;
+ hal_timer_start(&TxTimeoutTimer, timeout * 1000);
+ SX1272SetOpMode( RF_OPMODE_TRANSMITTER );
+}
+
+int16_t SX1272ReadRssi( RadioModems_t modem )
+{
+ int16_t rssi = 0;
+
+ switch( modem )
+ {
+ case MODEM_FSK:
+ rssi = -( SX1272Read( REG_RSSIVALUE ) >> 1 );
+ break;
+ case MODEM_LORA:
+ rssi = RSSI_OFFSET + SX1272Read( REG_LR_RSSIVALUE );
+ break;
+ default:
+ rssi = -1;
+ break;
+ }
+ return rssi;
+}
+
+void SX1272Reset( void )
+{
+ // Set RESET pin to 0
+ hal_gpio_init_out(SX1272_NRESET, 0);
+
+ // Wait 1 ms
+ hal_timer_delay(SX1272_TIMER_NUM, 1000);
+
+ // Drive reset high
+ hal_gpio_write(SX1272_NRESET, 1);
+
+ // Wait 6 ms
+ hal_timer_delay(SX1272_TIMER_NUM, 6000);
+}
+
+void SX1272SetOpMode( uint8_t opMode )
+{
+ if( opMode == RF_OPMODE_SLEEP )
+ {
+ SX1272SetAntSwLowPower( true );
+ }
+ else
+ {
+ SX1272SetAntSwLowPower( false );
+ SX1272SetAntSw( opMode );
+ }
+ SX1272Write( REG_OPMODE, ( SX1272Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
+}
+
+void SX1272SetModem( RadioModems_t modem )
+{
+ if( ( SX1272Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_ON ) != 0 )
+ {
+ SX1272.Settings.Modem = MODEM_LORA;
+ }
+ else
+ {
+ SX1272.Settings.Modem = MODEM_FSK;
+ }
+
+ if( SX1272.Settings.Modem == modem )
+ {
+ return;
+ }
+
+ SX1272.Settings.Modem = modem;
+ switch( SX1272.Settings.Modem )
+ {
+ default:
+ case MODEM_FSK:
+ SX1272SetSleep( );
+ SX1272Write( REG_OPMODE, ( SX1272Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
+
+ SX1272Write( REG_DIOMAPPING1, 0x00 );
+ SX1272Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
+ break;
+ case MODEM_LORA:
+ SX1272SetSleep( );
+ SX1272Write( REG_OPMODE, ( SX1272Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
+
+ SX1272Write( REG_DIOMAPPING1, 0x00 );
+ SX1272Write( REG_DIOMAPPING2, 0x00 );
+ break;
+ }
+}
+
+void SX1272Write( uint8_t addr, uint8_t data )
+{
+ SX1272WriteBuffer( addr, &data, 1 );
+}
+
+uint8_t SX1272Read( uint8_t addr )
+{
+ uint8_t data;
+ SX1272ReadBuffer( addr, &data, 1 );
+ return data;
+}
+
+void SX1272WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
+{
+ uint8_t i;
+
+ hal_gpio_write(RADIO_NSS, 0);
+
+ hal_spi_tx_val(RADIO_SPI_IDX, addr | 0x80);
+ for( i = 0; i < size; i++ )
+ {
+ hal_spi_tx_val(RADIO_SPI_IDX, buffer[i]);
+ }
+
+ hal_gpio_write(RADIO_NSS, 1);
+}
+
+void SX1272ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
+{
+ uint8_t i;
+
+ hal_gpio_write(RADIO_NSS, 0);
+
+ hal_spi_tx_val(RADIO_SPI_IDX, addr | 0x80);
+ for( i = 0; i < size; i++ )
+ {
+ hal_spi_tx_val(RADIO_SPI_IDX, buffer[i]);
+ }
+
+ hal_gpio_write(RADIO_NSS, 1);
+}
+
+void SX1272WriteFifo( uint8_t *buffer, uint8_t size )
+{
+ SX1272WriteBuffer( 0, buffer, size );
+}
+
+void SX1272ReadFifo( uint8_t *buffer, uint8_t size )
+{
+ SX1272ReadBuffer( 0, buffer, size );
+}
+
+void SX1272SetMaxPayloadLength( RadioModems_t modem, uint8_t max )
+{
+ SX1272SetModem( modem );
+
+ switch( modem )
+ {
+ case MODEM_FSK:
+ if( SX1272.Settings.Fsk.FixLen == false )
+ {
+ SX1272Write( REG_PAYLOADLENGTH, max );
+ }
+ break;
+ case MODEM_LORA:
+ SX1272Write( REG_LR_PAYLOADMAXLENGTH, max );
+ break;
+ }
+}
+
+void SX1272SetPublicNetwork( bool enable )
+{
+ SX1272SetModem( MODEM_LORA );
+ SX1272.Settings.LoRa.PublicNetwork = enable;
+ if( enable == true )
+ {
+ // Change LoRa modem SyncWord
+ SX1272Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
+ }
+ else
+ {
+ // Change LoRa modem SyncWord
+ SX1272Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );
+ }
+}
+
+void SX1272OnTimeoutIrq(void *unused)
+{
+ uint8_t i;
+
+ switch( SX1272.Settings.State )
+ {
+ case RF_RX_RUNNING:
+ if( SX1272.Settings.Modem == MODEM_FSK )
+ {
+ SX1272.Settings.FskPacketHandler.PreambleDetected = false;
+ SX1272.Settings.FskPacketHandler.SyncWordDetected = false;
+ SX1272.Settings.FskPacketHandler.NbBytes = 0;
+ SX1272.Settings.FskPacketHandler.Size = 0;
+
+ // Clear Irqs
+ SX1272Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
+ RF_IRQFLAGS1_PREAMBLEDETECT |
+ RF_IRQFLAGS1_SYNCADDRESSMATCH );
+ SX1272Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
+
+ if( SX1272.Settings.Fsk.RxContinuous == true )
+ {
+ // Continuous mode restart Rx chain
+ SX1272Write( REG_RXCONFIG, SX1272Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
+ hal_timer_stop(&RxTimeoutSyncWord);
+ hal_timer_start(&RxTimeoutSyncWord,
+ SX1272.Settings.Fsk.RxSingleTimeout * 1000);
+ }
+ else
+ {
+ SX1272.Settings.State = RF_IDLE;
+ hal_timer_stop(&RxTimeoutSyncWord);
+ }
+ }
+ if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )
+ {
+ RadioEvents->RxTimeout( );
+ }
+ 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
+ // it depends on the platform design.
+ //
+ // The workaround is to put the radio in a known state. Thus, we re-initialize it.
+
+ // BEGIN WORKAROUND
+
+ // Reset the radio
+ SX1272Reset( );
+
+ // Initialize radio default values
+ SX1272SetOpMode( RF_OPMODE_SLEEP );
+
+ for(i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
+ {
+ SX1272SetModem( RadioRegsInit[i].Modem );
+ SX1272Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
+ }
+ SX1272SetModem( MODEM_FSK );
+
+ // Restore previous network type setting.
+ SX1272SetPublicNetwork( SX1272.Settings.LoRa.PublicNetwork );
+ // END WORKAROUND
+
+ SX1272.Settings.State = RF_IDLE;
+ if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) )
+ {
+ RadioEvents->TxTimeout( );
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SX1272OnDio0Irq(void *unused)
+{
+ volatile uint8_t irqFlags = 0;
+
+ switch( SX1272.Settings.State )
+ {
+ case RF_RX_RUNNING:
+ //TimerStop( &RxTimeoutTimer );
+ // RxDone interrupt
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ if( SX1272.Settings.Fsk.CrcOn == true )
+ {
+ irqFlags = SX1272Read( REG_IRQFLAGS2 );
+ if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
+ {
+ // Clear Irqs
+ SX1272Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
+ RF_IRQFLAGS1_PREAMBLEDETECT |
+ RF_IRQFLAGS1_SYNCADDRESSMATCH );
+ SX1272Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
+
+ hal_timer_stop(&RxTimeoutTimer);
+
+ if( SX1272.Settings.Fsk.RxContinuous == false )
+ {
+ hal_timer_stop( &RxTimeoutSyncWord );
+ SX1272.Settings.State = RF_IDLE;
+ }
+ else
+ {
+ // Continuous mode restart Rx chain
+ SX1272Write( REG_RXCONFIG, SX1272Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
+ hal_timer_stop(&RxTimeoutSyncWord);
+ hal_timer_start(&RxTimeoutSyncWord,
+ SX1272.Settings.Fsk.RxSingleTimeout * 1000);
+ }
+
+ if( ( RadioEvents != NULL ) && ( RadioEvents->RxError != NULL ) )
+ {
+ RadioEvents->RxError( );
+ }
+ SX1272.Settings.FskPacketHandler.PreambleDetected = false;
+ SX1272.Settings.FskPacketHandler.SyncWordDetected = false;
+ SX1272.Settings.FskPacketHandler.NbBytes = 0;
+ SX1272.Settings.FskPacketHandler.Size = 0;
+ break;
+ }
+ }
+
+ // Read received packet size
+ if( ( SX1272.Settings.FskPacketHandler.Size == 0 ) && ( SX1272.Settings.FskPacketHandler.NbBytes == 0 ) )
+ {
+ if( SX1272.Settings.Fsk.FixLen == false )
+ {
+ SX1272ReadFifo( ( uint8_t* )&SX1272.Settings.FskPacketHandler.Size, 1 );
+ }
+ else
+ {
+ SX1272.Settings.FskPacketHandler.Size = SX1272Read( REG_PAYLOADLENGTH );
+ }
+ SX1272ReadFifo( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes, SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
+ SX1272.Settings.FskPacketHandler.NbBytes += ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
+ }
+ else
+ {
+ SX1272ReadFifo( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes, SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
+ SX1272.Settings.FskPacketHandler.NbBytes += ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
+ }
+
+ hal_timer_stop(&RxTimeoutTimer);
+
+ if( SX1272.Settings.Fsk.RxContinuous == false )
+ {
+ SX1272.Settings.State = RF_IDLE;
+ hal_timer_stop(&RxTimeoutSyncWord);
+ }
+ else
+ {
+ // Continuous mode restart Rx chain
+ SX1272Write( REG_RXCONFIG, SX1272Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
+ hal_timer_stop(&RxTimeoutSyncWord);
+ hal_timer_start(&RxTimeoutSyncWord,
+ SX1272.Settings.Fsk.RxSingleTimeout * 1000);
+ }
+
+ if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )
+ {
+ RadioEvents->RxDone( RxTxBuffer, SX1272.Settings.FskPacketHandler.Size, SX1272.Settings.FskPacketHandler.RssiValue, 0 );
+ }
+ SX1272.Settings.FskPacketHandler.PreambleDetected = false;
+ SX1272.Settings.FskPacketHandler.SyncWordDetected = false;
+ SX1272.Settings.FskPacketHandler.NbBytes = 0;
+ SX1272.Settings.FskPacketHandler.Size = 0;
+ break;
+ case MODEM_LORA:
+ {
+ int8_t snr = 0;
+
+ // Clear Irq
+ SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
+
+ irqFlags = SX1272Read( REG_LR_IRQFLAGS );
+ if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
+ {
+ // Clear Irq
+ SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
+
+ if( SX1272.Settings.LoRa.RxContinuous == false )
+ {
+ SX1272.Settings.State = RF_IDLE;
+ }
+ hal_timer_stop( &RxTimeoutTimer );
+
+ if( ( RadioEvents != NULL ) && ( RadioEvents->RxError != NULL ) )
+ {
+ RadioEvents->RxError( );
+ }
+ break;
+ }
+
+ SX1272.Settings.LoRaPacketHandler.SnrValue = SX1272Read( REG_LR_PKTSNRVALUE );
+ if( SX1272.Settings.LoRaPacketHandler.SnrValue & 0x80 ) // The SNR sign bit is 1
+ {
+ // Invert and divide by 4
+ snr = ( ( ~SX1272.Settings.LoRaPacketHandler.SnrValue + 1 ) & 0xFF ) >> 2;
+ snr = -snr;
+ }
+ else
+ {
+ // Divide by 4
+ snr = ( SX1272.Settings.LoRaPacketHandler.SnrValue & 0xFF ) >> 2;
+ }
+
+ int16_t rssi = SX1272Read( REG_LR_PKTRSSIVALUE );
+ if( snr < 0 )
+ {
+ SX1272.Settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET + rssi + ( rssi >> 4 ) +
+ snr;
+ }
+ else
+ {
+ SX1272.Settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET + rssi + ( rssi >> 4 );
+ }
+
+ SX1272.Settings.LoRaPacketHandler.Size = SX1272Read( REG_LR_RXNBBYTES );
+ SX1272ReadFifo( RxTxBuffer, SX1272.Settings.LoRaPacketHandler.Size );
+
+ if( SX1272.Settings.LoRa.RxContinuous == false )
+ {
+ SX1272.Settings.State = RF_IDLE;
+ }
+ hal_timer_stop(&RxTimeoutTimer);
+
+ if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )
+ {
+ RadioEvents->RxDone( RxTxBuffer, SX1272.Settings.LoRaPacketHandler.Size, SX1272.Settings.LoRaPacketHandler.RssiValue, SX1272.Settings.LoRaPacketHandler.SnrValue );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case RF_TX_RUNNING:
+ hal_timer_stop( &TxTimeoutTimer );
+ // TxDone interrupt
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_LORA:
+ // Clear Irq
+ SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
+ // Intentional fall through
+ case MODEM_FSK:
+ default:
+ SX1272.Settings.State = RF_IDLE;
+ if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) )
+ {
+ RadioEvents->TxDone( );
+ }
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SX1272OnDio1Irq(void *unused)
+{
+ switch( SX1272.Settings.State )
+ {
+ case RF_RX_RUNNING:
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ // FifoLevel interrupt
+ // Read received packet size
+ if( ( SX1272.Settings.FskPacketHandler.Size == 0 ) && ( SX1272.Settings.FskPacketHandler.NbBytes == 0 ) )
+ {
+ if( SX1272.Settings.Fsk.FixLen == false )
+ {
+ SX1272ReadFifo( ( uint8_t* )&SX1272.Settings.FskPacketHandler.Size, 1 );
+ }
+ else
+ {
+ SX1272.Settings.FskPacketHandler.Size = SX1272Read( REG_PAYLOADLENGTH );
+ }
+ }
+
+ if( ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes ) > SX1272.Settings.FskPacketHandler.FifoThresh )
+ {
+ SX1272ReadFifo( ( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes ), SX1272.Settings.FskPacketHandler.FifoThresh );
+ SX1272.Settings.FskPacketHandler.NbBytes += SX1272.Settings.FskPacketHandler.FifoThresh;
+ }
+ else
+ {
+ SX1272ReadFifo( ( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes ), SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
+ SX1272.Settings.FskPacketHandler.NbBytes += ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
+ }
+ break;
+ case MODEM_LORA:
+ // Sync time out
+ hal_timer_stop( &RxTimeoutTimer );
+ // Clear Irq
+ SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT );
+
+ SX1272.Settings.State = RF_IDLE;
+ if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )
+ {
+ RadioEvents->RxTimeout( );
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case RF_TX_RUNNING:
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ // FifoEmpty interrupt
+ if( ( SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes ) > SX1272.Settings.FskPacketHandler.ChunkSize )
+ {
+ SX1272WriteFifo( ( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes ), SX1272.Settings.FskPacketHandler.ChunkSize );
+ SX1272.Settings.FskPacketHandler.NbBytes += SX1272.Settings.FskPacketHandler.ChunkSize;
+ }
+ else
+ {
+ // Write the last chunk of data
+ SX1272WriteFifo( RxTxBuffer + SX1272.Settings.FskPacketHandler.NbBytes, SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes );
+ SX1272.Settings.FskPacketHandler.NbBytes += SX1272.Settings.FskPacketHandler.Size - SX1272.Settings.FskPacketHandler.NbBytes;
+ }
+ break;
+ case MODEM_LORA:
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SX1272OnDio2Irq(void *unused)
+{
+ switch( SX1272.Settings.State )
+ {
+ case RF_RX_RUNNING:
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ if( ( SX1272.Settings.FskPacketHandler.PreambleDetected == true ) && ( SX1272.Settings.FskPacketHandler.SyncWordDetected == false ) )
+ {
+ hal_timer_stop(&RxTimeoutSyncWord);
+
+ SX1272.Settings.FskPacketHandler.SyncWordDetected = true;
+
+ SX1272.Settings.FskPacketHandler.RssiValue = -( SX1272Read( REG_RSSIVALUE ) >> 1 );
+
+ SX1272.Settings.FskPacketHandler.AfcValue = ( int32_t )( double )( ( ( uint16_t )SX1272Read( REG_AFCMSB ) << 8 ) |
+ ( uint16_t )SX1272Read( REG_AFCLSB ) ) *
+ ( double )FREQ_STEP;
+ SX1272.Settings.FskPacketHandler.RxGain = ( SX1272Read( REG_LNA ) >> 5 ) & 0x07;
+ }
+ break;
+ case MODEM_LORA:
+ if( SX1272.Settings.LoRa.FreqHopOn == true )
+ {
+ // Clear Irq
+ SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
+
+ if( ( RadioEvents != NULL ) && ( RadioEvents->FhssChangeChannel != NULL ) )
+ {
+ RadioEvents->FhssChangeChannel( ( SX1272Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case RF_TX_RUNNING:
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ break;
+ case MODEM_LORA:
+ if( SX1272.Settings.LoRa.FreqHopOn == true )
+ {
+ // Clear Irq
+ SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
+
+ if( ( RadioEvents != NULL ) && ( RadioEvents->FhssChangeChannel != NULL ) )
+ {
+ RadioEvents->FhssChangeChannel( ( SX1272Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SX1272OnDio3Irq(void *unused)
+{
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ break;
+ case MODEM_LORA:
+ if( ( SX1272Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
+ {
+ // Clear Irq
+ SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
+ if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) )
+ {
+ RadioEvents->CadDone( true );
+ }
+ }
+ else
+ {
+ // Clear Irq
+ SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
+ if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) )
+ {
+ RadioEvents->CadDone( false );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void SX1272OnDio4Irq(void *unused)
+{
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ {
+ if( SX1272.Settings.FskPacketHandler.PreambleDetected == false )
+ {
+ SX1272.Settings.FskPacketHandler.PreambleDetected = true;
+ }
+ }
+ break;
+ case MODEM_LORA:
+ break;
+ default:
+ break;
+ }
+}
+
+void SX1272OnDio5Irq(void *unused)
+{
+ switch( SX1272.Settings.Modem )
+ {
+ case MODEM_FSK:
+ break;
+ case MODEM_LORA:
+ break;
+ default:
+ break;
+ }
+}
diff --git a/hw/drivers/lora/sx1272/src/sx1272.h b/hw/drivers/lora/sx1272/src/sx1272.h
new file mode 100644
index 000000000..12169c6da
--- /dev/null
+++ b/hw/drivers/lora/sx1272/src/sx1272.h
@@ -0,0 +1,393 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 Semtech
+
+Description: Generic SX1272 driver implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __SX1272_H__
+#define __SX1272_H__
+
+#include "sx1272Regs-Fsk.h"
+#include "sx1272Regs-LoRa.h"
+
+/*!
+ * Radio wake-up time from sleep
+ */
+#define RADIO_WAKEUP_TIME 1 // [ms]
+
+/*!
+ * Sync word for Private LoRa networks
+ */
+#define LORA_MAC_PRIVATE_SYNCWORD 0x12
+
+/*!
+ * Sync word for Public LoRa networks
+ */
+#define LORA_MAC_PUBLIC_SYNCWORD 0x34
+
+/*!
+ * Radio FSK modem parameters
+ */
+typedef struct
+{
+ int8_t Power;
+ uint32_t Fdev;
+ uint32_t Bandwidth;
+ uint32_t BandwidthAfc;
+ uint32_t Datarate;
+ uint16_t PreambleLen;
+ bool FixLen;
+ uint8_t PayloadLen;
+ bool CrcOn;
+ bool IqInverted;
+ bool RxContinuous;
+ uint32_t TxTimeout;
+ uint32_t RxSingleTimeout;
+}RadioFskSettings_t;
+
+/*!
+ * Radio FSK packet handler state
+ */
+typedef struct
+{
+ uint8_t PreambleDetected;
+ uint8_t SyncWordDetected;
+ int8_t RssiValue;
+ int32_t AfcValue;
+ uint8_t RxGain;
+ uint16_t Size;
+ uint16_t NbBytes;
+ uint8_t FifoThresh;
+ uint8_t ChunkSize;
+}RadioFskPacketHandler_t;
+
+/*!
+ * Radio LoRa modem parameters
+ */
+typedef struct
+{
+ int8_t Power;
+ uint32_t Bandwidth;
+ uint32_t Datarate;
+ bool LowDatarateOptimize;
+ uint8_t Coderate;
+ uint16_t PreambleLen;
+ bool FixLen;
+ uint8_t PayloadLen;
+ bool CrcOn;
+ bool FreqHopOn;
+ uint8_t HopPeriod;
+ bool IqInverted;
+ bool RxContinuous;
+ uint32_t TxTimeout;
+ bool PublicNetwork;
+}RadioLoRaSettings_t;
+
+/*!
+ * Radio LoRa packet handler state
+ */
+typedef struct
+{
+ int8_t SnrValue;
+ int16_t RssiValue;
+ uint8_t Size;
+}RadioLoRaPacketHandler_t;
+
+/*!
+ * Radio Settings
+ */
+typedef struct
+{
+ RadioState_t State;
+ RadioModems_t Modem;
+ uint32_t Channel;
+ RadioFskSettings_t Fsk;
+ RadioFskPacketHandler_t FskPacketHandler;
+ RadioLoRaSettings_t LoRa;
+ RadioLoRaPacketHandler_t LoRaPacketHandler;
+}RadioSettings_t;
+
+/*!
+ * Radio hardware and global parameters
+ */
+typedef struct SX1272_s
+{
+ RadioSettings_t Settings;
+}SX1272_t;
+
+/*!
+ * Hardware IO IRQ callback function definition
+ */
+typedef void ( DioIrqHandler )(void *arg);
+
+/*!
+ * SX1272 definitions
+ */
+#define XTAL_FREQ 32000000
+#define FREQ_STEP 61.03515625
+
+#define RX_BUFFER_SIZE 256
+
+/*!
+ * ============================================================================
+ * Public functions prototypes
+ * ============================================================================
+ */
+
+/*!
+ * \brief Initializes the radio
+ *
+ * \param [IN] events Structure containing the driver callback functions
+ */
+void SX1272Init( RadioEvents_t *events );
+
+/*!
+ * Return current radio status
+ *
+ * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING]
+ */
+RadioState_t SX1272GetStatus( void );
+
+/*!
+ * \brief Configures the radio with the given modem
+ *
+ * \param [IN] modem Modem to be used [0: FSK, 1: LoRa]
+ */
+void SX1272SetModem( RadioModems_t modem );
+
+/*!
+ * \brief Sets the channel configuration
+ *
+ * \param [IN] freq Channel RF frequency
+ */
+void SX1272SetChannel( uint32_t freq );
+
+/*!
+ * \brief Sets the channels configuration
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] freq Channel RF frequency
+ * \param [IN] rssiThresh RSSI threshold
+ *
+ * \retval isFree [true: Channel is free, false: Channel is not free]
+ */
+bool SX1272IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh );
+
+/*!
+ * \brief 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 SX1272SetRxConfig or
+ * SX1272SetTxConfig functions must be called.
+ *
+ * \retval randomValue 32 bits random value
+ */
+uint32_t SX1272Random( void );
+
+/*!
+ * \brief Sets the reception parameters
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] bandwidth Sets the bandwidth
+ * FSK : >= 2600 and <= 250000 Hz
+ * LoRa: [0: 125 kHz, 1: 250 kHz,
+ * 2: 500 kHz, 3: Reserved]
+ * \param [IN] 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 [IN] 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 [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only)
+ * FSK : >= 2600 and <= 250000 Hz
+ * LoRa: N/A ( set to 0 )
+ * \param [IN] preambleLen Sets the Preamble length
+ * FSK : Number of bytes
+ * LoRa: Length in symbols (the hardware adds 4 more symbols)
+ * \param [IN] symbTimeout Sets the RxSingle timeout value
+ * FSK : timeout number of bytes
+ * LoRa: timeout in symbols
+ * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed]
+ * \param [IN] payloadLen Sets payload length when fixed length is used
+ * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON]
+ * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping
+ * FSK : N/A ( set to 0 )
+ * LoRa: [0: OFF, 1: ON]
+ * \param [IN] HopPeriod Number of symbols between each hop
+ * FSK : N/A ( set to 0 )
+ * LoRa: Number of symbols
+ * \param [IN] iqInverted Inverts IQ signals (LoRa only)
+ * FSK : N/A ( set to 0 )
+ * LoRa: [0: not inverted, 1: inverted]
+ * \param [IN] rxContinuous Sets the reception in continuous mode
+ * [false: single mode, true: continuous mode]
+ */
+void SX1272SetRxConfig( RadioModems_t modem, uint32_t bandwidth,
+ uint32_t datarate, uint8_t coderate,
+ uint32_t bandwidthAfc, uint16_t preambleLen,
+ uint16_t symbTimeout, bool fixLen,
+ uint8_t payloadLen,
+ bool crcOn, bool FreqHopOn, uint8_t HopPeriod,
+ bool iqInverted, bool rxContinuous );
+
+/*!
+ * \brief Sets the transmission parameters
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] power Sets the output power [dBm]
+ * \param [IN] fdev Sets the frequency deviation (FSK only)
+ * FSK : [Hz]
+ * LoRa: 0
+ * \param [IN] bandwidth Sets the bandwidth (LoRa only)
+ * FSK : 0
+ * LoRa: [0: 125 kHz, 1: 250 kHz,
+ * 2: 500 kHz, 3: Reserved]
+ * \param [IN] 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 [IN] 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 [IN] preambleLen Sets the preamble length
+ * FSK : Number of bytes
+ * LoRa: Length in symbols (the hardware adds 4 more symbols)
+ * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed]
+ * \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON]
+ * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping
+ * FSK : N/A ( set to 0 )
+ * LoRa: [0: OFF, 1: ON]
+ * \param [IN] HopPeriod Number of symbols between each hop
+ * FSK : N/A ( set to 0 )
+ * LoRa: Number of symbols
+ * \param [IN] iqInverted Inverts IQ signals (LoRa only)
+ * FSK : N/A ( set to 0 )
+ * LoRa: [0: not inverted, 1: inverted]
+ * \param [IN] timeout Transmission timeout [ms]
+ */
+void SX1272SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
+ uint32_t bandwidth, uint32_t datarate,
+ uint8_t coderate, uint16_t preambleLen,
+ bool fixLen, bool crcOn, bool FreqHopOn,
+ uint8_t HopPeriod, bool iqInverted, uint32_t timeout );
+
+/*!
+ * \brief Computes the packet time on air in ms for the given payload
+ *
+ * \Remark Can only be called once SetRxConfig or SetTxConfig have been called
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] pktLen Packet payload length
+ *
+ * \retval airTime Computed airTime (ms) for the given packet payload length
+ */
+uint32_t SX1272GetTimeOnAir( RadioModems_t modem, uint8_t pktLen );
+
+/*!
+ * \brief Sends the buffer of size. Prepares the packet to be sent and sets
+ * the radio in transmission
+ *
+ * \param [IN]: buffer Buffer pointer
+ * \param [IN]: size Buffer size
+ */
+void SX1272Send( uint8_t *buffer, uint8_t size );
+
+/*!
+ * \brief Sets the radio in sleep mode
+ */
+void SX1272SetSleep( void );
+
+/*!
+ * \brief Sets the radio in standby mode
+ */
+void SX1272SetStby( void );
+
+/*!
+ * \brief Sets the radio in reception mode for the given time
+ * \param [IN] timeout Reception timeout [ms] [0: continuous, others timeout]
+ */
+void SX1272SetRx( uint32_t timeout );
+
+/*!
+ * \brief Start a Channel Activity Detection
+ */
+void SX1272StartCad( void );
+
+/*!
+ * \brief Sets the radio in continuous wave transmission mode
+ *
+ * \param [IN]: freq Channel RF frequency
+ * \param [IN]: power Sets the output power [dBm]
+ * \param [IN]: time Transmission mode timeout [s]
+ */
+void SX1272SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time );
+
+/*!
+ * \brief Reads the current RSSI value
+ *
+ * \retval rssiValue Current RSSI value in [dBm]
+ */
+int16_t SX1272ReadRssi( RadioModems_t modem );
+
+/*!
+ * \brief Writes the radio register at the specified address
+ *
+ * \param [IN]: addr Register address
+ * \param [IN]: data New register value
+ */
+void SX1272Write( uint8_t addr, uint8_t data );
+
+/*!
+ * \brief Reads the radio register at the specified address
+ *
+ * \param [IN]: addr Register address
+ * \retval data Register value
+ */
+uint8_t SX1272Read( uint8_t addr );
+
+/*!
+ * \brief Writes multiple radio registers starting at address
+ *
+ * \param [IN] addr First Radio register address
+ * \param [IN] buffer Buffer containing the new register's values
+ * \param [IN] size Number of registers to be written
+ */
+void SX1272WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size );
+
+/*!
+ * \brief Reads multiple radio registers starting at address
+ *
+ * \param [IN] addr First Radio register address
+ * \param [OUT] buffer Buffer where to copy the registers data
+ * \param [IN] size Number of registers to be read
+ */
+void SX1272ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size );
+
+/*!
+ * \brief Sets the maximum payload length.
+ *
+ * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
+ * \param [IN] max Maximum payload length in bytes
+ */
+void SX1272SetMaxPayloadLength( RadioModems_t modem, uint8_t max );
+
+/*!
+ * \brief Sets the network to public or private. Updates the sync byte.
+ *
+ * \remark Applies to LoRa modem only
+ *
+ * \param [IN] enable if true, it enables a public network
+ */
+void SX1272SetPublicNetwork( bool enable );
+
+#endif // __SX1272_H__
diff --git a/hw/drivers/lora/sx1272/src/sx1272Regs-Fsk.h b/hw/drivers/lora/sx1272/src/sx1272Regs-Fsk.h
new file mode 100644
index 000000000..2c2ac1796
--- /dev/null
+++ b/hw/drivers/lora/sx1272/src/sx1272Regs-Fsk.h
@@ -0,0 +1,1134 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 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
+*/
+#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/hw/drivers/lora/sx1272/src/sx1272Regs-LoRa.h b/hw/drivers/lora/sx1272/src/sx1272Regs-LoRa.h
new file mode 100644
index 000000000..fd571474e
--- /dev/null
+++ b/hw/drivers/lora/sx1272/src/sx1272Regs-LoRa.h
@@ -0,0 +1,545 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2013 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
+*/
+#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/hw/drivers/lora/sx1272/syscfg.yml b/hw/drivers/lora/sx1272/syscfg.yml
new file mode 100644
index 000000000..e3da9a34f
--- /dev/null
+++ b/hw/drivers/lora/sx1272/syscfg.yml
@@ -0,0 +1,44 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+ SX1272_SPI_IDX:
+ description:
+ value: -1
+
+ SX1272_SPI_CS_PIN:
+ description: 'SPI chip select pin number'
+ value: -1
+
+ SX1272_SPI_BAUDRATE:
+ description:
+ value: 500
+
+ SX1272_HAS_ANT_SW:
+ description: 'Set to 1 if board has an antenna switch'
+ restrictions:
+ - "!SX1272_HAS_COMP_ANT_SW"
+ value: 0
+
+ SX1272_HAS_COMP_ANT_SW:
+ description: 'Set to 1 if board has complementary antenna switch'
+ restrictions:
+ - "!SX1272_HAS_ANT_SW"
+ value: 1
+
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
With regards,
Apache Git Services