diff --git a/MinimouseSrc/Define.h b/MinimouseSrc/Define.h index c4ef424..c89d15f 100644 --- a/MinimouseSrc/Define.h +++ b/MinimouseSrc/Define.h @@ -162,7 +162,7 @@ enum { typedef enum{ RADIO_IRQ_NONE = 0x00, - SENT_PACKET_IRQ_FLAG = 0x20, + SENT_PACKET_IRQ_FLAG = 0x20, RECEIVE_PACKET_IRQ_FLAG = 0x40, BAD_PACKET_IRQ_FLAG = 0x60, RXTIMEOUT_IRQ_FLAG = 0x80, @@ -223,6 +223,7 @@ typedef enum { ERROR_CHANNEL_MASK = -1, OKCHANNEL = 0, }eStatusChannel; + typedef enum { NO_MORE_VALID_RX_PACKET, USER_RX_PACKET, @@ -230,10 +231,12 @@ typedef enum { NWKRXPACKET, JOIN_ACCEPT_PACKET, } eRxPacketType; + typedef enum { RX1, RX2 }eRxWinType; + /*************************/ /* SHARE WITH USER */ /*************************/ @@ -295,4 +298,3 @@ typedef struct sLoRaWanKeys { eDeviceTypeOTA_APB OtaDevice; }sLoRaWanKeys; #endif - diff --git a/MinimouseSrc/MacLayer.cpp b/MinimouseSrc/MacLayer.cpp index 7a226b9..7986f00 100644 --- a/MinimouseSrc/MacLayer.cpp +++ b/MinimouseSrc/MacLayer.cpp @@ -136,7 +136,7 @@ template void LoraWanContainer::Configure template void LoraWanContainer::ConfigureRadioForRx1 ( void ) { InsertTrace ( __COUNTER__, FileId ); - Phy.SetRxConfig(MacTxModulationCurrent,MacRx1FrequencyCurrent, MacRx1SfCurrent, MacRx1BwCurrent, MacRxWindowMs); + Phy.SetRxConfig(MacRx1ModulationCurrent, MacRx1FrequencyCurrent, MacRx1SfCurrent, MacRx1BwCurrent, MacRxWindowMs); }; /************************************************************************************************************************************/ /* ConfigureRadioForRx2 + ConfigureTimerForRx */ @@ -146,7 +146,7 @@ template void LoraWanContainer::Configure template void LoraWanContainer::ConfigureRadioForRx2 ( void ) { InsertTrace ( __COUNTER__, FileId ); - Phy.SetRxConfig(MacTxModulationCurrent, MacRx2Frequency, MacRx2SfCurrent, MacRx2BwCurrent, MacRxWindowMs ); + Phy.SetRxConfig(MacRx2ModulationCurrent, MacRx2Frequency, MacRx2SfCurrent, MacRx2BwCurrent, MacRxWindowMs ); }; template void LoraWanContainer::ConfigureRadioForRxClassC ( void ) { @@ -156,13 +156,18 @@ template void LoraWanContainer::Configure template void LoraWanContainer::ConfigureTimerForRx ( eRxWinType type ) { InsertTrace ( __COUNTER__, FileId ); - uint32_t tCurrentMillisec; + uint32_t tCurrentMillisec; uint32_t tAlarmMillisec; tCurrentMillisec = mcu.RtcGetTimeMs( ); if (type == RX1) { RegionSetRxConfig ( RX1 ); - ComputeRxWindowParameters ( MacRx1SfCurrent, MacRx1BwCurrent, CRYSTAL_ERROR, MacRx1Delay * 1000 , BOARD_DELAY_RX_SETTING_MS ); + if( MacRx1ModulationCurrent == LORA ){ + ComputeRxWindowParameters(MacRx1SfCurrent, MacRx1BwCurrent, CRYSTAL_ERROR, MacRx1Delay * 1000 , BOARD_DELAY_RX_SETTING_MS); + } + else{ + ComputeRxWindowParametersFSK(CRYSTAL_ERROR, MacRx1Delay * 1000 , BOARD_DELAY_RX_SETTING_MS); + } tAlarmMillisec = ( ( MacRx1Delay * 1000 )+ Phy.TimestampRtcIsr ) - tCurrentMillisec ; if ( (int)(tAlarmMillisec - RxOffsetMs) < 0 ) {// too late to launch a timer Phy.StateRadioProcess = RADIOSTATE_RX1FINISHED ; @@ -172,6 +177,12 @@ template void LoraWanContainer::Configure } } else { RegionSetRxConfig ( RX2 ); + if( MacRx2ModulationCurrent == LORA ){ + ComputeRxWindowParameters(MacRx2SfCurrent, MacRx2BwCurrent, CRYSTAL_ERROR, MacRx1Delay * 1000 , BOARD_DELAY_RX_SETTING_MS); + } + else{ + ComputeRxWindowParametersFSK(CRYSTAL_ERROR, MacRx1Delay * 1000 , BOARD_DELAY_RX_SETTING_MS); + } ComputeRxWindowParameters ( MacRx2SfCurrent, MacRx2BwCurrent, CRYSTAL_ERROR, MacRx1Delay * 1000 + 1000 , BOARD_DELAY_RX_SETTING_MS ); tAlarmMillisec = ( MacRx1Delay * 1000 ) + 1000 + Phy.TimestampRtcIsr - tCurrentMillisec ;// @note Rx2 Dalay is alway RX1DELAY + 1 second if ( (int)(tAlarmMillisec - RxOffsetMs) < 0 ) {// too late to launch a timer @@ -995,10 +1006,11 @@ template int LoraWanContainer::FindEnabl } return (-1) ; // for error case }; + template void LoraWanContainer::ComputeRxWindowParameters( uint8_t SF, eBandWidth BW, uint32_t ClockAccuracy, uint32_t RxDelayMs, uint8_t BoardDelayRxMs) { // ClockAccuracy is set in Define.h, it is board dependent. It must be equal to error in per thousand InsertTrace ( __COUNTER__, FileId ); - uint32_t RxErrorMs= ( ClockAccuracy * RxDelayMs ) / 1000; // for example with an clockaccuracy = 30 (3%) and a rx windows set to 5s => rxerror = 150 ms + uint32_t RxErrorMs= ( ClockAccuracy * RxDelayMs ) / 1000; // for example with an clockaccuracy = 30 (3%) and a rx windows set to 5s => rxerror = 150 ms int bwTemp = 125* ( BW + 1 ); double tSymbol = (double) (1< void LoraWanContainer::ComputeR MacRxWindowMs = MacRxWindowSymb * tSymbol ; }; +template void LoraWanContainer::ComputeRxWindowParametersFSK(uint32_t ClockAccuracy, uint32_t RxDelayMs, uint8_t BoardDelayRxMs) { + uint32_t RxErrorMs= ( ClockAccuracy * RxDelayMs ) / 1000; + MacRxWindowMs = 2 + 2*RxErrorMs; // Exact formula is 1.3 + 2*RxErrorMs + RxOffsetMs = MacRxWindowMs >> 1; +}; + template eStatusLoRaWan LoraWanContainer::CheckValidMulticastPayload( void ){ eStatusLoRaWan status = OKLORAWAN; uint8_t MtypeRxTmp = Phy.RxPhyPayload[0] >> 5 ; @@ -1042,4 +1060,4 @@ template eStatusLoRaWan LoraWanContainer template void LoraWanContainer::SetDevAddr( uint32_t address ){ DevAddr = address; Phy.DevAddrIsr = address ; -} \ No newline at end of file +} diff --git a/MinimouseSrc/MacLayer.h b/MinimouseSrc/MacLayer.h index 4a3e800..11b789b 100644 --- a/MinimouseSrc/MacLayer.h +++ b/MinimouseSrc/MacLayer.h @@ -200,11 +200,13 @@ protected : eBandWidth MacTxBwCurrent; uint32_t MacTxFrequencyCurrent; uint32_t MacRx1FrequencyCurrent; + eModulationType MacRx1ModulationCurrent; uint8_t MacRx1SfCurrent; eBandWidth MacRx1BwCurrent; + eModulationType MacRx2ModulationCurrent; uint8_t MacRx2SfCurrent; eBandWidth MacRx2BwCurrent; - int FindEnabledChannel ( uint8_t Index ); + int FindEnabledChannel ( uint8_t Index); void PrintMacContext ( void ) ; private : @@ -226,7 +228,8 @@ private : void RXTimingSetupParser ( void ); void DicChannelParser ( void ); void UpdateDataRateForAdr ( void ); - void ComputeRxWindowParameters ( uint8_t SF, eBandWidth BW, uint32_t ClockAccuracy, uint32_t RxDelayMs, uint8_t BoardDelayRxMs ); + void ComputeRxWindowParameters ( uint8_t SF, eBandWidth BW, uint32_t ClockAccuracy, uint32_t RxDelayMs ,uint8_t BoardDelayRxMs ); + void ComputeRxWindowParametersFSK(uint32_t ClockAccuracy, uint32_t RxDelayMs, uint8_t BoardDelayRxMs); sBackUpFlash BackUpFlash; uint8_t NwkPayloadIndex; uint8_t RxEmptyPayload; diff --git a/MinimouseSrc/PhyLayer.cpp b/MinimouseSrc/PhyLayer.cpp index 7e20c0d..71c6162 100644 --- a/MinimouseSrc/PhyLayer.cpp +++ b/MinimouseSrc/PhyLayer.cpp @@ -74,11 +74,12 @@ template void RadioContainer ::Send(eModulationType TxModulation , Radio->Reset( ); if ( TxModulation == LORA ) { InsertTrace ( __COUNTER__, FileId ); - DEBUG_PRINTF ( " TxFrequency = %d, RxSf = %d , RxBw = %d PayloadSize = %d\n", TxFrequency, TxSf,TxBw, TxPayloadSize) ; + DEBUG_PRINTF ( " TxFrequency = %d, RxSf = %d , RxBw = %d PayloadSize = %d\n", TxFrequency, TxSf,TxBw, TxPayloadSize); Radio->SendLora( TxPhyPayload, TxPayloadSize, TxSf, TxBw, TxFrequency, TxPower ); } else { InsertTrace ( __COUNTER__, FileId ); DEBUG_MSG("FSK TRANSMISSION \n"); + DEBUG_PRINTF ( " TxFrequency = %d, PayloadSize = %d\n", TxFrequency, TxPayloadSize); Radio->SendFsk( TxPhyPayload, TxPayloadSize, TxFrequency, TxPower ); } mcu.mwait_ms(1); diff --git a/MinimouseSrc/Regions.cpp b/MinimouseSrc/Regions.cpp index 034039a..a617902 100644 --- a/MinimouseSrc/Regions.cpp +++ b/MinimouseSrc/Regions.cpp @@ -170,8 +170,14 @@ template < class R >eStatusLoRaWan LoraRegionsEU::RegionMaxPayloadSize ( uint template < class R >void LoraRegionsEU::RegionSetRxConfig ( eRxWinType type ) { InsertTrace ( __COUNTER__, FileId ); if ( type == RX1 ) { - this->MacRx1SfCurrent = ( this->MacTxSfCurrent < 12 - this->MacRx1DataRateOffset) ? this->MacTxSfCurrent + this->MacRx1DataRateOffset : 12; - this->MacRx1BwCurrent = this->MacTxBwCurrent; + if( this->MacTxModulationCurrent == FSK && this->MacRx1DataRateOffset == 0){ + this->MacRx1ModulationCurrent = FSK; + } + else{ + this->MacRx1ModulationCurrent = LORA; + this->MacRx1SfCurrent = ( this->MacTxSfCurrent < 12 - this->MacRx1DataRateOffset) ? this->MacTxSfCurrent + this->MacRx1DataRateOffset : 12; + this->MacRx1BwCurrent = this->MacTxBwCurrent; + } } else if ( type == RX2 ) { Rx2DataRateToSfBw ( this->MacRx2DataRate ); } else { @@ -282,8 +288,8 @@ template < class R >void LoraRegionsEU::RegionSetDataRateDistribution( uint8_ this->MacNbTrans = 1; break; case USER_DR_DISTRIBUTION: //in this example 1/3 dr5 1/3 dr4 and 1/3 dr0 - DistriDataRateInit[7] = ( ( USER_DR_DISTRIBUTION_PARAMETERS )& ( 0x0000000F ) ); - DistriDataRateInit[6] = ( ( USER_DR_DISTRIBUTION_PARAMETERS )& ( 0x000000F0 ) ) >> 4; //fsk + DistriDataRateInit[7] = USER_DR_DISTRIBUTION_PARAMETERS & 0x0000000F; //fsk + DistriDataRateInit[6] = ( ( USER_DR_DISTRIBUTION_PARAMETERS )& ( 0x000000F0 ) ) >> 4; DistriDataRateInit[5] = ( ( USER_DR_DISTRIBUTION_PARAMETERS )& ( 0x00000F00 ) ) >> 8; DistriDataRateInit[4] = ( ( USER_DR_DISTRIBUTION_PARAMETERS )& ( 0x0000F000 ) ) >> 12; DistriDataRateInit[3] = ( ( USER_DR_DISTRIBUTION_PARAMETERS )& ( 0x000F0000 ) ) >> 16; @@ -530,36 +536,38 @@ template < class R >void LoraRegionsEU::RegionSetBadCrcInFlash ( void ){ /***********************************************************************************************/ //@notereview function a commun template < class R >void LoraRegionsEU:: TxDataRateToSfBw ( uint8_t dataRate ) { - InsertTrace ( __COUNTER__, FileId ); - this->MacTxModulationCurrent = LORA ; + InsertTrace ( __COUNTER__, FileId ); + this->MacTxModulationCurrent = LORA; if ( dataRate < 6 ){ - this->MacTxSfCurrent = 12 - dataRate ; - this->MacTxBwCurrent = BW125 ; + this->MacTxSfCurrent = 12 - dataRate; + this->MacTxBwCurrent = BW125; } else if ( dataRate == 6 ){ this->MacTxSfCurrent = 7; - this->MacTxBwCurrent = BW250 ;} - else if ( dataRate == 7 ) { - this->MacTxModulationCurrent = FSK ; + this->MacTxBwCurrent = BW250; + } else if ( dataRate == 7 ) { + this->MacTxModulationCurrent = FSK; } else { - this->MacTxSfCurrent = 12 ; - this->MacTxBwCurrent = BW125 ; - DEBUG_MSG( " Invalid Datarate \n" ) ; + this->MacTxSfCurrent = 12; + this->MacTxBwCurrent = BW125; + DEBUG_MSG( " Invalid Datarate \n" ); } } template < class R >void LoraRegionsEU:: Rx2DataRateToSfBw ( uint8_t dataRate ) { InsertTrace ( __COUNTER__, FileId ); - if ( dataRate < 6 ){ - this->MacRx2SfCurrent = 12 - dataRate ; - this->MacRx2BwCurrent = BW125 ; - } else if ( dataRate== 6 ){ + if ( dataRate < 6 ){ + this->MacRx2ModulationCurrent = LORA; + this->MacRx2SfCurrent = 12 - dataRate; + this->MacRx2BwCurrent = BW125; + } else if ( dataRate== 6 ){ + this->MacRx2ModulationCurrent = LORA; this->MacRx2SfCurrent = 7; - this->MacRx2BwCurrent = BW250 ;} - else if ( dataRate == 7 ) { - //@note tbd manage fsk case } + this->MacRx2BwCurrent = BW250; + } else if ( dataRate == 7 ) { + this->MacRx2ModulationCurrent = FSK; } else { - this->MacRx2SfCurrent = 12 ; - this->MacRx2BwCurrent = BW125 ; - DEBUG_MSG( " Invalid Datarate \n" ) ; + this->MacRx2SfCurrent = 12; + this->MacRx2BwCurrent = BW125; + DEBUG_MSG( " Invalid Datarate \n" ); } } diff --git a/radio/SX126X/SX126x.cpp b/radio/SX126X/SX126x.cpp index 34e28f5..bc4e098 100644 --- a/radio/SX126X/SX126x.cpp +++ b/radio/SX126X/SX126x.cpp @@ -23,9 +23,9 @@ Maintainer : Olivier Gimenez (SEMTECH) #define FSK_DATARATE_MOD_PARAMETER 0x005000 // = 32 * Fxtal / 50kbps #define FSK_PULSE_SHAPE_MOD_PARAMETER 0x09 // : Gaussian BT 0.5 #define FSK_RX_BW_MOD_PARAMETER 0x13 // : 93.8kHz DSB ==> ~ 50kHz SSB -#define FSK_FDEV_MOD_PARAMETER 0x006666 // = 25kHz * 2^25 / Fxtal +#define FSK_FDEV_MOD_PARAMETER 0x005D22 // = 25kHz * Fxtal / 2^25 -#define FSK_PREAMBLE_LENGTH_PACKET_PARAMETER 0x0005 +#define FSK_PREAMBLE_LENGTH_PACKET_PARAMETER 40 #define FSK_PREAMBLE_DETECTOR_LENGTH_PACKET_PARAMETER 0x05 // : Preamble detector over 2 Bytes #define FSK_SYNC_WORD_LENGTH_PACKET_PARAMETER 0x18 // : 3 Bytes #define FSK_ADDRESS_COMP_PACKET_PARAMETER 0x00 // : Address filtering disabled @@ -40,6 +40,7 @@ Maintainer : Olivier Gimenez (SEMTECH) #define REG_CRCSEEDBASEADDR 0x06bc #define REG_CRCPOLYBASEADDR 0x06be #define REG_SYNCWORDBASEADDRESS 0x06c0 +#define REG_WHITSEEDBASEADDR_MSB 0x06B8 /************************************************************************************************ * Public Methods * @@ -157,7 +158,7 @@ void SX126x::SendLora( //CalibrateImage( channel ); SetRfFrequency( channel ); SetModulationParamsLora( SF, BW ); - SetPacketParamsLora( payloadSize ); + SetPacketParamsLora( payloadSize, IQ_STANDARD ); SetTxParams( power ); WriteRegisters( REG_LORA_SYNC_WORD_MSB, ( uint8_t * ) this->LoraSyncword, 2 ); // Send the payload to the radio @@ -167,52 +168,53 @@ void SX126x::SendLora( ClearIrqStatus( IRQ_RADIO_ALL ); // Configure IRQ SetDioIrqParams( - 0xFFFF, - 0xFFFF, - IRQ_RADIO_NONE, - IRQ_RADIO_NONE - ); + 0xFFFF, + 0xFFFF, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE + ); ClearIrqStatus( IRQ_RADIO_ALL ); - + // Send ! No timeout here as it is already handled by the MAC SetTx( 0 ); } void SX126x::SendFsk( - uint8_t *payload, - uint8_t payloadSize, - uint32_t channel, - int8_t power - ) { + uint8_t *payload, + uint8_t payloadSize, + uint32_t channel, + int8_t power + ) { //! \warning: FSK is under still test and not officialy supported on this driver // Init radio - Reset( ); SetRegulatorMode( USE_DCDC ); SetDio2AsRfSwitchCtrl( true ); - SetStandby( STDBY_XOSC ); + SetStandby( STDBY_RC ); // Configure the radio SetPacketType( FSK ); - //CalibrateImage( channel ); + // CalibrateImage( channel ); SetRfFrequency( channel ); - SetModulationParamsFsk( ); - SetPacketParamsFsk( payloadSize ); - ConfigureCrcCCITT(); SetTxParams( power ); - SetSyncWordFskLorawan(); - // Send the payload to the radio SetBufferBaseAddress( 0, 0 ); + // Send the payload to the radio WriteBuffer( 0, payload, payloadSize ); + SetModulationParamsFsk( ); + SetPacketParamsFsk( payloadSize ); + ConfigureCrcCCITT(); + SetSyncWordFskLorawan(); + + SetWhiteningSeedFSK( 0x01FF ); ClearIrqStatus( IRQ_RADIO_ALL ); // Configure IRQ SetDioIrqParams( - 0xFFFF, - 0xFFFF, - IRQ_RADIO_NONE, - IRQ_RADIO_NONE - ); + 0xFFFF, + 0xFFFF, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE + ); ClearIrqStatus( IRQ_RADIO_ALL ); // Send ! No timeout here as it is already handled by the MAC @@ -221,49 +223,50 @@ void SX126x::SendFsk( // @TODO: SetRxBoosted ? void SX126x::RxLora( - eBandWidth BW, - uint8_t SF, - uint32_t channel, - uint32_t rxTimeoutMs - ) { - + eBandWidth BW, + uint8_t SF, + uint32_t channel, + uint32_t rxTimeoutMs + ) { + uint8_t val = 0; // Configure the radio SetPacketType( LORA ); SetRfFrequency( channel ); SetModulationParamsLora( SF, BW ); - SetPacketParamsLora( 0 ); + SetPacketParamsLora( 0, IQ_INVERTED ); StopTimerOnPreamble( true ); WriteRegisters( REG_LORA_SYNC_WORD_MSB, ( uint8_t * ) this->LoraSyncword, 2 ); // Configure IRQ SetDioIrqParams( - IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT, - IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT, - IRQ_RADIO_NONE, - IRQ_RADIO_NONE - ); + IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT, + IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE + ); ClearIrqStatus( IRQ_RADIO_ALL ); + SetRx( rxTimeoutMs << 6 ); } void SX126x::RxFsk( - uint32_t channel, - uint32_t rxTimeoutMs - ) { + uint32_t channel, + uint32_t rxTimeoutMs + ) { //! \warning: FSK is under still test and not officialy supported on this driver // Configure the radio SetPacketType( FSK ); SetRfFrequency( channel ); SetModulationParamsFsk(); - SetPacketParamsFsk( 0 ); + SetPacketParamsFsk( 0xFF ); StopTimerOnPreamble( true ); - SetSyncWordFskLorawan(); + SetSyncWordFskLorawan(); // Configure IRQ SetDioIrqParams( - IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT, - IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT, - IRQ_RADIO_NONE, - IRQ_RADIO_NONE - ); + IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT, + IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT, + IRQ_RADIO_NONE, + IRQ_RADIO_NONE + ); ClearIrqStatus( IRQ_RADIO_ALL ); SetRx( rxTimeoutMs << 6 ); } @@ -469,14 +472,14 @@ void SX126x::SetModulationParamsFsk( ) { WriteCommand( SET_MODULATION_PARAMS, buf, 8 ); } -void SX126x::SetPacketParamsLora( uint8_t payloadSize ) { +void SX126x::SetPacketParamsLora( uint8_t payloadSize, InvertIQ_t iq_type ) { uint8_t buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; buf[0] = 0x00; // Preamble of 0x08 symbols buf[1] = 0x08; buf[2] = 0x00; // Explicit header (Variable packet length) buf[3] = payloadSize; buf[4] = 0x01; // Uplink: CRC ON - buf[5] = IQ_STANDARD; // Uplink: Standard IQ + buf[5] = iq_type; // Uplink: Standard IQ WriteCommand( SET_PACKET_PARAMS, buf, 6 ); } @@ -488,7 +491,7 @@ void SX126x::SetPacketParamsFsk( uint8_t payloadSize ) { buf[3] = FSK_SYNC_WORD_LENGTH_PACKET_PARAMETER; buf[4] = FSK_ADDRESS_COMP_PACKET_PARAMETER; buf[5] = FSK_PACKET_TYPE_PACKET_PARAMETER; - buf[6] = FSK_PAYLOAD_LENGTH_PACKET_PARAMETER; + buf[6] = payloadSize; buf[7] = FSK_CRC_TYPE_PACKET_PARAMETER; buf[8] = FSK_WHITENING_PACKET_PARAMETER; WriteCommand( SET_PACKET_PARAMS, buf, 9 ); @@ -496,7 +499,7 @@ void SX126x::SetPacketParamsFsk( uint8_t payloadSize ) { void SX126x::ConfigureCrcCCITT(void) { this->SetCrcSeedFskCCITT( ); - this->SetCrcPolynomialFskCCITT( ); + this->SetCrcPolynomialFskCCITT( ); } void SX126x::SetCrcSeedFskCCITT(void) { @@ -517,15 +520,18 @@ void SX126x::SetCrcPolynomialFskCCITT(void) { void SX126x::SetSyncWordFskLorawan(void) { WriteRegister( REG_SYNCWORDBASEADDRESS, ( FSK_SYNCWORD_LORAWAN_REG_VALUE >> 16 ) & 0x0000FF ); - WriteRegister( REG_SYNCWORDBASEADDRESS, ( FSK_SYNCWORD_LORAWAN_REG_VALUE >> 8 ) & 0x0000FF ); - WriteRegister( REG_SYNCWORDBASEADDRESS, FSK_SYNCWORD_LORAWAN_REG_VALUE & 0x0000FF ); + WriteRegister( REG_SYNCWORDBASEADDRESS + 1, ( FSK_SYNCWORD_LORAWAN_REG_VALUE >> 8 ) & 0x0000FF ); + WriteRegister( REG_SYNCWORDBASEADDRESS + 2, FSK_SYNCWORD_LORAWAN_REG_VALUE & 0x0000FF ); } void SX126x::SetPacketType( eModulationType modulation ) { + uint8_t mod = 0; if ( modulation == LORA ) { - uint8_t mod = 1; - WriteCommand( SET_PACKET_TYPE, ( uint8_t* )&mod, 1 ); + mod = 1; + } else if (modulation == FSK ) { + mod = 0; } + WriteCommand( SET_PACKET_TYPE, ( uint8_t* )&mod, 1 ); } void SX126x::SetPaConfig( @@ -678,3 +684,11 @@ void SX126x::WriteRegister( uint16_t address, uint8_t value ){ this->WriteRegisters( address, &value, 1 ); } +void SX126x::SetWhiteningSeedFSK( uint16_t seed ) +{ + uint8_t regValue = 0; + regValue = ReadRegister( REG_WHITSEEDBASEADDR_MSB ) & 0xFE; + regValue = ( ( seed >> 8 ) & 0x01 ) | regValue; + WriteRegister( REG_WHITSEEDBASEADDR_MSB, regValue ); // only 1 bit. + WriteRegister( REG_WHITSEEDBASEADDR_MSB + 1, ( uint8_t )seed ); +} diff --git a/radio/SX126X/SX126x.h b/radio/SX126X/SX126x.h index aca2047..3b1b916 100644 --- a/radio/SX126X/SX126x.h +++ b/radio/SX126X/SX126x.h @@ -283,15 +283,14 @@ class SX126x { * \brief Sets the packet parameters for LORA */ void SetPacketParamsLora( - uint8_t payloadSize + uint8_t payloadSize, + InvertIQ_t iq_type ); /*! * \brief Sets the packet parameters for FSK */ - void SetPacketParamsFsk( - uint8_t payloadSize - ); + void SetPacketParamsFsk( uint8_t payloadSize ); /*! * \brief Sets the transmission parameters @@ -411,6 +410,7 @@ class SX126x { void SetCrcSeedFskCCITT(void); void SetCrcPolynomialFskCCITT(void); void SetSyncWordFskLorawan(void); + void SetWhiteningSeedFSK( uint16_t seed ); }; #endif diff --git a/radio/SX1276Lib/sx1276/sx1276.cpp b/radio/SX1276Lib/sx1276/sx1276.cpp index 3347565..8a0db7f 100644 --- a/radio/SX1276Lib/sx1276/sx1276.cpp +++ b/radio/SX1276Lib/sx1276/sx1276.cpp @@ -30,9 +30,8 @@ Maintainer : Olivier Gimenez (SEMTECH) #define FSK_PREAMBLE_LSB_LORAWAN_REG_VALUE 0x05 #define FSK_SYNCWORD_LORAWAN_REG_VALUE 0xC194C1 #define FSK_MAX_MODEM_PAYLOAD 64 -#define FSK_THRESHOLD_REFILL_LIMIT 32 +#define FSK_THRESHOLD_REFILL_LIMIT 0x0F #define LORAWAN_MIN_PACKET_SIZE 9 -#define MAX_PAYLOAD_SIZE 255 #define FSK_FAKE_IRQ_THRESHOLD 2 @@ -235,44 +234,59 @@ void SX1276::RxFsk(uint32_t channel, uint16_t timeOutMs) { rxPayloadSize = 0; uint8_t bytesReceived = 0; uint8_t remainingBytes = 0; - uint8_t firstBytesRx[LORAWAN_MIN_PACKET_SIZE] = {0x00}; uint8_t payloadChunkSize = FSK_THRESHOLD_REFILL_LIMIT; + uint32_t timeoutExpectedMS = 0x00000000; + bool preamble_detected = false; SetOpModeFsk( RF_OPMODE_MODULATIONTYPE_FSK, RFLR_OPMODE_FREQMODE_ACCESS_LF, RF_OPMODE_SLEEP ); SetRfFrequency( channel ); - uint8_t symbTimeout = timeOutMs / 0.32; // 0.32 = 16 * 1/50000 -> See datasheet for TimeoutRxPreamble - SetModulationParamsRxFsk( symbTimeout ); + SetModulationParamsRxFsk( ); SetFifoThreshold(LORAWAN_MIN_PACKET_SIZE - 1); SetOpMode( RF_OPMODE_RECEIVER ); - while(!IsFskFifoLevelReached()) { - mcu.mwait_ms(2); - if(this->HasTimeouted()) { - this->SetAndGenerateFakeIRQ(RXTIMEOUT_IRQ_FLAG); - return; + timeoutExpectedMS = mcu.RtcGetTimeMs() + timeOutMs; + while(true) { + if(mcu.RtcGetTimeMs() > timeoutExpectedMS) { + if(this->HasDetectedPreamble() && !preamble_detected){ + // A timeout has been detected so a payload might be in the process of being received. + // Allocate here the amount of time required to receive the 3 bytes of address and the + // LORAWAN_MIN_PACKET_SIZE that should trigger the FifoLevelReached. + timeoutExpectedMS += 2; + DEBUG_MSG(" ...Timeout but preamble detected...\n"); + preamble_detected = true; + } + else{ + this->Sleep(false); + this->SetAndGenerateFakeIRQ(RXTIMEOUT_IRQ_FLAG); + return; + } + } + mcu.mwait_ms(5); + if(this->IsFskFifoLevelReached()){ + break; } } - ReadFifo( &firstBytesRx[0], LORAWAN_MIN_PACKET_SIZE ); - rxPayloadSize = firstBytesRx[0]; bytesReceived = LORAWAN_MIN_PACKET_SIZE - 1; // -1 because the first one is the payload size, which is not included into the payload - memcpy(rxBuffer, firstBytesRx + 1, bytesReceived); + ReadFifo( &rxPayloadSize, 1 ); + ReadFifo( rxBuffer, bytesReceived ); remainingBytes = rxPayloadSize - bytesReceived; - SetFifoThreshold(payloadChunkSize - 1); - while(remainingBytes > payloadChunkSize) { - while(!IsFskFifoLevelReached()) { - mcu.mwait_ms(2); + if(rxPayloadSize > (FSK_MAX_MODEM_PAYLOAD - 1)){ + SetFifoThreshold(payloadChunkSize - 1); + while(remainingBytes > payloadChunkSize) { + while(!IsFskFifoLevelReached()) { + mcu.mwait_ms(3); + } + ReadFifo( &rxBuffer[0] + bytesReceived, payloadChunkSize ); + bytesReceived += payloadChunkSize; + remainingBytes = rxPayloadSize - bytesReceived; } - ReadFifo( rxBuffer + bytesReceived, payloadChunkSize ); - bytesReceived += payloadChunkSize; - remainingBytes = rxPayloadSize - bytesReceived; } - SetFifoThreshold(remainingBytes - 1); while(!IsPayloadReady()) { mcu.mwait_ms(2); } - ReadFifo( rxBuffer + bytesReceived, remainingBytes ); + ReadFifo( &rxBuffer[0] + bytesReceived, remainingBytes ); lastPacketRssi = this->GetCurrentRssi(); this->Sleep(false); this->SetAndGenerateFakeIRQ(RECEIVE_PACKET_IRQ_FLAG); @@ -368,6 +382,12 @@ bool SX1276::HasTimeouted() { return (irqFlags & 0x04); } +bool SX1276::HasDetectedPreamble() { + uint8_t irqFlags = 0x00; + Read(REG_IRQFLAGS1, &irqFlags, 1); + return (irqFlags & 0x02); +} + void SX1276::GetPacketStatusLora( int16_t *pktRssi, int16_t *snr, int16_t *signalRssi ) { *snr = ((int16_t) Read( REG_LR_PKTSNRVALUE ))/4; int16_t rssi = (int16_t) Read( REG_LR_PKTRSSIVALUE ); @@ -473,7 +493,7 @@ void SX1276::SetModulationParamsTxFsk( ) { Write( REG_DIOMAPPING2, 0x00 ); } -void SX1276::SetModulationParamsRxFsk( uint8_t symbTimeout ) { +void SX1276::SetModulationParamsRxFsk( void ) { this->SetModulationParamsCommonFsk(); this->ConfigureRssi(); Write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_10 | RF_DIOMAPPING1_DIO1_11 | RF_DIOMAPPING1_DIO2_10 | RF_DIOMAPPING1_DIO3_01 ); @@ -486,7 +506,9 @@ void SX1276::SetModulationParamsRxFsk( uint8_t symbTimeout ) { Write( REG_AFCFEI, RF_AFCFEI_AFCAUTOCLEAR_ON ); Write( REG_LNA, RF_LNA_GAIN_G1 | RF_LNA_BOOST_ON ); Write( REG_PAYLOADLENGTH, 0xFF ); - Write( REG_RXTIMEOUT2, symbTimeout ); + Write( REG_RXTIMEOUT1, 0x00 ); + Write( REG_RXTIMEOUT2, 0x00 ); + Write( REG_RXTIMEOUT3, 0x00 ); } void SX1276::SetModulationParamsRxLora( uint8_t SF, eBandWidth BW, uint16_t symbTimeout ) { diff --git a/radio/SX1276Lib/sx1276/sx1276.h b/radio/SX1276Lib/sx1276/sx1276.h index 746b0d1..04dae01 100644 --- a/radio/SX1276Lib/sx1276/sx1276.h +++ b/radio/SX1276Lib/sx1276/sx1276.h @@ -26,7 +26,7 @@ Maintainer : Olivier Gimenez (SEMTECH) #define XTAL_FREQ 32000000 #define FREQ_STEP 61.03515625 #define FREQ_STEP_8 15625 /* FREQ_STEP<<8 */ -#define RX_BUFFER_SIZE 256 +#define RX_BUFFER_SIZE 255 /*! * Constant values need to compute the RSSI value @@ -56,7 +56,7 @@ class SX1276 { uint32_t Channel; private: - uint8_t rxBuffer[255]; + uint8_t rxBuffer[RX_BUFFER_SIZE]; uint8_t rxPayloadSize; bool isFakeIrq; IrqFlags_t fakeIrqFlag; @@ -109,6 +109,8 @@ class SX1276 { */ bool HasTimeouted( void ); + bool HasDetectedPreamble(void); + bool IsPayloadReady(void); int8_t GetCurrentRssi(void); @@ -171,10 +173,8 @@ class SX1276 { * \brief Set the modulation parameters for FSK Tx * @see SX1276::SetPowerParamsTx, SX1276::SetRfFrequency */ - void SetModulationParamsTxFsk( void ); - - //void SetModulationParamsRxFsk( uint8_t symbTimeout ); - void SetModulationParamsCommonFsk( void ); + void SetModulationParamsTxFsk( void ); + void SetModulationParamsCommonFsk( void ); /*! * \brief Set the modulation parameters for Rx with Lora @@ -186,9 +186,8 @@ class SX1276 { /*! * \brief Set the modulation parameters for Rx with FSK - * @param [IN] symbTimeout : number of symbols before raising the timeout interrupt */ - void SetModulationParamsRxFsk( uint8_t symbTimeout ); + void SetModulationParamsRxFsk( void ); /*! * \brief Set the RF frequency @@ -216,7 +215,7 @@ class SX1276 { * \param [IN] lowFrequencyModeOn * \param [IN] opMode */ - void SetOpModeFsk( uint8_t modulationType, uint8_t lowFrequencyModeOn, uint8_t opMode ); + void SetOpModeFsk( uint8_t modulationType, uint8_t lowFrequencyModeOn, uint8_t opMode ); /*! * \brief Sets the radio opmode for FSK operations @@ -233,7 +232,7 @@ class SX1276 { * \brief Sets the radio opmode * @param [IN] opMode mode to put the radio into */ - void SetOpMode( uint8_t opMode ); + void SetOpMode( uint8_t opMode ); /*! * \brief Write Payload inside the sx1276 fifo