#ifndef __SX127X_H
#define __SX127X_H

#include "bsp.h"
#include "Public.h"
#include "main.h"

//Constant values need to compute the RSSI value
#define RSSI_OFFSET_LF				-164
#define RSSI_OFFSET_HF				-157
#define NOISE_ABSOLUTE_ZERO			-174
#define NOISE_FIGURE_LF				4
#define NOISE_FIGURE_HF				6
#define SIGNAL_BW_LOG_125KHZ			5	

//SX1276 definitions
#define XTAL_FREQ						32000000
#define FREQ_STEP						61.03515625

//SX1276 Internal registers Address
#define REG_LR_FIFO                                 0x00
// Common settings
#define REG_LR_OPMODE                               0x01
#define REG_LR_BANDSETTING                          0x04
#define REG_LR_FRFMSB                               0x06
#define REG_LR_FRFMID                               0x07
#define REG_LR_FRFLSB                               0x08
// Tx settings
#define REG_LR_PACONFIG                             0x09
#define REG_LR_PARAMP                               0x0A
#define REG_LR_OCP                                  0x0B
// Rx settings
#define REG_LR_LNA                                  0x0C
// LoRa registers
#define REG_LR_FIFOADDRPTR                          0x0D
#define REG_LR_FIFOTXBASEADDR                       0x0E
#define REG_LR_FIFORXBASEADDR                       0x0F
#define REG_LR_FIFORXCURRENTADDR                    0x10
#define REG_LR_IRQFLAGSMASK                         0x11
#define REG_LR_IRQFLAGS                             0x12
#define REG_LR_NBRXBYTES                            0x13
#define REG_LR_RXHEADERCNTVALUEMSB                  0x14
#define REG_LR_RXHEADERCNTVALUELSB                  0x15
#define REG_LR_RXPACKETCNTVALUEMSB                  0x16
#define REG_LR_RXPACKETCNTVALUELSB                  0x17
#define REG_LR_MODEMSTAT                            0x18
#define REG_LR_PKTSNRVALUE                          0x19
#define REG_LR_PKTRSSIVALUE                         0x1A
#define REG_LR_RSSIVALUE                            0x1B
#define REG_LR_HOPCHANNEL                           0x1C
#define REG_LR_MODEMCONFIG1                         0x1D
#define REG_LR_MODEMCONFIG2                         0x1E
#define REG_LR_SYMBTIMEOUTLSB                       0x1F
#define REG_LR_PREAMBLEMSB                          0x20
#define REG_LR_PREAMBLELSB                          0x21
#define REG_LR_PAYLOADLENGTH                        0x22
#define REG_LR_PAYLOADMAXLENGTH                     0x23
#define REG_LR_HOPPERIOD                            0x24
#define REG_LR_FIFORXBYTEADDR                       0x25
#define REG_LR_MODEMCONFIG3                         0x26
// end of documented register in datasheet
// I/O settings
#define REG_LR_DIOMAPPING1				0x40
#define REG_LR_DIOMAPPING2				0x41
// Version
#define REG_LR_VERSION						0x42
// Additional settings
#define REG_LR_PLLHOP						0x44
#define REG_LR_TCXO                                 0x4B
#define REG_LR_PADAC                                0x4D
#define REG_LR_FORMERTEMP                           0x5B
#define REG_LR_BITRATEFRAC                          0x5D
#define REG_LR_AGCREF                               0x61
#define REG_LR_AGCTHRESH1                           0x62
#define REG_LR_AGCTHRESH2                           0x63
#define REG_LR_AGCTHRESH3                           0x64

//RegOpMode
typedef enum{
	RFLR_OPMODE_LONGRANGEMODE_MASK		=0x7F,
	RFLR_OPMODE_LONGRANGEMODE_OFF			=0x00, // Default
	RFLR_OPMODE_LONGRANGEMODE_ON			=0x80,
	RFLR_OPMODE_ACCESSSHAREDREG_MASK		=0xBF,
	RFLR_OPMODE_ACCESSSHAREDREG_ENABLE	=0x40,
	RFLR_OPMODE_ACCESSSHAREDREG_DISABLE	=0x00, // Default
	RFLR_OPMODE_FREQMODE_ACCESS_MASK		=0xF7,
	RFLR_OPMODE_FREQMODE_ACCESS_LF			=0x08, // Default
	RFLR_OPMODE_FREQMODE_ACCESS_HF			=0x00,
	RFLR_OPMODE_MASK							=0xF8,
	RFLR_OPMODE_SLEEP							=0x00,
	RFLR_OPMODE_STANDBY						=0x01, // Default
	RFLR_OPMODE_SYNTHESIZER_TX				=0x02,
	RFLR_OPMODE_TRANSMITTER					=0x03,
	RFLR_OPMODE_SYNTHESIZER_RX				=0x04,
	RFLR_OPMODE_RECEIVER						=0x05,
	// LoRa specific modes
	RFLR_OPMODE_RECEIVER_SINGLE				=0x06,
	RFLR_OPMODE_CAD							=0x07
}Sx1276OpModeType;

