SX1276GenericLib to support sx1276 bassed LoRa modules, including HopeRF RFM95, Murata CMWX1ZZABZ and Semtech SX1276MB1MAS/SX1276MB1LAS modules

Dependents:   DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_USB_Rx ... more

Fork of SX1276Lib by Semtech

Committer:
mluis
Date:
Thu Jan 22 12:47:47 2015 +0000
Revision:
15:04374b1c33fa
Parent:
14:8552d0b840be
Child:
16:d447f8d2d2d6
Enabled by default the whitening when using FSK modem.; Added an invalid bandwidth to the Bandwidths table in order to avoid an error when selecting 250 kHz bandwidth when using FSK modem.

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