Files
HBshuiwuConcentrator/APP/sx1276-LoRa.c
2025-12-15 16:07:49 +08:00

833 lines
23 KiB
C

/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-LoRa.c
* \brief SX1276 RF chip driver mode LoRa
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
#include <math.h>
#include "hal_radio.h"
#include "sx1276-Fsk.h"
#include "sx1276-LoRaMisc.h"
#include "sx1276-LoRa.h"
/*!
* Frequency hopping frequencies table
*/
#if defined (HIGH_FREQUENCY)
const int32_t HoppingFrequencies[] =
{
916500000,
923500000,
906500000,
917500000,
917500000,
909000000,
903000000,
916000000,
912500000,
926000000,
925000000,
909500000,
913000000,
918500000,
918500000,
902500000,
911500000,
926500000,
902500000,
922000000,
924000000,
903500000,
913000000,
922000000,
926000000,
910000000,
920000000,
922500000,
911000000,
922000000,
909500000,
926000000,
922000000,
918000000,
925500000,
908000000,
917500000,
926500000,
908500000,
916000000,
905500000,
916000000,
903000000,
905000000,
915000000,
913000000,
907000000,
910000000,
926500000,
925500000,
911000000,
};
#else
const int32_t HoppingFrequencies[] =
{
#if 0
479000000,
484700000,
471500000,
479300000,
471700000,
479500000,
471900000,
479700000,
472100000,
479900000,
472300000,
480100000,
472500000,
480300000,
472700000,
480500000,
472900000,
480700000,
473100000,
480900000,
473300000,
481100000,
473500000,
481300000,
473700000,
481500000,
473900000,
481700000,
474100000,
481900000,
474300000,
482100000,
474500000,
482300000,
474700000,
482500000,
474900000,
482700000,
475100000,
482900000,
475300000,
483100000,
475500000,
483300000,
475700000,
483500000,
475900000,
483700000,
476100000,
483900000,
476500000,
484100000,
476700000,
484300000,
476900000,
484500000,
477100000,
484900000,
477300000,
485100000,
477500000,
485300000,
477700000,
485500000,
477900000,
485700000,
#endif
492000000,
492100000,
492200000,
492300000,
492400000,
492500000,
492600000,
492700000,
492800000,
492900000,
493000000,
493100000,
493200000,
493300000,
493400000,
493500000,
493600000,
493700000,
493800000,
493900000,
494000000,
494100000,
494200000,
494300000,
494400000,
494500000,
494600000,
494700000,
494800000,
494900000,
495000000,
495100000,
495200000,
495300000,
495400000,
495500000,
495600000,
495700000,
495800000,
495900000,
496000000,
496100000,
496200000,
496300000,
496400000,
496500000,
496600000,
496700000,
496800000,
496900000,
};
#endif
#define NO_HOP_LOW_FREQUENCY 479000000
#ifdef HOP_CHSS
#define HOP_CHANNELS 50
#endif
static u8 g_hopChannel = 0;
static u32 LoraSymbolTs;
static u32 loraWokePreambleLenth;
u8 SX1276Regs[0x70];
tSX1276LR* SX1276LR = (tSX1276LR*)SX1276Regs;
u32 g_SignalBw[10] = {7800, 10400, 15600, 20800, 31200, 41600, 62500, 125000, 250000, 500000};
tLoRaSettings LoRaSettings =
{
#ifdef HIGH_FREQUENCY
.RFFrequency = 920000000, // RFFrequency
#else
.RFFrequency = NO_HOP_LOW_FREQUENCY,
#endif
.Power = 0, // Power
.SignalBw = 6, // SignalBw [0: 7.8kHz, 1: 10.4 kHz, 2: 15.6 kHz, 3: 20.8 kHz, 4: 31.2 kHz,
// 5: 41.6 kHz, 6: 62.5 kHz, 7: 125 kHz, 8: 250 kHz, 9: 500 kHz, other: Reserved]
.SpreadingFactor = 7, // SpreadingFactor [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips]
.ErrorCoding = 2, // ErrorCoding [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
.CrcOn = true, // CrcOn [0: OFF, 1: ON]
.ImplicitHeaderOn = false, // ImplicitHeaderOn [0: OFF, 1: ON]
.RxSingleOn = false, // RxSingleOn [0: Continuous, 1 Single]
.FreqHopOn = false, // FreqHopOn [0: OFF, 1: ON]
.HopPeriod = 7, // HopPeriod Hops every frequency hopping period symbols
.TxPacketTimeout = 800, // TxPacketTimeout
.RxPacketTimeout = 800, // RxPacketTimeout
.PayloadLength = 254, // PayloadLength (used for implicit header mode)
.LowDatarateOptimize = false, // LowDatarateOptimize option
.PreambleLen = NORMALSYMBOLSLENGTH, // Preamble length
};
st_RF_LoRa_DypeDef g_RF_LoRa =
{
.rf_DataBufferValid = false,
.rf_state = RFLR_STATE_IDLE,
.rf_RxPacketSize = 0,
.rf_TxPacketSize = 0,
.rf_HeaderValid = false,
};
/*
typedef struct
{
u32 loraWokePreambleLenth;
uint8_t LoraChl;
st_RF_LoRa_DypeDef data;
u32 (*readLoraSymbolTs)(void);
int8_t (*getPacketSnr)(void);
u8 (*getRxPacketRssi)();
void (*LoRa_NormalTx)(u8 channel, u8 *PBuffer, u8 length);
void (*LoRa_WakeUpTx)(u8 channel, u8 *PBuffer, u8 length);
void (*LoRa_Receive_Packet)(u8 channel, bool wakeUp);
}st_Lora_port;
u32 readLoraSymbolTs(void)
{
return set_LoraSymbolTs(LoRaSettings.SignalBw, LoRaSettings.SpreadingFactor);
}
*/
/*****************************************************************************
* Function : set_LoraSymbolTs
* Description : none
* Input : uint8_t BwFlag
uint8_t SF
* Output : None
* Return : unit ms
* Others :
* Record
* 1.Date : 20170320
* Author : barry
* Modification: Created function
*****************************************************************************/
u32 set_LoraSymbolTs(uint8_t BwFlag ,uint8_t SF)
{
return (1 << SF)*1000/g_SignalBw[BwFlag];
}
u32 get_LoraSymbolTs(void)
{
return LoraSymbolTs;
}
/*****************************************************************************
* Function : set_LoRaWokeUpPreambleLenth
* Description : none
* Input : u32 period
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170320
* Author : barry
* Modification: Created function
*****************************************************************************/
u32 set_LoRaWokeUpPreambleLenth(u32 period, uint8_t BwFlag ,uint8_t SF)
{
return (u32)(period * g_SignalBw[BwFlag] / ((1 << SF) *1000)) + 6;
}
u32 get_LoRaWokeUpPreambleLenth(void)
{
return loraWokePreambleLenth;
}
/*****************************************************************************
Prototype : SX1276LoRaSetDefaults
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRaSetDefaults( void )
{
/* REMARK: See SX1276 datasheet for modified default values */
SX1276Read( REG_LR_VERSION, &SX1276LR->RegVersion );
}
/*****************************************************************************
Prototype : SX1276LoRaSetOpMode
Description : none
Input : uint8_t opMode
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRaSetOpMode( uint8_t opMode )
{
SX1276LR->RegOpMode = ( SX1276LR->RegOpMode & RFLR_OPMODE_MASK ) | opMode;
/* BEGIN: Added by Barry, 2014/3/14 */
#ifdef HIGH_FREQUENCY
SX1276LR->RegOpMode = ( SX1276LR->RegOpMode & RFLR_OPMODE_FREQMODE_ACCESS_MASK ) | RFLR_OPMODE_FREQMODE_ACCESS_HF; //Elvis
#endif
/* END: Added by Barry, 2014/3/14 */
SX1276Write( REG_LR_OPMODE, SX1276LR->RegOpMode );
}
/*****************************************************************************
Prototype : SX1276LoRaGetOpMode
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
uint8_t SX1276LoRaGetOpMode( void )
{
SX1276Read( REG_LR_OPMODE, &SX1276LR->RegOpMode );
return SX1276LR->RegOpMode & ~RFLR_OPMODE_MASK;
}
/*****************************************************************************
Prototype : SX1276LoRaReadRxGain
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
uint8_t SX1276LoRaReadRxGain( void )
{
SX1276Read( REG_LR_LNA, &SX1276LR->RegLna );
return( SX1276LR->RegLna >> 5 ) & 0x07;
}
/*****************************************************************************
Prototype : config_GDOx_Map
Description : none
Input : st_GDOx_Config GDOx_Map
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void config_GDOx_Map(st_GDOx_Config GDOx_Map)
{
SX1276LR->RegDioMapping1 = GDOx_Map.GDO0Config|
GDOx_Map.GDO1Config|
GDOx_Map.GDO2Config|
GDOx_Map.GDO3Config;
SX1276LR->RegDioMapping2 = GDOx_Map.GDO4Config|
GDOx_Map.GDO5Config;
SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );
}
/*****************************************************************************
Prototype : getPacketSnr
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
int8_t getPacketSnr(void)
{
uint8_t rxSnrEstimate;
int8_t RxPacketSnrEstimate;
SX1276Read( REG_LR_PKTSNRVALUE, &rxSnrEstimate );
/* The SNR sign bit is 1 */
if( rxSnrEstimate & 0x80 )
{
/* Invert and divide by 4 */
RxPacketSnrEstimate = ( ( ~rxSnrEstimate + 1 ) & 0xFF ) >> 2;
RxPacketSnrEstimate = -RxPacketSnrEstimate;
}
else
{
/* Divide by 4 */
RxPacketSnrEstimate = ( rxSnrEstimate & 0xFF ) >> 2;
}
return RxPacketSnrEstimate;
}
/*****************************************************************************
Prototype : get_RxPacketRssi
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
double get_RxPacketRssi(int8_t RxPacketSnr)
{
#define RSSI_OFFSET_LF -164.0
#define RSSI_OFFSET_HF -157.0
double RxPacketRssi;
SX1276Read( REG_LR_PKTRSSIVALUE, &SX1276LR->RegPktRssiValue );
if( LoRaSettings.RFFrequency < 860000000 ) // LF
{
if( RxPacketSnr < 0 )
{
RxPacketRssi = RSSI_OFFSET_LF + ((double)SX1276LR->RegPktRssiValue) + RxPacketSnr;
}
else
{
RxPacketRssi = RSSI_OFFSET_LF + ( 1.0666 * ((double)SX1276LR->RegPktRssiValue) );
}
}
else // HF
{
if( RxPacketSnr < 0 )
{
RxPacketRssi = RSSI_OFFSET_HF + ( ( double )SX1276LR->RegPktRssiValue ) + RxPacketSnr;
}
else
{
RxPacketRssi = RSSI_OFFSET_HF + ( 1.0666 * ((double)SX1276LR->RegPktRssiValue) );
}
}
return RxPacketRssi;
}
/*****************************************************************************
Prototype : read_Lora_Rssi
Description : none
Input : tRFLRStates state
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 read_Lora_Rssi(void)
{
int8_t pSnr = getPacketSnr();
u8 rssi = (u8)get_RxPacketRssi(pSnr);
if (rssi & 0x80)
{
rssi = (~rssi + 1);
}
return rssi;
}
/*****************************************************************************
Prototype : SX1276LoRaInit
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRaInit( void )
{
SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
SX1276LR->RegOpMode = ( SX1276LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON;
SX1276Write( REG_LR_OPMODE, SX1276LR->RegOpMode );
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
SX1276LoRaSetDefaults( );
SX1276ReadBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 );
SX1276LR->RegLna = RFLR_LNA_GAIN_G1;
SX1276Write( REG_LR_LNA, SX1276LR->RegLna );
/* Set the device in Sleep Mode */
SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
SX1276LoRaSetRFFrequency( LoRaSettings.RFFrequency );
SX1276LoRaSetSpreadingFactor( LoRaSettings.SpreadingFactor ); // SF6 only operates in implicit header mode.
SX1276LoRaSetErrorCoding( LoRaSettings.ErrorCoding );
SX1276LoRaSetPacketCrcOn( LoRaSettings.CrcOn );
SX1276LoRaSetSignalBandwidth( LoRaSettings.SignalBw );
SX1276LoRaSetImplicitHeaderOn( LoRaSettings.ImplicitHeaderOn );
SX1276LoRaSetSymbTimeout( 0x3FF );
SX1276LoRaSetPayloadLength( LoRaSettings.PayloadLength );
SX1276LoRaSetPreambleLength(LoRaSettings.PreambleLen);
/* seted true when a symble time over 16ms */
if (get_LoraSymbolTs() >= 16)
{
SX1276LoRaSetLowDatarateOptimize(true);
}
else
{
SX1276LoRaSetLowDatarateOptimize(false);
}
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO );
//SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST );
/* set max power 17DBm */
SX1276LoRaSetPa20dBm( false );
/* set power */
SX1276LoRaSetRFPower( LoRaSettings.Power );
SX1276StartSleep();
}
/*****************************************************************************
* Function : Lora_lowPower_Init
* Description : none
* Input : u32 period
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170526
* Author : barry
* Modification: Created function
*****************************************************************************/
void Lora_lowPower_Init(u32 period)
{
LoraSymbolTs = set_LoraSymbolTs(LoRaSettings.SignalBw, LoRaSettings.SpreadingFactor);
loraWokePreambleLenth = set_LoRaWokeUpPreambleLenth(period, LoRaSettings.SignalBw, LoRaSettings.SpreadingFactor);
}
u32 get_LoraWokeUpPreambleT(void)
{
return LoraSymbolTs*loraWokePreambleLenth;
}
/*****************************************************************************
Prototype : receiveRxData
Description : none
Input : bool spiDMA
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void receiveRxData(u8 *buf, u8 *length)
{
if( LoRaSettings.RxSingleOn == true )
{
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr;
}
else
{
SX1276Read( REG_LR_FIFORXCURRENTADDR, &SX1276LR->RegFifoRxCurrentAddr );
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr;
}
if( LoRaSettings.ImplicitHeaderOn == true )
{
*length = SX1276LR->RegPayloadLength;
}
else
{
SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes );
*length = SX1276LR->RegNbRxBytes;
}
SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );
SX1276ReadFifo(buf, *length);
}
/*****************************************************************************
* Function : SX1276LoRa_hopTx_config
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170320
* Author : barry
* Modification: Created function
*****************************************************************************/
void SX1276LoRa_hopTx_config(st_GDOx_Config *DIO_map_ptr)
{
SX1276LR->RegIrqFlagsMask &= (~RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL);
SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod;
DIO_map_ptr->GDO1Config = DIO1_FhssCC;
hal_DIOx_ITConfig(1,ENABLE);
}
/*****************************************************************************
Prototype : SX1276LoRa_Send_Packet
Description : none
Input : u8 *PBuffer
u8 length
bool FreqHop
bool spiDMA
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRa_Send_Packet(u8 channel, bool wakeUp, u8 *PBuffer,u8 length)
{
st_GDOx_Config DIO_map_conf = DEFAULT_DIO_config;
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
hal_DIOx_ITConfig(all, DISABLE);
switch_Tx();
DIO_map_conf.GDO0Config = DIO0_TxDone;
SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_ALL_MASK & (~RFLR_IRQFLAGS_TXDONE);
SX1276LoRaSetOpMode( RFLR_OPMODE_SYNTHESIZER_TX );
SX1276LR->RegHopPeriod = 0;
#ifdef HOP_CHSS
SX1276LoRa_hopTx_config(DIO_map_conf);
#endif
LoRaSettings.PreambleLen = wakeUp? get_LoRaWokeUpPreambleLenth():NORMALSYMBOLSLENGTH;
SX1276LoRaSetPreambleLength(LoRaSettings.PreambleLen);
config_GDOx_Map(DIO_map_conf);
SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );
SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );
SX1276LoRaSetRFFrequency(HoppingFrequencies[channel]);
SX1276LR->RegPayloadLength = length;
SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength);
SX1276LR->RegFifoTxBaseAddr = 0x00;
SX1276Write( REG_LR_FIFOTXBASEADDR, SX1276LR->RegFifoTxBaseAddr );
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoTxBaseAddr;
SX1276Write(REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr);
g_RF_LoRa.rf_state = RFLR_STATE_TX_RUNNING;
MemCpy(g_RF_LoRa.rf_DataBuffer, PBuffer, length);
g_RF_LoRa.rf_TxPacketSize = length;
SX1276WriteFifo(g_RF_LoRa.rf_DataBuffer,length);
SX1276LoRaSetOpMode(RFLR_OPMODE_TRANSMITTER);
hal_DIOx_ITConfig(0,ENABLE);
}
/*****************************************************************************
Prototype : SX1276LoRa_Receive_Packet
Description : none
Input : bool FreqHop
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRa_Receive_Packet(u8 channel, bool wakeUp)
{
st_GDOx_Config DIO_map_conf = DEFAULT_DIO_config;
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_ALL_MASK;
SX1276LR->RegIrqFlagsMask &= (~(RFLR_IRQFLAGS_RXDONE |
RFLR_IRQFLAGS_PAYLOADCRCERROR|
RFLR_IRQFLAGS_VALIDHEADER
/*|RFLR_IRQFLAGS_RXTIMEOUT*/
));
DIO_map_conf.GDO0Config = DIO0_RxDone;
DIO_map_conf.GDO3Config = DIO3_ValidHeader;
SX1276LR->RegHopPeriod = 0;
switch_Rx();
#ifdef HOP_CHSS
SX1276LoRa_hopTx_config(DIO_map_conf);
#endif
LoRaSettings.PreambleLen = wakeUp? get_LoRaWokeUpPreambleLenth():NORMALSYMBOLSLENGTH;
SX1276LoRaSetPreambleLength(LoRaSettings.PreambleLen);
SX1276LoRaSetSymbTimeout(0x3FF);
config_GDOx_Map(DIO_map_conf);
SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );
SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );
SX1276LoRaSetRFFrequency(HoppingFrequencies[channel]);
if (wakeUp)
{
SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
}
else
{
SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER );
}
g_RF_LoRa.rf_state = RFLR_STATE_RX_RUNNING;
hal_DIOx_ITConfig(0,ENABLE);
hal_DIOx_ITConfig(3,ENABLE);
}
/*****************************************************************************
Prototype : SX1276StartSleep
Description : none
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276StartSleep(void)
{
switch_Rx();
hal_DIOx_ITConfig(all, DISABLE);
hal_sRF_ClearAllRF_IT();
SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
g_RF_LoRa.rf_state = RFLR_STATE_SLEEP;
}
/*****************************************************************************
Prototype : SX1276LoRa_CAD_Scan
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRa_CAD_Scan(u8 channel)
{
st_GDOx_Config DIO_map_conf = DEFAULT_DIO_config;
switch_Rx();
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
SX1276LR->RegIrqFlagsMask |= RFLR_IRQFLAGS_ALL_MASK;
SX1276LR->RegIrqFlagsMask &= (~(RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE));
SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );
SX1276LoRaSetRFFrequency(HoppingFrequencies[channel]);
DIO_map_conf.GDO0Config = DIO0_CadDone;
DIO_map_conf.GDO1Config = DIO1_CadDetected;
config_GDOx_Map(DIO_map_conf);
hal_DIOx_ITConfig(0,ENABLE);
SX1276LoRaSetOpMode( RFLR_OPMODE_CAD );
g_RF_LoRa.rf_state = RFLR_STATE_CAD_RUNNING;
}
/*****************************************************************************
* Function : set_hop_Channel
* Description : none
* Input : u8 channel
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170320
* Author : barry
* Modification: Created function
*****************************************************************************/
void set_hop_Channel(u8 channel)
{
SX1276LoRaSetRFFrequency( HoppingFrequencies[ (g_hopChannel + channel&RFLR_HOPCHANNEL_CHANNEL_MASK)%HOP_CHANNELS] );
}