void SX1272SetRfTxPower( int8_t power ) { uint8_t paConfig = 0; uint8_t paDac = 0; paConfig = SX1272Read( REG_PACONFIG ); paDac = SX1272Read( REG_PADAC ); paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | SX1272GetPaSelect( SX1272.Settings.Channel ); if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) { if( power > 17 ) { paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON; } else { paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF; } if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON ) { if( power < 5 ) { power = 5; } if( power > 20 ) { power = 20; } paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); } else { if( power < 2 ) { power = 2; } if( power > 17 ) { power = 17; } paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); } } else { if( power < -1 ) { power = -1; } if( power > 14 ) { power = 14; } paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); } SX1272Write( REG_PACONFIG, paConfig ); SX1272Write( REG_PADAC, paDac ); }
void SX1272FskSetAfcOn( bool enable ) { SX1272Read( REG_RXCONFIG, &SX1272->RegRxConfig ); SX1272->RegRxConfig = ( SX1272->RegRxConfig & RF_RXCONFIG_AFCAUTO_MASK ) | ( enable << 4 ); SX1272Write( REG_RXCONFIG, SX1272->RegRxConfig ); FskSettings.AfcOn = enable; }
void SX1272FskSetPacketCrcOn( bool enable ) { SX1272Read( REG_PACKETCONFIG1, &SX1272->RegPacketConfig1 ); SX1272->RegPacketConfig1 = ( SX1272->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_MASK ) | ( enable << 4 ); SX1272Write( REG_PACKETCONFIG1, SX1272->RegPacketConfig1 ); FskSettings.CrcOn = enable; }
void SX1272LoRaSetOpMode( uint8_t opMode ) { static uint8_t opModePrev = RFLR_OPMODE_STANDBY; static bool antennaSwitchTxOnPrev = true; bool antennaSwitchTxOn = false; opModePrev = SX1272LR->RegOpMode & ~RFLR_OPMODE_MASK; if( opMode != opModePrev ) { if( opMode == RFLR_OPMODE_TRANSMITTER ) { antennaSwitchTxOn = true; } else { antennaSwitchTxOn = false; } if( antennaSwitchTxOn != antennaSwitchTxOnPrev ) { antennaSwitchTxOnPrev = antennaSwitchTxOn; RXTX( antennaSwitchTxOn ); // Antenna switch control } SX1272LR->RegOpMode = ( SX1272LR->RegOpMode & RFLR_OPMODE_MASK ) | opMode; SX1272Write( REG_LR_OPMODE, SX1272LR->RegOpMode ); } }
int8_t SX1272FskGetRawTemp( void ) { int8_t temp = 0; uint8_t previousOpMode; uint32_t startTick; // Enable Temperature reading SX1272Read( REG_IMAGECAL, &SX1272->RegImageCal ); SX1272->RegImageCal = ( SX1272->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_ON; SX1272Write( REG_IMAGECAL, SX1272->RegImageCal ); // save current Op Mode SX1272Read( REG_OPMODE, &SX1272->RegOpMode ); previousOpMode = SX1272->RegOpMode; // put device in FSK RxSynth SX1272->RegOpMode = RF_OPMODE_SYNTHESIZER_RX; SX1272Write( REG_OPMODE, SX1272->RegOpMode ); // Wait 1ms startTick = GET_TICK_COUNT( ); while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 2 ) ); // Disable Temperature reading SX1272Read( REG_IMAGECAL, &SX1272->RegImageCal ); SX1272->RegImageCal = ( SX1272->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_OFF; SX1272Write( REG_IMAGECAL, SX1272->RegImageCal ); // Read temperature SX1272Read( REG_TEMP, &SX1272->RegTemp ); temp = SX1272->RegTemp & 0x7F; if( ( SX1272->RegTemp & 0x80 ) == 0x80 ) { temp *= -1; } // Reload previous Op Mode SX1272Write( REG_OPMODE, previousOpMode ); return temp; }
void SX1272FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue ) { uint8_t mantisse = 0; uint8_t exponent = 0; if( reg == &SX1272->RegRxBw ) { *reg = ( uint8_t )dccValue & 0x60; } else { *reg = 0; } SX1272FskComputeRxBwMantExp( rxBwValue, &mantisse, &exponent ); switch( mantisse ) { case 16: *reg |= ( uint8_t )( 0x00 | ( exponent & 0x07 ) ); break; case 20: *reg |= ( uint8_t )( 0x08 | ( exponent & 0x07 ) ); break; case 24: *reg |= ( uint8_t )( 0x10 | ( exponent & 0x07 ) ); break; default: // Something went terribely wrong break; } if( reg == &SX1272->RegRxBw ) { SX1272Write( REG_RXBW, *reg ); FskSettings.RxBw = rxBwValue; } else { SX1272Write( REG_AFCBW, *reg ); FskSettings.RxBwAfc = rxBwValue; } }
void SX1272LoRaSetDefaults( void ) { // REMARK: See SX1272 datasheet for modified default values. // Sets IF frequency selection manual SX1272LR->RegDetectOptimize = 0x43; // default value 0xC3 SX1272Write( 0x31, SX1272LR->RegDetectOptimize ); SX1272Read( REG_LR_VERSION, &SX1272LR->RegVersion ); }
void SX1272FskSetRssiOffset( int8_t offset ) { SX1272Read( REG_RSSICONFIG, &SX1272->RegRssiConfig ); if( offset < 0 ) { offset = ( ~offset & 0x1F ); offset += 1; offset = -offset; } SX1272->RegRssiConfig |= ( uint8_t )( ( offset & 0x1F ) << 3 ); SX1272Write( REG_RSSICONFIG, SX1272->RegRssiConfig ); }
void SX1272FskRxCalibrate( void ) { uint32_t startTick; SX1272Write( REG_IMAGECAL, RF_IMAGECAL_AUTOIMAGECAL_OFF | RF_IMAGECAL_IMAGECAL_START | RF_IMAGECAL_TEMPTHRESHOLD_10 | RF_IMAGECAL_TEMPMONITOR_OFF ); // Wait 8ms startTick = GET_TICK_COUNT( ); while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 8 ) ); }
void SX1272FskSetPa20dBm( bool enale ) { SX1272Read( REG_PADAC, &SX1272->RegPaDac ); if( enale == true ) { SX1272->RegPaDac = 0x87; } else { SX1272->RegPaDac = 0x84; } SX1272Write( REG_PADAC, SX1272->RegPaDac ); }
void SX1272SetLoRaOn( bool enable ) { if( LoRaOnState == enable ) { return; } LoRaOnState = enable; LoRaOn = enable; if( LoRaOn == true ) { SX1272LoRaSetOpMode( RFLR_OPMODE_SLEEP ); SX1272LR->RegOpMode = ( SX1272LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON; SX1272Write( REG_LR_OPMODE, SX1272LR->RegOpMode ); SX1272LoRaSetOpMode( RFLR_OPMODE_STANDBY ); // RxDone RxTimeout FhssChangeChannel CadDone SX1272LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00; // CadDetected ModeReady SX1272LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00; SX1272WriteBuffer( REG_LR_DIOMAPPING1, &SX1272LR->RegDioMapping1, 2 ); SX1272ReadBuffer( REG_LR_OPMODE, SX1272Regs + 1, 0x70 - 1 ); } else { SX1272LoRaSetOpMode( RFLR_OPMODE_SLEEP ); SX1272LR->RegOpMode = ( SX1272LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF; SX1272Write( REG_LR_OPMODE, SX1272LR->RegOpMode ); SX1272LoRaSetOpMode( RFLR_OPMODE_STANDBY ); SX1272ReadBuffer( REG_OPMODE, SX1272Regs + 1, 0x70 - 1 ); } }
void SX1272FskSetRFPower( int8_t power ) { SX1272Read( REG_PACONFIG, &SX1272->RegPaConfig ); SX1272Read( REG_PADAC, &SX1272->RegPaDac ); if( ( SX1272->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) { if( ( SX1272->RegPaDac & 0x07 ) == 0x07 ) { if( power < 5 ) { power = 5; } if( power > 20 ) { power = 20; } SX1272->RegPaConfig = ( SX1272->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); } else { if( power < 2 ) { power = 2; } if( power > 17 ) { power = 17; } SX1272->RegPaConfig = ( SX1272->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); } } else { if( power < -1 ) { power = -1; } if( power > 14 ) { power = 14; } SX1272->RegPaConfig = ( SX1272->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); } SX1272Write( REG_PACONFIG, SX1272->RegPaConfig ); FskSettings.Power = power; }
void SX1272FskSetPaRamp( uint8_t value ) { SX1272Read( REG_PARAMP, &SX1272->RegPaRamp ); SX1272->RegPaRamp = ( SX1272->RegPaRamp & RF_PARAMP_MASK ) | ( value & ~RF_PARAMP_MASK ); SX1272Write( REG_PARAMP, SX1272->RegPaRamp ); }
void SX1272FskSetPayloadLength( uint8_t value ) { SX1272->RegPayloadLength = value; SX1272Write( REG_PAYLOADLENGTH, SX1272->RegPayloadLength ); FskSettings.PayloadLength = value; }
/*! * \brief Process the LoRa modem Rx and Tx state machines depending on the * SX1272 operating mode. * * \retval rfState Current RF state [RF_IDLE, RF_BUSY, * RF_RX_DONE, RF_RX_TIMEOUT, * RF_TX_DONE, RF_TX_TIMEOUT] */ uint32_t SX1272LoRaProcess( void ) { uint32_t result = RF_BUSY; switch( RFLRState ) { case RFLR_STATE_IDLE: break; case RFLR_STATE_RX_INIT: SX1272LoRaSetOpMode( RFLR_OPMODE_STANDBY ); SX1272LR->RegIrqFlagsMask = RFLR_IRQFLAGS_RXTIMEOUT | //RFLR_IRQFLAGS_RXDONE | //RFLR_IRQFLAGS_PAYLOADCRCERROR | RFLR_IRQFLAGS_VALIDHEADER | RFLR_IRQFLAGS_TXDONE | RFLR_IRQFLAGS_CADDONE | //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | RFLR_IRQFLAGS_CADDETECTED; SX1272Write( REG_LR_IRQFLAGSMASK, SX1272LR->RegIrqFlagsMask ); if( LoRaSettings.FreqHopOn == true ) { SX1272LR->RegHopPeriod = LoRaSettings.HopPeriod; SX1272Read( REG_LR_HOPCHANNEL, &SX1272LR->RegHopChannel ); SX1272LoRaSetRFFrequency( HoppingFrequencies[SX1272LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); } else { SX1272LR->RegHopPeriod = 255; } SX1272Write( REG_LR_HOPPERIOD, SX1272LR->RegHopPeriod ); // RxDone RxTimeout FhssChangeChannel CadDone SX1272LR->RegDioMapping1 = RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO1_00 | RFLR_DIOMAPPING1_DIO2_00 | RFLR_DIOMAPPING1_DIO3_00; // CadDetected ModeReady SX1272LR->RegDioMapping2 = RFLR_DIOMAPPING2_DIO4_00 | RFLR_DIOMAPPING2_DIO5_00; SX1272WriteBuffer( REG_LR_DIOMAPPING1, &SX1272LR->RegDioMapping1, 2 ); if( LoRaSettings.RxSingleOn == true ) // Rx single mode { SX1272LoRaSetOpMode( RFLR_OPMODE_RECEIVER_SINGLE ); } else // Rx continuous mode { SX1272LR->RegFifoAddrPtr = SX1272LR->RegFifoRxBaseAddr; SX1272Write( REG_LR_FIFOADDRPTR, SX1272LR->RegFifoAddrPtr ); SX1272LoRaSetOpMode( RFLR_OPMODE_RECEIVER ); } memset( RFBuffer, 0, ( size_t )RF_BUFFER_SIZE ); PacketTimeout = LoRaSettings.RxPacketTimeout; RxTimeoutTimer = GET_TICK_COUNT( ); RFLRState = RFLR_STATE_RX_RUNNING; break; case RFLR_STATE_RX_RUNNING: if( DIO0 == 1 ) // RxDone { RxTimeoutTimer = GET_TICK_COUNT( ); if( LoRaSettings.FreqHopOn == true ) { SX1272Read( REG_LR_HOPCHANNEL, &SX1272LR->RegHopChannel ); SX1272LoRaSetRFFrequency( HoppingFrequencies[SX1272LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); } // Clear Irq SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE ); RFLRState = RFLR_STATE_RX_DONE; } if( DIO2 == 1 ) // FHSS Changed Channel { RxTimeoutTimer = GET_TICK_COUNT( ); if( LoRaSettings.FreqHopOn == true ) { SX1272Read( REG_LR_HOPCHANNEL, &SX1272LR->RegHopChannel ); SX1272LoRaSetRFFrequency( HoppingFrequencies[SX1272LR->RegHopChannel & RFLR_HOPCHANNEL_CHANNEL_MASK] ); } // Clear Irq SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL ); // Debug RxGain = SX1272LoRaReadRxGain( ); } if( LoRaSettings.RxSingleOn == true ) // Rx single mode { if( ( GET_TICK_COUNT( ) - RxTimeoutTimer ) > PacketTimeout ) { RFLRState = RFLR_STATE_RX_TIMEOUT; } } break; case RFLR_STATE_RX_DONE: SX1272Read( REG_LR_IRQFLAGS, &SX1272LR->RegIrqFlags ); if( ( SX1272LR->RegIrqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR ) == RFLR_IRQFLAGS_PAYLOADCRCERROR ) { // Clear Irq SX1272Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR ); if( LoRaSettings.RxSingleOn == true ) // Rx single mode { RFLRState = RFLR_STATE_RX_INIT; } else { RFLRState = RFLR_STATE_RX_RUNNING; } break; } { uint8_t rxSnrEstimate; SX1272Read( REG_LR_PKTSNRVALUE, &rxSnrEstimate ); if( rxSnrEstimate & 0x80 ) // The SNR sign bit is 1 { // Invert and divide by 4 RxPacketSnrEstimate = ( ( ~rxSnrEstimate + 1 ) & 0xFF ) >> 2; RxPacketSnrEstimate = -RxPacketSnrEstimate; } else { // Divide by 4 RxPacketSnrEstimate = ( rxSnrEstimate & 0xFF ) >> 2; } }