//RegBandSetting
#define RFLR_BANDSETTING_MASK                    0x3F
#define RFLR_BANDSETTING_AUTO                    0x00 // Default
#define RFLR_BANDSETTING_DIV_BY_1                0x40
#define RFLR_BANDSETTING_DIV_BY_2                0x80
#define RFLR_BANDSETTING_DIV_BY_6                0xC0

//RegFrf (MHz)
#define RFLR_FRFMSB_434_MHZ                         0x6C // Default
#define RFLR_FRFMID_434_MHZ                         0x80 // Default
#define RFLR_FRFLSB_434_MHZ                         0x00 // Default
#define RFLR_FRFMSB_863_MHZ                         0xD7
#define RFLR_FRFMID_863_MHZ                         0xC0
#define RFLR_FRFLSB_863_MHZ                         0x00
#define RFLR_FRFMSB_864_MHZ                         0xD8
#define RFLR_FRFMID_864_MHZ                         0x00
#define RFLR_FRFLSB_864_MHZ                         0x00
#define RFLR_FRFMSB_865_MHZ                         0xD8
#define RFLR_FRFMID_865_MHZ                         0x40
#define RFLR_FRFLSB_865_MHZ                         0x00
#define RFLR_FRFMSB_866_MHZ                         0xD8
#define RFLR_FRFMID_866_MHZ                         0x80
#define RFLR_FRFLSB_866_MHZ                         0x00
#define RFLR_FRFMSB_867_MHZ                         0xD8
#define RFLR_FRFMID_867_MHZ                         0xC0
#define RFLR_FRFLSB_867_MHZ                         0x00
#define RFLR_FRFMSB_868_MHZ                         0xD9
#define RFLR_FRFMID_868_MHZ                         0x00
#define RFLR_FRFLSB_868_MHZ                         0x00
#define RFLR_FRFMSB_869_MHZ                         0xD9
#define RFLR_FRFMID_869_MHZ                         0x40
#define RFLR_FRFLSB_869_MHZ                         0x00
#define RFLR_FRFMSB_870_MHZ                         0xD9
#define RFLR_FRFMID_870_MHZ                         0x80
#define RFLR_FRFLSB_870_MHZ                         0x00
#define RFLR_FRFMSB_902_MHZ                         0xE1
#define RFLR_FRFMID_902_MHZ                         0x80
#define RFLR_FRFLSB_902_MHZ                         0x00
#define RFLR_FRFMSB_903_MHZ                         0xE1
#define RFLR_FRFMID_903_MHZ                         0xC0
#define RFLR_FRFLSB_903_MHZ                         0x00
#define RFLR_FRFMSB_904_MHZ                         0xE2
#define RFLR_FRFMID_904_MHZ                         0x00
#define RFLR_FRFLSB_904_MHZ                         0x00
#define RFLR_FRFMSB_905_MHZ                         0xE2
#define RFLR_FRFMID_905_MHZ                         0x40
#define RFLR_FRFLSB_905_MHZ                         0x00
#define RFLR_FRFMSB_906_MHZ                         0xE2
#define RFLR_FRFMID_906_MHZ                         0x80
#define RFLR_FRFLSB_906_MHZ                         0x00
#define RFLR_FRFMSB_907_MHZ                         0xE2
#define RFLR_FRFMID_907_MHZ                         0xC0
#define RFLR_FRFLSB_907_MHZ                         0x00
#define RFLR_FRFMSB_908_MHZ                         0xE3
#define RFLR_FRFMID_908_MHZ                         0x00
#define RFLR_FRFLSB_908_MHZ                         0x00
#define RFLR_FRFMSB_909_MHZ                         0xE3
#define RFLR_FRFMID_909_MHZ                         0x40
#define RFLR_FRFLSB_909_MHZ                         0x00
#define RFLR_FRFMSB_910_MHZ                         0xE3
#define RFLR_FRFMID_910_MHZ                         0x80
#define RFLR_FRFLSB_910_MHZ                         0x00
#define RFLR_FRFMSB_911_MHZ                         0xE3
#define RFLR_FRFMID_911_MHZ                         0xC0
#define RFLR_FRFLSB_911_MHZ                         0x00
#define RFLR_FRFMSB_912_MHZ                         0xE4
#define RFLR_FRFMID_912_MHZ                         0x00
#define RFLR_FRFLSB_912_MHZ                         0x00
#define RFLR_FRFMSB_913_MHZ                         0xE4
#define RFLR_FRFMID_913_MHZ                         0x40
#define RFLR_FRFLSB_913_MHZ                         0x00
#define RFLR_FRFMSB_914_MHZ                         0xE4
#define RFLR_FRFMID_914_MHZ                         0x80
#define RFLR_FRFLSB_914_MHZ                         0x00
#define RFLR_FRFMSB_915_MHZ                         0xE4  // Default
#define RFLR_FRFMID_915_MHZ                         0xC0  // Default
#define RFLR_FRFLSB_915_MHZ                         0x00  // Default
#define RFLR_FRFMSB_916_MHZ                         0xE5
#define RFLR_FRFMID_916_MHZ                         0x00
#define RFLR_FRFLSB_916_MHZ                         0x00
#define RFLR_FRFMSB_917_MHZ                         0xE5
#define RFLR_FRFMID_917_MHZ                         0x40
#define RFLR_FRFLSB_917_MHZ                         0x00
#define RFLR_FRFMSB_918_MHZ                         0xE5
#define RFLR_FRFMID_918_MHZ                         0x80
#define RFLR_FRFLSB_918_MHZ                         0x00
#define RFLR_FRFMSB_919_MHZ                         0xE5
#define RFLR_FRFMID_919_MHZ                         0xC0
#define RFLR_FRFLSB_919_MHZ                         0x00
#define RFLR_FRFMSB_920_MHZ                         0xE6
#define RFLR_FRFMID_920_MHZ                         0x00
#define RFLR_FRFLSB_920_MHZ                         0x00
#define RFLR_FRFMSB_921_MHZ                         0xE6
#define RFLR_FRFMID_921_MHZ                         0x40
#define RFLR_FRFLSB_921_MHZ                         0x00
#define RFLR_FRFMSB_922_MHZ                         0xE6
#define RFLR_FRFMID_922_MHZ                         0x80
#define RFLR_FRFLSB_922_MHZ                         0x00
#define RFLR_FRFMSB_923_MHZ                         0xE6
#define RFLR_FRFMID_923_MHZ                         0xC0
#define RFLR_FRFLSB_923_MHZ                         0x00
#define RFLR_FRFMSB_924_MHZ                         0xE7
#define RFLR_FRFMID_924_MHZ                         0x00
#define RFLR_FRFLSB_924_MHZ                         0x00
#define RFLR_FRFMSB_925_MHZ                         0xE7
#define RFLR_FRFMID_925_MHZ                         0x40
#define RFLR_FRFLSB_925_MHZ                         0x00
#define RFLR_FRFMSB_926_MHZ                         0xE7
#define RFLR_FRFMID_926_MHZ                         0x80
#define RFLR_FRFLSB_926_MHZ                         0x00
#define RFLR_FRFMSB_927_MHZ                         0xE7
#define RFLR_FRFMID_927_MHZ                         0xC0
#define RFLR_FRFLSB_927_MHZ                         0x00
#define RFLR_FRFMSB_928_MHZ                         0xE8
#define RFLR_FRFMID_928_MHZ                         0x00
#define RFLR_FRFLSB_928_MHZ                         0x00

