LoRaWAN-hello-world- code

Dependencies:   mbed LoRaWAN-lib

Committer:
amirchaudhary
Date:
Fri Mar 22 16:24:25 2019 +0000
Revision:
12:813e9e5f5ff6
Updated the code to Class C Lorawan.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
amirchaudhary 12:813e9e5f5ff6 1 /*
amirchaudhary 12:813e9e5f5ff6 2 / _____) _ | |
amirchaudhary 12:813e9e5f5ff6 3 ( (____ _____ ____ _| |_ _____ ____| |__
amirchaudhary 12:813e9e5f5ff6 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
amirchaudhary 12:813e9e5f5ff6 5 _____) ) ____| | | || |_| ____( (___| | | |
amirchaudhary 12:813e9e5f5ff6 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
amirchaudhary 12:813e9e5f5ff6 7 (C) 2014 Semtech
amirchaudhary 12:813e9e5f5ff6 8
amirchaudhary 12:813e9e5f5ff6 9 Description: Actual implementation of a SX1276 radio, inherits Radio
amirchaudhary 12:813e9e5f5ff6 10
amirchaudhary 12:813e9e5f5ff6 11 License: Revised BSD License, see LICENSE.TXT file include in the project
amirchaudhary 12:813e9e5f5ff6 12
amirchaudhary 12:813e9e5f5ff6 13 Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
amirchaudhary 12:813e9e5f5ff6 14 */
amirchaudhary 12:813e9e5f5ff6 15 #include "sx1276.h"
amirchaudhary 12:813e9e5f5ff6 16
amirchaudhary 12:813e9e5f5ff6 17 const FskBandwidth_t SX1276::FskBandwidths[] =
amirchaudhary 12:813e9e5f5ff6 18 {
amirchaudhary 12:813e9e5f5ff6 19 { 2600 , 0x17 },
amirchaudhary 12:813e9e5f5ff6 20 { 3100 , 0x0F },
amirchaudhary 12:813e9e5f5ff6 21 { 3900 , 0x07 },
amirchaudhary 12:813e9e5f5ff6 22 { 5200 , 0x16 },
amirchaudhary 12:813e9e5f5ff6 23 { 6300 , 0x0E },
amirchaudhary 12:813e9e5f5ff6 24 { 7800 , 0x06 },
amirchaudhary 12:813e9e5f5ff6 25 { 10400 , 0x15 },
amirchaudhary 12:813e9e5f5ff6 26 { 12500 , 0x0D },
amirchaudhary 12:813e9e5f5ff6 27 { 15600 , 0x05 },
amirchaudhary 12:813e9e5f5ff6 28 { 20800 , 0x14 },
amirchaudhary 12:813e9e5f5ff6 29 { 25000 , 0x0C },
amirchaudhary 12:813e9e5f5ff6 30 { 31300 , 0x04 },
amirchaudhary 12:813e9e5f5ff6 31 { 41700 , 0x13 },
amirchaudhary 12:813e9e5f5ff6 32 { 50000 , 0x0B },
amirchaudhary 12:813e9e5f5ff6 33 { 62500 , 0x03 },
amirchaudhary 12:813e9e5f5ff6 34 { 83333 , 0x12 },
amirchaudhary 12:813e9e5f5ff6 35 { 100000, 0x0A },
amirchaudhary 12:813e9e5f5ff6 36 { 125000, 0x02 },
amirchaudhary 12:813e9e5f5ff6 37 { 166700, 0x11 },
amirchaudhary 12:813e9e5f5ff6 38 { 200000, 0x09 },
amirchaudhary 12:813e9e5f5ff6 39 { 250000, 0x01 },
amirchaudhary 12:813e9e5f5ff6 40 { 300000, 0x00 }, // Invalid Bandwidth
amirchaudhary 12:813e9e5f5ff6 41 };
amirchaudhary 12:813e9e5f5ff6 42
amirchaudhary 12:813e9e5f5ff6 43
amirchaudhary 12:813e9e5f5ff6 44 SX1276::SX1276( RadioEvents_t *events,
amirchaudhary 12:813e9e5f5ff6 45 PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
amirchaudhary 12:813e9e5f5ff6 46 PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5 )
amirchaudhary 12:813e9e5f5ff6 47 : Radio( events ),
amirchaudhary 12:813e9e5f5ff6 48 spi( mosi, miso, sclk ),
amirchaudhary 12:813e9e5f5ff6 49 nss( nss ),
amirchaudhary 12:813e9e5f5ff6 50 reset( reset ),
amirchaudhary 12:813e9e5f5ff6 51 dio0( dio0 ), dio1( dio1 ), dio2( dio2 ), dio3( dio3 ), dio4( dio4 ), dio5( dio5 ),
amirchaudhary 12:813e9e5f5ff6 52 isRadioActive( false )
amirchaudhary 12:813e9e5f5ff6 53 {
amirchaudhary 12:813e9e5f5ff6 54 wait_ms( 10 );
amirchaudhary 12:813e9e5f5ff6 55 this->rxtxBuffer = new uint8_t[RX_BUFFER_SIZE];
amirchaudhary 12:813e9e5f5ff6 56
amirchaudhary 12:813e9e5f5ff6 57 this->RadioEvents = events;
amirchaudhary 12:813e9e5f5ff6 58
amirchaudhary 12:813e9e5f5ff6 59 this->dioIrq = new DioIrqHandler[6];
amirchaudhary 12:813e9e5f5ff6 60
amirchaudhary 12:813e9e5f5ff6 61 this->dioIrq[0] = &SX1276::OnDio0Irq;
amirchaudhary 12:813e9e5f5ff6 62 this->dioIrq[1] = &SX1276::OnDio1Irq;
amirchaudhary 12:813e9e5f5ff6 63 this->dioIrq[2] = &SX1276::OnDio2Irq;
amirchaudhary 12:813e9e5f5ff6 64 this->dioIrq[3] = &SX1276::OnDio3Irq;
amirchaudhary 12:813e9e5f5ff6 65 this->dioIrq[4] = &SX1276::OnDio4Irq;
amirchaudhary 12:813e9e5f5ff6 66 this->dioIrq[5] = NULL;
amirchaudhary 12:813e9e5f5ff6 67
amirchaudhary 12:813e9e5f5ff6 68 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 69 }
amirchaudhary 12:813e9e5f5ff6 70
amirchaudhary 12:813e9e5f5ff6 71 SX1276::~SX1276( )
amirchaudhary 12:813e9e5f5ff6 72 {
amirchaudhary 12:813e9e5f5ff6 73 delete this->rxtxBuffer;
amirchaudhary 12:813e9e5f5ff6 74 delete this->dioIrq;
amirchaudhary 12:813e9e5f5ff6 75 }
amirchaudhary 12:813e9e5f5ff6 76
amirchaudhary 12:813e9e5f5ff6 77 void SX1276::Init( RadioEvents_t *events )
amirchaudhary 12:813e9e5f5ff6 78 {
amirchaudhary 12:813e9e5f5ff6 79 this->RadioEvents = events;
amirchaudhary 12:813e9e5f5ff6 80 }
amirchaudhary 12:813e9e5f5ff6 81
amirchaudhary 12:813e9e5f5ff6 82 RadioState SX1276::GetStatus( void )
amirchaudhary 12:813e9e5f5ff6 83 {
amirchaudhary 12:813e9e5f5ff6 84 return this->settings.State;
amirchaudhary 12:813e9e5f5ff6 85 }
amirchaudhary 12:813e9e5f5ff6 86
amirchaudhary 12:813e9e5f5ff6 87 void SX1276::SetChannel( uint32_t freq )
amirchaudhary 12:813e9e5f5ff6 88 {
amirchaudhary 12:813e9e5f5ff6 89 this->settings.Channel = freq;
amirchaudhary 12:813e9e5f5ff6 90 freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
amirchaudhary 12:813e9e5f5ff6 91 Write( REG_FRFMSB, ( uint8_t )( ( freq >> 16 ) & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 92 Write( REG_FRFMID, ( uint8_t )( ( freq >> 8 ) & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 93 Write( REG_FRFLSB, ( uint8_t )( freq & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 94 }
amirchaudhary 12:813e9e5f5ff6 95
amirchaudhary 12:813e9e5f5ff6 96 bool SX1276::IsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh )
amirchaudhary 12:813e9e5f5ff6 97 {
amirchaudhary 12:813e9e5f5ff6 98 int16_t rssi = 0;
amirchaudhary 12:813e9e5f5ff6 99
amirchaudhary 12:813e9e5f5ff6 100 SetModem( modem );
amirchaudhary 12:813e9e5f5ff6 101
amirchaudhary 12:813e9e5f5ff6 102 SetChannel( freq );
amirchaudhary 12:813e9e5f5ff6 103
amirchaudhary 12:813e9e5f5ff6 104 SetOpMode( RF_OPMODE_RECEIVER );
amirchaudhary 12:813e9e5f5ff6 105
amirchaudhary 12:813e9e5f5ff6 106 wait_ms( 1 );
amirchaudhary 12:813e9e5f5ff6 107
amirchaudhary 12:813e9e5f5ff6 108 rssi = GetRssi( modem );
amirchaudhary 12:813e9e5f5ff6 109
amirchaudhary 12:813e9e5f5ff6 110 Sleep( );
amirchaudhary 12:813e9e5f5ff6 111
amirchaudhary 12:813e9e5f5ff6 112 if( rssi > rssiThresh )
amirchaudhary 12:813e9e5f5ff6 113 {
amirchaudhary 12:813e9e5f5ff6 114 return false;
amirchaudhary 12:813e9e5f5ff6 115 }
amirchaudhary 12:813e9e5f5ff6 116 return true;
amirchaudhary 12:813e9e5f5ff6 117 }
amirchaudhary 12:813e9e5f5ff6 118
amirchaudhary 12:813e9e5f5ff6 119 uint32_t SX1276::Random( void )
amirchaudhary 12:813e9e5f5ff6 120 {
amirchaudhary 12:813e9e5f5ff6 121 uint8_t i;
amirchaudhary 12:813e9e5f5ff6 122 uint32_t rnd = 0;
amirchaudhary 12:813e9e5f5ff6 123
amirchaudhary 12:813e9e5f5ff6 124 /*
amirchaudhary 12:813e9e5f5ff6 125 * Radio setup for random number generation
amirchaudhary 12:813e9e5f5ff6 126 */
amirchaudhary 12:813e9e5f5ff6 127 // Set LoRa modem ON
amirchaudhary 12:813e9e5f5ff6 128 SetModem( MODEM_LORA );
amirchaudhary 12:813e9e5f5ff6 129
amirchaudhary 12:813e9e5f5ff6 130 // Disable LoRa modem interrupts
amirchaudhary 12:813e9e5f5ff6 131 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
amirchaudhary 12:813e9e5f5ff6 132 RFLR_IRQFLAGS_RXDONE |
amirchaudhary 12:813e9e5f5ff6 133 RFLR_IRQFLAGS_PAYLOADCRCERROR |
amirchaudhary 12:813e9e5f5ff6 134 RFLR_IRQFLAGS_VALIDHEADER |
amirchaudhary 12:813e9e5f5ff6 135 RFLR_IRQFLAGS_TXDONE |
amirchaudhary 12:813e9e5f5ff6 136 RFLR_IRQFLAGS_CADDONE |
amirchaudhary 12:813e9e5f5ff6 137 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
amirchaudhary 12:813e9e5f5ff6 138 RFLR_IRQFLAGS_CADDETECTED );
amirchaudhary 12:813e9e5f5ff6 139
amirchaudhary 12:813e9e5f5ff6 140 // Set radio in continuous reception
amirchaudhary 12:813e9e5f5ff6 141 SetOpMode( RF_OPMODE_RECEIVER );
amirchaudhary 12:813e9e5f5ff6 142
amirchaudhary 12:813e9e5f5ff6 143 for( i = 0; i < 32; i++ )
amirchaudhary 12:813e9e5f5ff6 144 {
amirchaudhary 12:813e9e5f5ff6 145 wait_ms( 1 );
amirchaudhary 12:813e9e5f5ff6 146 // Unfiltered RSSI value reading. Only takes the LSB value
amirchaudhary 12:813e9e5f5ff6 147 rnd |= ( ( uint32_t )Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) << i;
amirchaudhary 12:813e9e5f5ff6 148 }
amirchaudhary 12:813e9e5f5ff6 149
amirchaudhary 12:813e9e5f5ff6 150 Sleep( );
amirchaudhary 12:813e9e5f5ff6 151
amirchaudhary 12:813e9e5f5ff6 152 return rnd;
amirchaudhary 12:813e9e5f5ff6 153 }
amirchaudhary 12:813e9e5f5ff6 154
amirchaudhary 12:813e9e5f5ff6 155 /*!
amirchaudhary 12:813e9e5f5ff6 156 * Performs the Rx chain calibration for LF and HF bands
amirchaudhary 12:813e9e5f5ff6 157 * \remark Must be called just after the reset so all registers are at their
amirchaudhary 12:813e9e5f5ff6 158 * default values
amirchaudhary 12:813e9e5f5ff6 159 */
amirchaudhary 12:813e9e5f5ff6 160 void SX1276::RxChainCalibration( void )
amirchaudhary 12:813e9e5f5ff6 161 {
amirchaudhary 12:813e9e5f5ff6 162 uint8_t regPaConfigInitVal;
amirchaudhary 12:813e9e5f5ff6 163 uint32_t initialFreq;
amirchaudhary 12:813e9e5f5ff6 164
amirchaudhary 12:813e9e5f5ff6 165 // Save context
amirchaudhary 12:813e9e5f5ff6 166 regPaConfigInitVal = this->Read( REG_PACONFIG );
amirchaudhary 12:813e9e5f5ff6 167 initialFreq = ( double )( ( ( uint32_t )this->Read( REG_FRFMSB ) << 16 ) |
amirchaudhary 12:813e9e5f5ff6 168 ( ( uint32_t )this->Read( REG_FRFMID ) << 8 ) |
amirchaudhary 12:813e9e5f5ff6 169 ( ( uint32_t )this->Read( REG_FRFLSB ) ) ) * ( double )FREQ_STEP;
amirchaudhary 12:813e9e5f5ff6 170
amirchaudhary 12:813e9e5f5ff6 171 // Cut the PA just in case, RFO output, power = -1 dBm
amirchaudhary 12:813e9e5f5ff6 172 this->Write( REG_PACONFIG, 0x00 );
amirchaudhary 12:813e9e5f5ff6 173
amirchaudhary 12:813e9e5f5ff6 174 // Launch Rx chain calibration for LF band
amirchaudhary 12:813e9e5f5ff6 175 Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
amirchaudhary 12:813e9e5f5ff6 176 while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
amirchaudhary 12:813e9e5f5ff6 177 {
amirchaudhary 12:813e9e5f5ff6 178 }
amirchaudhary 12:813e9e5f5ff6 179
amirchaudhary 12:813e9e5f5ff6 180 // Sets a Frequency in HF band
amirchaudhary 12:813e9e5f5ff6 181 SetChannel( 868000000 );
amirchaudhary 12:813e9e5f5ff6 182
amirchaudhary 12:813e9e5f5ff6 183 // Launch Rx chain calibration for HF band
amirchaudhary 12:813e9e5f5ff6 184 Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
amirchaudhary 12:813e9e5f5ff6 185 while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
amirchaudhary 12:813e9e5f5ff6 186 {
amirchaudhary 12:813e9e5f5ff6 187 }
amirchaudhary 12:813e9e5f5ff6 188
amirchaudhary 12:813e9e5f5ff6 189 // Restore context
amirchaudhary 12:813e9e5f5ff6 190 this->Write( REG_PACONFIG, regPaConfigInitVal );
amirchaudhary 12:813e9e5f5ff6 191 SetChannel( initialFreq );
amirchaudhary 12:813e9e5f5ff6 192 }
amirchaudhary 12:813e9e5f5ff6 193
amirchaudhary 12:813e9e5f5ff6 194 /*!
amirchaudhary 12:813e9e5f5ff6 195 * Returns the known FSK bandwidth registers value
amirchaudhary 12:813e9e5f5ff6 196 *
amirchaudhary 12:813e9e5f5ff6 197 * \param [IN] bandwidth Bandwidth value in Hz
amirchaudhary 12:813e9e5f5ff6 198 * \retval regValue Bandwidth register value.
amirchaudhary 12:813e9e5f5ff6 199 */
amirchaudhary 12:813e9e5f5ff6 200 uint8_t SX1276::GetFskBandwidthRegValue( uint32_t bandwidth )
amirchaudhary 12:813e9e5f5ff6 201 {
amirchaudhary 12:813e9e5f5ff6 202 uint8_t i;
amirchaudhary 12:813e9e5f5ff6 203
amirchaudhary 12:813e9e5f5ff6 204 for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ )
amirchaudhary 12:813e9e5f5ff6 205 {
amirchaudhary 12:813e9e5f5ff6 206 if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) )
amirchaudhary 12:813e9e5f5ff6 207 {
amirchaudhary 12:813e9e5f5ff6 208 return FskBandwidths[i].RegValue;
amirchaudhary 12:813e9e5f5ff6 209 }
amirchaudhary 12:813e9e5f5ff6 210 }
amirchaudhary 12:813e9e5f5ff6 211 // ERROR: Value not found
amirchaudhary 12:813e9e5f5ff6 212 while( 1 );
amirchaudhary 12:813e9e5f5ff6 213 }
amirchaudhary 12:813e9e5f5ff6 214
amirchaudhary 12:813e9e5f5ff6 215 void SX1276::SetRxConfig( RadioModems_t modem, uint32_t bandwidth,
amirchaudhary 12:813e9e5f5ff6 216 uint32_t datarate, uint8_t coderate,
amirchaudhary 12:813e9e5f5ff6 217 uint32_t bandwidthAfc, uint16_t preambleLen,
amirchaudhary 12:813e9e5f5ff6 218 uint16_t symbTimeout, bool fixLen,
amirchaudhary 12:813e9e5f5ff6 219 uint8_t payloadLen,
amirchaudhary 12:813e9e5f5ff6 220 bool crcOn, bool freqHopOn, uint8_t hopPeriod,
amirchaudhary 12:813e9e5f5ff6 221 bool iqInverted, bool rxContinuous )
amirchaudhary 12:813e9e5f5ff6 222 {
amirchaudhary 12:813e9e5f5ff6 223 SetModem( modem );
amirchaudhary 12:813e9e5f5ff6 224
amirchaudhary 12:813e9e5f5ff6 225 switch( modem )
amirchaudhary 12:813e9e5f5ff6 226 {
amirchaudhary 12:813e9e5f5ff6 227 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 228 {
amirchaudhary 12:813e9e5f5ff6 229 this->settings.Fsk.Bandwidth = bandwidth;
amirchaudhary 12:813e9e5f5ff6 230 this->settings.Fsk.Datarate = datarate;
amirchaudhary 12:813e9e5f5ff6 231 this->settings.Fsk.BandwidthAfc = bandwidthAfc;
amirchaudhary 12:813e9e5f5ff6 232 this->settings.Fsk.FixLen = fixLen;
amirchaudhary 12:813e9e5f5ff6 233 this->settings.Fsk.PayloadLen = payloadLen;
amirchaudhary 12:813e9e5f5ff6 234 this->settings.Fsk.CrcOn = crcOn;
amirchaudhary 12:813e9e5f5ff6 235 this->settings.Fsk.IqInverted = iqInverted;
amirchaudhary 12:813e9e5f5ff6 236 this->settings.Fsk.RxContinuous = rxContinuous;
amirchaudhary 12:813e9e5f5ff6 237 this->settings.Fsk.PreambleLen = preambleLen;
amirchaudhary 12:813e9e5f5ff6 238 this->settings.Fsk.RxSingleTimeout = symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1e3;
amirchaudhary 12:813e9e5f5ff6 239
amirchaudhary 12:813e9e5f5ff6 240 datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
amirchaudhary 12:813e9e5f5ff6 241 Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
amirchaudhary 12:813e9e5f5ff6 242 Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 243
amirchaudhary 12:813e9e5f5ff6 244 Write( REG_RXBW, GetFskBandwidthRegValue( bandwidth ) );
amirchaudhary 12:813e9e5f5ff6 245 Write( REG_AFCBW, GetFskBandwidthRegValue( bandwidthAfc ) );
amirchaudhary 12:813e9e5f5ff6 246
amirchaudhary 12:813e9e5f5ff6 247 Write( REG_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 248 Write( REG_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 249
amirchaudhary 12:813e9e5f5ff6 250 if( fixLen == 1 )
amirchaudhary 12:813e9e5f5ff6 251 {
amirchaudhary 12:813e9e5f5ff6 252 Write( REG_PAYLOADLENGTH, payloadLen );
amirchaudhary 12:813e9e5f5ff6 253 }
amirchaudhary 12:813e9e5f5ff6 254 else
amirchaudhary 12:813e9e5f5ff6 255 {
amirchaudhary 12:813e9e5f5ff6 256 Write( REG_PAYLOADLENGTH, 0xFF ); // Set payload length to the maximum
amirchaudhary 12:813e9e5f5ff6 257 }
amirchaudhary 12:813e9e5f5ff6 258
amirchaudhary 12:813e9e5f5ff6 259 Write( REG_PACKETCONFIG1,
amirchaudhary 12:813e9e5f5ff6 260 ( Read( REG_PACKETCONFIG1 ) &
amirchaudhary 12:813e9e5f5ff6 261 RF_PACKETCONFIG1_CRC_MASK &
amirchaudhary 12:813e9e5f5ff6 262 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
amirchaudhary 12:813e9e5f5ff6 263 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
amirchaudhary 12:813e9e5f5ff6 264 ( crcOn << 4 ) );
amirchaudhary 12:813e9e5f5ff6 265 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
amirchaudhary 12:813e9e5f5ff6 266 }
amirchaudhary 12:813e9e5f5ff6 267 break;
amirchaudhary 12:813e9e5f5ff6 268 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 269 {
amirchaudhary 12:813e9e5f5ff6 270 if( bandwidth > 2 )
amirchaudhary 12:813e9e5f5ff6 271 {
amirchaudhary 12:813e9e5f5ff6 272 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
amirchaudhary 12:813e9e5f5ff6 273 while( 1 );
amirchaudhary 12:813e9e5f5ff6 274 }
amirchaudhary 12:813e9e5f5ff6 275 bandwidth += 7;
amirchaudhary 12:813e9e5f5ff6 276 this->settings.LoRa.Bandwidth = bandwidth;
amirchaudhary 12:813e9e5f5ff6 277 this->settings.LoRa.Datarate = datarate;
amirchaudhary 12:813e9e5f5ff6 278 this->settings.LoRa.Coderate = coderate;
amirchaudhary 12:813e9e5f5ff6 279 this->settings.LoRa.PreambleLen = preambleLen;
amirchaudhary 12:813e9e5f5ff6 280 this->settings.LoRa.FixLen = fixLen;
amirchaudhary 12:813e9e5f5ff6 281 this->settings.LoRa.PayloadLen = payloadLen;
amirchaudhary 12:813e9e5f5ff6 282 this->settings.LoRa.CrcOn = crcOn;
amirchaudhary 12:813e9e5f5ff6 283 this->settings.LoRa.FreqHopOn = freqHopOn;
amirchaudhary 12:813e9e5f5ff6 284 this->settings.LoRa.HopPeriod = hopPeriod;
amirchaudhary 12:813e9e5f5ff6 285 this->settings.LoRa.IqInverted = iqInverted;
amirchaudhary 12:813e9e5f5ff6 286 this->settings.LoRa.RxContinuous = rxContinuous;
amirchaudhary 12:813e9e5f5ff6 287
amirchaudhary 12:813e9e5f5ff6 288 if( datarate > 12 )
amirchaudhary 12:813e9e5f5ff6 289 {
amirchaudhary 12:813e9e5f5ff6 290 datarate = 12;
amirchaudhary 12:813e9e5f5ff6 291 }
amirchaudhary 12:813e9e5f5ff6 292 else if( datarate < 6 )
amirchaudhary 12:813e9e5f5ff6 293 {
amirchaudhary 12:813e9e5f5ff6 294 datarate = 6;
amirchaudhary 12:813e9e5f5ff6 295 }
amirchaudhary 12:813e9e5f5ff6 296
amirchaudhary 12:813e9e5f5ff6 297 if( ( ( bandwidth == 7 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
amirchaudhary 12:813e9e5f5ff6 298 ( ( bandwidth == 8 ) && ( datarate == 12 ) ) )
amirchaudhary 12:813e9e5f5ff6 299 {
amirchaudhary 12:813e9e5f5ff6 300 this->settings.LoRa.LowDatarateOptimize = 0x01;
amirchaudhary 12:813e9e5f5ff6 301 }
amirchaudhary 12:813e9e5f5ff6 302 else
amirchaudhary 12:813e9e5f5ff6 303 {
amirchaudhary 12:813e9e5f5ff6 304 this->settings.LoRa.LowDatarateOptimize = 0x00;
amirchaudhary 12:813e9e5f5ff6 305 }
amirchaudhary 12:813e9e5f5ff6 306
amirchaudhary 12:813e9e5f5ff6 307 Write( REG_LR_MODEMCONFIG1,
amirchaudhary 12:813e9e5f5ff6 308 ( Read( REG_LR_MODEMCONFIG1 ) &
amirchaudhary 12:813e9e5f5ff6 309 RFLR_MODEMCONFIG1_BW_MASK &
amirchaudhary 12:813e9e5f5ff6 310 RFLR_MODEMCONFIG1_CODINGRATE_MASK &
amirchaudhary 12:813e9e5f5ff6 311 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) |
amirchaudhary 12:813e9e5f5ff6 312 ( bandwidth << 4 ) | ( coderate << 1 ) |
amirchaudhary 12:813e9e5f5ff6 313 fixLen );
amirchaudhary 12:813e9e5f5ff6 314
amirchaudhary 12:813e9e5f5ff6 315 Write( REG_LR_MODEMCONFIG2,
amirchaudhary 12:813e9e5f5ff6 316 ( Read( REG_LR_MODEMCONFIG2 ) &
amirchaudhary 12:813e9e5f5ff6 317 RFLR_MODEMCONFIG2_SF_MASK &
amirchaudhary 12:813e9e5f5ff6 318 RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK &
amirchaudhary 12:813e9e5f5ff6 319 RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) |
amirchaudhary 12:813e9e5f5ff6 320 ( datarate << 4 ) | ( crcOn << 2 ) |
amirchaudhary 12:813e9e5f5ff6 321 ( ( symbTimeout >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) );
amirchaudhary 12:813e9e5f5ff6 322
amirchaudhary 12:813e9e5f5ff6 323 Write( REG_LR_MODEMCONFIG3,
amirchaudhary 12:813e9e5f5ff6 324 ( Read( REG_LR_MODEMCONFIG3 ) &
amirchaudhary 12:813e9e5f5ff6 325 RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) |
amirchaudhary 12:813e9e5f5ff6 326 ( this->settings.LoRa.LowDatarateOptimize << 3 ) );
amirchaudhary 12:813e9e5f5ff6 327
amirchaudhary 12:813e9e5f5ff6 328 Write( REG_LR_SYMBTIMEOUTLSB, ( uint8_t )( symbTimeout & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 329
amirchaudhary 12:813e9e5f5ff6 330 Write( REG_LR_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 331 Write( REG_LR_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 332
amirchaudhary 12:813e9e5f5ff6 333 if( fixLen == 1 )
amirchaudhary 12:813e9e5f5ff6 334 {
amirchaudhary 12:813e9e5f5ff6 335 Write( REG_LR_PAYLOADLENGTH, payloadLen );
amirchaudhary 12:813e9e5f5ff6 336 }
amirchaudhary 12:813e9e5f5ff6 337
amirchaudhary 12:813e9e5f5ff6 338 if( this->settings.LoRa.FreqHopOn == true )
amirchaudhary 12:813e9e5f5ff6 339 {
amirchaudhary 12:813e9e5f5ff6 340 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
amirchaudhary 12:813e9e5f5ff6 341 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
amirchaudhary 12:813e9e5f5ff6 342 }
amirchaudhary 12:813e9e5f5ff6 343
amirchaudhary 12:813e9e5f5ff6 344 if( ( bandwidth == 9 ) && ( this->settings.Channel > RF_MID_BAND_THRESH ) )
amirchaudhary 12:813e9e5f5ff6 345 {
amirchaudhary 12:813e9e5f5ff6 346 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
amirchaudhary 12:813e9e5f5ff6 347 Write( REG_LR_TEST36, 0x02 );
amirchaudhary 12:813e9e5f5ff6 348 Write( REG_LR_TEST3A, 0x64 );
amirchaudhary 12:813e9e5f5ff6 349 }
amirchaudhary 12:813e9e5f5ff6 350 else if( bandwidth == 9 )
amirchaudhary 12:813e9e5f5ff6 351 {
amirchaudhary 12:813e9e5f5ff6 352 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
amirchaudhary 12:813e9e5f5ff6 353 Write( REG_LR_TEST36, 0x02 );
amirchaudhary 12:813e9e5f5ff6 354 Write( REG_LR_TEST3A, 0x7F );
amirchaudhary 12:813e9e5f5ff6 355 }
amirchaudhary 12:813e9e5f5ff6 356 else
amirchaudhary 12:813e9e5f5ff6 357 {
amirchaudhary 12:813e9e5f5ff6 358 // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
amirchaudhary 12:813e9e5f5ff6 359 Write( REG_LR_TEST36, 0x03 );
amirchaudhary 12:813e9e5f5ff6 360 }
amirchaudhary 12:813e9e5f5ff6 361
amirchaudhary 12:813e9e5f5ff6 362 if( datarate == 6 )
amirchaudhary 12:813e9e5f5ff6 363 {
amirchaudhary 12:813e9e5f5ff6 364 Write( REG_LR_DETECTOPTIMIZE,
amirchaudhary 12:813e9e5f5ff6 365 ( Read( REG_LR_DETECTOPTIMIZE ) &
amirchaudhary 12:813e9e5f5ff6 366 RFLR_DETECTIONOPTIMIZE_MASK ) |
amirchaudhary 12:813e9e5f5ff6 367 RFLR_DETECTIONOPTIMIZE_SF6 );
amirchaudhary 12:813e9e5f5ff6 368 Write( REG_LR_DETECTIONTHRESHOLD,
amirchaudhary 12:813e9e5f5ff6 369 RFLR_DETECTIONTHRESH_SF6 );
amirchaudhary 12:813e9e5f5ff6 370 }
amirchaudhary 12:813e9e5f5ff6 371 else
amirchaudhary 12:813e9e5f5ff6 372 {
amirchaudhary 12:813e9e5f5ff6 373 Write( REG_LR_DETECTOPTIMIZE,
amirchaudhary 12:813e9e5f5ff6 374 ( Read( REG_LR_DETECTOPTIMIZE ) &
amirchaudhary 12:813e9e5f5ff6 375 RFLR_DETECTIONOPTIMIZE_MASK ) |
amirchaudhary 12:813e9e5f5ff6 376 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
amirchaudhary 12:813e9e5f5ff6 377 Write( REG_LR_DETECTIONTHRESHOLD,
amirchaudhary 12:813e9e5f5ff6 378 RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
amirchaudhary 12:813e9e5f5ff6 379 }
amirchaudhary 12:813e9e5f5ff6 380 }
amirchaudhary 12:813e9e5f5ff6 381 break;
amirchaudhary 12:813e9e5f5ff6 382 }
amirchaudhary 12:813e9e5f5ff6 383 }
amirchaudhary 12:813e9e5f5ff6 384
amirchaudhary 12:813e9e5f5ff6 385 void SX1276::SetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
amirchaudhary 12:813e9e5f5ff6 386 uint32_t bandwidth, uint32_t datarate,
amirchaudhary 12:813e9e5f5ff6 387 uint8_t coderate, uint16_t preambleLen,
amirchaudhary 12:813e9e5f5ff6 388 bool fixLen, bool crcOn, bool freqHopOn,
amirchaudhary 12:813e9e5f5ff6 389 uint8_t hopPeriod, bool iqInverted, uint32_t timeout )
amirchaudhary 12:813e9e5f5ff6 390 {
amirchaudhary 12:813e9e5f5ff6 391 SetModem( modem );
amirchaudhary 12:813e9e5f5ff6 392
amirchaudhary 12:813e9e5f5ff6 393 SetRfTxPower( power );
amirchaudhary 12:813e9e5f5ff6 394
amirchaudhary 12:813e9e5f5ff6 395 switch( modem )
amirchaudhary 12:813e9e5f5ff6 396 {
amirchaudhary 12:813e9e5f5ff6 397 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 398 {
amirchaudhary 12:813e9e5f5ff6 399 this->settings.Fsk.Power = power;
amirchaudhary 12:813e9e5f5ff6 400 this->settings.Fsk.Fdev = fdev;
amirchaudhary 12:813e9e5f5ff6 401 this->settings.Fsk.Bandwidth = bandwidth;
amirchaudhary 12:813e9e5f5ff6 402 this->settings.Fsk.Datarate = datarate;
amirchaudhary 12:813e9e5f5ff6 403 this->settings.Fsk.PreambleLen = preambleLen;
amirchaudhary 12:813e9e5f5ff6 404 this->settings.Fsk.FixLen = fixLen;
amirchaudhary 12:813e9e5f5ff6 405 this->settings.Fsk.CrcOn = crcOn;
amirchaudhary 12:813e9e5f5ff6 406 this->settings.Fsk.IqInverted = iqInverted;
amirchaudhary 12:813e9e5f5ff6 407 this->settings.Fsk.TxTimeout = timeout;
amirchaudhary 12:813e9e5f5ff6 408
amirchaudhary 12:813e9e5f5ff6 409 fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
amirchaudhary 12:813e9e5f5ff6 410 Write( REG_FDEVMSB, ( uint8_t )( fdev >> 8 ) );
amirchaudhary 12:813e9e5f5ff6 411 Write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 412
amirchaudhary 12:813e9e5f5ff6 413 datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
amirchaudhary 12:813e9e5f5ff6 414 Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
amirchaudhary 12:813e9e5f5ff6 415 Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
amirchaudhary 12:813e9e5f5ff6 416
amirchaudhary 12:813e9e5f5ff6 417 Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
amirchaudhary 12:813e9e5f5ff6 418 Write( REG_PREAMBLELSB, preambleLen & 0xFF );
amirchaudhary 12:813e9e5f5ff6 419
amirchaudhary 12:813e9e5f5ff6 420 Write( REG_PACKETCONFIG1,
amirchaudhary 12:813e9e5f5ff6 421 ( Read( REG_PACKETCONFIG1 ) &
amirchaudhary 12:813e9e5f5ff6 422 RF_PACKETCONFIG1_CRC_MASK &
amirchaudhary 12:813e9e5f5ff6 423 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
amirchaudhary 12:813e9e5f5ff6 424 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
amirchaudhary 12:813e9e5f5ff6 425 ( crcOn << 4 ) );
amirchaudhary 12:813e9e5f5ff6 426 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
amirchaudhary 12:813e9e5f5ff6 427 }
amirchaudhary 12:813e9e5f5ff6 428 break;
amirchaudhary 12:813e9e5f5ff6 429 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 430 {
amirchaudhary 12:813e9e5f5ff6 431 this->settings.LoRa.Power = power;
amirchaudhary 12:813e9e5f5ff6 432 if( bandwidth > 2 )
amirchaudhary 12:813e9e5f5ff6 433 {
amirchaudhary 12:813e9e5f5ff6 434 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
amirchaudhary 12:813e9e5f5ff6 435 while( 1 );
amirchaudhary 12:813e9e5f5ff6 436 }
amirchaudhary 12:813e9e5f5ff6 437 bandwidth += 7;
amirchaudhary 12:813e9e5f5ff6 438 this->settings.LoRa.Bandwidth = bandwidth;
amirchaudhary 12:813e9e5f5ff6 439 this->settings.LoRa.Datarate = datarate;
amirchaudhary 12:813e9e5f5ff6 440 this->settings.LoRa.Coderate = coderate;
amirchaudhary 12:813e9e5f5ff6 441 this->settings.LoRa.PreambleLen = preambleLen;
amirchaudhary 12:813e9e5f5ff6 442 this->settings.LoRa.FixLen = fixLen;
amirchaudhary 12:813e9e5f5ff6 443 this->settings.LoRa.FreqHopOn = freqHopOn;
amirchaudhary 12:813e9e5f5ff6 444 this->settings.LoRa.HopPeriod = hopPeriod;
amirchaudhary 12:813e9e5f5ff6 445 this->settings.LoRa.CrcOn = crcOn;
amirchaudhary 12:813e9e5f5ff6 446 this->settings.LoRa.IqInverted = iqInverted;
amirchaudhary 12:813e9e5f5ff6 447 this->settings.LoRa.TxTimeout = timeout;
amirchaudhary 12:813e9e5f5ff6 448
amirchaudhary 12:813e9e5f5ff6 449 if( datarate > 12 )
amirchaudhary 12:813e9e5f5ff6 450 {
amirchaudhary 12:813e9e5f5ff6 451 datarate = 12;
amirchaudhary 12:813e9e5f5ff6 452 }
amirchaudhary 12:813e9e5f5ff6 453 else if( datarate < 6 )
amirchaudhary 12:813e9e5f5ff6 454 {
amirchaudhary 12:813e9e5f5ff6 455 datarate = 6;
amirchaudhary 12:813e9e5f5ff6 456 }
amirchaudhary 12:813e9e5f5ff6 457 if( ( ( bandwidth == 7 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
amirchaudhary 12:813e9e5f5ff6 458 ( ( bandwidth == 8 ) && ( datarate == 12 ) ) )
amirchaudhary 12:813e9e5f5ff6 459 {
amirchaudhary 12:813e9e5f5ff6 460 this->settings.LoRa.LowDatarateOptimize = 0x01;
amirchaudhary 12:813e9e5f5ff6 461 }
amirchaudhary 12:813e9e5f5ff6 462 else
amirchaudhary 12:813e9e5f5ff6 463 {
amirchaudhary 12:813e9e5f5ff6 464 this->settings.LoRa.LowDatarateOptimize = 0x00;
amirchaudhary 12:813e9e5f5ff6 465 }
amirchaudhary 12:813e9e5f5ff6 466
amirchaudhary 12:813e9e5f5ff6 467 if( this->settings.LoRa.FreqHopOn == true )
amirchaudhary 12:813e9e5f5ff6 468 {
amirchaudhary 12:813e9e5f5ff6 469 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
amirchaudhary 12:813e9e5f5ff6 470 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
amirchaudhary 12:813e9e5f5ff6 471 }
amirchaudhary 12:813e9e5f5ff6 472
amirchaudhary 12:813e9e5f5ff6 473 Write( REG_LR_MODEMCONFIG1,
amirchaudhary 12:813e9e5f5ff6 474 ( Read( REG_LR_MODEMCONFIG1 ) &
amirchaudhary 12:813e9e5f5ff6 475 RFLR_MODEMCONFIG1_BW_MASK &
amirchaudhary 12:813e9e5f5ff6 476 RFLR_MODEMCONFIG1_CODINGRATE_MASK &
amirchaudhary 12:813e9e5f5ff6 477 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) |
amirchaudhary 12:813e9e5f5ff6 478 ( bandwidth << 4 ) | ( coderate << 1 ) |
amirchaudhary 12:813e9e5f5ff6 479 fixLen );
amirchaudhary 12:813e9e5f5ff6 480
amirchaudhary 12:813e9e5f5ff6 481 Write( REG_LR_MODEMCONFIG2,
amirchaudhary 12:813e9e5f5ff6 482 ( Read( REG_LR_MODEMCONFIG2 ) &
amirchaudhary 12:813e9e5f5ff6 483 RFLR_MODEMCONFIG2_SF_MASK &
amirchaudhary 12:813e9e5f5ff6 484 RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) |
amirchaudhary 12:813e9e5f5ff6 485 ( datarate << 4 ) | ( crcOn << 2 ) );
amirchaudhary 12:813e9e5f5ff6 486
amirchaudhary 12:813e9e5f5ff6 487 Write( REG_LR_MODEMCONFIG3,
amirchaudhary 12:813e9e5f5ff6 488 ( Read( REG_LR_MODEMCONFIG3 ) &
amirchaudhary 12:813e9e5f5ff6 489 RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) |
amirchaudhary 12:813e9e5f5ff6 490 ( this->settings.LoRa.LowDatarateOptimize << 3 ) );
amirchaudhary 12:813e9e5f5ff6 491
amirchaudhary 12:813e9e5f5ff6 492 Write( REG_LR_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
amirchaudhary 12:813e9e5f5ff6 493 Write( REG_LR_PREAMBLELSB, preambleLen & 0xFF );
amirchaudhary 12:813e9e5f5ff6 494
amirchaudhary 12:813e9e5f5ff6 495 if( datarate == 6 )
amirchaudhary 12:813e9e5f5ff6 496 {
amirchaudhary 12:813e9e5f5ff6 497 Write( REG_LR_DETECTOPTIMIZE,
amirchaudhary 12:813e9e5f5ff6 498 ( Read( REG_LR_DETECTOPTIMIZE ) &
amirchaudhary 12:813e9e5f5ff6 499 RFLR_DETECTIONOPTIMIZE_MASK ) |
amirchaudhary 12:813e9e5f5ff6 500 RFLR_DETECTIONOPTIMIZE_SF6 );
amirchaudhary 12:813e9e5f5ff6 501 Write( REG_LR_DETECTIONTHRESHOLD,
amirchaudhary 12:813e9e5f5ff6 502 RFLR_DETECTIONTHRESH_SF6 );
amirchaudhary 12:813e9e5f5ff6 503 }
amirchaudhary 12:813e9e5f5ff6 504 else
amirchaudhary 12:813e9e5f5ff6 505 {
amirchaudhary 12:813e9e5f5ff6 506 Write( REG_LR_DETECTOPTIMIZE,
amirchaudhary 12:813e9e5f5ff6 507 ( Read( REG_LR_DETECTOPTIMIZE ) &
amirchaudhary 12:813e9e5f5ff6 508 RFLR_DETECTIONOPTIMIZE_MASK ) |
amirchaudhary 12:813e9e5f5ff6 509 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
amirchaudhary 12:813e9e5f5ff6 510 Write( REG_LR_DETECTIONTHRESHOLD,
amirchaudhary 12:813e9e5f5ff6 511 RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
amirchaudhary 12:813e9e5f5ff6 512 }
amirchaudhary 12:813e9e5f5ff6 513 }
amirchaudhary 12:813e9e5f5ff6 514 break;
amirchaudhary 12:813e9e5f5ff6 515 }
amirchaudhary 12:813e9e5f5ff6 516 }
amirchaudhary 12:813e9e5f5ff6 517
amirchaudhary 12:813e9e5f5ff6 518 uint32_t SX1276::TimeOnAir( RadioModems_t modem, uint8_t pktLen )
amirchaudhary 12:813e9e5f5ff6 519 {
amirchaudhary 12:813e9e5f5ff6 520 uint32_t airTime = 0;
amirchaudhary 12:813e9e5f5ff6 521
amirchaudhary 12:813e9e5f5ff6 522 switch( modem )
amirchaudhary 12:813e9e5f5ff6 523 {
amirchaudhary 12:813e9e5f5ff6 524 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 525 {
amirchaudhary 12:813e9e5f5ff6 526 airTime = rint( ( 8 * ( this->settings.Fsk.PreambleLen +
amirchaudhary 12:813e9e5f5ff6 527 ( ( Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
amirchaudhary 12:813e9e5f5ff6 528 ( ( this->settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
amirchaudhary 12:813e9e5f5ff6 529 ( ( ( Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
amirchaudhary 12:813e9e5f5ff6 530 pktLen +
amirchaudhary 12:813e9e5f5ff6 531 ( ( this->settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) /
amirchaudhary 12:813e9e5f5ff6 532 this->settings.Fsk.Datarate ) * 1e3 );
amirchaudhary 12:813e9e5f5ff6 533 }
amirchaudhary 12:813e9e5f5ff6 534 break;
amirchaudhary 12:813e9e5f5ff6 535 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 536 {
amirchaudhary 12:813e9e5f5ff6 537 double bw = 0.0;
amirchaudhary 12:813e9e5f5ff6 538 // REMARK: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
amirchaudhary 12:813e9e5f5ff6 539 switch( this->settings.LoRa.Bandwidth )
amirchaudhary 12:813e9e5f5ff6 540 {
amirchaudhary 12:813e9e5f5ff6 541 //case 0: // 7.8 kHz
amirchaudhary 12:813e9e5f5ff6 542 // bw = 78e2;
amirchaudhary 12:813e9e5f5ff6 543 // break;
amirchaudhary 12:813e9e5f5ff6 544 //case 1: // 10.4 kHz
amirchaudhary 12:813e9e5f5ff6 545 // bw = 104e2;
amirchaudhary 12:813e9e5f5ff6 546 // break;
amirchaudhary 12:813e9e5f5ff6 547 //case 2: // 15.6 kHz
amirchaudhary 12:813e9e5f5ff6 548 // bw = 156e2;
amirchaudhary 12:813e9e5f5ff6 549 // break;
amirchaudhary 12:813e9e5f5ff6 550 //case 3: // 20.8 kHz
amirchaudhary 12:813e9e5f5ff6 551 // bw = 208e2;
amirchaudhary 12:813e9e5f5ff6 552 // break;
amirchaudhary 12:813e9e5f5ff6 553 //case 4: // 31.2 kHz
amirchaudhary 12:813e9e5f5ff6 554 // bw = 312e2;
amirchaudhary 12:813e9e5f5ff6 555 // break;
amirchaudhary 12:813e9e5f5ff6 556 //case 5: // 41.4 kHz
amirchaudhary 12:813e9e5f5ff6 557 // bw = 414e2;
amirchaudhary 12:813e9e5f5ff6 558 // break;
amirchaudhary 12:813e9e5f5ff6 559 //case 6: // 62.5 kHz
amirchaudhary 12:813e9e5f5ff6 560 // bw = 625e2;
amirchaudhary 12:813e9e5f5ff6 561 // break;
amirchaudhary 12:813e9e5f5ff6 562 case 7: // 125 kHz
amirchaudhary 12:813e9e5f5ff6 563 bw = 125e3;
amirchaudhary 12:813e9e5f5ff6 564 break;
amirchaudhary 12:813e9e5f5ff6 565 case 8: // 250 kHz
amirchaudhary 12:813e9e5f5ff6 566 bw = 250e3;
amirchaudhary 12:813e9e5f5ff6 567 break;
amirchaudhary 12:813e9e5f5ff6 568 case 9: // 500 kHz
amirchaudhary 12:813e9e5f5ff6 569 bw = 500e3;
amirchaudhary 12:813e9e5f5ff6 570 break;
amirchaudhary 12:813e9e5f5ff6 571 }
amirchaudhary 12:813e9e5f5ff6 572
amirchaudhary 12:813e9e5f5ff6 573 // Symbol rate : time for one symbol (secs)
amirchaudhary 12:813e9e5f5ff6 574 double rs = bw / ( 1 << this->settings.LoRa.Datarate );
amirchaudhary 12:813e9e5f5ff6 575 double ts = 1 / rs;
amirchaudhary 12:813e9e5f5ff6 576 // time of preamble
amirchaudhary 12:813e9e5f5ff6 577 double tPreamble = ( this->settings.LoRa.PreambleLen + 4.25 ) * ts;
amirchaudhary 12:813e9e5f5ff6 578 // Symbol length of payload and time
amirchaudhary 12:813e9e5f5ff6 579 double tmp = ceil( ( 8 * pktLen - 4 * this->settings.LoRa.Datarate +
amirchaudhary 12:813e9e5f5ff6 580 28 + 16 * this->settings.LoRa.CrcOn -
amirchaudhary 12:813e9e5f5ff6 581 ( this->settings.LoRa.FixLen ? 20 : 0 ) ) /
amirchaudhary 12:813e9e5f5ff6 582 ( double )( 4 * ( this->settings.LoRa.Datarate -
amirchaudhary 12:813e9e5f5ff6 583 ( ( this->settings.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
amirchaudhary 12:813e9e5f5ff6 584 ( this->settings.LoRa.Coderate + 4 );
amirchaudhary 12:813e9e5f5ff6 585 double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
amirchaudhary 12:813e9e5f5ff6 586 double tPayload = nPayload * ts;
amirchaudhary 12:813e9e5f5ff6 587 // Time on air
amirchaudhary 12:813e9e5f5ff6 588 double tOnAir = tPreamble + tPayload;
amirchaudhary 12:813e9e5f5ff6 589 // return ms secs
amirchaudhary 12:813e9e5f5ff6 590 airTime = floor( tOnAir * 1e3 + 0.999 );
amirchaudhary 12:813e9e5f5ff6 591 }
amirchaudhary 12:813e9e5f5ff6 592 break;
amirchaudhary 12:813e9e5f5ff6 593 }
amirchaudhary 12:813e9e5f5ff6 594 return airTime;
amirchaudhary 12:813e9e5f5ff6 595 }
amirchaudhary 12:813e9e5f5ff6 596
amirchaudhary 12:813e9e5f5ff6 597 void SX1276::Send( uint8_t *buffer, uint8_t size )
amirchaudhary 12:813e9e5f5ff6 598 {
amirchaudhary 12:813e9e5f5ff6 599 uint32_t txTimeout = 0;
amirchaudhary 12:813e9e5f5ff6 600
amirchaudhary 12:813e9e5f5ff6 601 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 602 {
amirchaudhary 12:813e9e5f5ff6 603 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 604 {
amirchaudhary 12:813e9e5f5ff6 605 this->settings.FskPacketHandler.NbBytes = 0;
amirchaudhary 12:813e9e5f5ff6 606 this->settings.FskPacketHandler.Size = size;
amirchaudhary 12:813e9e5f5ff6 607
amirchaudhary 12:813e9e5f5ff6 608 if( this->settings.Fsk.FixLen == false )
amirchaudhary 12:813e9e5f5ff6 609 {
amirchaudhary 12:813e9e5f5ff6 610 WriteFifo( ( uint8_t* )&size, 1 );
amirchaudhary 12:813e9e5f5ff6 611 }
amirchaudhary 12:813e9e5f5ff6 612 else
amirchaudhary 12:813e9e5f5ff6 613 {
amirchaudhary 12:813e9e5f5ff6 614 Write( REG_PAYLOADLENGTH, size );
amirchaudhary 12:813e9e5f5ff6 615 }
amirchaudhary 12:813e9e5f5ff6 616
amirchaudhary 12:813e9e5f5ff6 617 if( ( size > 0 ) && ( size <= 64 ) )
amirchaudhary 12:813e9e5f5ff6 618 {
amirchaudhary 12:813e9e5f5ff6 619 this->settings.FskPacketHandler.ChunkSize = size;
amirchaudhary 12:813e9e5f5ff6 620 }
amirchaudhary 12:813e9e5f5ff6 621 else
amirchaudhary 12:813e9e5f5ff6 622 {
amirchaudhary 12:813e9e5f5ff6 623 memcpy( rxtxBuffer, buffer, size );
amirchaudhary 12:813e9e5f5ff6 624 this->settings.FskPacketHandler.ChunkSize = 32;
amirchaudhary 12:813e9e5f5ff6 625 }
amirchaudhary 12:813e9e5f5ff6 626
amirchaudhary 12:813e9e5f5ff6 627 // Write payload buffer
amirchaudhary 12:813e9e5f5ff6 628 WriteFifo( buffer, this->settings.FskPacketHandler.ChunkSize );
amirchaudhary 12:813e9e5f5ff6 629 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
amirchaudhary 12:813e9e5f5ff6 630 txTimeout = this->settings.Fsk.TxTimeout;
amirchaudhary 12:813e9e5f5ff6 631 }
amirchaudhary 12:813e9e5f5ff6 632 break;
amirchaudhary 12:813e9e5f5ff6 633 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 634 {
amirchaudhary 12:813e9e5f5ff6 635 if( this->settings.LoRa.IqInverted == true )
amirchaudhary 12:813e9e5f5ff6 636 {
amirchaudhary 12:813e9e5f5ff6 637 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) );
amirchaudhary 12:813e9e5f5ff6 638 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
amirchaudhary 12:813e9e5f5ff6 639 }
amirchaudhary 12:813e9e5f5ff6 640 else
amirchaudhary 12:813e9e5f5ff6 641 {
amirchaudhary 12:813e9e5f5ff6 642 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
amirchaudhary 12:813e9e5f5ff6 643 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
amirchaudhary 12:813e9e5f5ff6 644 }
amirchaudhary 12:813e9e5f5ff6 645
amirchaudhary 12:813e9e5f5ff6 646 this->settings.LoRaPacketHandler.Size = size;
amirchaudhary 12:813e9e5f5ff6 647
amirchaudhary 12:813e9e5f5ff6 648 // Initializes the payload size
amirchaudhary 12:813e9e5f5ff6 649 Write( REG_LR_PAYLOADLENGTH, size );
amirchaudhary 12:813e9e5f5ff6 650
amirchaudhary 12:813e9e5f5ff6 651 // Full buffer used for Tx
amirchaudhary 12:813e9e5f5ff6 652 Write( REG_LR_FIFOTXBASEADDR, 0 );
amirchaudhary 12:813e9e5f5ff6 653 Write( REG_LR_FIFOADDRPTR, 0 );
amirchaudhary 12:813e9e5f5ff6 654
amirchaudhary 12:813e9e5f5ff6 655 // FIFO operations can not take place in Sleep mode
amirchaudhary 12:813e9e5f5ff6 656 if( ( Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP )
amirchaudhary 12:813e9e5f5ff6 657 {
amirchaudhary 12:813e9e5f5ff6 658 Standby( );
amirchaudhary 12:813e9e5f5ff6 659 wait_ms( 1 );
amirchaudhary 12:813e9e5f5ff6 660 }
amirchaudhary 12:813e9e5f5ff6 661 // Write payload buffer
amirchaudhary 12:813e9e5f5ff6 662 WriteFifo( buffer, size );
amirchaudhary 12:813e9e5f5ff6 663 txTimeout = this->settings.LoRa.TxTimeout;
amirchaudhary 12:813e9e5f5ff6 664 }
amirchaudhary 12:813e9e5f5ff6 665 break;
amirchaudhary 12:813e9e5f5ff6 666 }
amirchaudhary 12:813e9e5f5ff6 667
amirchaudhary 12:813e9e5f5ff6 668 Tx( txTimeout );
amirchaudhary 12:813e9e5f5ff6 669 }
amirchaudhary 12:813e9e5f5ff6 670
amirchaudhary 12:813e9e5f5ff6 671 void SX1276::Sleep( void )
amirchaudhary 12:813e9e5f5ff6 672 {
amirchaudhary 12:813e9e5f5ff6 673 txTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 674 rxTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 675
amirchaudhary 12:813e9e5f5ff6 676 SetOpMode( RF_OPMODE_SLEEP );
amirchaudhary 12:813e9e5f5ff6 677 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 678 }
amirchaudhary 12:813e9e5f5ff6 679
amirchaudhary 12:813e9e5f5ff6 680 void SX1276::Standby( void )
amirchaudhary 12:813e9e5f5ff6 681 {
amirchaudhary 12:813e9e5f5ff6 682 txTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 683 rxTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 684
amirchaudhary 12:813e9e5f5ff6 685 SetOpMode( RF_OPMODE_STANDBY );
amirchaudhary 12:813e9e5f5ff6 686 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 687 }
amirchaudhary 12:813e9e5f5ff6 688
amirchaudhary 12:813e9e5f5ff6 689 void SX1276::Rx( uint32_t timeout )
amirchaudhary 12:813e9e5f5ff6 690 {
amirchaudhary 12:813e9e5f5ff6 691 bool rxContinuous = false;
amirchaudhary 12:813e9e5f5ff6 692
amirchaudhary 12:813e9e5f5ff6 693 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 694 {
amirchaudhary 12:813e9e5f5ff6 695 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 696 {
amirchaudhary 12:813e9e5f5ff6 697 rxContinuous = this->settings.Fsk.RxContinuous;
amirchaudhary 12:813e9e5f5ff6 698
amirchaudhary 12:813e9e5f5ff6 699 // DIO0=PayloadReady
amirchaudhary 12:813e9e5f5ff6 700 // DIO1=FifoLevel
amirchaudhary 12:813e9e5f5ff6 701 // DIO2=SyncAddr
amirchaudhary 12:813e9e5f5ff6 702 // DIO3=FifoEmpty
amirchaudhary 12:813e9e5f5ff6 703 // DIO4=Preamble
amirchaudhary 12:813e9e5f5ff6 704 // DIO5=ModeReady
amirchaudhary 12:813e9e5f5ff6 705 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
amirchaudhary 12:813e9e5f5ff6 706 RF_DIOMAPPING1_DIO1_MASK &
amirchaudhary 12:813e9e5f5ff6 707 RF_DIOMAPPING1_DIO2_MASK ) |
amirchaudhary 12:813e9e5f5ff6 708 RF_DIOMAPPING1_DIO0_00 |
amirchaudhary 12:813e9e5f5ff6 709 RF_DIOMAPPING1_DIO1_00 |
amirchaudhary 12:813e9e5f5ff6 710 RF_DIOMAPPING1_DIO2_11 );
amirchaudhary 12:813e9e5f5ff6 711
amirchaudhary 12:813e9e5f5ff6 712 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
amirchaudhary 12:813e9e5f5ff6 713 RF_DIOMAPPING2_MAP_MASK ) |
amirchaudhary 12:813e9e5f5ff6 714 RF_DIOMAPPING2_DIO4_11 |
amirchaudhary 12:813e9e5f5ff6 715 RF_DIOMAPPING2_MAP_PREAMBLEDETECT );
amirchaudhary 12:813e9e5f5ff6 716
amirchaudhary 12:813e9e5f5ff6 717 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
amirchaudhary 12:813e9e5f5ff6 718
amirchaudhary 12:813e9e5f5ff6 719 Write( REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT );
amirchaudhary 12:813e9e5f5ff6 720
amirchaudhary 12:813e9e5f5ff6 721 this->settings.FskPacketHandler.PreambleDetected = false;
amirchaudhary 12:813e9e5f5ff6 722 this->settings.FskPacketHandler.SyncWordDetected = false;
amirchaudhary 12:813e9e5f5ff6 723 this->settings.FskPacketHandler.NbBytes = 0;
amirchaudhary 12:813e9e5f5ff6 724 this->settings.FskPacketHandler.Size = 0;
amirchaudhary 12:813e9e5f5ff6 725 }
amirchaudhary 12:813e9e5f5ff6 726 break;
amirchaudhary 12:813e9e5f5ff6 727 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 728 {
amirchaudhary 12:813e9e5f5ff6 729 if( this->settings.LoRa.IqInverted == true )
amirchaudhary 12:813e9e5f5ff6 730 {
amirchaudhary 12:813e9e5f5ff6 731 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF ) );
amirchaudhary 12:813e9e5f5ff6 732 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
amirchaudhary 12:813e9e5f5ff6 733 }
amirchaudhary 12:813e9e5f5ff6 734 else
amirchaudhary 12:813e9e5f5ff6 735 {
amirchaudhary 12:813e9e5f5ff6 736 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
amirchaudhary 12:813e9e5f5ff6 737 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
amirchaudhary 12:813e9e5f5ff6 738 }
amirchaudhary 12:813e9e5f5ff6 739
amirchaudhary 12:813e9e5f5ff6 740 // ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal
amirchaudhary 12:813e9e5f5ff6 741 if( this->settings.LoRa.Bandwidth < 9 )
amirchaudhary 12:813e9e5f5ff6 742 {
amirchaudhary 12:813e9e5f5ff6 743 Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) & 0x7F );
amirchaudhary 12:813e9e5f5ff6 744 Write( REG_LR_TEST30, 0x00 );
amirchaudhary 12:813e9e5f5ff6 745 switch( this->settings.LoRa.Bandwidth )
amirchaudhary 12:813e9e5f5ff6 746 {
amirchaudhary 12:813e9e5f5ff6 747 case 0: // 7.8 kHz
amirchaudhary 12:813e9e5f5ff6 748 Write( REG_LR_TEST2F, 0x48 );
amirchaudhary 12:813e9e5f5ff6 749 SetChannel(this->settings.Channel + 7.81e3 );
amirchaudhary 12:813e9e5f5ff6 750 break;
amirchaudhary 12:813e9e5f5ff6 751 case 1: // 10.4 kHz
amirchaudhary 12:813e9e5f5ff6 752 Write( REG_LR_TEST2F, 0x44 );
amirchaudhary 12:813e9e5f5ff6 753 SetChannel(this->settings.Channel + 10.42e3 );
amirchaudhary 12:813e9e5f5ff6 754 break;
amirchaudhary 12:813e9e5f5ff6 755 case 2: // 15.6 kHz
amirchaudhary 12:813e9e5f5ff6 756 Write( REG_LR_TEST2F, 0x44 );
amirchaudhary 12:813e9e5f5ff6 757 SetChannel(this->settings.Channel + 15.62e3 );
amirchaudhary 12:813e9e5f5ff6 758 break;
amirchaudhary 12:813e9e5f5ff6 759 case 3: // 20.8 kHz
amirchaudhary 12:813e9e5f5ff6 760 Write( REG_LR_TEST2F, 0x44 );
amirchaudhary 12:813e9e5f5ff6 761 SetChannel(this->settings.Channel + 20.83e3 );
amirchaudhary 12:813e9e5f5ff6 762 break;
amirchaudhary 12:813e9e5f5ff6 763 case 4: // 31.2 kHz
amirchaudhary 12:813e9e5f5ff6 764 Write( REG_LR_TEST2F, 0x44 );
amirchaudhary 12:813e9e5f5ff6 765 SetChannel(this->settings.Channel + 31.25e3 );
amirchaudhary 12:813e9e5f5ff6 766 break;
amirchaudhary 12:813e9e5f5ff6 767 case 5: // 41.4 kHz
amirchaudhary 12:813e9e5f5ff6 768 Write( REG_LR_TEST2F, 0x44 );
amirchaudhary 12:813e9e5f5ff6 769 SetChannel(this->settings.Channel + 41.67e3 );
amirchaudhary 12:813e9e5f5ff6 770 break;
amirchaudhary 12:813e9e5f5ff6 771 case 6: // 62.5 kHz
amirchaudhary 12:813e9e5f5ff6 772 Write( REG_LR_TEST2F, 0x40 );
amirchaudhary 12:813e9e5f5ff6 773 break;
amirchaudhary 12:813e9e5f5ff6 774 case 7: // 125 kHz
amirchaudhary 12:813e9e5f5ff6 775 Write( REG_LR_TEST2F, 0x40 );
amirchaudhary 12:813e9e5f5ff6 776 break;
amirchaudhary 12:813e9e5f5ff6 777 case 8: // 250 kHz
amirchaudhary 12:813e9e5f5ff6 778 Write( REG_LR_TEST2F, 0x40 );
amirchaudhary 12:813e9e5f5ff6 779 break;
amirchaudhary 12:813e9e5f5ff6 780 }
amirchaudhary 12:813e9e5f5ff6 781 }
amirchaudhary 12:813e9e5f5ff6 782 else
amirchaudhary 12:813e9e5f5ff6 783 {
amirchaudhary 12:813e9e5f5ff6 784 Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) | 0x80 );
amirchaudhary 12:813e9e5f5ff6 785 }
amirchaudhary 12:813e9e5f5ff6 786
amirchaudhary 12:813e9e5f5ff6 787 rxContinuous = this->settings.LoRa.RxContinuous;
amirchaudhary 12:813e9e5f5ff6 788
amirchaudhary 12:813e9e5f5ff6 789 if( this->settings.LoRa.FreqHopOn == true )
amirchaudhary 12:813e9e5f5ff6 790 {
amirchaudhary 12:813e9e5f5ff6 791 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
amirchaudhary 12:813e9e5f5ff6 792 //RFLR_IRQFLAGS_RXDONE |
amirchaudhary 12:813e9e5f5ff6 793 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
amirchaudhary 12:813e9e5f5ff6 794 RFLR_IRQFLAGS_VALIDHEADER |
amirchaudhary 12:813e9e5f5ff6 795 RFLR_IRQFLAGS_TXDONE |
amirchaudhary 12:813e9e5f5ff6 796 RFLR_IRQFLAGS_CADDONE |
amirchaudhary 12:813e9e5f5ff6 797 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
amirchaudhary 12:813e9e5f5ff6 798 RFLR_IRQFLAGS_CADDETECTED );
amirchaudhary 12:813e9e5f5ff6 799
amirchaudhary 12:813e9e5f5ff6 800 // DIO0=RxDone, DIO2=FhssChangeChannel
amirchaudhary 12:813e9e5f5ff6 801 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00 );
amirchaudhary 12:813e9e5f5ff6 802 }
amirchaudhary 12:813e9e5f5ff6 803 else
amirchaudhary 12:813e9e5f5ff6 804 {
amirchaudhary 12:813e9e5f5ff6 805 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
amirchaudhary 12:813e9e5f5ff6 806 //RFLR_IRQFLAGS_RXDONE |
amirchaudhary 12:813e9e5f5ff6 807 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
amirchaudhary 12:813e9e5f5ff6 808 RFLR_IRQFLAGS_VALIDHEADER |
amirchaudhary 12:813e9e5f5ff6 809 RFLR_IRQFLAGS_TXDONE |
amirchaudhary 12:813e9e5f5ff6 810 RFLR_IRQFLAGS_CADDONE |
amirchaudhary 12:813e9e5f5ff6 811 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
amirchaudhary 12:813e9e5f5ff6 812 RFLR_IRQFLAGS_CADDETECTED );
amirchaudhary 12:813e9e5f5ff6 813
amirchaudhary 12:813e9e5f5ff6 814 // DIO0=RxDone
amirchaudhary 12:813e9e5f5ff6 815 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
amirchaudhary 12:813e9e5f5ff6 816 }
amirchaudhary 12:813e9e5f5ff6 817 Write( REG_LR_FIFORXBASEADDR, 0 );
amirchaudhary 12:813e9e5f5ff6 818 Write( REG_LR_FIFOADDRPTR, 0 );
amirchaudhary 12:813e9e5f5ff6 819 }
amirchaudhary 12:813e9e5f5ff6 820 break;
amirchaudhary 12:813e9e5f5ff6 821 }
amirchaudhary 12:813e9e5f5ff6 822
amirchaudhary 12:813e9e5f5ff6 823 memset( rxtxBuffer, 0, ( size_t )RX_BUFFER_SIZE );
amirchaudhary 12:813e9e5f5ff6 824
amirchaudhary 12:813e9e5f5ff6 825 this->settings.State = RF_RX_RUNNING;
amirchaudhary 12:813e9e5f5ff6 826 if( timeout != 0 )
amirchaudhary 12:813e9e5f5ff6 827 {
amirchaudhary 12:813e9e5f5ff6 828 rxTimeoutTimer.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout * 1e3 );
amirchaudhary 12:813e9e5f5ff6 829 }
amirchaudhary 12:813e9e5f5ff6 830
amirchaudhary 12:813e9e5f5ff6 831 if( this->settings.Modem == MODEM_FSK )
amirchaudhary 12:813e9e5f5ff6 832 {
amirchaudhary 12:813e9e5f5ff6 833 SetOpMode( RF_OPMODE_RECEIVER );
amirchaudhary 12:813e9e5f5ff6 834
amirchaudhary 12:813e9e5f5ff6 835 if( rxContinuous == false )
amirchaudhary 12:813e9e5f5ff6 836 {
amirchaudhary 12:813e9e5f5ff6 837 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
amirchaudhary 12:813e9e5f5ff6 838 this->settings.Fsk.RxSingleTimeout * 1e3 );
amirchaudhary 12:813e9e5f5ff6 839 }
amirchaudhary 12:813e9e5f5ff6 840 }
amirchaudhary 12:813e9e5f5ff6 841 else
amirchaudhary 12:813e9e5f5ff6 842 {
amirchaudhary 12:813e9e5f5ff6 843 if( rxContinuous == true )
amirchaudhary 12:813e9e5f5ff6 844 {
amirchaudhary 12:813e9e5f5ff6 845 SetOpMode( RFLR_OPMODE_RECEIVER );
amirchaudhary 12:813e9e5f5ff6 846 }
amirchaudhary 12:813e9e5f5ff6 847 else
amirchaudhary 12:813e9e5f5ff6 848 {
amirchaudhary 12:813e9e5f5ff6 849 SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
amirchaudhary 12:813e9e5f5ff6 850 }
amirchaudhary 12:813e9e5f5ff6 851 }
amirchaudhary 12:813e9e5f5ff6 852 }
amirchaudhary 12:813e9e5f5ff6 853
amirchaudhary 12:813e9e5f5ff6 854 void SX1276::Tx( uint32_t timeout )
amirchaudhary 12:813e9e5f5ff6 855 {
amirchaudhary 12:813e9e5f5ff6 856
amirchaudhary 12:813e9e5f5ff6 857 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 858 {
amirchaudhary 12:813e9e5f5ff6 859 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 860 {
amirchaudhary 12:813e9e5f5ff6 861 // DIO0=PacketSent
amirchaudhary 12:813e9e5f5ff6 862 // DIO1=FifoEmpty
amirchaudhary 12:813e9e5f5ff6 863 // DIO2=FifoFull
amirchaudhary 12:813e9e5f5ff6 864 // DIO3=FifoEmpty
amirchaudhary 12:813e9e5f5ff6 865 // DIO4=LowBat
amirchaudhary 12:813e9e5f5ff6 866 // DIO5=ModeReady
amirchaudhary 12:813e9e5f5ff6 867 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
amirchaudhary 12:813e9e5f5ff6 868 RF_DIOMAPPING1_DIO1_MASK &
amirchaudhary 12:813e9e5f5ff6 869 RF_DIOMAPPING1_DIO2_MASK ) |
amirchaudhary 12:813e9e5f5ff6 870 RF_DIOMAPPING1_DIO1_01 );
amirchaudhary 12:813e9e5f5ff6 871
amirchaudhary 12:813e9e5f5ff6 872 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
amirchaudhary 12:813e9e5f5ff6 873 RF_DIOMAPPING2_MAP_MASK ) );
amirchaudhary 12:813e9e5f5ff6 874 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
amirchaudhary 12:813e9e5f5ff6 875 }
amirchaudhary 12:813e9e5f5ff6 876 break;
amirchaudhary 12:813e9e5f5ff6 877 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 878 {
amirchaudhary 12:813e9e5f5ff6 879 if( this->settings.LoRa.FreqHopOn == true )
amirchaudhary 12:813e9e5f5ff6 880 {
amirchaudhary 12:813e9e5f5ff6 881 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
amirchaudhary 12:813e9e5f5ff6 882 RFLR_IRQFLAGS_RXDONE |
amirchaudhary 12:813e9e5f5ff6 883 RFLR_IRQFLAGS_PAYLOADCRCERROR |
amirchaudhary 12:813e9e5f5ff6 884 RFLR_IRQFLAGS_VALIDHEADER |
amirchaudhary 12:813e9e5f5ff6 885 //RFLR_IRQFLAGS_TXDONE |
amirchaudhary 12:813e9e5f5ff6 886 RFLR_IRQFLAGS_CADDONE |
amirchaudhary 12:813e9e5f5ff6 887 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
amirchaudhary 12:813e9e5f5ff6 888 RFLR_IRQFLAGS_CADDETECTED );
amirchaudhary 12:813e9e5f5ff6 889
amirchaudhary 12:813e9e5f5ff6 890 // DIO0=TxDone, DIO2=FhssChangeChannel
amirchaudhary 12:813e9e5f5ff6 891 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_01 | RFLR_DIOMAPPING1_DIO2_00 );
amirchaudhary 12:813e9e5f5ff6 892 }
amirchaudhary 12:813e9e5f5ff6 893 else
amirchaudhary 12:813e9e5f5ff6 894 {
amirchaudhary 12:813e9e5f5ff6 895 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
amirchaudhary 12:813e9e5f5ff6 896 RFLR_IRQFLAGS_RXDONE |
amirchaudhary 12:813e9e5f5ff6 897 RFLR_IRQFLAGS_PAYLOADCRCERROR |
amirchaudhary 12:813e9e5f5ff6 898 RFLR_IRQFLAGS_VALIDHEADER |
amirchaudhary 12:813e9e5f5ff6 899 //RFLR_IRQFLAGS_TXDONE |
amirchaudhary 12:813e9e5f5ff6 900 RFLR_IRQFLAGS_CADDONE |
amirchaudhary 12:813e9e5f5ff6 901 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
amirchaudhary 12:813e9e5f5ff6 902 RFLR_IRQFLAGS_CADDETECTED );
amirchaudhary 12:813e9e5f5ff6 903
amirchaudhary 12:813e9e5f5ff6 904 // DIO0=TxDone
amirchaudhary 12:813e9e5f5ff6 905 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
amirchaudhary 12:813e9e5f5ff6 906 }
amirchaudhary 12:813e9e5f5ff6 907 }
amirchaudhary 12:813e9e5f5ff6 908 break;
amirchaudhary 12:813e9e5f5ff6 909 }
amirchaudhary 12:813e9e5f5ff6 910
amirchaudhary 12:813e9e5f5ff6 911 this->settings.State = RF_TX_RUNNING;
amirchaudhary 12:813e9e5f5ff6 912 txTimeoutTimer.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout * 1e3 );
amirchaudhary 12:813e9e5f5ff6 913 SetOpMode( RF_OPMODE_TRANSMITTER );
amirchaudhary 12:813e9e5f5ff6 914 }
amirchaudhary 12:813e9e5f5ff6 915
amirchaudhary 12:813e9e5f5ff6 916 void SX1276::StartCad( void )
amirchaudhary 12:813e9e5f5ff6 917 {
amirchaudhary 12:813e9e5f5ff6 918 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 919 {
amirchaudhary 12:813e9e5f5ff6 920 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 921 {
amirchaudhary 12:813e9e5f5ff6 922
amirchaudhary 12:813e9e5f5ff6 923 }
amirchaudhary 12:813e9e5f5ff6 924 break;
amirchaudhary 12:813e9e5f5ff6 925 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 926 {
amirchaudhary 12:813e9e5f5ff6 927 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
amirchaudhary 12:813e9e5f5ff6 928 RFLR_IRQFLAGS_RXDONE |
amirchaudhary 12:813e9e5f5ff6 929 RFLR_IRQFLAGS_PAYLOADCRCERROR |
amirchaudhary 12:813e9e5f5ff6 930 RFLR_IRQFLAGS_VALIDHEADER |
amirchaudhary 12:813e9e5f5ff6 931 RFLR_IRQFLAGS_TXDONE |
amirchaudhary 12:813e9e5f5ff6 932 //RFLR_IRQFLAGS_CADDONE |
amirchaudhary 12:813e9e5f5ff6 933 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
amirchaudhary 12:813e9e5f5ff6 934 //RFLR_IRQFLAGS_CADDETECTED
amirchaudhary 12:813e9e5f5ff6 935 );
amirchaudhary 12:813e9e5f5ff6 936
amirchaudhary 12:813e9e5f5ff6 937 // DIO3=CADDone
amirchaudhary 12:813e9e5f5ff6 938 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO3_MASK ) | RFLR_DIOMAPPING1_DIO3_00 );
amirchaudhary 12:813e9e5f5ff6 939
amirchaudhary 12:813e9e5f5ff6 940 this->settings.State = RF_CAD;
amirchaudhary 12:813e9e5f5ff6 941 SetOpMode( RFLR_OPMODE_CAD );
amirchaudhary 12:813e9e5f5ff6 942 }
amirchaudhary 12:813e9e5f5ff6 943 break;
amirchaudhary 12:813e9e5f5ff6 944 default:
amirchaudhary 12:813e9e5f5ff6 945 break;
amirchaudhary 12:813e9e5f5ff6 946 }
amirchaudhary 12:813e9e5f5ff6 947 }
amirchaudhary 12:813e9e5f5ff6 948
amirchaudhary 12:813e9e5f5ff6 949 void SX1276::SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
amirchaudhary 12:813e9e5f5ff6 950 {
amirchaudhary 12:813e9e5f5ff6 951 uint32_t timeout = ( uint32_t )( time * 1e6 );
amirchaudhary 12:813e9e5f5ff6 952
amirchaudhary 12:813e9e5f5ff6 953 SetChannel( freq );
amirchaudhary 12:813e9e5f5ff6 954
amirchaudhary 12:813e9e5f5ff6 955 SetTxConfig( MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, timeout );
amirchaudhary 12:813e9e5f5ff6 956
amirchaudhary 12:813e9e5f5ff6 957 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) & RF_PACKETCONFIG2_DATAMODE_MASK ) );
amirchaudhary 12:813e9e5f5ff6 958 // Disable radio interrupts
amirchaudhary 12:813e9e5f5ff6 959 Write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 );
amirchaudhary 12:813e9e5f5ff6 960 Write( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 );
amirchaudhary 12:813e9e5f5ff6 961
amirchaudhary 12:813e9e5f5ff6 962 this->settings.State = RF_TX_RUNNING;
amirchaudhary 12:813e9e5f5ff6 963 txTimeoutTimer.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout );
amirchaudhary 12:813e9e5f5ff6 964 SetOpMode( RF_OPMODE_TRANSMITTER );
amirchaudhary 12:813e9e5f5ff6 965 }
amirchaudhary 12:813e9e5f5ff6 966
amirchaudhary 12:813e9e5f5ff6 967 int16_t SX1276::GetRssi( RadioModems_t modem )
amirchaudhary 12:813e9e5f5ff6 968 {
amirchaudhary 12:813e9e5f5ff6 969 int16_t rssi = 0;
amirchaudhary 12:813e9e5f5ff6 970
amirchaudhary 12:813e9e5f5ff6 971 switch( modem )
amirchaudhary 12:813e9e5f5ff6 972 {
amirchaudhary 12:813e9e5f5ff6 973 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 974 rssi = -( Read( REG_RSSIVALUE ) >> 1 );
amirchaudhary 12:813e9e5f5ff6 975 break;
amirchaudhary 12:813e9e5f5ff6 976 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 977 if( this->settings.Channel > RF_MID_BAND_THRESH )
amirchaudhary 12:813e9e5f5ff6 978 {
amirchaudhary 12:813e9e5f5ff6 979 rssi = RSSI_OFFSET_HF + Read( REG_LR_RSSIVALUE );
amirchaudhary 12:813e9e5f5ff6 980 }
amirchaudhary 12:813e9e5f5ff6 981 else
amirchaudhary 12:813e9e5f5ff6 982 {
amirchaudhary 12:813e9e5f5ff6 983 rssi = RSSI_OFFSET_LF + Read( REG_LR_RSSIVALUE );
amirchaudhary 12:813e9e5f5ff6 984 }
amirchaudhary 12:813e9e5f5ff6 985 break;
amirchaudhary 12:813e9e5f5ff6 986 default:
amirchaudhary 12:813e9e5f5ff6 987 rssi = -1;
amirchaudhary 12:813e9e5f5ff6 988 break;
amirchaudhary 12:813e9e5f5ff6 989 }
amirchaudhary 12:813e9e5f5ff6 990 return rssi;
amirchaudhary 12:813e9e5f5ff6 991 }
amirchaudhary 12:813e9e5f5ff6 992
amirchaudhary 12:813e9e5f5ff6 993 void SX1276::SetOpMode( uint8_t opMode )
amirchaudhary 12:813e9e5f5ff6 994 {
amirchaudhary 12:813e9e5f5ff6 995 if( opMode == RF_OPMODE_SLEEP )
amirchaudhary 12:813e9e5f5ff6 996 {
amirchaudhary 12:813e9e5f5ff6 997 SetAntSwLowPower( true );
amirchaudhary 12:813e9e5f5ff6 998 }
amirchaudhary 12:813e9e5f5ff6 999 else
amirchaudhary 12:813e9e5f5ff6 1000 {
amirchaudhary 12:813e9e5f5ff6 1001 SetAntSwLowPower( false );
amirchaudhary 12:813e9e5f5ff6 1002 SetAntSw( opMode );
amirchaudhary 12:813e9e5f5ff6 1003 }
amirchaudhary 12:813e9e5f5ff6 1004 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
amirchaudhary 12:813e9e5f5ff6 1005 }
amirchaudhary 12:813e9e5f5ff6 1006
amirchaudhary 12:813e9e5f5ff6 1007 void SX1276::SetModem( RadioModems_t modem )
amirchaudhary 12:813e9e5f5ff6 1008 {
amirchaudhary 12:813e9e5f5ff6 1009 if( ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_ON ) != 0 )
amirchaudhary 12:813e9e5f5ff6 1010 {
amirchaudhary 12:813e9e5f5ff6 1011 this->settings.Modem = MODEM_LORA;
amirchaudhary 12:813e9e5f5ff6 1012 }
amirchaudhary 12:813e9e5f5ff6 1013 else
amirchaudhary 12:813e9e5f5ff6 1014 {
amirchaudhary 12:813e9e5f5ff6 1015 this->settings.Modem = MODEM_FSK;
amirchaudhary 12:813e9e5f5ff6 1016 }
amirchaudhary 12:813e9e5f5ff6 1017
amirchaudhary 12:813e9e5f5ff6 1018 if( this->settings.Modem == modem )
amirchaudhary 12:813e9e5f5ff6 1019 {
amirchaudhary 12:813e9e5f5ff6 1020 return;
amirchaudhary 12:813e9e5f5ff6 1021 }
amirchaudhary 12:813e9e5f5ff6 1022
amirchaudhary 12:813e9e5f5ff6 1023 this->settings.Modem = modem;
amirchaudhary 12:813e9e5f5ff6 1024 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1025 {
amirchaudhary 12:813e9e5f5ff6 1026 default:
amirchaudhary 12:813e9e5f5ff6 1027 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1028 Sleep( );
amirchaudhary 12:813e9e5f5ff6 1029 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
amirchaudhary 12:813e9e5f5ff6 1030
amirchaudhary 12:813e9e5f5ff6 1031 Write( REG_DIOMAPPING1, 0x00 );
amirchaudhary 12:813e9e5f5ff6 1032 Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
amirchaudhary 12:813e9e5f5ff6 1033 break;
amirchaudhary 12:813e9e5f5ff6 1034 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1035 Sleep( );
amirchaudhary 12:813e9e5f5ff6 1036 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
amirchaudhary 12:813e9e5f5ff6 1037
amirchaudhary 12:813e9e5f5ff6 1038 Write( REG_DIOMAPPING1, 0x00 );
amirchaudhary 12:813e9e5f5ff6 1039 Write( REG_DIOMAPPING2, 0x00 );
amirchaudhary 12:813e9e5f5ff6 1040 break;
amirchaudhary 12:813e9e5f5ff6 1041 }
amirchaudhary 12:813e9e5f5ff6 1042 }
amirchaudhary 12:813e9e5f5ff6 1043
amirchaudhary 12:813e9e5f5ff6 1044 void SX1276::SetMaxPayloadLength( RadioModems_t modem, uint8_t max )
amirchaudhary 12:813e9e5f5ff6 1045 {
amirchaudhary 12:813e9e5f5ff6 1046 this->SetModem( modem );
amirchaudhary 12:813e9e5f5ff6 1047
amirchaudhary 12:813e9e5f5ff6 1048 switch( modem )
amirchaudhary 12:813e9e5f5ff6 1049 {
amirchaudhary 12:813e9e5f5ff6 1050 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1051 if( this->settings.Fsk.FixLen == false )
amirchaudhary 12:813e9e5f5ff6 1052 {
amirchaudhary 12:813e9e5f5ff6 1053 this->Write( REG_PAYLOADLENGTH, max );
amirchaudhary 12:813e9e5f5ff6 1054 }
amirchaudhary 12:813e9e5f5ff6 1055 break;
amirchaudhary 12:813e9e5f5ff6 1056 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1057 this->Write( REG_LR_PAYLOADMAXLENGTH, max );
amirchaudhary 12:813e9e5f5ff6 1058 break;
amirchaudhary 12:813e9e5f5ff6 1059 }
amirchaudhary 12:813e9e5f5ff6 1060 }
amirchaudhary 12:813e9e5f5ff6 1061
amirchaudhary 12:813e9e5f5ff6 1062 void SX1276::SetPublicNetwork( bool enable )
amirchaudhary 12:813e9e5f5ff6 1063 {
amirchaudhary 12:813e9e5f5ff6 1064 SetModem( MODEM_LORA );
amirchaudhary 12:813e9e5f5ff6 1065 this->settings.LoRa.PublicNetwork = enable;
amirchaudhary 12:813e9e5f5ff6 1066 if( enable == true )
amirchaudhary 12:813e9e5f5ff6 1067 {
amirchaudhary 12:813e9e5f5ff6 1068 // Change LoRa modem SyncWord
amirchaudhary 12:813e9e5f5ff6 1069 Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
amirchaudhary 12:813e9e5f5ff6 1070 }
amirchaudhary 12:813e9e5f5ff6 1071 else
amirchaudhary 12:813e9e5f5ff6 1072 {
amirchaudhary 12:813e9e5f5ff6 1073 // Change LoRa modem SyncWord
amirchaudhary 12:813e9e5f5ff6 1074 Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );
amirchaudhary 12:813e9e5f5ff6 1075 }
amirchaudhary 12:813e9e5f5ff6 1076 }
amirchaudhary 12:813e9e5f5ff6 1077
amirchaudhary 12:813e9e5f5ff6 1078 void SX1276::OnTimeoutIrq( void )
amirchaudhary 12:813e9e5f5ff6 1079 {
amirchaudhary 12:813e9e5f5ff6 1080 switch( this->settings.State )
amirchaudhary 12:813e9e5f5ff6 1081 {
amirchaudhary 12:813e9e5f5ff6 1082 case RF_RX_RUNNING:
amirchaudhary 12:813e9e5f5ff6 1083 if( this->settings.Modem == MODEM_FSK )
amirchaudhary 12:813e9e5f5ff6 1084 {
amirchaudhary 12:813e9e5f5ff6 1085 this->settings.FskPacketHandler.PreambleDetected = false;
amirchaudhary 12:813e9e5f5ff6 1086 this->settings.FskPacketHandler.SyncWordDetected = false;
amirchaudhary 12:813e9e5f5ff6 1087 this->settings.FskPacketHandler.NbBytes = 0;
amirchaudhary 12:813e9e5f5ff6 1088 this->settings.FskPacketHandler.Size = 0;
amirchaudhary 12:813e9e5f5ff6 1089
amirchaudhary 12:813e9e5f5ff6 1090 // Clear Irqs
amirchaudhary 12:813e9e5f5ff6 1091 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
amirchaudhary 12:813e9e5f5ff6 1092 RF_IRQFLAGS1_PREAMBLEDETECT |
amirchaudhary 12:813e9e5f5ff6 1093 RF_IRQFLAGS1_SYNCADDRESSMATCH );
amirchaudhary 12:813e9e5f5ff6 1094 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
amirchaudhary 12:813e9e5f5ff6 1095
amirchaudhary 12:813e9e5f5ff6 1096 if( this->settings.Fsk.RxContinuous == true )
amirchaudhary 12:813e9e5f5ff6 1097 {
amirchaudhary 12:813e9e5f5ff6 1098 // Continuous mode restart Rx chain
amirchaudhary 12:813e9e5f5ff6 1099 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
amirchaudhary 12:813e9e5f5ff6 1100 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
amirchaudhary 12:813e9e5f5ff6 1101 this->settings.Fsk.RxSingleTimeout * 1e3 );
amirchaudhary 12:813e9e5f5ff6 1102 }
amirchaudhary 12:813e9e5f5ff6 1103 else
amirchaudhary 12:813e9e5f5ff6 1104 {
amirchaudhary 12:813e9e5f5ff6 1105 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 1106 rxTimeoutSyncWord.detach( );
amirchaudhary 12:813e9e5f5ff6 1107 }
amirchaudhary 12:813e9e5f5ff6 1108 }
amirchaudhary 12:813e9e5f5ff6 1109 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1110 {
amirchaudhary 12:813e9e5f5ff6 1111 this->RadioEvents->RxTimeout( );
amirchaudhary 12:813e9e5f5ff6 1112 }
amirchaudhary 12:813e9e5f5ff6 1113 break;
amirchaudhary 12:813e9e5f5ff6 1114 case RF_TX_RUNNING:
amirchaudhary 12:813e9e5f5ff6 1115 // Tx timeout shouldn't happen.
amirchaudhary 12:813e9e5f5ff6 1116 // But it has been observed that when it happens it is a result of a corrupted SPI transfer
amirchaudhary 12:813e9e5f5ff6 1117 // it depends on the platform design.
amirchaudhary 12:813e9e5f5ff6 1118 //
amirchaudhary 12:813e9e5f5ff6 1119 // The workaround is to put the radio in a known state. Thus, we re-initialize it.
amirchaudhary 12:813e9e5f5ff6 1120
amirchaudhary 12:813e9e5f5ff6 1121 // BEGIN WORKAROUND
amirchaudhary 12:813e9e5f5ff6 1122
amirchaudhary 12:813e9e5f5ff6 1123 // Reset the radio
amirchaudhary 12:813e9e5f5ff6 1124 Reset( );
amirchaudhary 12:813e9e5f5ff6 1125
amirchaudhary 12:813e9e5f5ff6 1126 // Calibrate Rx chain
amirchaudhary 12:813e9e5f5ff6 1127 RxChainCalibration( );
amirchaudhary 12:813e9e5f5ff6 1128
amirchaudhary 12:813e9e5f5ff6 1129 // Initialize radio default values
amirchaudhary 12:813e9e5f5ff6 1130 SetOpMode( RF_OPMODE_SLEEP );
amirchaudhary 12:813e9e5f5ff6 1131
amirchaudhary 12:813e9e5f5ff6 1132 RadioRegistersInit( );
amirchaudhary 12:813e9e5f5ff6 1133
amirchaudhary 12:813e9e5f5ff6 1134 SetModem( MODEM_FSK );
amirchaudhary 12:813e9e5f5ff6 1135
amirchaudhary 12:813e9e5f5ff6 1136 // Restore previous network type setting.
amirchaudhary 12:813e9e5f5ff6 1137 SetPublicNetwork( this->settings.LoRa.PublicNetwork );
amirchaudhary 12:813e9e5f5ff6 1138 // END WORKAROUND
amirchaudhary 12:813e9e5f5ff6 1139
amirchaudhary 12:813e9e5f5ff6 1140 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 1141 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxTimeout != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1142 {
amirchaudhary 12:813e9e5f5ff6 1143 this->RadioEvents->TxTimeout( );
amirchaudhary 12:813e9e5f5ff6 1144 }
amirchaudhary 12:813e9e5f5ff6 1145 break;
amirchaudhary 12:813e9e5f5ff6 1146 default:
amirchaudhary 12:813e9e5f5ff6 1147 break;
amirchaudhary 12:813e9e5f5ff6 1148 }
amirchaudhary 12:813e9e5f5ff6 1149 }
amirchaudhary 12:813e9e5f5ff6 1150
amirchaudhary 12:813e9e5f5ff6 1151 void SX1276::OnDio0Irq( void )
amirchaudhary 12:813e9e5f5ff6 1152 {
amirchaudhary 12:813e9e5f5ff6 1153 volatile uint8_t irqFlags = 0;
amirchaudhary 12:813e9e5f5ff6 1154
amirchaudhary 12:813e9e5f5ff6 1155 switch( this->settings.State )
amirchaudhary 12:813e9e5f5ff6 1156 {
amirchaudhary 12:813e9e5f5ff6 1157 case RF_RX_RUNNING:
amirchaudhary 12:813e9e5f5ff6 1158 //TimerStop( &RxTimeoutTimer );
amirchaudhary 12:813e9e5f5ff6 1159 // RxDone interrupt
amirchaudhary 12:813e9e5f5ff6 1160 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1161 {
amirchaudhary 12:813e9e5f5ff6 1162 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1163 if( this->settings.Fsk.CrcOn == true )
amirchaudhary 12:813e9e5f5ff6 1164 {
amirchaudhary 12:813e9e5f5ff6 1165 irqFlags = Read( REG_IRQFLAGS2 );
amirchaudhary 12:813e9e5f5ff6 1166 if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
amirchaudhary 12:813e9e5f5ff6 1167 {
amirchaudhary 12:813e9e5f5ff6 1168 // Clear Irqs
amirchaudhary 12:813e9e5f5ff6 1169 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
amirchaudhary 12:813e9e5f5ff6 1170 RF_IRQFLAGS1_PREAMBLEDETECT |
amirchaudhary 12:813e9e5f5ff6 1171 RF_IRQFLAGS1_SYNCADDRESSMATCH );
amirchaudhary 12:813e9e5f5ff6 1172 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
amirchaudhary 12:813e9e5f5ff6 1173
amirchaudhary 12:813e9e5f5ff6 1174 rxTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 1175
amirchaudhary 12:813e9e5f5ff6 1176 if( this->settings.Fsk.RxContinuous == false )
amirchaudhary 12:813e9e5f5ff6 1177 {
amirchaudhary 12:813e9e5f5ff6 1178 rxTimeoutSyncWord.detach( );
amirchaudhary 12:813e9e5f5ff6 1179 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 1180 }
amirchaudhary 12:813e9e5f5ff6 1181 else
amirchaudhary 12:813e9e5f5ff6 1182 {
amirchaudhary 12:813e9e5f5ff6 1183 // Continuous mode restart Rx chain
amirchaudhary 12:813e9e5f5ff6 1184 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
amirchaudhary 12:813e9e5f5ff6 1185 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
amirchaudhary 12:813e9e5f5ff6 1186 this->settings.Fsk.RxSingleTimeout * 1e3 );
amirchaudhary 12:813e9e5f5ff6 1187 }
amirchaudhary 12:813e9e5f5ff6 1188
amirchaudhary 12:813e9e5f5ff6 1189 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1190 {
amirchaudhary 12:813e9e5f5ff6 1191 this->RadioEvents->RxError( );
amirchaudhary 12:813e9e5f5ff6 1192 }
amirchaudhary 12:813e9e5f5ff6 1193 this->settings.FskPacketHandler.PreambleDetected = false;
amirchaudhary 12:813e9e5f5ff6 1194 this->settings.FskPacketHandler.SyncWordDetected = false;
amirchaudhary 12:813e9e5f5ff6 1195 this->settings.FskPacketHandler.NbBytes = 0;
amirchaudhary 12:813e9e5f5ff6 1196 this->settings.FskPacketHandler.Size = 0;
amirchaudhary 12:813e9e5f5ff6 1197 break;
amirchaudhary 12:813e9e5f5ff6 1198 }
amirchaudhary 12:813e9e5f5ff6 1199 }
amirchaudhary 12:813e9e5f5ff6 1200
amirchaudhary 12:813e9e5f5ff6 1201 // Read received packet size
amirchaudhary 12:813e9e5f5ff6 1202 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
amirchaudhary 12:813e9e5f5ff6 1203 {
amirchaudhary 12:813e9e5f5ff6 1204 if( this->settings.Fsk.FixLen == false )
amirchaudhary 12:813e9e5f5ff6 1205 {
amirchaudhary 12:813e9e5f5ff6 1206 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
amirchaudhary 12:813e9e5f5ff6 1207 }
amirchaudhary 12:813e9e5f5ff6 1208 else
amirchaudhary 12:813e9e5f5ff6 1209 {
amirchaudhary 12:813e9e5f5ff6 1210 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
amirchaudhary 12:813e9e5f5ff6 1211 }
amirchaudhary 12:813e9e5f5ff6 1212 ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
amirchaudhary 12:813e9e5f5ff6 1213 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
amirchaudhary 12:813e9e5f5ff6 1214 }
amirchaudhary 12:813e9e5f5ff6 1215 else
amirchaudhary 12:813e9e5f5ff6 1216 {
amirchaudhary 12:813e9e5f5ff6 1217 ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
amirchaudhary 12:813e9e5f5ff6 1218 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
amirchaudhary 12:813e9e5f5ff6 1219 }
amirchaudhary 12:813e9e5f5ff6 1220
amirchaudhary 12:813e9e5f5ff6 1221 rxTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 1222
amirchaudhary 12:813e9e5f5ff6 1223 if( this->settings.Fsk.RxContinuous == false )
amirchaudhary 12:813e9e5f5ff6 1224 {
amirchaudhary 12:813e9e5f5ff6 1225 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 1226 rxTimeoutSyncWord.detach( );
amirchaudhary 12:813e9e5f5ff6 1227 }
amirchaudhary 12:813e9e5f5ff6 1228 else
amirchaudhary 12:813e9e5f5ff6 1229 {
amirchaudhary 12:813e9e5f5ff6 1230 // Continuous mode restart Rx chain
amirchaudhary 12:813e9e5f5ff6 1231 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
amirchaudhary 12:813e9e5f5ff6 1232 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
amirchaudhary 12:813e9e5f5ff6 1233 this->settings.Fsk.RxSingleTimeout * 1e3 );
amirchaudhary 12:813e9e5f5ff6 1234 }
amirchaudhary 12:813e9e5f5ff6 1235
amirchaudhary 12:813e9e5f5ff6 1236 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1237 {
amirchaudhary 12:813e9e5f5ff6 1238 this->RadioEvents->RxDone( rxtxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 );
amirchaudhary 12:813e9e5f5ff6 1239 }
amirchaudhary 12:813e9e5f5ff6 1240 this->settings.FskPacketHandler.PreambleDetected = false;
amirchaudhary 12:813e9e5f5ff6 1241 this->settings.FskPacketHandler.SyncWordDetected = false;
amirchaudhary 12:813e9e5f5ff6 1242 this->settings.FskPacketHandler.NbBytes = 0;
amirchaudhary 12:813e9e5f5ff6 1243 this->settings.FskPacketHandler.Size = 0;
amirchaudhary 12:813e9e5f5ff6 1244 break;
amirchaudhary 12:813e9e5f5ff6 1245 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1246 {
amirchaudhary 12:813e9e5f5ff6 1247 int8_t snr = 0;
amirchaudhary 12:813e9e5f5ff6 1248
amirchaudhary 12:813e9e5f5ff6 1249 // Clear Irq
amirchaudhary 12:813e9e5f5ff6 1250 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
amirchaudhary 12:813e9e5f5ff6 1251
amirchaudhary 12:813e9e5f5ff6 1252 irqFlags = Read( REG_LR_IRQFLAGS );
amirchaudhary 12:813e9e5f5ff6 1253 if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
amirchaudhary 12:813e9e5f5ff6 1254 {
amirchaudhary 12:813e9e5f5ff6 1255 // Clear Irq
amirchaudhary 12:813e9e5f5ff6 1256 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
amirchaudhary 12:813e9e5f5ff6 1257
amirchaudhary 12:813e9e5f5ff6 1258 if( this->settings.LoRa.RxContinuous == false )
amirchaudhary 12:813e9e5f5ff6 1259 {
amirchaudhary 12:813e9e5f5ff6 1260 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 1261 }
amirchaudhary 12:813e9e5f5ff6 1262 rxTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 1263
amirchaudhary 12:813e9e5f5ff6 1264 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1265 {
amirchaudhary 12:813e9e5f5ff6 1266 this->RadioEvents->RxError( );
amirchaudhary 12:813e9e5f5ff6 1267 }
amirchaudhary 12:813e9e5f5ff6 1268 break;
amirchaudhary 12:813e9e5f5ff6 1269 }
amirchaudhary 12:813e9e5f5ff6 1270
amirchaudhary 12:813e9e5f5ff6 1271 this->settings.LoRaPacketHandler.SnrValue = Read( REG_LR_PKTSNRVALUE );
amirchaudhary 12:813e9e5f5ff6 1272 if( this->settings.LoRaPacketHandler.SnrValue & 0x80 ) // The SNR sign bit is 1
amirchaudhary 12:813e9e5f5ff6 1273 {
amirchaudhary 12:813e9e5f5ff6 1274 // Invert and divide by 4
amirchaudhary 12:813e9e5f5ff6 1275 snr = ( ( ~this->settings.LoRaPacketHandler.SnrValue + 1 ) & 0xFF ) >> 2;
amirchaudhary 12:813e9e5f5ff6 1276 snr = -snr;
amirchaudhary 12:813e9e5f5ff6 1277 }
amirchaudhary 12:813e9e5f5ff6 1278 else
amirchaudhary 12:813e9e5f5ff6 1279 {
amirchaudhary 12:813e9e5f5ff6 1280 // Divide by 4
amirchaudhary 12:813e9e5f5ff6 1281 snr = ( this->settings.LoRaPacketHandler.SnrValue & 0xFF ) >> 2;
amirchaudhary 12:813e9e5f5ff6 1282 }
amirchaudhary 12:813e9e5f5ff6 1283
amirchaudhary 12:813e9e5f5ff6 1284 int16_t rssi = Read( REG_LR_PKTRSSIVALUE );
amirchaudhary 12:813e9e5f5ff6 1285 if( snr < 0 )
amirchaudhary 12:813e9e5f5ff6 1286 {
amirchaudhary 12:813e9e5f5ff6 1287 if( this->settings.Channel > RF_MID_BAND_THRESH )
amirchaudhary 12:813e9e5f5ff6 1288 {
amirchaudhary 12:813e9e5f5ff6 1289 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 ) +
amirchaudhary 12:813e9e5f5ff6 1290 snr;
amirchaudhary 12:813e9e5f5ff6 1291 }
amirchaudhary 12:813e9e5f5ff6 1292 else
amirchaudhary 12:813e9e5f5ff6 1293 {
amirchaudhary 12:813e9e5f5ff6 1294 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 ) +
amirchaudhary 12:813e9e5f5ff6 1295 snr;
amirchaudhary 12:813e9e5f5ff6 1296 }
amirchaudhary 12:813e9e5f5ff6 1297 }
amirchaudhary 12:813e9e5f5ff6 1298 else
amirchaudhary 12:813e9e5f5ff6 1299 {
amirchaudhary 12:813e9e5f5ff6 1300 if( this->settings.Channel > RF_MID_BAND_THRESH )
amirchaudhary 12:813e9e5f5ff6 1301 {
amirchaudhary 12:813e9e5f5ff6 1302 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 );
amirchaudhary 12:813e9e5f5ff6 1303 }
amirchaudhary 12:813e9e5f5ff6 1304 else
amirchaudhary 12:813e9e5f5ff6 1305 {
amirchaudhary 12:813e9e5f5ff6 1306 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 );
amirchaudhary 12:813e9e5f5ff6 1307 }
amirchaudhary 12:813e9e5f5ff6 1308 }
amirchaudhary 12:813e9e5f5ff6 1309
amirchaudhary 12:813e9e5f5ff6 1310 this->settings.LoRaPacketHandler.Size = Read( REG_LR_RXNBBYTES );
amirchaudhary 12:813e9e5f5ff6 1311 ReadFifo( rxtxBuffer, this->settings.LoRaPacketHandler.Size );
amirchaudhary 12:813e9e5f5ff6 1312
amirchaudhary 12:813e9e5f5ff6 1313 if( this->settings.LoRa.RxContinuous == false )
amirchaudhary 12:813e9e5f5ff6 1314 {
amirchaudhary 12:813e9e5f5ff6 1315 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 1316 }
amirchaudhary 12:813e9e5f5ff6 1317 rxTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 1318
amirchaudhary 12:813e9e5f5ff6 1319 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1320 {
amirchaudhary 12:813e9e5f5ff6 1321 this->RadioEvents->RxDone( rxtxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue );
amirchaudhary 12:813e9e5f5ff6 1322 }
amirchaudhary 12:813e9e5f5ff6 1323 }
amirchaudhary 12:813e9e5f5ff6 1324 break;
amirchaudhary 12:813e9e5f5ff6 1325 default:
amirchaudhary 12:813e9e5f5ff6 1326 break;
amirchaudhary 12:813e9e5f5ff6 1327 }
amirchaudhary 12:813e9e5f5ff6 1328 break;
amirchaudhary 12:813e9e5f5ff6 1329 case RF_TX_RUNNING:
amirchaudhary 12:813e9e5f5ff6 1330 txTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 1331 // TxDone interrupt
amirchaudhary 12:813e9e5f5ff6 1332 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1333 {
amirchaudhary 12:813e9e5f5ff6 1334 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1335 // Clear Irq
amirchaudhary 12:813e9e5f5ff6 1336 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
amirchaudhary 12:813e9e5f5ff6 1337 // Intentional fall through
amirchaudhary 12:813e9e5f5ff6 1338 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1339 default:
amirchaudhary 12:813e9e5f5ff6 1340 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 1341 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxDone != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1342 {
amirchaudhary 12:813e9e5f5ff6 1343 this->RadioEvents->TxDone( );
amirchaudhary 12:813e9e5f5ff6 1344 }
amirchaudhary 12:813e9e5f5ff6 1345 break;
amirchaudhary 12:813e9e5f5ff6 1346 }
amirchaudhary 12:813e9e5f5ff6 1347 break;
amirchaudhary 12:813e9e5f5ff6 1348 default:
amirchaudhary 12:813e9e5f5ff6 1349 break;
amirchaudhary 12:813e9e5f5ff6 1350 }
amirchaudhary 12:813e9e5f5ff6 1351 }
amirchaudhary 12:813e9e5f5ff6 1352
amirchaudhary 12:813e9e5f5ff6 1353 void SX1276::OnDio1Irq( void )
amirchaudhary 12:813e9e5f5ff6 1354 {
amirchaudhary 12:813e9e5f5ff6 1355 switch( this->settings.State )
amirchaudhary 12:813e9e5f5ff6 1356 {
amirchaudhary 12:813e9e5f5ff6 1357 case RF_RX_RUNNING:
amirchaudhary 12:813e9e5f5ff6 1358 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1359 {
amirchaudhary 12:813e9e5f5ff6 1360 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1361 // FifoLevel interrupt
amirchaudhary 12:813e9e5f5ff6 1362 // Read received packet size
amirchaudhary 12:813e9e5f5ff6 1363 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
amirchaudhary 12:813e9e5f5ff6 1364 {
amirchaudhary 12:813e9e5f5ff6 1365 if( this->settings.Fsk.FixLen == false )
amirchaudhary 12:813e9e5f5ff6 1366 {
amirchaudhary 12:813e9e5f5ff6 1367 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
amirchaudhary 12:813e9e5f5ff6 1368 }
amirchaudhary 12:813e9e5f5ff6 1369 else
amirchaudhary 12:813e9e5f5ff6 1370 {
amirchaudhary 12:813e9e5f5ff6 1371 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
amirchaudhary 12:813e9e5f5ff6 1372 }
amirchaudhary 12:813e9e5f5ff6 1373 }
amirchaudhary 12:813e9e5f5ff6 1374
amirchaudhary 12:813e9e5f5ff6 1375 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.FifoThresh )
amirchaudhary 12:813e9e5f5ff6 1376 {
amirchaudhary 12:813e9e5f5ff6 1377 ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.FifoThresh );
amirchaudhary 12:813e9e5f5ff6 1378 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.FifoThresh;
amirchaudhary 12:813e9e5f5ff6 1379 }
amirchaudhary 12:813e9e5f5ff6 1380 else
amirchaudhary 12:813e9e5f5ff6 1381 {
amirchaudhary 12:813e9e5f5ff6 1382 ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
amirchaudhary 12:813e9e5f5ff6 1383 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
amirchaudhary 12:813e9e5f5ff6 1384 }
amirchaudhary 12:813e9e5f5ff6 1385 break;
amirchaudhary 12:813e9e5f5ff6 1386 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1387 // Sync time out
amirchaudhary 12:813e9e5f5ff6 1388 rxTimeoutTimer.detach( );
amirchaudhary 12:813e9e5f5ff6 1389 // Clear Irq
amirchaudhary 12:813e9e5f5ff6 1390 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT );
amirchaudhary 12:813e9e5f5ff6 1391
amirchaudhary 12:813e9e5f5ff6 1392 this->settings.State = RF_IDLE;
amirchaudhary 12:813e9e5f5ff6 1393 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1394 {
amirchaudhary 12:813e9e5f5ff6 1395 this->RadioEvents->RxTimeout( );
amirchaudhary 12:813e9e5f5ff6 1396 }
amirchaudhary 12:813e9e5f5ff6 1397 break;
amirchaudhary 12:813e9e5f5ff6 1398 default:
amirchaudhary 12:813e9e5f5ff6 1399 break;
amirchaudhary 12:813e9e5f5ff6 1400 }
amirchaudhary 12:813e9e5f5ff6 1401 break;
amirchaudhary 12:813e9e5f5ff6 1402 case RF_TX_RUNNING:
amirchaudhary 12:813e9e5f5ff6 1403 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1404 {
amirchaudhary 12:813e9e5f5ff6 1405 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1406 // FifoEmpty interrupt
amirchaudhary 12:813e9e5f5ff6 1407 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.ChunkSize )
amirchaudhary 12:813e9e5f5ff6 1408 {
amirchaudhary 12:813e9e5f5ff6 1409 WriteFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.ChunkSize );
amirchaudhary 12:813e9e5f5ff6 1410 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
amirchaudhary 12:813e9e5f5ff6 1411 }
amirchaudhary 12:813e9e5f5ff6 1412 else
amirchaudhary 12:813e9e5f5ff6 1413 {
amirchaudhary 12:813e9e5f5ff6 1414 // Write the last chunk of data
amirchaudhary 12:813e9e5f5ff6 1415 WriteFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
amirchaudhary 12:813e9e5f5ff6 1416 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes;
amirchaudhary 12:813e9e5f5ff6 1417 }
amirchaudhary 12:813e9e5f5ff6 1418 break;
amirchaudhary 12:813e9e5f5ff6 1419 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1420 break;
amirchaudhary 12:813e9e5f5ff6 1421 default:
amirchaudhary 12:813e9e5f5ff6 1422 break;
amirchaudhary 12:813e9e5f5ff6 1423 }
amirchaudhary 12:813e9e5f5ff6 1424 break;
amirchaudhary 12:813e9e5f5ff6 1425 default:
amirchaudhary 12:813e9e5f5ff6 1426 break;
amirchaudhary 12:813e9e5f5ff6 1427 }
amirchaudhary 12:813e9e5f5ff6 1428 }
amirchaudhary 12:813e9e5f5ff6 1429
amirchaudhary 12:813e9e5f5ff6 1430 void SX1276::OnDio2Irq( void )
amirchaudhary 12:813e9e5f5ff6 1431 {
amirchaudhary 12:813e9e5f5ff6 1432 switch( this->settings.State )
amirchaudhary 12:813e9e5f5ff6 1433 {
amirchaudhary 12:813e9e5f5ff6 1434 case RF_RX_RUNNING:
amirchaudhary 12:813e9e5f5ff6 1435 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1436 {
amirchaudhary 12:813e9e5f5ff6 1437 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1438 // Checks if DIO4 is connected. If it is not PreambleDtected is set to true.
amirchaudhary 12:813e9e5f5ff6 1439 if( this->dioIrq[4] == NULL )
amirchaudhary 12:813e9e5f5ff6 1440 {
amirchaudhary 12:813e9e5f5ff6 1441 this->settings.FskPacketHandler.PreambleDetected = true;
amirchaudhary 12:813e9e5f5ff6 1442 }
amirchaudhary 12:813e9e5f5ff6 1443
amirchaudhary 12:813e9e5f5ff6 1444 if( ( this->settings.FskPacketHandler.PreambleDetected == true ) && ( this->settings.FskPacketHandler.SyncWordDetected == false ) )
amirchaudhary 12:813e9e5f5ff6 1445 {
amirchaudhary 12:813e9e5f5ff6 1446 rxTimeoutSyncWord.detach( );
amirchaudhary 12:813e9e5f5ff6 1447
amirchaudhary 12:813e9e5f5ff6 1448 this->settings.FskPacketHandler.SyncWordDetected = true;
amirchaudhary 12:813e9e5f5ff6 1449
amirchaudhary 12:813e9e5f5ff6 1450 this->settings.FskPacketHandler.RssiValue = -( Read( REG_RSSIVALUE ) >> 1 );
amirchaudhary 12:813e9e5f5ff6 1451
amirchaudhary 12:813e9e5f5ff6 1452 this->settings.FskPacketHandler.AfcValue = ( int32_t )( double )( ( ( uint16_t )Read( REG_AFCMSB ) << 8 ) |
amirchaudhary 12:813e9e5f5ff6 1453 ( uint16_t )Read( REG_AFCLSB ) ) *
amirchaudhary 12:813e9e5f5ff6 1454 ( double )FREQ_STEP;
amirchaudhary 12:813e9e5f5ff6 1455 this->settings.FskPacketHandler.RxGain = ( Read( REG_LNA ) >> 5 ) & 0x07;
amirchaudhary 12:813e9e5f5ff6 1456 }
amirchaudhary 12:813e9e5f5ff6 1457 break;
amirchaudhary 12:813e9e5f5ff6 1458 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1459 if( this->settings.LoRa.FreqHopOn == true )
amirchaudhary 12:813e9e5f5ff6 1460 {
amirchaudhary 12:813e9e5f5ff6 1461 // Clear Irq
amirchaudhary 12:813e9e5f5ff6 1462 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
amirchaudhary 12:813e9e5f5ff6 1463
amirchaudhary 12:813e9e5f5ff6 1464 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1465 {
amirchaudhary 12:813e9e5f5ff6 1466 this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
amirchaudhary 12:813e9e5f5ff6 1467 }
amirchaudhary 12:813e9e5f5ff6 1468 }
amirchaudhary 12:813e9e5f5ff6 1469 break;
amirchaudhary 12:813e9e5f5ff6 1470 default:
amirchaudhary 12:813e9e5f5ff6 1471 break;
amirchaudhary 12:813e9e5f5ff6 1472 }
amirchaudhary 12:813e9e5f5ff6 1473 break;
amirchaudhary 12:813e9e5f5ff6 1474 case RF_TX_RUNNING:
amirchaudhary 12:813e9e5f5ff6 1475 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1476 {
amirchaudhary 12:813e9e5f5ff6 1477 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1478 break;
amirchaudhary 12:813e9e5f5ff6 1479 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1480 if( this->settings.LoRa.FreqHopOn == true )
amirchaudhary 12:813e9e5f5ff6 1481 {
amirchaudhary 12:813e9e5f5ff6 1482 // Clear Irq
amirchaudhary 12:813e9e5f5ff6 1483 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
amirchaudhary 12:813e9e5f5ff6 1484
amirchaudhary 12:813e9e5f5ff6 1485 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1486 {
amirchaudhary 12:813e9e5f5ff6 1487 this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
amirchaudhary 12:813e9e5f5ff6 1488 }
amirchaudhary 12:813e9e5f5ff6 1489 }
amirchaudhary 12:813e9e5f5ff6 1490 break;
amirchaudhary 12:813e9e5f5ff6 1491 default:
amirchaudhary 12:813e9e5f5ff6 1492 break;
amirchaudhary 12:813e9e5f5ff6 1493 }
amirchaudhary 12:813e9e5f5ff6 1494 break;
amirchaudhary 12:813e9e5f5ff6 1495 default:
amirchaudhary 12:813e9e5f5ff6 1496 break;
amirchaudhary 12:813e9e5f5ff6 1497 }
amirchaudhary 12:813e9e5f5ff6 1498 }
amirchaudhary 12:813e9e5f5ff6 1499
amirchaudhary 12:813e9e5f5ff6 1500 void SX1276::OnDio3Irq( void )
amirchaudhary 12:813e9e5f5ff6 1501 {
amirchaudhary 12:813e9e5f5ff6 1502 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1503 {
amirchaudhary 12:813e9e5f5ff6 1504 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1505 break;
amirchaudhary 12:813e9e5f5ff6 1506 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1507 if( ( Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
amirchaudhary 12:813e9e5f5ff6 1508 {
amirchaudhary 12:813e9e5f5ff6 1509 // Clear Irq
amirchaudhary 12:813e9e5f5ff6 1510 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
amirchaudhary 12:813e9e5f5ff6 1511 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1512 {
amirchaudhary 12:813e9e5f5ff6 1513 this->RadioEvents->CadDone( true );
amirchaudhary 12:813e9e5f5ff6 1514 }
amirchaudhary 12:813e9e5f5ff6 1515 }
amirchaudhary 12:813e9e5f5ff6 1516 else
amirchaudhary 12:813e9e5f5ff6 1517 {
amirchaudhary 12:813e9e5f5ff6 1518 // Clear Irq
amirchaudhary 12:813e9e5f5ff6 1519 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
amirchaudhary 12:813e9e5f5ff6 1520 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
amirchaudhary 12:813e9e5f5ff6 1521 {
amirchaudhary 12:813e9e5f5ff6 1522 this->RadioEvents->CadDone( false );
amirchaudhary 12:813e9e5f5ff6 1523 }
amirchaudhary 12:813e9e5f5ff6 1524 }
amirchaudhary 12:813e9e5f5ff6 1525 break;
amirchaudhary 12:813e9e5f5ff6 1526 default:
amirchaudhary 12:813e9e5f5ff6 1527 break;
amirchaudhary 12:813e9e5f5ff6 1528 }
amirchaudhary 12:813e9e5f5ff6 1529 }
amirchaudhary 12:813e9e5f5ff6 1530
amirchaudhary 12:813e9e5f5ff6 1531 void SX1276::OnDio4Irq( void )
amirchaudhary 12:813e9e5f5ff6 1532 {
amirchaudhary 12:813e9e5f5ff6 1533 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1534 {
amirchaudhary 12:813e9e5f5ff6 1535 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1536 {
amirchaudhary 12:813e9e5f5ff6 1537 if( this->settings.FskPacketHandler.PreambleDetected == false )
amirchaudhary 12:813e9e5f5ff6 1538 {
amirchaudhary 12:813e9e5f5ff6 1539 this->settings.FskPacketHandler.PreambleDetected = true;
amirchaudhary 12:813e9e5f5ff6 1540 }
amirchaudhary 12:813e9e5f5ff6 1541 }
amirchaudhary 12:813e9e5f5ff6 1542 break;
amirchaudhary 12:813e9e5f5ff6 1543 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1544 break;
amirchaudhary 12:813e9e5f5ff6 1545 default:
amirchaudhary 12:813e9e5f5ff6 1546 break;
amirchaudhary 12:813e9e5f5ff6 1547 }
amirchaudhary 12:813e9e5f5ff6 1548 }
amirchaudhary 12:813e9e5f5ff6 1549
amirchaudhary 12:813e9e5f5ff6 1550 void SX1276::OnDio5Irq( void )
amirchaudhary 12:813e9e5f5ff6 1551 {
amirchaudhary 12:813e9e5f5ff6 1552 switch( this->settings.Modem )
amirchaudhary 12:813e9e5f5ff6 1553 {
amirchaudhary 12:813e9e5f5ff6 1554 case MODEM_FSK:
amirchaudhary 12:813e9e5f5ff6 1555 break;
amirchaudhary 12:813e9e5f5ff6 1556 case MODEM_LORA:
amirchaudhary 12:813e9e5f5ff6 1557 break;
amirchaudhary 12:813e9e5f5ff6 1558 default:
amirchaudhary 12:813e9e5f5ff6 1559 break;
amirchaudhary 12:813e9e5f5ff6 1560 }
amirchaudhary 12:813e9e5f5ff6 1561 }