SX1276Lib updated in order to be RTOS aware

Fork of SX1276Lib by Semtech

Committer:
Lorenzo Maiorfi
Date:
Sat Mar 03 18:08:11 2018 +0100
Revision:
31:a9575b07944d
Parent:
27:8a37a9362714
Fix debug

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