//RegPaConfig
#define RFLR_PACONFIG_PASELECT_MASK                 0x7F
#define RFLR_PACONFIG_PASELECT_PABOOST              0x80
#define RFLR_PACONFIG_PASELECT_RFO                  0x00 // Default
#define RFLR_PACONFIG_MAX_POWER_MASK                0x8F
#define RFLR_PACONFIG_OUTPUTPOWER_MASK              0xF0

//RegPaRamp
#define RFLR_PARAMP_TXBANDFORCE_MASK                0xEF
#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL            0x10
#define RFLR_PARAMP_TXBANDFORCE_AUTO                0x00 // Default
#define RFLR_PARAMP_MASK                            0xF0
#define RFLR_PARAMP_3400_US                         0x00
#define RFLR_PARAMP_2000_US                         0x01
#define RFLR_PARAMP_1000_US                         0x02
#define RFLR_PARAMP_0500_US                         0x03
#define RFLR_PARAMP_0250_US                         0x04
#define RFLR_PARAMP_0125_US                         0x05
#define RFLR_PARAMP_0100_US                         0x06
#define RFLR_PARAMP_0062_US                         0x07
#define RFLR_PARAMP_0050_US                         0x08
#define RFLR_PARAMP_0040_US                         0x09 // Default
#define RFLR_PARAMP_0031_US                         0x0A
#define RFLR_PARAMP_0025_US                         0x0B
#define RFLR_PARAMP_0020_US                         0x0C
#define RFLR_PARAMP_0015_US                         0x0D
#define RFLR_PARAMP_0012_US                         0x0E
#define RFLR_PARAMP_0010_US                         0x0F

//RegOcp
#define RFLR_OCP_MASK                               0xDF
#define RFLR_OCP_ON                                 0x20 // Default
#define RFLR_OCP_OFF                                0x00
#define RFLR_OCP_TRIM_MASK                          0xE0
#define RFLR_OCP_TRIM_045_MA                        0x00
#define RFLR_OCP_TRIM_050_MA                        0x01
#define RFLR_OCP_TRIM_055_MA                        0x02
#define RFLR_OCP_TRIM_060_MA                        0x03
#define RFLR_OCP_TRIM_065_MA                        0x04
#define RFLR_OCP_TRIM_070_MA                        0x05
#define RFLR_OCP_TRIM_075_MA                        0x06
#define RFLR_OCP_TRIM_080_MA                        0x07
#define RFLR_OCP_TRIM_085_MA                        0x08
#define RFLR_OCP_TRIM_090_MA                        0x09
#define RFLR_OCP_TRIM_095_MA                        0x0A
#define RFLR_OCP_TRIM_100_MA                        0x0B  // Default
#define RFLR_OCP_TRIM_105_MA                        0x0C
#define RFLR_OCP_TRIM_110_MA                        0x0D
#define RFLR_OCP_TRIM_115_MA                        0x0E
#define RFLR_OCP_TRIM_120_MA                        0x0F
#define RFLR_OCP_TRIM_130_MA                        0x10
#define RFLR_OCP_TRIM_140_MA                        0x11
#define RFLR_OCP_TRIM_150_MA                        0x12
#define RFLR_OCP_TRIM_160_MA                        0x13
#define RFLR_OCP_TRIM_170_MA                        0x14
#define RFLR_OCP_TRIM_180_MA                        0x15
#define RFLR_OCP_TRIM_190_MA                        0x16
#define RFLR_OCP_TRIM_200_MA                        0x17
#define RFLR_OCP_TRIM_210_MA                        0x18
#define RFLR_OCP_TRIM_220_MA                        0x19
#define RFLR_OCP_TRIM_230_MA                        0x1A
#define RFLR_OCP_TRIM_240_MA                        0x1B

