655 lines
24 KiB
C
655 lines
24 KiB
C
|
|
#include "sx127x.h"
|
||
|
|
#include "Debug.h"
|
||
|
|
|
||
|
|
#if (LORA_MODULE == SX1278W1)
|
||
|
|
static Sx1276Type_t LoRaPara = {
|
||
|
|
.ucChannel = 4,
|
||
|
|
.dwFreqHz = FREQ_CENT,
|
||
|
|
.ucPower = 20,
|
||
|
|
.SignalBw = SX1276_BW_250K,
|
||
|
|
.SpreadFactor = SX1276_SF_512,
|
||
|
|
.ErrorCoding = SX1276_EC_4_6,
|
||
|
|
.RegPreamble = 10,
|
||
|
|
.ucOpModePrev = RFLR_OPMODE_STANDBY,
|
||
|
|
.bAntSwPrev = RF_ANT_RECEIVER,
|
||
|
|
.RegBuff = 0,
|
||
|
|
.State = SX1276_IDLE,
|
||
|
|
.ucRxPacketSize = 0,
|
||
|
|
.ucTxPacketSize = 0,
|
||
|
|
.RxCallBack = NULL,
|
||
|
|
};
|
||
|
|
|
||
|
|
void LoraReset(void)
|
||
|
|
{
|
||
|
|
LORA_RESET_CLR();
|
||
|
|
Ddl_Delay1ms(1);
|
||
|
|
LORA_RESET_SET();
|
||
|
|
}
|
||
|
|
|
||
|
|
/////////////////////////////////////////////////
|
||
|
|
void SX1276SetAntSw(Sx1276AntStatus_m Status)
|
||
|
|
{
|
||
|
|
switch(Status){
|
||
|
|
case RF_ANT_TRANSMITTER:
|
||
|
|
LORA_ANTTXEN();
|
||
|
|
break;
|
||
|
|
case RF_ANT_RECEIVER:
|
||
|
|
LORA_ANTRXEN();
|
||
|
|
break;
|
||
|
|
case RF_ANT_CLOSE:
|
||
|
|
LORA_ANTCLOSE();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276ReadBuffer(uint8_t ucAddr, uint8_t *pucBuff, uint8_t ucLen)
|
||
|
|
{
|
||
|
|
uint8_t ucCnt;
|
||
|
|
LORA_SPI_NSS_CLR();
|
||
|
|
LORA_SPI_READ_WRITE(ucAddr & 0x7F);
|
||
|
|
for( ucCnt = 0; ucCnt < ucLen; ucCnt++ ){
|
||
|
|
pucBuff[ucCnt] = LORA_SPI_READ_WRITE(0);
|
||
|
|
}
|
||
|
|
LORA_SPI_NSS_SET();
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276WriteBuffer(uint8_t ucAddr, uint8_t *pucBuff, uint8_t ucLen)
|
||
|
|
{
|
||
|
|
uint8_t ucCnt;
|
||
|
|
LORA_SPI_NSS_CLR();
|
||
|
|
LORA_SPI_READ_WRITE(ucAddr | 0x80);
|
||
|
|
for( ucCnt = 0; ucCnt < ucLen; ucCnt++ ){
|
||
|
|
LORA_SPI_READ_WRITE(pucBuff[ucCnt]);
|
||
|
|
}
|
||
|
|
LORA_SPI_NSS_SET();
|
||
|
|
|
||
|
|
|
||
|
|
void SX1276Write(uint8_t ucAddr, uint8_t ucData)
|
||
|
|
{
|
||
|
|
SX1276WriteBuffer(ucAddr, &ucData, 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276Read(uint8_t ucAddr, uint8_t * pucData)
|
||
|
|
{
|
||
|
|
SX1276ReadBuffer(ucAddr, pucData, 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276WriteFifo(uint8_t *pucBuff, uint8_t ucLen)
|
||
|
|
{
|
||
|
|
SX1276WriteBuffer(0, pucBuff, ucLen);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276ReadFifo(uint8_t *pucBuff, uint8_t ucLen)
|
||
|
|
{
|
||
|
|
SX1276ReadBuffer(0, pucBuff, ucLen);
|
||
|
|
}
|
||
|
|
|
||
|
|
/////////////////////////////////////////////////
|
||
|
|
void SX1276LoRaSetNbTrigPeaks(uint8_t ucValue)
|
||
|
|
{
|
||
|
|
SX1276Read(0x31, &(LoRaPara.RegBuff.RegTestReserved31));
|
||
|
|
LoRaPara.RegBuff.RegTestReserved31 = (LoRaPara.RegBuff.RegTestReserved31 & 0xF8) | ucValue;
|
||
|
|
SX1276Write(0x31, LoRaPara.RegBuff.RegTestReserved31 );
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetSignalBandwidth(Sx1276BwType Bw)
|
||
|
|
{
|
||
|
|
SX1276Read(REG_LR_MODEMCONFIG1, &(LoRaPara.RegBuff.RegModemConfig1));
|
||
|
|
LoRaPara.RegBuff.RegModemConfig1 = (LoRaPara.RegBuff.RegModemConfig1 & RFLR_MODEMCONFIG1_BW_MASK) | Bw;
|
||
|
|
SX1276Write(REG_LR_MODEMCONFIG1, LoRaPara.RegBuff.RegModemConfig1);
|
||
|
|
LoRaPara.SignalBw = Bw;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetSpreadingFactor(Sx1276SpreadFactorType Factor)
|
||
|
|
{
|
||
|
|
if (Factor > SX1276_SF_4096){
|
||
|
|
Factor = SX1276_SF_4096;
|
||
|
|
}
|
||
|
|
else if (Factor < SX1276_SF_64){
|
||
|
|
Factor = SX1276_SF_64;
|
||
|
|
}
|
||
|
|
if (Factor == SX1276_SF_64){
|
||
|
|
SX1276LoRaSetNbTrigPeaks(5);
|
||
|
|
}
|
||
|
|
else{
|
||
|
|
SX1276LoRaSetNbTrigPeaks(3);
|
||
|
|
}
|
||
|
|
SX1276Read(REG_LR_MODEMCONFIG2, &(LoRaPara.RegBuff.RegModemConfig2));
|
||
|
|
LoRaPara.RegBuff.RegModemConfig2 = (LoRaPara.RegBuff.RegModemConfig2 & RFLR_MODEMCONFIG2_SF_MASK ) | Factor;
|
||
|
|
SX1276Write(REG_LR_MODEMCONFIG2, LoRaPara.RegBuff.RegModemConfig2);
|
||
|
|
LoRaPara.SpreadFactor = Factor;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetErrorCoding(Sx1276ErrorCodingType Value){
|
||
|
|
SX1276Read(REG_LR_MODEMCONFIG1, &(LoRaPara.RegBuff.RegModemConfig1));
|
||
|
|
LoRaPara.RegBuff.RegModemConfig1 = (LoRaPara.RegBuff.RegModemConfig1 & RFLR_MODEMCONFIG1_CODINGRATE_MASK ) | Value;
|
||
|
|
SX1276Write(REG_LR_MODEMCONFIG1, LoRaPara.RegBuff.RegModemConfig1 );
|
||
|
|
LoRaPara.ErrorCoding = Value;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetFreqHz(uint32_t dwFreqHz)
|
||
|
|
{
|
||
|
|
LoRaPara.dwFreqHz = dwFreqHz;
|
||
|
|
dwFreqHz = ( uint32_t )( ( double )dwFreqHz / ( double )FREQ_STEP );
|
||
|
|
LoRaPara.RegBuff.RegFrfMsb = ( uint8_t )( ( dwFreqHz >> 16 ) & 0xFF );
|
||
|
|
LoRaPara.RegBuff.RegFrfMid = ( uint8_t )( ( dwFreqHz >> 8 ) & 0xFF );
|
||
|
|
LoRaPara.RegBuff.RegFrfLsb = ( uint8_t )( dwFreqHz & 0xFF );
|
||
|
|
SX1276WriteBuffer(REG_LR_FRFMSB, &(LoRaPara.RegBuff.RegFrfMsb), 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetSymbTimeout(uint16_t ucValue)
|
||
|
|
{
|
||
|
|
SX1276ReadBuffer(REG_LR_MODEMCONFIG2, &(LoRaPara.RegBuff.RegModemConfig2), 2);
|
||
|
|
LoRaPara.RegBuff.RegModemConfig2 = (LoRaPara.RegBuff.RegModemConfig2 & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK) | (( ucValue >> 8) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK );
|
||
|
|
LoRaPara.RegBuff.RegSymbTimeoutLsb = ucValue & 0xFF;
|
||
|
|
SX1276WriteBuffer(REG_LR_MODEMCONFIG2, &(LoRaPara.RegBuff.RegModemConfig2), 2);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetLowDatarateOptimize(bool bEnable)
|
||
|
|
{
|
||
|
|
SX1276Read(REG_LR_MODEMCONFIG3, &(LoRaPara.RegBuff.RegModemConfig3));
|
||
|
|
LoRaPara.RegBuff.RegModemConfig3 = (LoRaPara.RegBuff.RegModemConfig3 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) | ( bEnable << 3 );
|
||
|
|
SX1276Write(REG_LR_MODEMCONFIG3, LoRaPara.RegBuff.RegModemConfig3);
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetPAOutput(uint8_t ucOutputPin)
|
||
|
|
{
|
||
|
|
SX1276Read(REG_LR_PACONFIG, &(LoRaPara.RegBuff.RegPaConfig));
|
||
|
|
LoRaPara.RegBuff.RegPaConfig = (LoRaPara.RegBuff.RegPaConfig & RFLR_PACONFIG_PASELECT_MASK ) | ucOutputPin;
|
||
|
|
SX1276Write(REG_LR_PACONFIG, LoRaPara.RegBuff.RegPaConfig );
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetPa20dBm(bool bEnable)
|
||
|
|
{
|
||
|
|
SX1276Read(REG_LR_PADAC, &(LoRaPara.RegBuff.RegPaDac));
|
||
|
|
SX1276Read(REG_LR_PACONFIG, &(LoRaPara.RegBuff.RegPaConfig));
|
||
|
|
if ((LoRaPara.RegBuff.RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST ) {
|
||
|
|
if( bEnable == true ){
|
||
|
|
LoRaPara.RegBuff.RegPaDac = 0x87;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else{
|
||
|
|
LoRaPara.RegBuff.RegPaDac = 0x84;
|
||
|
|
}
|
||
|
|
SX1276Write(REG_LR_PADAC, LoRaPara.RegBuff.RegPaDac );
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetRfPower(int8_t sbPower)
|
||
|
|
{
|
||
|
|
SX1276Read(REG_LR_PACONFIG, &(LoRaPara.RegBuff.RegPaConfig));
|
||
|
|
SX1276Read(REG_LR_PADAC, &(LoRaPara.RegBuff.RegPaDac));
|
||
|
|
if ((LoRaPara.RegBuff.RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST ) {
|
||
|
|
if ((LoRaPara.RegBuff.RegPaDac & 0x87) == 0x87){
|
||
|
|
if( sbPower < 5 ){
|
||
|
|
sbPower = 5;
|
||
|
|
}
|
||
|
|
if( sbPower > 20){
|
||
|
|
sbPower = 20;
|
||
|
|
}
|
||
|
|
LoRaPara.RegBuff.RegPaConfig = (LoRaPara.RegBuff.RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70;
|
||
|
|
LoRaPara.RegBuff.RegPaConfig = (LoRaPara.RegBuff.RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) |
|
||
|
|
( uint8_t )( ( uint16_t )( sbPower - 5 ) & 0x0F );
|
||
|
|
}
|
||
|
|
else{
|
||
|
|
if( sbPower < 2){
|
||
|
|
sbPower = 2;
|
||
|
|
}
|
||
|
|
if( sbPower > 17){
|
||
|
|
sbPower = 17;
|
||
|
|
}
|
||
|
|
LoRaPara.RegBuff.RegPaConfig = (LoRaPara.RegBuff.RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70;
|
||
|
|
LoRaPara.RegBuff.RegPaConfig = (LoRaPara.RegBuff.RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) |
|
||
|
|
( uint8_t )( ( uint16_t )( sbPower - 2 ) & 0x0F );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else{
|
||
|
|
if( sbPower < -1){
|
||
|
|
sbPower = -1;
|
||
|
|
}
|
||
|
|
if( sbPower > 14){
|
||
|
|
sbPower = 14;
|
||
|
|
}
|
||
|
|
LoRaPara.RegBuff.RegPaConfig = (LoRaPara.RegBuff.RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70;
|
||
|
|
LoRaPara.RegBuff.RegPaConfig = (LoRaPara.RegBuff.RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) |
|
||
|
|
( uint8_t )( ( uint16_t )( sbPower + 1 ) & 0x0F );
|
||
|
|
}
|
||
|
|
SX1276Write(REG_LR_PACONFIG, LoRaPara.RegBuff.RegPaConfig);
|
||
|
|
LoRaPara.ucPower = sbPower;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaSetOpMode(Sx1276OpModeType ucOpMode)
|
||
|
|
{
|
||
|
|
Sx1276AntStatus_m bAntSwStatus = RF_ANT_RECEIVER;
|
||
|
|
LoRaPara.ucOpModePrev = LoRaPara.RegBuff.RegOpMode & ~RFLR_OPMODE_MASK;
|
||
|
|
if( ucOpMode != LoRaPara.ucOpModePrev){
|
||
|
|
if(ucOpMode == RFLR_OPMODE_TRANSMITTER){
|
||
|
|
LORA_RXEN_CLR();
|
||
|
|
LORA_TXEN_SET();
|
||
|
|
bAntSwStatus = RF_ANT_TRANSMITTER;
|
||
|
|
}
|
||
|
|
else if(ucOpMode == RFLR_OPMODE_RECEIVER){
|
||
|
|
LORA_TXEN_CLR();
|
||
|
|
LORA_RXEN_SET();
|
||
|
|
bAntSwStatus = RF_ANT_RECEIVER;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
LORA_TXEN_CLR();
|
||
|
|
LORA_RXEN_CLR();
|
||
|
|
bAntSwStatus = RF_ANT_CLOSE;
|
||
|
|
}
|
||
|
|
if( bAntSwStatus != LoRaPara.bAntSwPrev ){
|
||
|
|
LoRaPara.bAntSwPrev = bAntSwStatus;
|
||
|
|
SX1276SetAntSw(bAntSwStatus);
|
||
|
|
}
|
||
|
|
LoRaPara.RegBuff.RegOpMode = (LoRaPara.RegBuff.RegOpMode & RFLR_OPMODE_MASK ) | ucOpMode;
|
||
|
|
SX1276Write( REG_LR_OPMODE, LoRaPara.RegBuff.RegOpMode);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
void Sx1276LoRaEnterRx(void)
|
||
|
|
{
|
||
|
|
uint8_t ucCnt;
|
||
|
|
SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY);
|
||
|
|
LoRaPara.RegBuff.RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | RFLR_IRQFLAGS_VALIDHEADER | RFLR_IRQFLAGS_TXDONE;
|
||
|
|
SX1276Write(REG_LR_IRQFLAGSMASK, LoRaPara.RegBuff.RegIrqFlagsMask);
|
||
|
|
LoRaPara.RegBuff.RegHopPeriod = 255;
|
||
|
|
SX1276Write(REG_LR_HOPPERIOD, LoRaPara.RegBuff.RegHopPeriod );
|
||
|
|
// RxDone RxTimeout FhssChangeChannel ValidHeader
|
||
|
|
LoRaPara.RegBuff.RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_01 | RFLR_DIOMAPPING1_DIO3_01;
|
||
|
|
// CadDetected ModeReady
|
||
|
|
LoRaPara.RegBuff.RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00;
|
||
|
|
SX1276WriteBuffer(REG_LR_DIOMAPPING1, &(LoRaPara.RegBuff.RegDioMapping1), 2);
|
||
|
|
LoRaPara.RegBuff.RegFifoAddrPtr = LoRaPara.RegBuff.RegFifoRxBaseAddr;
|
||
|
|
SX1276Write(REG_LR_FIFOADDRPTR, LoRaPara.RegBuff.RegFifoAddrPtr);
|
||
|
|
SX1276LoRaSetOpMode(RFLR_OPMODE_RECEIVER);
|
||
|
|
for (ucCnt=0; ucCnt< LORA_BUFF_SIZE; ucCnt++){
|
||
|
|
LoRaPara.RxTxBuff[ucCnt] = 0;
|
||
|
|
}
|
||
|
|
LoRaPara.State = SX1276_IDLE;//COMST_RX
|
||
|
|
uint8_t temp;
|
||
|
|
SX1276Read(REG_LR_IRQFLAGS, &temp);
|
||
|
|
}
|
||
|
|
|
||
|
|
/////////////////////////////////////////////////
|
||
|
|
void Sx1276LoRaInit(DataRevCallBack RxCallBack)
|
||
|
|
{
|
||
|
|
if(RxCallBack != NULL) {
|
||
|
|
LoRaPara.RxCallBack = RxCallBack;
|
||
|
|
}
|
||
|
|
LoraReset();
|
||
|
|
SX1276LoRaSetOpMode(RFLR_OPMODE_SLEEP);
|
||
|
|
LoRaPara.RegBuff.RegOpMode = (LoRaPara.RegBuff.RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON;
|
||
|
|
SX1276Write(REG_LR_OPMODE, LoRaPara.RegBuff.RegOpMode );
|
||
|
|
SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY);
|
||
|
|
// RxDone RxTimeout FhssChangeChannel ValidHeader
|
||
|
|
LoRaPara.RegBuff.RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_01;
|
||
|
|
// CadDetected ModeReady
|
||
|
|
LoRaPara.RegBuff.RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00;
|
||
|
|
SX1276WriteBuffer(REG_LR_DIOMAPPING1, &(LoRaPara.RegBuff.RegDioMapping1), 2 );
|
||
|
|
SX1276ReadBuffer(REG_LR_OPMODE, (uint8_t*)&(LoRaPara.RegBuff) + 1, SIZE_OF_REGISTERS);
|
||
|
|
LoRaPara.State = SX1276_BUSY;
|
||
|
|
SX1276Read(REG_LR_VERSION, &(LoRaPara.RegBuff.RegVersion));
|
||
|
|
SX1276ReadBuffer(REG_LR_OPMODE, (uint8_t*)&(LoRaPara.RegBuff) + 1, SIZE_OF_REGISTERS);
|
||
|
|
LoRaPara.RegBuff.RegLna = RFLR_LNA_GAIN_G1;
|
||
|
|
SX1276WriteBuffer(REG_LR_OPMODE, (uint8_t*)&(LoRaPara.RegBuff) + 1, SIZE_OF_REGISTERS);
|
||
|
|
|
||
|
|
// set the RF settings
|
||
|
|
SX1276LoRaWriteChannel(LoRaPara.ucChannel);
|
||
|
|
//SX1276LoRaSetFreqHz(LoRaPara.dwFreqHz);
|
||
|
|
//REG_LR_MODEMCONFIG1
|
||
|
|
SX1276Read(REG_LR_MODEMCONFIG1, &(LoRaPara.RegBuff.RegModemConfig1));
|
||
|
|
//SignalBandwidth
|
||
|
|
LoRaPara.RegBuff.RegModemConfig1 = (LoRaPara.RegBuff.RegModemConfig1 & RFLR_MODEMCONFIG1_BW_MASK ) | LoRaPara.SignalBw;
|
||
|
|
//ErrorCoding
|
||
|
|
LoRaPara.RegBuff.RegModemConfig1 = (LoRaPara.RegBuff.RegModemConfig1 & RFLR_MODEMCONFIG1_CODINGRATE_MASK ) | LoRaPara.ErrorCoding;
|
||
|
|
//IMPLICITHEADER
|
||
|
|
LoRaPara.RegBuff.RegModemConfig1 = LoRaPara.RegBuff.RegModemConfig1 | RFLR_MODEMCONFIG1_IMPLICITHEADER_ON;
|
||
|
|
SX1276Write(REG_LR_MODEMCONFIG1, LoRaPara.RegBuff.RegModemConfig1);
|
||
|
|
//REG_LR_MODEMCONFIG2
|
||
|
|
SX1276Read(REG_LR_MODEMCONFIG2, &(LoRaPara.RegBuff.RegModemConfig2));
|
||
|
|
//SpreadingFactor
|
||
|
|
if( LoRaPara.SpreadFactor == SX1276_SF_64){
|
||
|
|
SX1276LoRaSetNbTrigPeaks(5);
|
||
|
|
SX1276LoRaSetLowDatarateOptimize(true); //低数据速率设置
|
||
|
|
}
|
||
|
|
else{
|
||
|
|
SX1276LoRaSetNbTrigPeaks(3);
|
||
|
|
SX1276LoRaSetLowDatarateOptimize(false); //低数据速率设置
|
||
|
|
}
|
||
|
|
LoRaPara.RegBuff.RegModemConfig2 = (LoRaPara.RegBuff.RegModemConfig2 & RFLR_MODEMCONFIG2_SF_MASK ) | LoRaPara.SpreadFactor;
|
||
|
|
//PacketCrcOn
|
||
|
|
LoRaPara.RegBuff.RegModemConfig2 = (LoRaPara.RegBuff.RegModemConfig2 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) | SX1276_CRC_ON; //SX1276_CRC_OFF
|
||
|
|
SX1276Write(REG_LR_MODEMCONFIG2, LoRaPara.RegBuff.RegModemConfig2);
|
||
|
|
LoRaPara.RegBuff.RegModemConfig2 = 0;
|
||
|
|
SX1276Read(REG_LR_MODEMCONFIG2, &(LoRaPara.RegBuff.RegModemConfig2));
|
||
|
|
|
||
|
|
SX1276LoRaSetSymbTimeout(0x3FF);
|
||
|
|
LoRaPara.RegBuff.RegPreambleMsb= (LoRaPara.RegPreamble >> 8) & 0x00ff;
|
||
|
|
LoRaPara.RegBuff.RegPreambleLsb= LoRaPara.RegPreamble & 0x00ff;
|
||
|
|
SX1276Write(REG_LR_PREAMBLEMSB, LoRaPara.RegBuff.RegPreambleMsb);
|
||
|
|
SX1276Write(REG_LR_PREAMBLELSB, LoRaPara.RegBuff.RegPreambleLsb);
|
||
|
|
SX1276Write(REG_LR_PAYLOADLENGTH, LORA_BUFF_SIZE);
|
||
|
|
SX1276Write(REG_LR_PAYLOADMAXLENGTH, LORA_BUFF_SIZE);
|
||
|
|
LoRaPara.RegBuff.RegPayloadLength = LORA_BUFF_SIZE;
|
||
|
|
|
||
|
|
#ifndef USE_LORA_860_PA
|
||
|
|
if(LoRaPara.dwFreqHz > 860000000 ){
|
||
|
|
SX1276LoRaSetPAOutput(RFLR_PACONFIG_PASELECT_RFO);
|
||
|
|
SX1276LoRaSetPa20dBm(false);
|
||
|
|
LoRaPara.ucPower = 14;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
#endif
|
||
|
|
{
|
||
|
|
SX1276LoRaSetPAOutput(RFLR_PACONFIG_PASELECT_PABOOST);
|
||
|
|
SX1276LoRaSetPa20dBm(true);
|
||
|
|
LoRaPara.ucPower = 20;
|
||
|
|
}
|
||
|
|
SX1276LoRaSetRfPower(LoRaPara.ucPower);
|
||
|
|
SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY);
|
||
|
|
Sx1276LoRaEnterRx();
|
||
|
|
}
|
||
|
|
|
||
|
|
void IsrSx1276LoRaTxRx(GateWayPara GateWay)
|
||
|
|
{
|
||
|
|
switch (LoRaPara.State){
|
||
|
|
case SX1276_IDLE:
|
||
|
|
case SX1276_RX:
|
||
|
|
// Clear Irq
|
||
|
|
LORA_RXLED_ON();
|
||
|
|
do {
|
||
|
|
SX1276Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE);
|
||
|
|
SX1276Read(REG_LR_IRQFLAGS, &(LoRaPara.RegBuff.RegIrqFlags));
|
||
|
|
if((LoRaPara.RegBuff.RegIrqFlags & RFLR_IRQFLAGS_RXDONE) != RFLR_IRQFLAGS_RXDONE)
|
||
|
|
break;
|
||
|
|
}while(1);
|
||
|
|
if((LoRaPara.RegBuff.RegIrqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR ) == RFLR_IRQFLAGS_PAYLOADCRCERROR) {
|
||
|
|
// Clear Irq
|
||
|
|
SX1276Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR);
|
||
|
|
LoRaPara.State = SX1276_IDLE;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
SX1276Read(REG_LR_PKTSNRVALUE, &(LoRaPara.RegBuff.RegPktSnrValue));
|
||
|
|
SX1276Read(REG_LR_RSSIVALUE, &(LoRaPara.RegBuff.RegRssiValue));
|
||
|
|
SX1276Read(REG_LR_PKTRSSIVALUE, &(LoRaPara.RegBuff.RegPktRssiValue));
|
||
|
|
SX1276Read(REG_LR_FIFORXCURRENTADDR, &(LoRaPara.RegBuff.RegFifoRxCurrentAddr));
|
||
|
|
SX1276Read(REG_LR_NBRXBYTES, &(LoRaPara.RegBuff.RegNbRxBytes));
|
||
|
|
LoRaPara.ucRxPacketSize = LoRaPara.RegBuff.RegNbRxBytes;
|
||
|
|
LoRaPara.RegBuff.RegFifoAddrPtr = LoRaPara.RegBuff.RegFifoRxCurrentAddr;
|
||
|
|
SX1276Write(REG_LR_FIFOADDRPTR, LoRaPara.RegBuff.RegFifoAddrPtr);
|
||
|
|
SX1276ReadFifo(LoRaPara.RxTxBuff, (LoRaPara.ucRxPacketSize > LORA_BUFF_SIZE) ? LORA_BUFF_SIZE : LoRaPara.ucRxPacketSize);
|
||
|
|
uint8_t ucLen;
|
||
|
|
if(LoRaPara.ucRxPacketSize < LORA_BUFF_SIZE) {
|
||
|
|
ucLen= LoRaPara.ucRxPacketSize;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
ucLen= LORA_BUFF_SIZE;
|
||
|
|
}
|
||
|
|
LoRaPara.RxTxBuff[ucLen] = 0;
|
||
|
|
if(LoRaPara.RxCallBack != NULL)
|
||
|
|
LoRaPara.RxRet = LoRaPara.RxCallBack(GateWay, LoRaPara.RxTxBuff, ucLen);
|
||
|
|
|
||
|
|
LoRaPara.ucRxPacketSize = 0;
|
||
|
|
LoRaPara.State = SX1276_IDLE;
|
||
|
|
LORA_RXLED_OFF();
|
||
|
|
break;
|
||
|
|
case SX1276_TX:
|
||
|
|
// Clear Irq
|
||
|
|
SX1276Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE);
|
||
|
|
LORA_TXLED_OFF();
|
||
|
|
Sx1276LoRaEnterRx();
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sx1276LoRaLoopHandler(GateWayPara GateWay)
|
||
|
|
{
|
||
|
|
if(LORA_GETDIO0() > 0){ // RxDone or TxDone
|
||
|
|
IsrSx1276LoRaTxRx(GateWay);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
void Sx1276LoRaSendBuffer(uint8_t* pucBuff, uint16_t ucLen)
|
||
|
|
{
|
||
|
|
LoRaPara.State = SX1276_BUSY;
|
||
|
|
if (ucLen > LORA_BUFF_SIZE){
|
||
|
|
ucLen = LORA_BUFF_SIZE;
|
||
|
|
}
|
||
|
|
LoRaPara.ucTxPacketSize = ucLen;
|
||
|
|
while(ucLen--){
|
||
|
|
LoRaPara.RxTxBuff[ucLen] = pucBuff[ucLen];
|
||
|
|
};
|
||
|
|
SX1276LoRaSetOpMode(RFLR_OPMODE_STANDBY);
|
||
|
|
LoRaPara.RegBuff.RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | RFLR_IRQFLAGS_RXDONE | RFLR_IRQFLAGS_PAYLOADCRCERROR | RFLR_IRQFLAGS_VALIDHEADER;
|
||
|
|
//LoRaPara.RegBuff.RegHopPeriod = 0;
|
||
|
|
//SX1276Write(REG_LR_HOPPERIOD, LoRaPara.RegBuff.RegHopPeriod);
|
||
|
|
SX1276Write(REG_LR_IRQFLAGSMASK, LoRaPara.RegBuff.RegIrqFlagsMask);
|
||
|
|
// Initializes the payload size
|
||
|
|
LoRaPara.RegBuff.RegPayloadLength = LoRaPara.ucTxPacketSize;
|
||
|
|
SX1276Write(REG_LR_PAYLOADLENGTH, LoRaPara.RegBuff.RegPayloadLength);
|
||
|
|
LoRaPara.RegBuff.RegFifoTxBaseAddr = 0x00; // Full buffer used for Tx
|
||
|
|
SX1276Write(REG_LR_FIFOTXBASEADDR, LoRaPara.RegBuff.RegFifoTxBaseAddr);
|
||
|
|
LoRaPara.RegBuff.RegFifoAddrPtr = LoRaPara.RegBuff.RegFifoTxBaseAddr;
|
||
|
|
SX1276Write(REG_LR_FIFOADDRPTR, LoRaPara.RegBuff.RegFifoAddrPtr);
|
||
|
|
// Write payload buffer to LORA modem
|
||
|
|
SX1276WriteFifo(LoRaPara.RxTxBuff, LoRaPara.RegBuff.RegPayloadLength);
|
||
|
|
// TxDone RxTimeout FhssChangeChannel ValidHeader
|
||
|
|
LoRaPara.RegBuff.RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_01;
|
||
|
|
// PllLock Mode Ready
|
||
|
|
LoRaPara.RegBuff.RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_01 | RFLR_DIOMAPPING2_DIO5_00;
|
||
|
|
SX1276WriteBuffer(REG_LR_DIOMAPPING1, &(LoRaPara.RegBuff.RegDioMapping1), 2);
|
||
|
|
SX1276LoRaSetOpMode(RFLR_OPMODE_TRANSMITTER);
|
||
|
|
uint8_t temp;
|
||
|
|
SX1276Read(REG_LR_IRQFLAGS, &temp);
|
||
|
|
LORA_TXLED_ON();
|
||
|
|
LoRaPara.State = SX1276_TX;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sx1276LoRaSleep(void)
|
||
|
|
{
|
||
|
|
SX1276LoRaSetOpMode(RFLR_OPMODE_SLEEP);//RFLR_OPMODE_STANDBY
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sx1276LoRaWakeup(void)
|
||
|
|
{
|
||
|
|
Sx1276LoRaEnterRx();
|
||
|
|
}
|
||
|
|
|
||
|
|
////////////////////////////////////////
|
||
|
|
//配置本层参数的函数
|
||
|
|
//频道表
|
||
|
|
const uint32_t gdwSx1276ChannelTbl[SX1276_CHANNEL_MAX]={
|
||
|
|
FREQ_CENT-FREQ_DEV*8, FREQ_CENT-FREQ_DEV*7, FREQ_CENT-FREQ_DEV*6, FREQ_CENT-FREQ_DEV*5,
|
||
|
|
FREQ_CENT-FREQ_DEV*4, FREQ_CENT-FREQ_DEV*3, FREQ_CENT-FREQ_DEV*2, FREQ_CENT-FREQ_DEV*1,
|
||
|
|
FREQ_CENT+FREQ_DEV*0, FREQ_CENT+FREQ_DEV*1, FREQ_CENT+FREQ_DEV*2, FREQ_CENT+FREQ_DEV*3,
|
||
|
|
FREQ_CENT+FREQ_DEV*4, FREQ_CENT+FREQ_DEV*5, FREQ_CENT+FREQ_DEV*6, FREQ_CENT+FREQ_DEV*7,
|
||
|
|
FREQ_CENT+FREQ_DEV*8
|
||
|
|
};
|
||
|
|
|
||
|
|
//LORAPT_CHANNEL
|
||
|
|
uint8_t SX1276LoRaReadChannel(void)
|
||
|
|
{
|
||
|
|
return LoRaPara.ucChannel;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool SX1276LoRaWriteChannel(uint8_t Channel)
|
||
|
|
{
|
||
|
|
if(Channel > SX1276_CHANNEL_MAX) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
LoRaPara.dwFreqHz = gdwSx1276ChannelTbl[Channel];
|
||
|
|
SX1276LoRaSetFreqHz(LoRaPara.dwFreqHz);
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
//LORAPT_FREQ,
|
||
|
|
uint32_t SX1276LoRaReadFreq(void)
|
||
|
|
{
|
||
|
|
return LoRaPara.dwFreqHz;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaWriteFreq(uint32_t Freq)
|
||
|
|
{
|
||
|
|
SX1276LoRaSetFreqHz(Freq);
|
||
|
|
}
|
||
|
|
|
||
|
|
//LORAPT_BW,
|
||
|
|
uint32_t SX1276LoRaReadBw(void)
|
||
|
|
{
|
||
|
|
return LoRaPara.SignalBw;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaWriteBw(Sx1276BwType SignalBw)
|
||
|
|
{
|
||
|
|
LoRaPara.SignalBw = SignalBw;
|
||
|
|
SX1276LoRaSetSignalBandwidth(SignalBw);
|
||
|
|
}
|
||
|
|
|
||
|
|
//LORAPT_SF,
|
||
|
|
uint8_t SX1276LoRaReadSf(void)
|
||
|
|
{
|
||
|
|
return LoRaPara.SpreadFactor;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaWriteSf(Sx1276SpreadFactorType SpreadFactor)
|
||
|
|
{
|
||
|
|
LoRaPara.SpreadFactor = SpreadFactor;
|
||
|
|
SX1276LoRaSetSpreadingFactor(LoRaPara.SpreadFactor);
|
||
|
|
}
|
||
|
|
|
||
|
|
//LORAPT_EC,
|
||
|
|
uint8_t SX1276LoRaReadEc(void)
|
||
|
|
{
|
||
|
|
return LoRaPara.ErrorCoding;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SX1276LoRaWriteEc(Sx1276ErrorCodingType ErrorCoding)
|
||
|
|
{
|
||
|
|
LoRaPara.ErrorCoding = ErrorCoding;
|
||
|
|
SX1276LoRaSetErrorCoding(ErrorCoding);
|
||
|
|
}
|
||
|
|
|
||
|
|
//LORAPT_RSSI,
|
||
|
|
uint32_t SX1276LoRaParaReadRssi(void)
|
||
|
|
{
|
||
|
|
uint32_t rssi;
|
||
|
|
|
||
|
|
SX1276Read(REG_LR_PKTRSSIVALUE, &(LoRaPara.RegBuff.RegPktRssiValue));
|
||
|
|
SX1276Read(REG_LR_RSSIVALUE, &(LoRaPara.RegBuff.RegRssiValue));
|
||
|
|
rssi = (uint16_t)(LoRaPara.RegBuff.RegPktSnrValue)<<16;
|
||
|
|
rssi |= (uint16_t)(LoRaPara.RegBuff.RegRssiValue)<<8;
|
||
|
|
rssi |= LoRaPara.RegBuff.RegPktRssiValue;
|
||
|
|
return rssi;
|
||
|
|
}
|
||
|
|
|
||
|
|
uint8_t SX1276LoRaReadRssiPkt(void)
|
||
|
|
{
|
||
|
|
uint8_t RssiPkt;
|
||
|
|
|
||
|
|
SX1276Read(REG_LR_PKTRSSIVALUE, &LoRaPara.RegBuff.RegPktRssiValue);
|
||
|
|
RssiPkt = LoRaPara.RegBuff.RegPktRssiValue;
|
||
|
|
return RssiPkt;
|
||
|
|
}
|
||
|
|
|
||
|
|
//LORAPT_POWER,
|
||
|
|
void SX1276LoRaWritePwr(int8_t Pwr)
|
||
|
|
{
|
||
|
|
SX1276LoRaSetRfPower(Pwr);
|
||
|
|
}
|
||
|
|
|
||
|
|
//LORAPT_SET_RX,
|
||
|
|
void SX1276LoRaWriteRx(void)
|
||
|
|
{
|
||
|
|
Sx1276LoRaEnterRx();
|
||
|
|
}
|
||
|
|
|
||
|
|
//LORAPT_SET_SLEEP,true-Sleep, false-Wakeup
|
||
|
|
void SX1276LoRaWriteSleep(bool Sleep)
|
||
|
|
{
|
||
|
|
if(Sleep){
|
||
|
|
Sx1276LoRaSleep();
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
Sx1276LoRaWakeup();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Sx1276StateType_t SX1276LoRaReadStatus(void)
|
||
|
|
{
|
||
|
|
return LoRaPara.State;
|
||
|
|
}
|
||
|
|
|
||
|
|
///////////////RSSI Calc///////////////
|
||
|
|
void SX1276LoCalcRssiSnr(int16_t *pswRssi, int8_t *psbSnr)
|
||
|
|
{
|
||
|
|
int8_t sbSnr= LoRaPara.RegBuff.RegPktSnrValue & 0x80 ? (-1)*((int8_t)(((~LoRaPara.RegBuff.RegPktSnrValue+ 1)& 0xFF)/4)): (~LoRaPara.RegBuff.RegPktSnrValue& 0xFF)/4;
|
||
|
|
if (*psbSnr > 0) {
|
||
|
|
*pswRssi= RSSI_OFFSET_LF+ LoRaPara.RegBuff.RegPktRssiValue;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
*pswRssi= NOISE_ABSOLUTE_ZERO + 10 + SIGNAL_BW_LOG_125KHZ + NOISE_FIGURE_LF + sbSnr;
|
||
|
|
}
|
||
|
|
*psbSnr= sbSnr;
|
||
|
|
}
|
||
|
|
|
||
|
|
int GetSx1276RxRetValue(void)
|
||
|
|
{
|
||
|
|
return LoRaPara.RxRet;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sx1276RxRetValue(void)
|
||
|
|
{
|
||
|
|
LoRaPara.RxRet = -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LoraSetChannel(uint8_t Channel)
|
||
|
|
{
|
||
|
|
if(Channel > 16)
|
||
|
|
return false;
|
||
|
|
LoRaPara.ucChannel = Channel;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LoraSetPower(uint8_t Power)
|
||
|
|
{
|
||
|
|
if(Power > 20)
|
||
|
|
return false;
|
||
|
|
LoRaPara.ucPower = Power;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LoraSetSignalBw(uint8_t SignalBw)
|
||
|
|
{
|
||
|
|
if(SignalBw > 9)
|
||
|
|
return false;
|
||
|
|
LoRaPara.SignalBw = (SignalBw << 4);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LoraSetSpreadFactor(uint8_t SpreadFactor)
|
||
|
|
{
|
||
|
|
if(SpreadFactor < 4 || SpreadFactor > 12)
|
||
|
|
return false;
|
||
|
|
LoRaPara.SpreadFactor = SpreadFactor << 4;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LoraSetErrorCoding(uint8_t ErrorCoding)
|
||
|
|
{
|
||
|
|
if(ErrorCoding == 0 || ErrorCoding > 4)
|
||
|
|
return false;
|
||
|
|
LoRaPara.ErrorCoding = ErrorCoding << 1;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool LoraSetRegPreamble(uint8_t RegPreamble)
|
||
|
|
{
|
||
|
|
LoRaPara.RegPreamble = RegPreamble;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
#endif
|