1

Committer:
floatlei
Date:
Sat Oct 08 02:35:14 2016 +0000
Revision:
0:7e14d7c443f1
11

Who changed what in which revision?

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