//RegLna
#define RFLR_LNA_GAIN_MASK                          0x1F
#define RFLR_LNA_GAIN_G1                            0x20 // Default
#define RFLR_LNA_GAIN_G2                            0x40
#define RFLR_LNA_GAIN_G3                            0x60
#define RFLR_LNA_GAIN_G4                            0x80
#define RFLR_LNA_GAIN_G5                            0xA0
#define RFLR_LNA_GAIN_G6                            0xC0
#define RFLR_LNA_BOOST_LF_MASK                      0xE7
#define RFLR_LNA_BOOST_LF_DEFAULT                   0x00 // Default
#define RFLR_LNA_BOOST_LF_GAIN                      0x08
#define RFLR_LNA_BOOST_LF_IP3                       0x10
#define RFLR_LNA_BOOST_LF_BOOST                     0x18
#define RFLR_LNA_RXBANDFORCE_MASK                   0xFB
#define RFLR_LNA_RXBANDFORCE_BAND_SEL               0x04
#define RFLR_LNA_RXBANDFORCE_AUTO                   0x00 // Default
#define RFLR_LNA_BOOST_HF_MASK                      0xFC
#define RFLR_LNA_BOOST_HF_OFF                       0x00 // Default
#define RFLR_LNA_BOOST_HF_ON                        0x03

//RegFifoAddrPtr
#define RFLR_FIFOADDRPTR                            0x00 // Default

//RegFifoTxBaseAddr
#define RFLR_FIFOTXBASEADDR                         0x80 // Default

//RegFifoTxBaseAddr
#define RFLR_FIFORXBASEADDR                         0x00 // Default

//RegFifoRxCurrentAddr (Read Only)

//RegIrqFlagsMask
#define RFLR_IRQFLAGS_RXTIMEOUT_MASK                0x80
#define RFLR_IRQFLAGS_RXDONE_MASK                   0x40
#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK          0x20
#define RFLR_IRQFLAGS_VALIDHEADER_MASK              0x10
#define RFLR_IRQFLAGS_TXDONE_MASK                   0x08
#define RFLR_IRQFLAGS_CADDONE_MASK                  0x04
#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK       0x02
#define RFLR_IRQFLAGS_CADDETECTED_MASK              0x01

//RegIrqFlags
#define RFLR_IRQFLAGS_RXTIMEOUT                     0x80
#define RFLR_IRQFLAGS_RXDONE                        0x40
#define RFLR_IRQFLAGS_PAYLOADCRCERROR               0x20
#define RFLR_IRQFLAGS_VALIDHEADER                   0x10
#define RFLR_IRQFLAGS_TXDONE                        0x08
#define RFLR_IRQFLAGS_CADDONE                       0x04
#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL            0x02
#define RFLR_IRQFLAGS_CADDETECTED                   0x01

 //RegModemStat (Read Only)
#define RFLR_MODEMSTAT_RX_CR_MASK                   0x1F
#define RFLR_MODEMSTAT_MODEM_STATUS_MASK            0xE0

//RegModemConfig1
#define RFLR_MODEMCONFIG1_BW_MASK                   0x0F
#define RFLR_MODEMCONFIG1_BW_7_81_KHZ               0x00
#define RFLR_MODEMCONFIG1_BW_10_41_KHZ              0x10
#define RFLR_MODEMCONFIG1_BW_15_62_KHZ              0x20
#define RFLR_MODEMCONFIG1_BW_20_83_KHZ              0x30
#define RFLR_MODEMCONFIG1_BW_31_25_KHZ              0x40
#define RFLR_MODEMCONFIG1_BW_41_66_KHZ              0x50
#define RFLR_MODEMCONFIG1_BW_62_50_KHZ              0x60
#define RFLR_MODEMCONFIG1_BW_125_KHZ                0x70 // Default
#define RFLR_MODEMCONFIG1_BW_250_KHZ                0x80
#define RFLR_MODEMCONFIG1_BW_500_KHZ                0x90
#define RFLR_MODEMCONFIG1_CODINGRATE_MASK           0xF1
#define RFLR_MODEMCONFIG1_CODINGRATE_4_5            0x02
#define RFLR_MODEMCONFIG1_CODINGRATE_4_6            0x04 // Default
#define RFLR_MODEMCONFIG1_CODINGRATE_4_7            0x06
#define RFLR_MODEMCONFIG1_CODINGRATE_4_8            0x08
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK       0xFE
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON         0x00
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF        0x01 // Default

 //RegModemConfig2
