1111

Fork of SX1276Lib by Semtech

Committer:
GregCr
Date:
Mon Aug 18 14:24:46 2014 +0000
Revision:
0:e6ceb13d2d05
Child:
4:f0ce52e94d3f
SX1276 Library first attempt

Who changed what in which revision?

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