Driver for the SX1276 RF Transceiver

Dependents:   LoRa_PIR LoRaWAN-lmic-app SX1276PingPong LoRaWAN-lmic-app ... more

Committer:
mverdy
Date:
Tue Oct 16 15:50:04 2018 +0000
Revision:
27:737e89f8d4f3
Parent:
26:d09a8ef807e2
Remove debug folder as it is now available in mbed library

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