#define RFLR_MODEMCONFIG2_SF_MASK                   0x0F
#define RFLR_MODEMCONFIG2_SF_6                      0x60
#define RFLR_MODEMCONFIG2_SF_7                      0x70 // Default
#define RFLR_MODEMCONFIG2_SF_8                      0x80
#define RFLR_MODEMCONFIG2_SF_9                      0x90
#define RFLR_MODEMCONFIG2_SF_10                     0xA0
#define RFLR_MODEMCONFIG2_SF_11                     0xB0
#define RFLR_MODEMCONFIG2_SF_12                     0xC0

#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK     0xF7
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON       0x08
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF      0x00

#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK         0xFB
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON           0x04
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF          0x00 // Default

#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK       0xFC
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB            0x00 // Default


//RegHopChannel (Read Only)
#define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK       0x7F
#define RFLR_HOPCHANNEL_PLL_LOCK_FAIL               0x80
#define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED            0x00 // Default
#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_MASK          0xBF
#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_ON            0x40
#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_OFF           0x00 // Default
#define RFLR_HOPCHANNEL_CHANNEL_MASK                0x3F


//RegSymbTimeoutLsb
#define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT             0x64 // Default

//RegPreambleLengthMsb
#define RFLR_PREAMBLELENGTHMSB                      0x00 // Default

//RegPreambleLengthLsb
#define RFLR_PREAMBLELENGTHLSB                      0x08 // Default

//RegPayloadLength
#define RFLR_PAYLOADLENGTH                          0x0E // Default

//RegPayloadMaxLength
#define RFLR_PAYLOADMAXLENGTH                       0xFF // Default

//RegHopPeriod
#define RFLR_HOPPERIOD_FREQFOPPINGPERIOD            0x00 // Default


//RegDioMapping1
//DIO0
#define RFLR_DIOMAPPING1_DIO0_MASK                  0x3F
#define RFLR_DIOMAPPING1_DIO0_00                    0x00  // Default
#define RFLR_DIOMAPPING1_DIO0_01                    0x40
#define RFLR_DIOMAPPING1_DIO0_10                    0x80
#define RFLR_DIOMAPPING1_DIO0_11                    0xC0
//DIO1
#define RFLR_DIOMAPPING1_DIO1_MASK                  0xCF
#define RFLR_DIOMAPPING1_DIO1_00                    0x00  // Default
#define RFLR_DIOMAPPING1_DIO1_01                    0x10
#define RFLR_DIOMAPPING1_DIO1_10                    0x20
#define RFLR_DIOMAPPING1_DIO1_11                    0x30
//DIO2
#define RFLR_DIOMAPPING1_DIO2_MASK                  0xF3
#define RFLR_DIOMAPPING1_DIO2_00                    0x00  // Default
#define RFLR_DIOMAPPING1_DIO2_01                    0x04
#define RFLR_DIOMAPPING1_DIO2_10                    0x08
#define RFLR_DIOMAPPING1_DIO2_11                    0x0C
//DIO3
#define RFLR_DIOMAPPING1_DIO3_MASK                  0xFC
#define RFLR_DIOMAPPING1_DIO3_00                    0x00  // Default
#define RFLR_DIOMAPPING1_DIO3_01                    0x01
#define RFLR_DIOMAPPING1_DIO3_10                    0x02
#define RFLR_DIOMAPPING1_DIO3_11                    0x03

//RegDioMapping2
//DIO4
#define RFLR_DIOMAPPING2_DIO4_MASK                  0x3F
#define RFLR_DIOMAPPING2_DIO4_00                    0x00  // Default
#define RFLR_DIOMAPPING2_DIO4_01                    0x40
#define RFLR_DIOMAPPING2_DIO4_10                    0x80
#define RFLR_DIOMAPPING2_DIO4_11                    0xC0
//DIO5
#define RFLR_DIOMAPPING2_DIO5_MASK                  0xCF
#define RFLR_DIOMAPPING2_DIO5_00                    0x00  // Default
#define RFLR_DIOMAPPING2_DIO5_01                    0x10
#define RFLR_DIOMAPPING2_DIO5_10                    0x20
#define RFLR_DIOMAPPING2_DIO5_11                    0x30
//MAP
#define RFLR_DIOMAPPING2_MAP_MASK                   0xFE
#define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT         0x01
#define RFLR_DIOMAPPING2_MAP_RSSI                   0x00  // Default

// RegPllHop
#define RFLR_PLLHOP_FASTHOP_MASK                    0x7F
#define RFLR_PLLHOP_FASTHOP_ON                      0x80
#define RFLR_PLLHOP_FASTHOP_OFF                     0x00 // Default

//RegTcxo
#define RFLR_TCXO_TCXOINPUT_MASK                    0xEF
#define RFLR_TCXO_TCXOINPUT_ON                      0x10
#define RFLR_TCXO_TCXOINPUT_OFF                     0x00  // Default

//RegPaDac
#define RFLR_PADAC_20DBM_MASK                       0xF8
#define RFLR_PADAC_20DBM_ON                         0x07
#define RFLR_PADAC_20DBM_OFF                        0x04  // Default

//RegPll
#define RFLR_PLL_BANDWIDTH_MASK                     0x3F
#define RFLR_PLL_BANDWIDTH_75                       0x00
#define RFLR_PLL_BANDWIDTH_150                      0x40
#define RFLR_PLL_BANDWIDTH_225                      0x80
#define RFLR_PLL_BANDWIDTH_300                      0xC0  // Default

