Update LoRaMac-node to Version 4.4.4,fix Security breach found by Tencent Blade Team please refer to security advisory - CVE-2020-11068
fix Security breach found by Tencent Blade Team please refer to security advisory - CVE-2020-11068
This commit is contained in:
@@ -23,7 +23,7 @@ cmake_minimum_required(VERSION 3.6)
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
||||
# Allow switching of radios
|
||||
set(RADIO_LIST sx1272 sx1276 sx126x)
|
||||
set(RADIO_LIST sx1272 sx1276 sx126x lr1110)
|
||||
set(RADIO sx1272 CACHE STRING "Default radio is sx1272")
|
||||
set_property(CACHE RADIO PROPERTY STRINGS ${RADIO_LIST})
|
||||
set_property(CACHE RADIO PROPERTY ADVANCED)
|
||||
@@ -32,17 +32,47 @@ set_property(CACHE RADIO PROPERTY ADVANCED)
|
||||
# Target
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
||||
file(GLOB ${PROJECT_NAME}_SOURCES "${RADIO}/*.c")
|
||||
foreach( R ${RADIO_LIST} )
|
||||
if(${R} MATCHES ${RADIO} )
|
||||
list(APPEND ${PROJECT_NAME}_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/radio.c
|
||||
)
|
||||
list(APPEND ${PROJECT_NAME}_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/${RADIO}_driver/src/lr1110_bootloader.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/${RADIO}_driver/src/lr1110_crypto_engine.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/${RADIO}_driver/src/lr1110_gnss.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/${RADIO}_driver/src/lr1110_radio.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/${RADIO}_driver/src/lr1110_regmem.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/${RADIO}_driver/src/lr1110_system.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/${RADIO}_driver/src/lr1110_wifi.c
|
||||
)
|
||||
else()
|
||||
file(GLOB ${PROJECT_NAME}_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/*.c
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_library(${PROJECT_NAME} OBJECT EXCLUDE_FROM_ALL ${${PROJECT_NAME}_SOURCES})
|
||||
|
||||
add_dependencies(${PROJECT_NAME} board)
|
||||
|
||||
foreach( R ${RADIO_LIST} )
|
||||
if(${R} MATCHES lr1110 )
|
||||
list(APPEND ${PROJECT_NAME}_INCLUDES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO})
|
||||
list(APPEND ${PROJECT_NAME}_INCLUDES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}/${RADIO}_driver/src)
|
||||
else()
|
||||
list(APPEND ${PROJECT_NAME}_INCLUDES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${RADIO}
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sx126x
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sx1272
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sx1276
|
||||
${${PROJECT_NAME}_INCLUDES}
|
||||
$<TARGET_PROPERTY:board,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:system,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
117
components/connectivity/LoraWAN/radio/lr1110/lr1110.h
Normal file
117
components/connectivity/LoraWAN/radio/lr1110/lr1110.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*!
|
||||
* \file lr1110.h
|
||||
*
|
||||
* \brief LR1110 driver implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see file LICENSE.txt
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2019-2019 Semtech
|
||||
*
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#ifndef __LR1110_H__
|
||||
#define __LR1110_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include "gpio.h"
|
||||
#include "spi.h"
|
||||
#include "radio.h"
|
||||
#include "lr1110_hal.h"
|
||||
#include "lr1110_radio_types.h"
|
||||
|
||||
/*!
|
||||
* \brief The type describing the modulation parameters for every packet types
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
lr1110_radio_packet_types_t packet_type; //!< Packet to which the modulation parameters are referring to.
|
||||
struct
|
||||
{
|
||||
lr1110_radio_modulation_param_gfsk_t gfsk;
|
||||
lr1110_radio_modulation_param_lora_t lora;
|
||||
}modulation; //!< Holds the modulation parameters structure
|
||||
} lr1110_modulation_params_t;
|
||||
|
||||
/*!
|
||||
* \brief The type describing the packet parameters for every packet types
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
lr1110_radio_packet_types_t packet_type; //!< Packet to which the packet parameters are referring to.
|
||||
struct
|
||||
{
|
||||
lr1110_radio_packet_param_gfsk_t gfsk;
|
||||
lr1110_radio_packet_param_lora_t lora;
|
||||
}packet; //!< Holds the packet parameters structure
|
||||
} lr1110_packet_params_t;
|
||||
|
||||
/*!
|
||||
* \brief Radio operating modes
|
||||
*/
|
||||
typedef enum lr1110_hal_operating_mode_e
|
||||
{
|
||||
LR1110_HAL_OP_MODE_SLEEP = 0x00, //! The radio is in sleep mode
|
||||
LR1110_HAL_OP_MODE_STDBY_RC, //! The radio is in standby mode with RC oscillator
|
||||
LR1110_HAL_OP_MODE_STDBY_XOSC, //! The radio is in standby mode with XOSC oscillator
|
||||
LR1110_HAL_OP_MODE_FS, //! The radio is in frequency synthesis mode
|
||||
LR1110_HAL_OP_MODE_TX, //! The radio is in transmit mode
|
||||
LR1110_HAL_OP_MODE_RX, //! The radio is in receive single mode
|
||||
LR1110_HAL_OP_MODE_RX_C, //! The radio is in receive continuous mode
|
||||
LR1110_HAL_OP_MODE_RX_DC, //! The radio is in receive duty cycle mode
|
||||
LR1110_HAL_OP_MODE_CAD //! The radio is in channel activity detection mode
|
||||
} lr1110_hal_operating_mode_t;
|
||||
|
||||
/*!
|
||||
* Radio hardware and global parameters
|
||||
*/
|
||||
typedef struct lr1110_s
|
||||
{
|
||||
Gpio_t reset;
|
||||
Gpio_t busy;
|
||||
Gpio_t dio_1;
|
||||
Spi_t spi;
|
||||
lr1110_hal_operating_mode_t op_mode;
|
||||
lr1110_modulation_params_t modulation_params;
|
||||
lr1110_packet_params_t packet_params;
|
||||
} lr1110_t;
|
||||
|
||||
/*!
|
||||
* Hardware IO IRQ callback function definition
|
||||
*/
|
||||
typedef void ( *lr1110_dio_irq_handler )( void* context );
|
||||
|
||||
/*!
|
||||
* Get radio operating mode
|
||||
*
|
||||
* \remark Must be implemented by the upper layer
|
||||
*
|
||||
* \param [in] context Radio implementation parameters
|
||||
* \retval op_mode Radio current operating mode
|
||||
*/
|
||||
lr1110_hal_operating_mode_t lr1110_hal_get_operating_mode( const void* context );
|
||||
|
||||
/*!
|
||||
* Set radio operating mode
|
||||
*
|
||||
* \remark Must be implemented by the upper layer
|
||||
*
|
||||
* \param [in] context Radio implementation parameters
|
||||
* \param [in] op_mode Radio operating mode
|
||||
*/
|
||||
void lr1110_hal_set_operating_mode( const void* context, const lr1110_hal_operating_mode_t op_mode );
|
||||
|
||||
#endif // __LR1110_H__
|
1349
components/connectivity/LoraWAN/radio/lr1110/radio.c
Normal file
1349
components/connectivity/LoraWAN/radio/lr1110/radio.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,11 @@
|
||||
#ifndef __RADIO_H__
|
||||
#define __RADIO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -91,6 +96,16 @@ typedef struct
|
||||
* \param [IN] channelDetected Channel Activity detected during the CAD
|
||||
*/
|
||||
void ( *CadDone ) ( bool channelActivityDetected );
|
||||
|
||||
/*!
|
||||
* \brief Gnss Done Done callback prototype.
|
||||
*/
|
||||
void ( *GnssDone )( void );
|
||||
|
||||
/*!
|
||||
* \brief Gnss Done Done callback prototype.
|
||||
*/
|
||||
void ( *WifiDone )( void );
|
||||
}RadioEvents_t;
|
||||
|
||||
/*!
|
||||
@@ -243,11 +258,30 @@ struct Radio_s
|
||||
* \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
|
||||
* \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] 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] payloadLen Sets payload length when fixed length is used
|
||||
* \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON]
|
||||
*
|
||||
* \retval airTime Computed airTime (ms) for the given packet payload length
|
||||
*/
|
||||
uint32_t ( *TimeOnAir )( RadioModems_t modem, uint8_t pktLen );
|
||||
uint32_t ( *TimeOnAir )( RadioModems_t modem, uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn );
|
||||
/*!
|
||||
* \brief Sends the buffer of size. Prepares the packet to be sent and sets
|
||||
* the radio in transmission
|
||||
@@ -294,14 +328,14 @@ struct Radio_s
|
||||
* \param [IN]: addr Register address
|
||||
* \param [IN]: data New register value
|
||||
*/
|
||||
void ( *Write )( uint16_t addr, uint8_t data );
|
||||
void ( *Write )( uint32_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 )( uint16_t addr );
|
||||
uint8_t ( *Read )( uint32_t addr );
|
||||
/*!
|
||||
* \brief Writes multiple radio registers starting at address
|
||||
*
|
||||
@@ -309,7 +343,7 @@ struct Radio_s
|
||||
* \param [IN] buffer Buffer containing the new register's values
|
||||
* \param [IN] size Number of registers to be written
|
||||
*/
|
||||
void ( *WriteBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
void ( *WriteBuffer )( uint32_t addr, uint8_t *buffer, uint8_t size );
|
||||
/*!
|
||||
* \brief Reads multiple radio registers starting at address
|
||||
*
|
||||
@@ -317,7 +351,7 @@ struct Radio_s
|
||||
* \param [OUT] buffer Buffer where to copy the registers data
|
||||
* \param [IN] size Number of registers to be read
|
||||
*/
|
||||
void ( *ReadBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
void ( *ReadBuffer )( uint32_t addr, uint8_t *buffer, uint8_t size );
|
||||
/*!
|
||||
* \brief Sets the maximum payload length.
|
||||
*
|
||||
@@ -374,4 +408,8 @@ struct Radio_s
|
||||
*/
|
||||
extern const struct Radio_s Radio;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __RADIO_H__
|
||||
|
@@ -184,11 +184,30 @@ bool RadioCheckRfFrequency( uint32_t frequency );
|
||||
* \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
|
||||
* \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] 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] payloadLen Sets payload length when fixed length is used
|
||||
* \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON]
|
||||
*
|
||||
* \retval airTime Computed airTime (ms) for the given packet payload length
|
||||
*/
|
||||
uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen );
|
||||
uint32_t RadioTimeOnAir( RadioModems_t modem, uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn );
|
||||
|
||||
/*!
|
||||
* \brief Sends the buffer of size. Prepares the packet to be sent and sets
|
||||
@@ -243,7 +262,7 @@ int16_t RadioRssi( RadioModems_t modem );
|
||||
* \param [IN]: addr Register address
|
||||
* \param [IN]: data New register value
|
||||
*/
|
||||
void RadioWrite( uint16_t addr, uint8_t data );
|
||||
void RadioWrite( uint32_t addr, uint8_t data );
|
||||
|
||||
/*!
|
||||
* \brief Reads the radio register at the specified address
|
||||
@@ -251,7 +270,7 @@ void RadioWrite( uint16_t addr, uint8_t data );
|
||||
* \param [IN]: addr Register address
|
||||
* \retval data Register value
|
||||
*/
|
||||
uint8_t RadioRead( uint16_t addr );
|
||||
uint8_t RadioRead( uint32_t addr );
|
||||
|
||||
/*!
|
||||
* \brief Writes multiple radio registers starting at address
|
||||
@@ -260,7 +279,7 @@ uint8_t RadioRead( uint16_t addr );
|
||||
* \param [IN] buffer Buffer containing the new register's values
|
||||
* \param [IN] size Number of registers to be written
|
||||
*/
|
||||
void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
void RadioWriteBuffer( uint32_t addr, uint8_t *buffer, uint8_t size );
|
||||
|
||||
/*!
|
||||
* \brief Reads multiple radio registers starting at address
|
||||
@@ -269,7 +288,7 @@ void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
* \param [OUT] buffer Buffer where to copy the registers data
|
||||
* \param [IN] size Number of registers to be read
|
||||
*/
|
||||
void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
void RadioReadBuffer( uint32_t addr, uint8_t *buffer, uint8_t size );
|
||||
|
||||
/*!
|
||||
* \brief Sets the maximum payload length.
|
||||
@@ -395,11 +414,6 @@ const FskBandwidth_t FskBandwidths[] =
|
||||
|
||||
const RadioLoRaBandwidths_t Bandwidths[] = { LORA_BW_125, LORA_BW_250, LORA_BW_500 };
|
||||
|
||||
// SF12 SF11 SF10 SF9 SF8 SF7
|
||||
static double RadioLoRaSymbTime[3][6] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024 }, // 125 KHz
|
||||
{ 16.384, 8.192, 4.096, 2.048, 1.024, 0.512 }, // 250 KHz
|
||||
{ 8.192, 4.096, 2.048, 1.024, 0.512, 0.256 }}; // 500 KHz
|
||||
|
||||
uint8_t MaxPayloadLength = 0xFF;
|
||||
|
||||
uint32_t TxTimeout = 0;
|
||||
@@ -562,6 +576,8 @@ bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh,
|
||||
int16_t rssi = 0;
|
||||
uint32_t carrierSenseTime = 0;
|
||||
|
||||
RadioSleep( );
|
||||
|
||||
RadioSetModem( modem );
|
||||
|
||||
RadioSetChannel( freq );
|
||||
@@ -589,7 +605,6 @@ bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh,
|
||||
|
||||
uint32_t RadioRandom( void )
|
||||
{
|
||||
uint8_t i;
|
||||
uint32_t rnd = 0;
|
||||
|
||||
/*
|
||||
@@ -598,17 +613,10 @@ uint32_t RadioRandom( void )
|
||||
// Set LoRa modem ON
|
||||
RadioSetModem( MODEM_LORA );
|
||||
|
||||
// Set radio in continuous reception
|
||||
SX126xSetRx( 0 );
|
||||
// Disable LoRa modem interrupts
|
||||
SX126xSetDioIrqParams( IRQ_RADIO_NONE, IRQ_RADIO_NONE, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
|
||||
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
DelayMs( 1 );
|
||||
// Unfiltered RSSI value reading. Only takes the LSB value
|
||||
rnd |= ( ( uint32_t )SX126xGetRssiInst( ) & 0x01 ) << i;
|
||||
}
|
||||
|
||||
RadioSleep( );
|
||||
rnd = SX126xGetRandom( );
|
||||
|
||||
return rnd;
|
||||
}
|
||||
@@ -675,7 +683,6 @@ void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth,
|
||||
|
||||
case MODEM_LORA:
|
||||
SX126xSetStopRxTimerOnPreambleDetect( false );
|
||||
SX126xSetLoRaSymbNumTimeout( symbTimeout );
|
||||
SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA;
|
||||
SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t )datarate;
|
||||
SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth];
|
||||
@@ -716,9 +723,24 @@ void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth,
|
||||
SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn;
|
||||
SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted;
|
||||
|
||||
RadioStandby( );
|
||||
RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA );
|
||||
SX126xSetModulationParams( &SX126x.ModulationParams );
|
||||
SX126xSetPacketParams( &SX126x.PacketParams );
|
||||
SX126xSetLoRaSymbNumTimeout( symbTimeout );
|
||||
|
||||
// WORKAROUND - Optimizing the Inverted IQ Operation, see DS_SX1261-2_V1.2 datasheet chapter 15.4
|
||||
if( SX126x.PacketParams.Params.LoRa.InvertIQ == LORA_IQ_INVERTED )
|
||||
{
|
||||
// RegIqPolaritySetup = @address 0x0736
|
||||
SX126xWriteRegister( 0x0736, SX126xReadRegister( 0x0736 ) & ~( 1 << 2 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// RegIqPolaritySetup @address 0x0736
|
||||
SX126xWriteRegister( 0x0736, SX126xReadRegister( 0x0736 ) | ( 1 << 2 ) );
|
||||
}
|
||||
// WORKAROUND END
|
||||
|
||||
// Timeout Max, Timeout handled directly in SetRx function
|
||||
RxTimeout = 0xFFFF;
|
||||
@@ -815,6 +837,20 @@ void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
|
||||
SX126xSetPacketParams( &SX126x.PacketParams );
|
||||
break;
|
||||
}
|
||||
|
||||
// WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see DS_SX1261-2_V1.2 datasheet chapter 15.1
|
||||
if( ( modem == MODEM_LORA ) && ( SX126x.ModulationParams.Params.LoRa.Bandwidth == LORA_BW_500 ) )
|
||||
{
|
||||
// RegTxModulation = @address 0x0889
|
||||
SX126xWriteRegister( 0x0889, SX126xReadRegister( 0x0889 ) & ~( 1 << 2 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// RegTxModulation = @address 0x0889
|
||||
SX126xWriteRegister( 0x0889, SX126xReadRegister( 0x0889 ) | ( 1 << 2 ) );
|
||||
}
|
||||
// WORKAROUND END
|
||||
|
||||
SX126xSetRfTxPower( power );
|
||||
TxTimeout = timeout;
|
||||
}
|
||||
@@ -824,44 +860,158 @@ bool RadioCheckRfFrequency( uint32_t frequency )
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen )
|
||||
static uint32_t RadioGetLoRaBandwidthInHz( RadioLoRaBandwidths_t bw )
|
||||
{
|
||||
uint32_t airTime = 0;
|
||||
uint32_t bandwidthInHz = 0;
|
||||
|
||||
switch( bw )
|
||||
{
|
||||
case LORA_BW_007:
|
||||
bandwidthInHz = 7812UL;
|
||||
break;
|
||||
case LORA_BW_010:
|
||||
bandwidthInHz = 10417UL;
|
||||
break;
|
||||
case LORA_BW_015:
|
||||
bandwidthInHz = 15625UL;
|
||||
break;
|
||||
case LORA_BW_020:
|
||||
bandwidthInHz = 20833UL;
|
||||
break;
|
||||
case LORA_BW_031:
|
||||
bandwidthInHz = 31250UL;
|
||||
break;
|
||||
case LORA_BW_041:
|
||||
bandwidthInHz = 41667UL;
|
||||
break;
|
||||
case LORA_BW_062:
|
||||
bandwidthInHz = 62500UL;
|
||||
break;
|
||||
case LORA_BW_125:
|
||||
bandwidthInHz = 125000UL;
|
||||
break;
|
||||
case LORA_BW_250:
|
||||
bandwidthInHz = 250000UL;
|
||||
break;
|
||||
case LORA_BW_500:
|
||||
bandwidthInHz = 500000UL;
|
||||
break;
|
||||
}
|
||||
|
||||
return bandwidthInHz;
|
||||
}
|
||||
|
||||
static uint32_t RadioGetGfskTimeOnAirNumerator( uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn )
|
||||
{
|
||||
const RadioAddressComp_t addrComp = RADIO_ADDRESSCOMP_FILT_OFF;
|
||||
const uint8_t syncWordLength = 3;
|
||||
|
||||
return ( preambleLen << 3 ) +
|
||||
( ( fixLen == false ) ? 8 : 0 ) +
|
||||
( syncWordLength << 3 ) +
|
||||
( ( payloadLen +
|
||||
( addrComp == RADIO_ADDRESSCOMP_FILT_OFF ? 0 : 1 ) +
|
||||
( ( crcOn == true ) ? 2 : 0 )
|
||||
) << 3
|
||||
);
|
||||
}
|
||||
|
||||
static uint32_t RadioGetLoRaTimeOnAirNumerator( uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn )
|
||||
{
|
||||
int32_t crDenom = coderate + 4;
|
||||
bool lowDatareOptimize = false;
|
||||
|
||||
// Ensure that the preamble length is at least 12 symbols when using SF5 or
|
||||
// SF6
|
||||
if( ( datarate == 5 ) || ( datarate == 6 ) )
|
||||
{
|
||||
if( preambleLen < 12 )
|
||||
{
|
||||
preambleLen = 12;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
|
||||
( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
|
||||
{
|
||||
lowDatareOptimize = true;
|
||||
}
|
||||
|
||||
int32_t ceilDenominator;
|
||||
int32_t ceilNumerator = ( payloadLen << 3 ) +
|
||||
( crcOn ? 16 : 0 ) -
|
||||
( 4 * datarate ) +
|
||||
( fixLen ? 0 : 20 );
|
||||
|
||||
if( datarate <= 6 )
|
||||
{
|
||||
ceilDenominator = 4 * datarate;
|
||||
}
|
||||
else
|
||||
{
|
||||
ceilNumerator += 8;
|
||||
|
||||
if( lowDatareOptimize == true )
|
||||
{
|
||||
ceilDenominator = 4 * ( datarate - 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
ceilDenominator = 4 * datarate;
|
||||
}
|
||||
}
|
||||
|
||||
if( ceilNumerator < 0 )
|
||||
{
|
||||
ceilNumerator = 0;
|
||||
}
|
||||
|
||||
// Perform integral ceil()
|
||||
int32_t intermediate =
|
||||
( ( ceilNumerator + ceilDenominator - 1 ) / ceilDenominator ) * crDenom + preambleLen + 12;
|
||||
|
||||
if( datarate <= 6 )
|
||||
{
|
||||
intermediate += 2;
|
||||
}
|
||||
|
||||
return ( uint32_t )( ( 4 * intermediate + 1 ) * ( 1 << ( datarate - 2 ) ) );
|
||||
}
|
||||
|
||||
uint32_t RadioTimeOnAir( RadioModems_t modem, uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn )
|
||||
{
|
||||
uint32_t numerator = 0;
|
||||
uint32_t denominator = 1;
|
||||
|
||||
switch( modem )
|
||||
{
|
||||
case MODEM_FSK:
|
||||
{
|
||||
airTime = rint( ( 8 * ( SX126x.PacketParams.Params.Gfsk.PreambleLength +
|
||||
( SX126x.PacketParams.Params.Gfsk.SyncWordLength >> 3 ) +
|
||||
( ( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_FIXED_LENGTH ) ? 0.0 : 1.0 ) +
|
||||
pktLen +
|
||||
( ( SX126x.PacketParams.Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES ) ? 2.0 : 0 ) ) /
|
||||
SX126x.ModulationParams.Params.Gfsk.BitRate ) * 1e3 );
|
||||
numerator = 1000U * RadioGetGfskTimeOnAirNumerator( datarate, coderate,
|
||||
preambleLen, fixLen,
|
||||
payloadLen, crcOn );
|
||||
denominator = datarate;
|
||||
}
|
||||
break;
|
||||
case MODEM_LORA:
|
||||
{
|
||||
double ts = RadioLoRaSymbTime[SX126x.ModulationParams.Params.LoRa.Bandwidth - 4][12 - SX126x.ModulationParams.Params.LoRa.SpreadingFactor];
|
||||
// time of preamble
|
||||
double tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 4.25 ) * ts;
|
||||
// Symbol length of payload and time
|
||||
double tmp = ceil( ( 8 * pktLen - 4 * SX126x.ModulationParams.Params.LoRa.SpreadingFactor +
|
||||
28 + 16 * SX126x.PacketParams.Params.LoRa.CrcMode -
|
||||
( ( SX126x.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_FIXED_LENGTH ) ? 20 : 0 ) ) /
|
||||
( double )( 4 * ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor -
|
||||
( ( SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
|
||||
( ( SX126x.ModulationParams.Params.LoRa.CodingRate % 4 ) + 4 );
|
||||
double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
|
||||
double tPayload = nPayload * ts;
|
||||
// Time on air
|
||||
double tOnAir = tPreamble + tPayload;
|
||||
// return milli seconds
|
||||
airTime = floor( tOnAir + 0.999 );
|
||||
numerator = 1000U * RadioGetLoRaTimeOnAirNumerator( bandwidth, datarate,
|
||||
coderate, preambleLen,
|
||||
fixLen, payloadLen, crcOn );
|
||||
denominator = RadioGetLoRaBandwidthInHz( Bandwidths[bandwidth] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return airTime;
|
||||
// Perform integral ceil()
|
||||
return ( numerator + denominator - 1 ) / denominator;
|
||||
}
|
||||
|
||||
void RadioSend( uint8_t *buffer, uint8_t size )
|
||||
@@ -954,21 +1104,19 @@ void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime )
|
||||
|
||||
void RadioStartCad( void )
|
||||
{
|
||||
SX126xSetDioIrqParams( IRQ_CAD_DONE | IRQ_CAD_ACTIVITY_DETECTED, IRQ_CAD_DONE | IRQ_CAD_ACTIVITY_DETECTED, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
|
||||
SX126xSetCad( );
|
||||
}
|
||||
|
||||
void RadioTx( uint32_t timeout )
|
||||
{
|
||||
SX126xSetTx( timeout << 6 );
|
||||
}
|
||||
|
||||
void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
|
||||
{
|
||||
uint32_t timeout = ( uint32_t )time * 1000;
|
||||
|
||||
SX126xSetRfFrequency( freq );
|
||||
SX126xSetRfTxPower( power );
|
||||
SX126xSetTxContinuousWave( );
|
||||
|
||||
TimerSetValue( &TxTimeoutTimer, time * 1e3 );
|
||||
TimerSetValue( &TxTimeoutTimer, timeout );
|
||||
TimerStart( &TxTimeoutTimer );
|
||||
}
|
||||
|
||||
@@ -977,36 +1125,26 @@ int16_t RadioRssi( RadioModems_t modem )
|
||||
return SX126xGetRssiInst( );
|
||||
}
|
||||
|
||||
void RadioWrite( uint16_t addr, uint8_t data )
|
||||
void RadioWrite( uint32_t addr, uint8_t data )
|
||||
{
|
||||
SX126xWriteRegister( addr, data );
|
||||
}
|
||||
|
||||
uint8_t RadioRead( uint16_t addr )
|
||||
uint8_t RadioRead( uint32_t addr )
|
||||
{
|
||||
return SX126xReadRegister( addr );
|
||||
}
|
||||
|
||||
void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
|
||||
void RadioWriteBuffer( uint32_t addr, uint8_t *buffer, uint8_t size )
|
||||
{
|
||||
SX126xWriteRegisters( addr, buffer, size );
|
||||
}
|
||||
|
||||
void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
|
||||
void RadioReadBuffer( uint32_t addr, uint8_t *buffer, uint8_t size )
|
||||
{
|
||||
SX126xReadRegisters( addr, buffer, size );
|
||||
}
|
||||
|
||||
void RadioWriteFifo( uint8_t *buffer, uint8_t size )
|
||||
{
|
||||
SX126xWriteBuffer( 0, buffer, size );
|
||||
}
|
||||
|
||||
void RadioReadFifo( uint8_t *buffer, uint8_t size )
|
||||
{
|
||||
SX126xReadBuffer( 0, buffer, size );
|
||||
}
|
||||
|
||||
void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max )
|
||||
{
|
||||
if( modem == MODEM_LORA )
|
||||
@@ -1094,32 +1232,41 @@ void RadioIrqProcess( void )
|
||||
|
||||
if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
|
||||
{
|
||||
uint8_t size;
|
||||
if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
|
||||
{
|
||||
if( RxContinuous == false )
|
||||
{
|
||||
//!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC
|
||||
SX126xSetOperatingMode( MODE_STDBY_RC );
|
||||
}
|
||||
if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) )
|
||||
{
|
||||
RadioEvents->RxError( );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t size;
|
||||
|
||||
TimerStop( &RxTimeoutTimer );
|
||||
if( RxContinuous == false )
|
||||
{
|
||||
//!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC
|
||||
SX126xSetOperatingMode( MODE_STDBY_RC );
|
||||
}
|
||||
SX126xGetPayload( RadioRxPayload, &size , 255 );
|
||||
SX126xGetPacketStatus( &RadioPktStatus );
|
||||
if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )
|
||||
{
|
||||
RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.LoRa.RssiPkt, RadioPktStatus.Params.LoRa.SnrPkt );
|
||||
}
|
||||
}
|
||||
TimerStop( &RxTimeoutTimer );
|
||||
if( RxContinuous == false )
|
||||
{
|
||||
//!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC
|
||||
SX126xSetOperatingMode( MODE_STDBY_RC );
|
||||
|
||||
if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
|
||||
{
|
||||
if( RxContinuous == false )
|
||||
{
|
||||
//!< Update operating mode state to a value lower than \ref MODE_STDBY_XOSC
|
||||
SX126xSetOperatingMode( MODE_STDBY_RC );
|
||||
}
|
||||
if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) )
|
||||
{
|
||||
RadioEvents->RxError( );
|
||||
// WORKAROUND - Implicit Header Mode Timeout Behavior, see DS_SX1261-2_V1.2 datasheet chapter 15.3
|
||||
// RegRtcControl = @address 0x0902
|
||||
SX126xWriteRegister( 0x0902, 0x00 );
|
||||
// RegEventMask = @address 0x0944
|
||||
SX126xWriteRegister( 0x0944, SX126xReadRegister( 0x0944 ) | ( 1 << 1 ) );
|
||||
// WORKAROUND END
|
||||
}
|
||||
SX126xGetPayload( RadioRxPayload, &size , 255 );
|
||||
SX126xGetPacketStatus( &RadioPktStatus );
|
||||
if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )
|
||||
{
|
||||
RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.LoRa.RssiPkt, RadioPktStatus.Params.LoRa.SnrPkt );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -47,6 +47,11 @@ static RadioOperatingModes_t OperatingMode;
|
||||
*/
|
||||
static RadioPacketTypes_t PacketType;
|
||||
|
||||
/*!
|
||||
* \brief Stores the current packet header type set in the radio
|
||||
*/
|
||||
static volatile RadioLoRaPacketLengthsMode_t LoRaHeaderType;
|
||||
|
||||
/*!
|
||||
* \brief Stores the last frequency error measured on LoRa received packet
|
||||
*/
|
||||
@@ -90,13 +95,8 @@ void SX126xInit( DioIrqHandler dioIrq )
|
||||
SX126xWakeup( );
|
||||
SX126xSetStandby( STDBY_RC );
|
||||
|
||||
#ifdef USE_TCXO
|
||||
CalibrationParams_t calibParam;
|
||||
|
||||
SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_1_7V, SX126xGetBoardTcxoWakeupTime( ) << 6 ); // convert from ms to SX126x time base
|
||||
calibParam.Value = 0x7F;
|
||||
SX126xCalibrate( calibParam );
|
||||
#endif
|
||||
// Initialize TCXO control
|
||||
SX126xIoTcxoInit( );
|
||||
|
||||
SX126xSetDio2AsRfSwitchCtrl( true );
|
||||
SX126xSetOperatingMode( MODE_STDBY_RC );
|
||||
@@ -227,25 +227,37 @@ void SX126xSetWhiteningSeed( uint16_t seed )
|
||||
|
||||
uint32_t SX126xGetRandom( void )
|
||||
{
|
||||
uint8_t buf[] = { 0, 0, 0, 0 };
|
||||
uint32_t number = 0;
|
||||
uint8_t regAnaLna = 0;
|
||||
uint8_t regAnaMixer = 0;
|
||||
|
||||
regAnaLna = SX126xReadRegister( REG_ANA_LNA );
|
||||
SX126xWriteRegister( REG_ANA_LNA, regAnaLna & ~( 1 << 0 ) );
|
||||
|
||||
regAnaMixer = SX126xReadRegister( REG_ANA_MIXER );
|
||||
SX126xWriteRegister( REG_ANA_MIXER, regAnaMixer & ~( 1 << 7 ) );
|
||||
|
||||
// Set radio in continuous reception
|
||||
SX126xSetRx( 0 );
|
||||
SX126xSetRx( 0xFFFFFF ); // Rx Continuous
|
||||
|
||||
DelayMs( 1 );
|
||||
|
||||
SX126xReadRegisters( RANDOM_NUMBER_GENERATORBASEADDR, buf, 4 );
|
||||
SX126xReadRegisters( RANDOM_NUMBER_GENERATORBASEADDR, ( uint8_t* )&number, 4 );
|
||||
|
||||
SX126xSetStandby( STDBY_RC );
|
||||
|
||||
return ( buf[0] << 24 ) | ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3];
|
||||
SX126xWriteRegister( REG_ANA_LNA, regAnaLna );
|
||||
SX126xWriteRegister( REG_ANA_MIXER, regAnaMixer );
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
void SX126xSetSleep( SleepParams_t sleepConfig )
|
||||
{
|
||||
SX126xAntSwOff( );
|
||||
|
||||
SX126xWriteCommand( RADIO_SET_SLEEP, &sleepConfig.Value, 1 );
|
||||
uint8_t value = ( ( ( uint8_t )sleepConfig.Fields.WarmStart << 2 ) |
|
||||
( ( uint8_t )sleepConfig.Fields.Reset << 1 ) |
|
||||
( ( uint8_t )sleepConfig.Fields.WakeUpRTC ) );
|
||||
SX126xWriteCommand( RADIO_SET_SLEEP, &value, 1 );
|
||||
SX126xSetOperatingMode( MODE_SLEEP );
|
||||
}
|
||||
|
||||
@@ -344,6 +356,19 @@ void SX126xSetStopRxTimerOnPreambleDetect( bool enable )
|
||||
void SX126xSetLoRaSymbNumTimeout( uint8_t SymbNum )
|
||||
{
|
||||
SX126xWriteCommand( RADIO_SET_LORASYMBTIMEOUT, &SymbNum, 1 );
|
||||
|
||||
uint8_t mant = SymbNum >> 1;
|
||||
uint8_t exp = 0;
|
||||
uint8_t reg = 0;
|
||||
|
||||
while( mant > 31 )
|
||||
{
|
||||
mant >>= 2;
|
||||
exp++;
|
||||
}
|
||||
|
||||
reg = exp + ( mant << 3 );
|
||||
SX126xWriteRegister( REG_LR_SYNCH_TIMEOUT, reg );
|
||||
}
|
||||
|
||||
void SX126xSetRegulatorMode( RadioRegulatorMode_t mode )
|
||||
@@ -353,7 +378,15 @@ void SX126xSetRegulatorMode( RadioRegulatorMode_t mode )
|
||||
|
||||
void SX126xCalibrate( CalibrationParams_t calibParam )
|
||||
{
|
||||
SX126xWriteCommand( RADIO_CALIBRATE, ( uint8_t* )&calibParam, 1 );
|
||||
uint8_t value = ( ( ( uint8_t )calibParam.Fields.ImgEnable << 6 ) |
|
||||
( ( uint8_t )calibParam.Fields.ADCBulkPEnable << 5 ) |
|
||||
( ( uint8_t )calibParam.Fields.ADCBulkNEnable << 4 ) |
|
||||
( ( uint8_t )calibParam.Fields.ADCPulseEnable << 3 ) |
|
||||
( ( uint8_t )calibParam.Fields.PLLEnable << 2 ) |
|
||||
( ( uint8_t )calibParam.Fields.RC13MEnable << 1 ) |
|
||||
( ( uint8_t )calibParam.Fields.RC64KEnable ) );
|
||||
|
||||
SX126xWriteCommand( RADIO_CALIBRATE, &value, 1 );
|
||||
}
|
||||
|
||||
void SX126xCalibrateImage( uint32_t freq )
|
||||
@@ -501,6 +534,11 @@ void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime )
|
||||
}
|
||||
else // sx1262
|
||||
{
|
||||
// WORKAROUND - Better Resistance of the SX1262 Tx to Antenna Mismatch, see DS_SX1261-2_V1.2 datasheet chapter 15.2
|
||||
// RegTxClampConfig = @address 0x08D8
|
||||
SX126xWriteRegister( 0x08D8, SX126xReadRegister( 0x08D8 ) | ( 0x0F << 1 ) );
|
||||
// WORKAROUND END
|
||||
|
||||
SX126xSetPaConfig( 0x04, 0x07, 0x00, 0x01 );
|
||||
if( power > 22 )
|
||||
{
|
||||
@@ -609,7 +647,7 @@ void SX126xSetPacketParams( PacketParams_t *packetParams )
|
||||
n = 6;
|
||||
buf[0] = ( packetParams->Params.LoRa.PreambleLength >> 8 ) & 0xFF;
|
||||
buf[1] = packetParams->Params.LoRa.PreambleLength;
|
||||
buf[2] = packetParams->Params.LoRa.HeaderType;
|
||||
buf[2] = LoRaHeaderType = packetParams->Params.LoRa.HeaderType;
|
||||
buf[3] = packetParams->Params.LoRa.PayloadLength;
|
||||
buf[4] = packetParams->Params.LoRa.CrcMode;
|
||||
buf[5] = packetParams->Params.LoRa.InvertIQ;
|
||||
@@ -632,7 +670,7 @@ void SX126xSetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak,
|
||||
buf[4] = ( uint8_t )( ( cadTimeout >> 16 ) & 0xFF );
|
||||
buf[5] = ( uint8_t )( ( cadTimeout >> 8 ) & 0xFF );
|
||||
buf[6] = ( uint8_t )( cadTimeout & 0xFF );
|
||||
SX126xWriteCommand( RADIO_SET_CADPARAMS, buf, 5 );
|
||||
SX126xWriteCommand( RADIO_SET_CADPARAMS, buf, 7 );
|
||||
SX126xSetOperatingMode( MODE_CAD );
|
||||
}
|
||||
|
||||
@@ -648,10 +686,11 @@ void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress )
|
||||
RadioStatus_t SX126xGetStatus( void )
|
||||
{
|
||||
uint8_t stat = 0;
|
||||
RadioStatus_t status;
|
||||
RadioStatus_t status = { .Value = 0 };
|
||||
|
||||
SX126xReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 );
|
||||
status.Value = stat;
|
||||
stat = SX126xReadCommand( RADIO_GET_STATUS, NULL, 0 );
|
||||
status.Fields.CmdStatus = ( stat & ( 0x07 << 1 ) ) >> 1;
|
||||
status.Fields.ChipMode = ( stat & ( 0x07 << 4 ) ) >> 4;
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -673,7 +712,7 @@ void SX126xGetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPoin
|
||||
|
||||
// In case of LORA fixed header, the payloadLength is obtained by reading
|
||||
// the register REG_LR_PAYLOADLENGTH
|
||||
if( ( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) && ( SX126xReadRegister( REG_LR_PACKETPARAMS ) >> 7 == 1 ) )
|
||||
if( ( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) && ( LoRaHeaderType == LORA_PACKET_FIXED_LENGTH ) )
|
||||
{
|
||||
*payloadLength = SX126xReadRegister( REG_LR_PAYLOADLENGTH );
|
||||
}
|
||||
@@ -720,9 +759,18 @@ void SX126xGetPacketStatus( PacketStatus_t *pktStatus )
|
||||
|
||||
RadioError_t SX126xGetDeviceErrors( void )
|
||||
{
|
||||
RadioError_t error;
|
||||
uint8_t err[] = { 0, 0 };
|
||||
RadioError_t error = { .Value = 0 };
|
||||
|
||||
SX126xReadCommand( RADIO_GET_ERROR, ( uint8_t * )&error, 2 );
|
||||
SX126xReadCommand( RADIO_GET_ERROR, ( uint8_t* )err, 2 );
|
||||
error.Fields.PaRamp = ( err[0] & ( 1 << 0 ) ) >> 0;
|
||||
error.Fields.PllLock = ( err[1] & ( 1 << 6 ) ) >> 6;
|
||||
error.Fields.XoscStart = ( err[1] & ( 1 << 5 ) ) >> 5;
|
||||
error.Fields.ImgCalib = ( err[1] & ( 1 << 4 ) ) >> 4;
|
||||
error.Fields.AdcCalib = ( err[1] & ( 1 << 3 ) ) >> 3;
|
||||
error.Fields.PllCalib = ( err[1] & ( 1 << 2 ) ) >> 2;
|
||||
error.Fields.Rc13mCalib = ( err[1] & ( 1 << 1 ) ) >> 1;
|
||||
error.Fields.Rc64kCalib = ( err[1] & ( 1 << 0 ) ) >> 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,11 @@
|
||||
#ifndef __SX126x_H__
|
||||
#define __SX126x_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
@@ -90,6 +95,11 @@
|
||||
*/
|
||||
#define REG_LR_PAYLOADLENGTH 0x0702
|
||||
|
||||
/*!
|
||||
* \brief The address of the register holding the re-calculated number of symbols
|
||||
*/
|
||||
#define REG_LR_SYNCH_TIMEOUT 0x0706
|
||||
|
||||
/*!
|
||||
* \brief The addresses of the registers holding SyncWords values
|
||||
*/
|
||||
@@ -110,11 +120,22 @@
|
||||
*/
|
||||
#define LORA_MAC_PUBLIC_SYNCWORD 0x3444
|
||||
|
||||
|
||||
/*!
|
||||
* The address of the register giving a 4 bytes random number
|
||||
* The address of the register giving a 32-bit random number
|
||||
*/
|
||||
#define RANDOM_NUMBER_GENERATORBASEADDR 0x0819
|
||||
|
||||
/*!
|
||||
* The address of the register used to disable the LNA
|
||||
*/
|
||||
#define REG_ANA_LNA 0x08E2
|
||||
|
||||
/*!
|
||||
* The address of the register used to disable the mixer
|
||||
*/
|
||||
#define REG_ANA_MIXER 0x08E5
|
||||
|
||||
/*!
|
||||
* The address of the register holding RX Gain value (0x94: power saving, 0x96: rx boosted)
|
||||
*/
|
||||
@@ -138,10 +159,10 @@ typedef union RadioStatus_u
|
||||
uint8_t Value;
|
||||
struct
|
||||
{ //bit order is lsb -> msb
|
||||
uint8_t Reserved : 1; //!< Reserved
|
||||
uint8_t : 1; //!< Reserved
|
||||
uint8_t CmdStatus : 3; //!< Command status
|
||||
uint8_t ChipMode : 3; //!< Chip mode
|
||||
uint8_t CpuBusy : 1; //!< Flag for CPU radio busy
|
||||
uint8_t : 1; //!< Reserved
|
||||
}Fields;
|
||||
}RadioStatus_t;
|
||||
|
||||
@@ -643,7 +664,7 @@ typedef union
|
||||
uint8_t ImgCalib : 1; //!< Image calibration failed
|
||||
uint8_t XoscStart : 1; //!< XOSC oscillator failed to start
|
||||
uint8_t PllLock : 1; //!< PLL lock failed
|
||||
uint8_t BuckStart : 1; //!< Buck converter failed to start
|
||||
uint8_t : 1; //!< Buck converter failed to start
|
||||
uint8_t PaRamp : 1; //!< PA ramp failed
|
||||
uint8_t : 7; //!< Reserved
|
||||
}Fields;
|
||||
@@ -796,9 +817,19 @@ void SX126xSetCrcPolynomial( uint16_t polynomial );
|
||||
void SX126xSetWhiteningSeed( uint16_t seed );
|
||||
|
||||
/*!
|
||||
* \brief Gets a 32 bits random value generated by the radio
|
||||
* \brief Gets a 32-bit random value generated by the radio
|
||||
*
|
||||
* \remark A valid packet type must have been configured with \ref SX126xSetPacketType
|
||||
* before using this command.
|
||||
*
|
||||
* \remark The radio must be in reception mode before executing this function
|
||||
* This code can potentially result in interrupt generation. It is the responsibility of
|
||||
* the calling code to disable radio interrupts before calling this function,
|
||||
* and re-enable them afterwards if necessary, or be certain that any interrupts
|
||||
* generated during this process will not cause undesired side-effects in the software.
|
||||
*
|
||||
* Please note that the random numbers produced by the generator do not have a uniform or Gaussian distribution. If
|
||||
* uniformity is needed, perform appropriate software post-processing.
|
||||
*
|
||||
* \retval randomValue 32 bits random value
|
||||
*/
|
||||
@@ -1113,4 +1144,8 @@ void SX126xClearDeviceErrors( void );
|
||||
*/
|
||||
void SX126xClearIrqStatus( uint16_t irq );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SX126x_H__
|
||||
|
@@ -260,6 +260,8 @@ bool SX1272IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh
|
||||
int16_t rssi = 0;
|
||||
uint32_t carrierSenseTime = 0;
|
||||
|
||||
SX1272SetSleep( );
|
||||
|
||||
SX1272SetModem( modem );
|
||||
|
||||
SX1272SetChannel( freq );
|
||||
@@ -610,61 +612,136 @@ void SX1272SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t SX1272GetTimeOnAir( RadioModems_t modem, uint8_t pktLen )
|
||||
static uint32_t SX1272GetLoRaBandwidthInHz( uint32_t bw )
|
||||
{
|
||||
uint32_t airTime = 0;
|
||||
uint32_t bandwidthInHz = 0;
|
||||
|
||||
switch( bw )
|
||||
{
|
||||
case 0: // 125 kHz
|
||||
bandwidthInHz = 125000UL;
|
||||
break;
|
||||
case 1: // 250 kHz
|
||||
bandwidthInHz = 250000UL;
|
||||
break;
|
||||
case 2: // 500 kHz
|
||||
bandwidthInHz = 500000UL;
|
||||
break;
|
||||
}
|
||||
|
||||
return bandwidthInHz;
|
||||
}
|
||||
|
||||
static uint32_t SX1272GetGfskTimeOnAirNumerator( uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn )
|
||||
{
|
||||
const uint8_t syncWordLength = 3;
|
||||
|
||||
return ( preambleLen << 3 ) +
|
||||
( ( fixLen == false ) ? 8 : 0 ) +
|
||||
( syncWordLength << 3 ) +
|
||||
( ( payloadLen +
|
||||
( 0 ) + // Address filter size
|
||||
( ( crcOn == true ) ? 2 : 0 )
|
||||
) << 3
|
||||
);
|
||||
}
|
||||
|
||||
static uint32_t SX1272GetLoRaTimeOnAirNumerator( uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn )
|
||||
{
|
||||
int32_t crDenom = coderate + 4;
|
||||
bool lowDatareOptimize = false;
|
||||
|
||||
// Ensure that the preamble length is at least 12 symbols when using SF5 or
|
||||
// SF6
|
||||
if( ( datarate == 5 ) || ( datarate == 6 ) )
|
||||
{
|
||||
if( preambleLen < 12 )
|
||||
{
|
||||
preambleLen = 12;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
|
||||
( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
|
||||
{
|
||||
lowDatareOptimize = true;
|
||||
}
|
||||
|
||||
int32_t ceilDenominator;
|
||||
int32_t ceilNumerator = ( payloadLen << 3 ) +
|
||||
( crcOn ? 16 : 0 ) -
|
||||
( 4 * datarate ) +
|
||||
( fixLen ? 0 : 20 );
|
||||
|
||||
if( datarate <= 6 )
|
||||
{
|
||||
ceilDenominator = 4 * datarate;
|
||||
}
|
||||
else
|
||||
{
|
||||
ceilNumerator += 8;
|
||||
|
||||
if( lowDatareOptimize == true )
|
||||
{
|
||||
ceilDenominator = 4 * ( datarate - 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
ceilDenominator = 4 * datarate;
|
||||
}
|
||||
}
|
||||
|
||||
if( ceilNumerator < 0 )
|
||||
{
|
||||
ceilNumerator = 0;
|
||||
}
|
||||
|
||||
// Perform integral ceil()
|
||||
int32_t intermediate =
|
||||
( ( ceilNumerator + ceilDenominator - 1 ) / ceilDenominator ) * crDenom + preambleLen + 12;
|
||||
|
||||
if( datarate <= 6 )
|
||||
{
|
||||
intermediate += 2;
|
||||
}
|
||||
|
||||
return ( uint32_t )( ( 4 * intermediate + 1 ) * ( 1 << ( datarate - 2 ) ) );
|
||||
}
|
||||
|
||||
uint32_t SX1272GetTimeOnAir( RadioModems_t modem, uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn )
|
||||
{
|
||||
uint32_t numerator = 0;
|
||||
uint32_t denominator = 1;
|
||||
|
||||
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 ) * 1000 );
|
||||
numerator = 1000U * SX1272GetGfskTimeOnAirNumerator( datarate, coderate,
|
||||
preambleLen, fixLen,
|
||||
payloadLen, crcOn );
|
||||
denominator = datarate;
|
||||
}
|
||||
break;
|
||||
case MODEM_LORA:
|
||||
{
|
||||
double bw = 0.0;
|
||||
switch( SX1272.Settings.LoRa.Bandwidth )
|
||||
{
|
||||
case 0: // 125 kHz
|
||||
bw = 125000;
|
||||
break;
|
||||
case 1: // 250 kHz
|
||||
bw = 250000;
|
||||
break;
|
||||
case 2: // 500 kHz
|
||||
bw = 500000;
|
||||
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 * 1000 + 0.999 );
|
||||
numerator = 1000U * SX1272GetLoRaTimeOnAirNumerator( bandwidth, datarate,
|
||||
coderate, preambleLen,
|
||||
fixLen, payloadLen, crcOn );
|
||||
denominator = SX1272GetLoRaBandwidthInHz( bandwidth );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return airTime;
|
||||
// Perform integral ceil()
|
||||
return ( numerator + denominator - 1 ) / denominator;
|
||||
}
|
||||
|
||||
void SX1272Send( uint8_t *buffer, uint8_t size )
|
||||
@@ -745,8 +822,13 @@ void SX1272SetSleep( void )
|
||||
{
|
||||
TimerStop( &RxTimeoutTimer );
|
||||
TimerStop( &TxTimeoutTimer );
|
||||
TimerStop( &RxTimeoutSyncWord );
|
||||
|
||||
SX1272SetOpMode( RF_OPMODE_SLEEP );
|
||||
|
||||
// Disable TCXO radio is in SLEEP mode
|
||||
SX1272SetBoardTcxo( false );
|
||||
|
||||
SX1272.Settings.State = RF_IDLE;
|
||||
}
|
||||
|
||||
@@ -754,6 +836,7 @@ void SX1272SetStby( void )
|
||||
{
|
||||
TimerStop( &RxTimeoutTimer );
|
||||
TimerStop( &TxTimeoutTimer );
|
||||
TimerStop( &RxTimeoutSyncWord );
|
||||
|
||||
SX1272SetOpMode( RF_OPMODE_STANDBY );
|
||||
SX1272.Settings.State = RF_IDLE;
|
||||
@@ -762,6 +845,7 @@ void SX1272SetStby( void )
|
||||
void SX1272SetRx( uint32_t timeout )
|
||||
{
|
||||
bool rxContinuous = false;
|
||||
TimerStop( &TxTimeoutTimer );
|
||||
|
||||
switch( SX1272.Settings.Modem )
|
||||
{
|
||||
@@ -880,6 +964,8 @@ void SX1272SetRx( uint32_t timeout )
|
||||
|
||||
void SX1272SetTx( uint32_t timeout )
|
||||
{
|
||||
TimerStop( &RxTimeoutTimer );
|
||||
|
||||
TimerSetValue( &TxTimeoutTimer, timeout );
|
||||
|
||||
switch( SX1272.Settings.Modem )
|
||||
@@ -976,7 +1062,7 @@ void SX1272StartCad( void )
|
||||
|
||||
void SX1272SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
|
||||
{
|
||||
uint32_t timeout = ( uint32_t )( time * 1000 );
|
||||
uint32_t timeout = ( uint32_t )time * 1000;
|
||||
|
||||
SX1272SetChannel( freq );
|
||||
|
||||
@@ -1039,6 +1125,8 @@ void SX1272SetOpMode( uint8_t opMode )
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enable TCXO if operating mode different from SLEEP.
|
||||
SX1272SetBoardTcxo( true );
|
||||
SX1272SetAntSwLowPower( false );
|
||||
SX1272SetAntSw( opMode );
|
||||
}
|
||||
@@ -1066,14 +1154,14 @@ void SX1272SetModem( RadioModems_t modem )
|
||||
{
|
||||
default:
|
||||
case MODEM_FSK:
|
||||
SX1272SetSleep( );
|
||||
SX1272SetOpMode( RF_OPMODE_SLEEP );
|
||||
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( );
|
||||
SX1272SetOpMode( RF_OPMODE_SLEEP );
|
||||
SX1272Write( REG_OPMODE, ( SX1272Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
|
||||
|
||||
SX1272Write( REG_DIOMAPPING1, 0x00 );
|
||||
@@ -1082,19 +1170,19 @@ void SX1272SetModem( RadioModems_t modem )
|
||||
}
|
||||
}
|
||||
|
||||
void SX1272Write( uint16_t addr, uint8_t data )
|
||||
void SX1272Write( uint32_t addr, uint8_t data )
|
||||
{
|
||||
SX1272WriteBuffer( addr, &data, 1 );
|
||||
}
|
||||
|
||||
uint8_t SX1272Read( uint16_t addr )
|
||||
uint8_t SX1272Read( uint32_t addr )
|
||||
{
|
||||
uint8_t data;
|
||||
SX1272ReadBuffer( addr, &data, 1 );
|
||||
return data;
|
||||
}
|
||||
|
||||
void SX1272WriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
|
||||
void SX1272WriteBuffer( uint32_t addr, uint8_t *buffer, uint8_t size )
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
@@ -1111,7 +1199,7 @@ void SX1272WriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
|
||||
GpioWrite( &SX1272.Spi.Nss, 1 );
|
||||
}
|
||||
|
||||
void SX1272ReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
|
||||
void SX1272ReadBuffer( uint32_t addr, uint8_t *buffer, uint8_t size )
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
@@ -1200,7 +1288,6 @@ void SX1272OnTimeoutIrq( void* context )
|
||||
{
|
||||
// Continuous mode restart Rx chain
|
||||
SX1272Write( REG_RXCONFIG, SX1272Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
|
||||
TimerStart( &RxTimeoutSyncWord );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1215,10 +1302,12 @@ void SX1272OnTimeoutIrq( void* context )
|
||||
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.
|
||||
// Reported issue of SPI data corruption resulting in TX TIMEOUT
|
||||
// is NOT related to a bug in radio transceiver.
|
||||
// It is mainly caused by improper PCB routing of SPI lines and/or
|
||||
// violation of SPI specifications.
|
||||
// To mitigate redesign, Semtech offers a workaround which resets
|
||||
// the radio transceiver and putting it into a known state.
|
||||
|
||||
// BEGIN WORKAROUND
|
||||
|
||||
@@ -1284,7 +1373,6 @@ void SX1272OnDio0Irq( void* context )
|
||||
{
|
||||
// Continuous mode restart Rx chain
|
||||
SX1272Write( REG_RXCONFIG, SX1272Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
|
||||
TimerStart( &RxTimeoutSyncWord );
|
||||
}
|
||||
|
||||
if( ( RadioEvents != NULL ) && ( RadioEvents->RxError != NULL ) )
|
||||
@@ -1330,7 +1418,6 @@ void SX1272OnDio0Irq( void* context )
|
||||
{
|
||||
// Continuous mode restart Rx chain
|
||||
SX1272Write( REG_RXCONFIG, SX1272Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
|
||||
TimerStart( &RxTimeoutSyncWord );
|
||||
}
|
||||
|
||||
if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )
|
||||
@@ -1432,6 +1519,9 @@ void SX1272OnDio1Irq( void* context )
|
||||
switch( SX1272.Settings.Modem )
|
||||
{
|
||||
case MODEM_FSK:
|
||||
// Stop timer
|
||||
TimerStop( &RxTimeoutSyncWord );
|
||||
|
||||
// FifoLevel interrupt
|
||||
// Read received packet size
|
||||
if( ( SX1272.Settings.FskPacketHandler.Size == 0 ) && ( SX1272.Settings.FskPacketHandler.NbBytes == 0 ) )
|
||||
|
@@ -23,6 +23,11 @@
|
||||
#ifndef __SX1272_H__
|
||||
#define __SX1272_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "gpio.h"
|
||||
@@ -308,12 +313,31 @@ void SX1272SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
|
||||
*
|
||||
* \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
|
||||
* \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] 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] payloadLen Sets payload length when fixed length is used
|
||||
* \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON]
|
||||
*
|
||||
* \retval airTime Computed airTime (ms) for the given packet payload length
|
||||
*/
|
||||
uint32_t SX1272GetTimeOnAir( RadioModems_t modem, uint8_t pktLen );
|
||||
uint32_t SX1272GetTimeOnAir( RadioModems_t modem, uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn );
|
||||
|
||||
/*!
|
||||
* \brief Sends the buffer of size. Prepares the packet to be sent and sets
|
||||
@@ -367,7 +391,7 @@ int16_t SX1272ReadRssi( RadioModems_t modem );
|
||||
* \param [IN]: addr Register address
|
||||
* \param [IN]: data New register value
|
||||
*/
|
||||
void SX1272Write( uint16_t addr, uint8_t data );
|
||||
void SX1272Write( uint32_t addr, uint8_t data );
|
||||
|
||||
/*!
|
||||
* \brief Reads the radio register at the specified address
|
||||
@@ -375,7 +399,7 @@ void SX1272Write( uint16_t addr, uint8_t data );
|
||||
* \param [IN]: addr Register address
|
||||
* \retval data Register value
|
||||
*/
|
||||
uint8_t SX1272Read( uint16_t addr );
|
||||
uint8_t SX1272Read( uint32_t addr );
|
||||
|
||||
/*!
|
||||
* \brief Writes multiple radio registers starting at address
|
||||
@@ -384,7 +408,7 @@ uint8_t SX1272Read( uint16_t addr );
|
||||
* \param [IN] buffer Buffer containing the new register's values
|
||||
* \param [IN] size Number of registers to be written
|
||||
*/
|
||||
void SX1272WriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
void SX1272WriteBuffer( uint32_t addr, uint8_t *buffer, uint8_t size );
|
||||
|
||||
/*!
|
||||
* \brief Reads multiple radio registers starting at address
|
||||
@@ -393,7 +417,7 @@ void SX1272WriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
* \param [OUT] buffer Buffer where to copy the registers data
|
||||
* \param [IN] size Number of registers to be read
|
||||
*/
|
||||
void SX1272ReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
void SX1272ReadBuffer( uint32_t addr, uint8_t *buffer, uint8_t size );
|
||||
|
||||
/*!
|
||||
* \brief Sets the maximum payload length.
|
||||
@@ -419,4 +443,8 @@ void SX1272SetPublicNetwork( bool enable );
|
||||
*/
|
||||
uint32_t SX1272GetWakeupTime( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SX1272_H__
|
||||
|
@@ -23,6 +23,11 @@
|
||||
#ifndef __SX1272_REGS_FSK_H__
|
||||
#define __SX1272_REGS_FSK_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* ============================================================================
|
||||
* SX1272 Internal registers Address
|
||||
@@ -1139,4 +1144,8 @@
|
||||
*/
|
||||
#define RF_BITRATEFRAC_MASK 0xF0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SX1272_REGS_FSK_H__
|
||||
|
@@ -23,6 +23,11 @@
|
||||
#ifndef __SX1272_REGS_LORA_H__
|
||||
#define __SX1272_REGS_LORA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* ============================================================================
|
||||
* SX1272 Internal registers Address
|
||||
@@ -550,4 +555,8 @@
|
||||
* RegFormerTemp
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SX1272_REGS_LORA_H__
|
||||
|
@@ -271,6 +271,8 @@ bool SX1276IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh
|
||||
int16_t rssi = 0;
|
||||
uint32_t carrierSenseTime = 0;
|
||||
|
||||
SX1276SetSleep( );
|
||||
|
||||
SX1276SetModem( modem );
|
||||
|
||||
SX1276SetChannel( freq );
|
||||
@@ -695,83 +697,136 @@ void SX1276SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t SX1276GetTimeOnAir( RadioModems_t modem, uint8_t pktLen )
|
||||
static uint32_t SX1276GetLoRaBandwidthInHz( uint32_t bw )
|
||||
{
|
||||
uint32_t airTime = 0;
|
||||
uint32_t bandwidthInHz = 0;
|
||||
|
||||
switch( bw )
|
||||
{
|
||||
case 0: // 125 kHz
|
||||
bandwidthInHz = 125000UL;
|
||||
break;
|
||||
case 1: // 250 kHz
|
||||
bandwidthInHz = 250000UL;
|
||||
break;
|
||||
case 2: // 500 kHz
|
||||
bandwidthInHz = 500000UL;
|
||||
break;
|
||||
}
|
||||
|
||||
return bandwidthInHz;
|
||||
}
|
||||
|
||||
static uint32_t SX1276GetGfskTimeOnAirNumerator( uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn )
|
||||
{
|
||||
const uint8_t syncWordLength = 3;
|
||||
|
||||
return ( preambleLen << 3 ) +
|
||||
( ( fixLen == false ) ? 8 : 0 ) +
|
||||
( syncWordLength << 3 ) +
|
||||
( ( payloadLen +
|
||||
( 0 ) + // Address filter size
|
||||
( ( crcOn == true ) ? 2 : 0 )
|
||||
) << 3
|
||||
);
|
||||
}
|
||||
|
||||
static uint32_t SX1276GetLoRaTimeOnAirNumerator( uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn )
|
||||
{
|
||||
int32_t crDenom = coderate + 4;
|
||||
bool lowDatareOptimize = false;
|
||||
|
||||
// Ensure that the preamble length is at least 12 symbols when using SF5 or
|
||||
// SF6
|
||||
if( ( datarate == 5 ) || ( datarate == 6 ) )
|
||||
{
|
||||
if( preambleLen < 12 )
|
||||
{
|
||||
preambleLen = 12;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
|
||||
( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
|
||||
{
|
||||
lowDatareOptimize = true;
|
||||
}
|
||||
|
||||
int32_t ceilDenominator;
|
||||
int32_t ceilNumerator = ( payloadLen << 3 ) +
|
||||
( crcOn ? 16 : 0 ) -
|
||||
( 4 * datarate ) +
|
||||
( fixLen ? 0 : 20 );
|
||||
|
||||
if( datarate <= 6 )
|
||||
{
|
||||
ceilDenominator = 4 * datarate;
|
||||
}
|
||||
else
|
||||
{
|
||||
ceilNumerator += 8;
|
||||
|
||||
if( lowDatareOptimize == true )
|
||||
{
|
||||
ceilDenominator = 4 * ( datarate - 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
ceilDenominator = 4 * datarate;
|
||||
}
|
||||
}
|
||||
|
||||
if( ceilNumerator < 0 )
|
||||
{
|
||||
ceilNumerator = 0;
|
||||
}
|
||||
|
||||
// Perform integral ceil()
|
||||
int32_t intermediate =
|
||||
( ( ceilNumerator + ceilDenominator - 1 ) / ceilDenominator ) * crDenom + preambleLen + 12;
|
||||
|
||||
if( datarate <= 6 )
|
||||
{
|
||||
intermediate += 2;
|
||||
}
|
||||
|
||||
return ( uint32_t )( ( 4 * intermediate + 1 ) * ( 1 << ( datarate - 2 ) ) );
|
||||
}
|
||||
|
||||
uint32_t SX1276GetTimeOnAir( RadioModems_t modem, uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn )
|
||||
{
|
||||
uint32_t numerator = 0;
|
||||
uint32_t denominator = 1;
|
||||
|
||||
switch( modem )
|
||||
{
|
||||
case MODEM_FSK:
|
||||
{
|
||||
airTime = round( ( 8 * ( SX1276.Settings.Fsk.PreambleLen +
|
||||
( ( SX1276Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
|
||||
( ( SX1276.Settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
|
||||
( ( ( SX1276Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
|
||||
pktLen +
|
||||
( ( SX1276.Settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) /
|
||||
SX1276.Settings.Fsk.Datarate ) * 1000 );
|
||||
numerator = 1000U * SX1276GetGfskTimeOnAirNumerator( datarate, coderate,
|
||||
preambleLen, fixLen,
|
||||
payloadLen, crcOn );
|
||||
denominator = datarate;
|
||||
}
|
||||
break;
|
||||
case MODEM_LORA:
|
||||
{
|
||||
double bw = 0.0;
|
||||
// REMARK: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
|
||||
switch( SX1276.Settings.LoRa.Bandwidth )
|
||||
{
|
||||
//case 0: // 7.8 kHz
|
||||
// bw = 7800;
|
||||
// break;
|
||||
//case 1: // 10.4 kHz
|
||||
// bw = 10400;
|
||||
// break;
|
||||
//case 2: // 15.6 kHz
|
||||
// bw = 15600;
|
||||
// break;
|
||||
//case 3: // 20.8 kHz
|
||||
// bw = 20800;
|
||||
// break;
|
||||
//case 4: // 31.2 kHz
|
||||
// bw = 31200;
|
||||
// break;
|
||||
//case 5: // 41.4 kHz
|
||||
// bw = 41400;
|
||||
// break;
|
||||
//case 6: // 62.5 kHz
|
||||
// bw = 62500;
|
||||
// break;
|
||||
case 7: // 125 kHz
|
||||
bw = 125000;
|
||||
break;
|
||||
case 8: // 250 kHz
|
||||
bw = 250000;
|
||||
break;
|
||||
case 9: // 500 kHz
|
||||
bw = 500000;
|
||||
break;
|
||||
}
|
||||
|
||||
// Symbol rate : time for one symbol (secs)
|
||||
double rs = bw / ( 1 << SX1276.Settings.LoRa.Datarate );
|
||||
double ts = 1 / rs;
|
||||
// time of preamble
|
||||
double tPreamble = ( SX1276.Settings.LoRa.PreambleLen + 4.25 ) * ts;
|
||||
// Symbol length of payload and time
|
||||
double tmp = ceil( ( 8 * pktLen - 4 * SX1276.Settings.LoRa.Datarate +
|
||||
28 + 16 * SX1276.Settings.LoRa.CrcOn -
|
||||
( SX1276.Settings.LoRa.FixLen ? 20 : 0 ) ) /
|
||||
( double )( 4 * ( SX1276.Settings.LoRa.Datarate -
|
||||
( ( SX1276.Settings.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
|
||||
( SX1276.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 * 1000 + 0.999 );
|
||||
numerator = 1000U * SX1276GetLoRaTimeOnAirNumerator( bandwidth, datarate,
|
||||
coderate, preambleLen,
|
||||
fixLen, payloadLen, crcOn );
|
||||
denominator = SX1276GetLoRaBandwidthInHz( bandwidth );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return airTime;
|
||||
// Perform integral ceil()
|
||||
return ( numerator + denominator - 1 ) / denominator;
|
||||
}
|
||||
|
||||
void SX1276Send( uint8_t *buffer, uint8_t size )
|
||||
@@ -852,8 +907,13 @@ void SX1276SetSleep( void )
|
||||
{
|
||||
TimerStop( &RxTimeoutTimer );
|
||||
TimerStop( &TxTimeoutTimer );
|
||||
TimerStop( &RxTimeoutSyncWord );
|
||||
|
||||
SX1276SetOpMode( RF_OPMODE_SLEEP );
|
||||
|
||||
// Disable TCXO radio is in SLEEP mode
|
||||
SX1276SetBoardTcxo( false );
|
||||
|
||||
SX1276.Settings.State = RF_IDLE;
|
||||
}
|
||||
|
||||
@@ -861,6 +921,7 @@ void SX1276SetStby( void )
|
||||
{
|
||||
TimerStop( &RxTimeoutTimer );
|
||||
TimerStop( &TxTimeoutTimer );
|
||||
TimerStop( &RxTimeoutSyncWord );
|
||||
|
||||
SX1276SetOpMode( RF_OPMODE_STANDBY );
|
||||
SX1276.Settings.State = RF_IDLE;
|
||||
@@ -869,6 +930,7 @@ void SX1276SetStby( void )
|
||||
void SX1276SetRx( uint32_t timeout )
|
||||
{
|
||||
bool rxContinuous = false;
|
||||
TimerStop( &TxTimeoutTimer );
|
||||
|
||||
switch( SX1276.Settings.Modem )
|
||||
{
|
||||
@@ -1034,6 +1096,8 @@ void SX1276SetRx( uint32_t timeout )
|
||||
|
||||
void SX1276SetTx( uint32_t timeout )
|
||||
{
|
||||
TimerStop( &RxTimeoutTimer );
|
||||
|
||||
TimerSetValue( &TxTimeoutTimer, timeout );
|
||||
|
||||
switch( SX1276.Settings.Modem )
|
||||
@@ -1130,7 +1194,7 @@ void SX1276StartCad( void )
|
||||
|
||||
void SX1276SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
|
||||
{
|
||||
uint32_t timeout = ( uint32_t )( time * 1000 );
|
||||
uint32_t timeout = ( uint32_t )time * 1000;
|
||||
|
||||
SX1276SetChannel( freq );
|
||||
|
||||
@@ -1200,6 +1264,8 @@ void SX1276SetOpMode( uint8_t opMode )
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enable TCXO if operating mode different from SLEEP.
|
||||
SX1276SetBoardTcxo( true );
|
||||
SX1276SetAntSwLowPower( false );
|
||||
SX1276SetAntSw( opMode );
|
||||
}
|
||||
@@ -1227,14 +1293,14 @@ void SX1276SetModem( RadioModems_t modem )
|
||||
{
|
||||
default:
|
||||
case MODEM_FSK:
|
||||
SX1276SetSleep( );
|
||||
SX1276SetOpMode( RF_OPMODE_SLEEP );
|
||||
SX1276Write( REG_OPMODE, ( SX1276Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
|
||||
|
||||
SX1276Write( REG_DIOMAPPING1, 0x00 );
|
||||
SX1276Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
|
||||
break;
|
||||
case MODEM_LORA:
|
||||
SX1276SetSleep( );
|
||||
SX1276SetOpMode( RF_OPMODE_SLEEP );
|
||||
SX1276Write( REG_OPMODE, ( SX1276Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
|
||||
|
||||
SX1276Write( REG_DIOMAPPING1, 0x00 );
|
||||
@@ -1243,19 +1309,19 @@ void SX1276SetModem( RadioModems_t modem )
|
||||
}
|
||||
}
|
||||
|
||||
void SX1276Write( uint16_t addr, uint8_t data )
|
||||
void SX1276Write( uint32_t addr, uint8_t data )
|
||||
{
|
||||
SX1276WriteBuffer( addr, &data, 1 );
|
||||
}
|
||||
|
||||
uint8_t SX1276Read( uint16_t addr )
|
||||
uint8_t SX1276Read( uint32_t addr )
|
||||
{
|
||||
uint8_t data;
|
||||
SX1276ReadBuffer( addr, &data, 1 );
|
||||
return data;
|
||||
}
|
||||
|
||||
void SX1276WriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
|
||||
void SX1276WriteBuffer( uint32_t addr, uint8_t *buffer, uint8_t size )
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
@@ -1272,7 +1338,7 @@ void SX1276WriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
|
||||
GpioWrite( &SX1276.Spi.Nss, 1 );
|
||||
}
|
||||
|
||||
void SX1276ReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
|
||||
void SX1276ReadBuffer( uint32_t addr, uint8_t *buffer, uint8_t size )
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
@@ -1361,7 +1427,6 @@ void SX1276OnTimeoutIrq( void* context )
|
||||
{
|
||||
// Continuous mode restart Rx chain
|
||||
SX1276Write( REG_RXCONFIG, SX1276Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
|
||||
TimerStart( &RxTimeoutSyncWord );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1376,10 +1441,12 @@ void SX1276OnTimeoutIrq( void* context )
|
||||
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.
|
||||
// Reported issue of SPI data corruption resulting in TX TIMEOUT
|
||||
// is NOT related to a bug in radio transceiver.
|
||||
// It is mainly caused by improper PCB routing of SPI lines and/or
|
||||
// violation of SPI specifications.
|
||||
// To mitigate redesign, Semtech offers a workaround which resets
|
||||
// the radio transceiver and putting it into a known state.
|
||||
|
||||
// BEGIN WORKAROUND
|
||||
|
||||
@@ -1448,7 +1515,6 @@ void SX1276OnDio0Irq( void* context )
|
||||
{
|
||||
// Continuous mode restart Rx chain
|
||||
SX1276Write( REG_RXCONFIG, SX1276Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
|
||||
TimerStart( &RxTimeoutSyncWord );
|
||||
}
|
||||
|
||||
if( ( RadioEvents != NULL ) && ( RadioEvents->RxError != NULL ) )
|
||||
@@ -1494,7 +1560,6 @@ void SX1276OnDio0Irq( void* context )
|
||||
{
|
||||
// Continuous mode restart Rx chain
|
||||
SX1276Write( REG_RXCONFIG, SX1276Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
|
||||
TimerStart( &RxTimeoutSyncWord );
|
||||
}
|
||||
|
||||
if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )
|
||||
@@ -1611,6 +1676,9 @@ void SX1276OnDio1Irq( void* context )
|
||||
switch( SX1276.Settings.Modem )
|
||||
{
|
||||
case MODEM_FSK:
|
||||
// Stop timer
|
||||
TimerStop( &RxTimeoutSyncWord );
|
||||
|
||||
// FifoLevel interrupt
|
||||
// Read received packet size
|
||||
if( ( SX1276.Settings.FskPacketHandler.Size == 0 ) && ( SX1276.Settings.FskPacketHandler.NbBytes == 0 ) )
|
||||
|
@@ -23,6 +23,11 @@
|
||||
#ifndef __SX1276_H__
|
||||
#define __SX1276_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "gpio.h"
|
||||
@@ -312,12 +317,31 @@ void SX1276SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
|
||||
*
|
||||
* \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
|
||||
* \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] 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] payloadLen Sets payload length when fixed length is used
|
||||
* \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON]
|
||||
*
|
||||
* \retval airTime Computed airTime (ms) for the given packet payload length
|
||||
*/
|
||||
uint32_t SX1276GetTimeOnAir( RadioModems_t modem, uint8_t pktLen );
|
||||
uint32_t SX1276GetTimeOnAir( RadioModems_t modem, uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint16_t preambleLen, bool fixLen, uint8_t payloadLen,
|
||||
bool crcOn );
|
||||
|
||||
/*!
|
||||
* \brief Sends the buffer of size. Prepares the packet to be sent and sets
|
||||
@@ -371,7 +395,7 @@ int16_t SX1276ReadRssi( RadioModems_t modem );
|
||||
* \param [IN]: addr Register address
|
||||
* \param [IN]: data New register value
|
||||
*/
|
||||
void SX1276Write( uint16_t addr, uint8_t data );
|
||||
void SX1276Write( uint32_t addr, uint8_t data );
|
||||
|
||||
/*!
|
||||
* \brief Reads the radio register at the specified address
|
||||
@@ -379,7 +403,7 @@ void SX1276Write( uint16_t addr, uint8_t data );
|
||||
* \param [IN]: addr Register address
|
||||
* \retval data Register value
|
||||
*/
|
||||
uint8_t SX1276Read( uint16_t addr );
|
||||
uint8_t SX1276Read( uint32_t addr );
|
||||
|
||||
/*!
|
||||
* \brief Writes multiple radio registers starting at address
|
||||
@@ -388,7 +412,7 @@ uint8_t SX1276Read( uint16_t addr );
|
||||
* \param [IN] buffer Buffer containing the new register's values
|
||||
* \param [IN] size Number of registers to be written
|
||||
*/
|
||||
void SX1276WriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
void SX1276WriteBuffer( uint32_t addr, uint8_t *buffer, uint8_t size );
|
||||
|
||||
/*!
|
||||
* \brief Reads multiple radio registers starting at address
|
||||
@@ -397,7 +421,7 @@ void SX1276WriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
* \param [OUT] buffer Buffer where to copy the registers data
|
||||
* \param [IN] size Number of registers to be read
|
||||
*/
|
||||
void SX1276ReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
void SX1276ReadBuffer( uint32_t addr, uint8_t *buffer, uint8_t size );
|
||||
|
||||
/*!
|
||||
* \brief Sets the maximum payload length.
|
||||
@@ -423,4 +447,8 @@ void SX1276SetPublicNetwork( bool enable );
|
||||
*/
|
||||
uint32_t SX1276GetWakeupTime( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SX1276_H__
|
||||
|
@@ -23,6 +23,11 @@
|
||||
#ifndef __SX1276_REGS_FSK_H__
|
||||
#define __SX1276_REGS_FSK_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* ============================================================================
|
||||
* SX1276 Internal registers Address
|
||||
@@ -1139,4 +1144,8 @@
|
||||
#define RF_PLL_BANDWIDTH_225 0x80
|
||||
#define RF_PLL_BANDWIDTH_300 0xC0 // Default
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SX1276_REGS_FSK_H__
|
||||
|
@@ -23,6 +23,11 @@
|
||||
#ifndef __SX1276_REGS_LORA_H__
|
||||
#define __SX1276_REGS_LORA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* ============================================================================
|
||||
* SX1276 Internal registers Address
|
||||
@@ -570,4 +575,8 @@
|
||||
#define RF_PLL_BANDWIDTH_225 0x80
|
||||
#define RF_PLL_BANDWIDTH_300 0xC0 // Default
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SX1276_REGS_LORA_H__
|
||||
|
Reference in New Issue
Block a user