//RegPllLowPn
#define RFLR_PLLLOWPN_BANDWIDTH_MASK                0x3F
#define RFLR_PLLLOWPN_BANDWIDTH_75                  0x00
#define RFLR_PLLLOWPN_BANDWIDTH_150                 0x40
#define RFLR_PLLLOWPN_BANDWIDTH_225                 0x80
#define RFLR_PLLLOWPN_BANDWIDTH_300                 0xC0  // Default

//RegModemConfig3
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK  0xF7
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON    0x08
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF   0x00 // Default
#define RFLR_MODEMCONFIG3_AGCAUTO_MASK              0xFB
#define RFLR_MODEMCONFIG3_AGCAUTO_ON                0x04 // Default
#define RFLR_MODEMCONFIG3_AGCAUTO_OFF               0x00

//REGISTER
typedef struct _Sx1276RegType{
    uint8_t RegFifo;                                // 0x00
    // Common settings
    uint8_t RegOpMode;                              // 0x01
    uint8_t RegRes02;                               // 0x02
    uint8_t RegRes03;                               // 0x03
    uint8_t RegBandSetting;                         // 0x04
    uint8_t RegRes05;                               // 0x05
    uint8_t RegFrfMsb;                              // 0x06
    uint8_t RegFrfMid;                              // 0x07
    uint8_t RegFrfLsb;                              // 0x08
    // Tx settings
    uint8_t RegPaConfig;                            // 0x09
    uint8_t RegPaRamp;                              // 0x0A
    uint8_t RegOcp;                                 // 0x0B
    // Rx settings
    uint8_t RegLna;                                 // 0x0C
    // LoRa registers
    uint8_t RegFifoAddrPtr;                         // 0x0D
    uint8_t RegFifoTxBaseAddr;                      // 0x0E
    uint8_t RegFifoRxBaseAddr;                      // 0x0F
    uint8_t RegFifoRxCurrentAddr;                   // 0x10
    uint8_t RegIrqFlagsMask;                        // 0x11
    uint8_t RegIrqFlags;                            // 0x12
    uint8_t RegNbRxBytes;                           // 0x13
    uint8_t RegRxHeaderCntValueMsb;                 // 0x14
    uint8_t RegRxHeaderCntValueLsb;                 // 0x15
    uint8_t RegRxPacketCntValueMsb;                 // 0x16
    uint8_t RegRxPacketCntValueLsb;                 // 0x17
    uint8_t RegModemStat;                           // 0x18
    uint8_t RegPktSnrValue;                         // 0x19
    uint8_t RegPktRssiValue;                        // 0x1A
    uint8_t RegRssiValue;                           // 0x1B
    uint8_t RegHopChannel;                          // 0x1C
    uint8_t RegModemConfig1;                        // 0x1D
    uint8_t RegModemConfig2;                        // 0x1E
    uint8_t RegSymbTimeoutLsb;                      // 0x1F
    uint8_t RegPreambleMsb;                         // 0x20
    uint8_t RegPreambleLsb;                         // 0x21
    uint8_t RegPayloadLength;                       // 0x22
    uint8_t RegMaxPayloadLength;                    // 0x23
    uint8_t RegHopPeriod;                           // 0x24
    uint8_t RegFifoRxByteAddr;                      // 0x25
    uint8_t RegModemConfig3;                        // 0x26
    uint8_t RegTestReserved27[0x30 - 0x27];         // 0x27-0x30
    uint8_t RegTestReserved31;                      // 0x31
    uint8_t RegTestReserved32[0x40 - 0x32];         // 0x32-0x40
    // I/O settings
    uint8_t RegDioMapping1;                         // 0x40
    uint8_t RegDioMapping2;                         // 0x41
    // Version
    uint8_t RegVersion;                             // 0x42
    // Additional settings
    uint8_t RegAgcRef;                              // 0x43
    uint8_t RegAgcThresh1;                          // 0x44
    uint8_t RegAgcThresh2;                          // 0x45
    uint8_t RegAgcThresh3;                          // 0x46
    // Test
    uint8_t RegTestReserved47[0x4B - 0x47];         // 0x47-0x4A
    // Additional settings
    uint8_t RegPllHop;                              // 0x4B
    uint8_t RegTestReserved4C;                      // 0x4C
    uint8_t RegPaDac;                               // 0x4D
    // Test
    //uint8_t RegTestReserved4E[0x58-0x4E];           // 0x4E-0x57
    // Additional settings
    //uint8_t RegTcxo;                                // 0x58
    // Test
    //uint8_t RegTestReserved59;                      // 0x59
    // Test
    //uint8_t RegTestReserved5B;                      // 0x5B
    // Additional settings
    //uint8_t RegPll;                                 // 0x5C
    // Test
    //uint8_t RegTestReserved5D;                      // 0x5D
    // Additional settings
    //uint8_t RegPllLowPn;                            // 0x5E
    // Test
    //uint8_t RegTestReserved5F[0x6C - 0x5F];         // 0x5F-0x6B
    // Additional settings
    //uint8_t RegFormerTemp;                          // 0x6C
    // Test
    //uint8_t RegTestReserved6D[0x71 - 0x6D];         // 0x6D-0x70
}Sx1276RegType;

#define SIZE_OF_REGISTERS			(sizeof(Sx1276RegType))

//RF state machine
typedef enum{
    RFLR_STATE_IDLE,
    RFLR_STATE_RX_RUNNING,
    RFLR_STATE_TX_RUNNING,
}LRStateType;

typedef enum{
    RADIO_RESET_OFF,
    RADIO_RESET_ON,
}tRadioResetState;

typedef enum{
    RF_IDLE,
    RF_BUSY,
    RF_RX_DONE,
    RF_RX_TIMEOUT,
    RF_TX_DONE,
    RF_TX_TIMEOUT,
    RF_LEN_ERROR,
    RF_CHANNEL_EMPTY,
    RF_CHANNEL_ACTIVITY_DETECTED,
}Sx1276RetType;

typedef enum{
	SX1276_BW_7K8=	(0),
	SX1276_BW_10K4=	(1<<4),
	SX1276_BW_15K6=	(2<<4),
	SX1276_BW_20K8=	(3<<4),
	SX1276_BW_31K2=	(4<<4),
	SX1276_BW_41K6=	(5<<4),
	SX1276_BW_62K5=	(6<<4),
	SX1276_BW_125K=	(7<<4),
	SX1276_BW_250K=	(8<<4),
	SX1276_BW_500K=	(9<<4)
}Sx1276BwType;

typedef enum{
	SX1276_SF_64=		(6<<4),
	SX1276_SF_128=	(7<<4),
	SX1276_SF_256=	(8<<4),
	SX1276_SF_512=	(9<<4),
	SX1276_SF_1024=	(10<<4),
	SX1276_SF_2048=	(11<<4),
	SX1276_SF_4096=	(12<<4)
}Sx1276SpreadFactorType;

typedef enum{
	SX1276_EC_4_5=	(1<<1),
	SX1276_EC_4_6=	(2<<1),
	SX1276_EC_4_7=	(3<<1),
	SX1276_EC_4_8=	(4<<1)
}Sx1276ErrorCodingType;

typedef enum{
	SX1276_CRC_OFF=	(0),
	SX1276_CRC_ON=	(1<<2)
}Sx1276CrcOnType;

typedef enum{
	SX1276_IH_OFF=	(0),
	SX1276_IH_ON=		(1)
}Sx1276ImplicitHeaderOnType;

//可变速率
typedef struct _AutoSfType{
	Sx1276SpreadFactorType Sf;
	uint8_t ucRssiMin, ucRssiMax;
	uint16_t wTimeout;
}AutoSfType, *PAutoSf;

//Parameter
typedef enum{
	LORAPT_STATUS,
	LORAPT_CHANNEL,
	LORAPT_FREQ,
	LORAPT_BW,	
	LORAPT_SF,	
	LORAPT_EC,
	LORAPT_RSSI,
	LORAPT_POWER,
	LORAPT_SET_RX,
	LORAPT_SET_SLEEP,
	LORAPT_MAX
}Sx1276LoraParaType;

#define SX1276_CHANNEL_MAX			17

#define	LORA_SPI_NSS_SET()			SPI2_NSS_SET()		
#define	LORA_SPI_NSS_CLR()			SPI2_NSS_CLR()
#define	LORA_SPI_READ_WRITE(x)	Spi2SendReceive(x)
#define	LORA_GETDIO0()					LORA_DIO_GET()
//#define	LORA_GETDIO1()					GET_LORA_DIO1()

#define	USE_RF_SW					0
#define	USE_LORA_LED			1
#if USE_RF_SW == 1
#define	LORA_ANTTXEN()					{ \
																	SET_LORA_TXEN_PIN();\
																	CLR_LORA_RXEN_PIN();\
																}

#define	LORA_ANTRXEN()					{ \
																	SET_LORA_RXEN_PIN();\
																	CLR_LORA_TXEN_PIN();\
																}

#define	LORA_ANTCLOSE()					{ \
																	CLR_LORA_RXEN_PIN();\
																	CLR_LORA_TXEN_PIN();\
																}
#else
#define	LORA_ANTTXEN()
#define	LORA_ANTRXEN()
#define	LORA_ANTCLOSE()
#endif

#if USE_LORA_LED == 1
#define LORA_TXLED_ON()					POWER_LED_ON()
#define LORA_TXLED_OFF()				POWER_LED_OFF()
#define LORA_RXLED_ON()					POWER_LED_ON()
#define LORA_RXLED_OFF()				POWER_LED_OFF()
#else
#define LORA_TXLED_ON()					
#define LORA_TXLED_OFF()				
#endif

#define	LORA_BUFF_SIZE				255

typedef enum {
	RF_ANT_TRANSMITTER,
	RF_ANT_RECEIVER,
	RF_ANT_CLOSE,
}Sx1276AntStatus_m;

typedef enum {
	SX1276_SLEEP,
	SX1276_IDLE,
	SX1276_RX,
	SX1276_TX,
	SX1276_BUSY,
	SX1276_ERROR,
	SX1276_MAX
}Sx1276StateType_t;

typedef struct {
	uint8_t ucChannel;
	uint32_t dwFreqHz;
	int8_t ucPower;
	Sx1276BwType SignalBw;
	Sx1276SpreadFactorType SpreadFactor;
	Sx1276ErrorCodingType ErrorCoding;
	uint8_t RegPreamble;
	uint8_t ucOpModePrev;
	Sx1276AntStatus_m bAntSwPrev;
	Sx1276RegType RegBuff;
	Sx1276StateType_t State;
	uint8_t ucRxPacketSize;
	uint8_t ucTxPacketSize;
	uint8_t RxTxBuff[LORA_BUFF_SIZE];
	DataRevCallBack RxCallBack;
	int RxRet;
}Sx1276Type_t, *pSx1276Type;


//ISM Freq In China
//Up Link:
//CH0-5: 470.3-471.3MHz
//CH39-44:478.1-479.1MHz
//CH78-95:485.9-489.3MHz
//Down Link:
//CH0-47:500.3-509.7MHz

#define USE_915MHZ      0//=1使用915   =0使用433

#if (USE_915MHZ == 1)
  //中心频率，不定义则默认为449000000Hz
  #define FREQ_CENT       915000000ul
  //860MHz-1GHz使用PA功放，不定义则默认不使用
  //SX127x不定义，HOPERF模块需要定义
  #define USE_LORA_860_PA
#endif

/*
中心频率配置：433100000ul + 200000*N
*/
#define CH0 	(433100000ul + 0) //测试频率
#define CH1		(433100000ul + 200000)
#define CH2		(433100000ul + 400000)
#define CH3		(433100000ul + 600000)
#define CH4		(433100000ul + 800000)
#define CH5		(433100000ul + 1000000)
#define CH6		(433100000ul + 1200000)
#define CH7		(433100000ul + 1400000)
#define CH8		(433100000ul + 1600000)
#define CH9		(433100000ul + 1800000)
#define CH10	(433100000ul + 2000000)

#if (MAC_ADDR_TYPE == 0)
#define	FREQ_CENT				CH0
#elif (MAC_ADDR_TYPE == 1)
#define	FREQ_CENT				CH1
#elif (MAC_ADDR_TYPE == 2)
#define	FREQ_CENT				CH2
#elif (MAC_ADDR_TYPE == 3)
#define	FREQ_CENT				CH3
#elif (MAC_ADDR_TYPE == 4)
#define	FREQ_CENT				CH4
#elif (MAC_ADDR_TYPE == 5)
#define	FREQ_CENT				CH5
#elif (MAC_ADDR_TYPE == 6)
#define	FREQ_CENT				CH6
#elif (MAC_ADDR_TYPE == 7)
#define	FREQ_CENT				CH7
#elif (MAC_ADDR_TYPE == 8)
#define	FREQ_CENT				CH8
#elif (MAC_ADDR_TYPE == 9)
#define	FREQ_CENT				CH9
#elif (MAC_ADDR_TYPE == 10)
#define	FREQ_CENT				CH10
#endif

#if !defined FREQ_CENT
#define FREQ_CENT				(433100000ul + 0)//200000
#endif
#if !defined FREQ_DEV
#define FREQ_DEV				1000000ul
#endif

//////////////////////////////////////////////////////////////////////
void Sx1276LoRaLoopHandler(GateWayPara GateWay);
void IsrSx1276LoRaTxRx(GateWayPara GateWay);
void Sx1276LoRaInit(DataRevCallBack RxCallBack);
void Sx1276LoRaSendBuffer(uint8_t* pucBuff, uint16_t ucLen);
uint8_t SX1276LoRaReadChannel(void);
bool SX1276LoRaWriteChannel(uint8_t Channel);
uint32_t SX1276LoRaReadFreq(void);
void SX1276LoRaWriteFreq(uint32_t Freq);
void SX1276LoRaWriteBw(Sx1276BwType SignalBw);
uint32_t SX1276LoRaReadBw(void);
uint8_t SX1276LoRaReadSf(void);
void SX1276LoRaWriteSf(Sx1276SpreadFactorType SpreadFactor);
void SX1276LoRaWriteEc(Sx1276ErrorCodingType ErrorCoding);
uint8_t SX1276LoRaReadEc(void);
uint32_t SX1276LoRaParaReadRssi(void);
uint8_t SX1276LoRaReadRssiPkt(void);
void SX1276LoRaWritePwr(int8_t Pwr);
void SX1276LoRaWriteRx(void);
void SX1276LoRaWriteSleep(bool Sleep);
Sx1276StateType_t SX1276LoRaReadStatus(void);
void SX1276LoCalcRssiSnr(int16_t *pswRssi, int8_t *psbSnr);
void Sx1276LoRaSleep(void);
void Sx1276LoRaWakeup(void);
int GetSx1276RxRetValue(void);
void Sx1276RxRetValue(void);

bool LoraSetChannel(uint8_t Channel);
bool LoraSetPower(uint8_t Power);
bool LoraSetSignalBw(uint8_t SignalBw);
bool LoraSetSpreadFactor(uint8_t SpreadFactor);
bool LoraSetErrorCoding(uint8_t ErrorCoding);
bool LoraSetRegPreamble(uint8_t RegPreamble);
#endif

