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

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

Fork of SX1276Lib by Semtech

Committer:
Helmut Tschemernjak
Date:
Mon May 01 18:56:35 2017 +0200
Revision:
33:5db0d1e716b1
Parent:
31:e50929bd3f32
Child:
34:07e89f23c734
Added more typedefs for bandwidth, coding rate, data rate, etc.
This makes the maintenance and debugging much easier.

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[] =
Helmut Tschemernjak 31:e50929bd3f32 18 {
GregCr 0:e6ceb13d2d05 19 { 2600 , 0x17 },
GregCr 0:e6ceb13d2d05 20 { 3100 , 0x0F },
GregCr 0:e6ceb13d2d05 21 { 3900 , 0x07 },
GregCr 0:e6ceb13d2d05 22 { 5200 , 0x16 },
GregCr 0:e6ceb13d2d05 23 { 6300 , 0x0E },
GregCr 0:e6ceb13d2d05 24 { 7800 , 0x06 },
GregCr 0:e6ceb13d2d05 25 { 10400 , 0x15 },
GregCr 0:e6ceb13d2d05 26 { 12500 , 0x0D },
GregCr 0:e6ceb13d2d05 27 { 15600 , 0x05 },
GregCr 0:e6ceb13d2d05 28 { 20800 , 0x14 },
GregCr 0:e6ceb13d2d05 29 { 25000 , 0x0C },
GregCr 0:e6ceb13d2d05 30 { 31300 , 0x04 },
GregCr 0:e6ceb13d2d05 31 { 41700 , 0x13 },
GregCr 0:e6ceb13d2d05 32 { 50000 , 0x0B },
GregCr 0:e6ceb13d2d05 33 { 62500 , 0x03 },
GregCr 0:e6ceb13d2d05 34 { 83333 , 0x12 },
GregCr 0:e6ceb13d2d05 35 { 100000, 0x0A },
GregCr 0:e6ceb13d2d05 36 { 125000, 0x02 },
GregCr 0:e6ceb13d2d05 37 { 166700, 0x11 },
GregCr 0:e6ceb13d2d05 38 { 200000, 0x09 },
mluis 15:04374b1c33fa 39 { 250000, 0x01 },
Helmut Tschemernjak 31:e50929bd3f32 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 );
GregCr 23:1e143575df0f 55 this->rxtxBuffer = new uint8_t[RX_BUFFER_SIZE];
mluis 13:618826a997e2 56
mluis 21:2e496deb7858 57 this->RadioEvents = events;
mluis 21:2e496deb7858 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 13:618826a997e2 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 {
GregCr 23:1e143575df0f 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 25:3778e6204cc1 99
GregCr 0:e6ceb13d2d05 100 SetModem( modem );
GregCr 0:e6ceb13d2d05 101
GregCr 0:e6ceb13d2d05 102 SetChannel( freq );
mluis 25:3778e6204cc1 103
GregCr 0:e6ceb13d2d05 104 SetOpMode( RF_OPMODE_RECEIVER );
GregCr 0:e6ceb13d2d05 105
GregCr 4:f0ce52e94d3f 106 wait_ms( 1 );
mluis 25:3778e6204cc1 107
GregCr 0:e6ceb13d2d05 108 rssi = GetRssi( modem );
mluis 25:3778e6204cc1 109
GregCr 0:e6ceb13d2d05 110 Sleep( );
mluis 25:3778e6204cc1 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 25:3778e6204cc1 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
Helmut Tschemernjak 31:e50929bd3f32 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;
Helmut Tschemernjak 31:e50929bd3f32 238 this->settings.Fsk.RxSingleTimeout = symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1e3;
Helmut Tschemernjak 31:e50929bd3f32 239
mluis 25:3778e6204cc1 240
GregCr 0:e6ceb13d2d05 241 datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
GregCr 0:e6ceb13d2d05 242 Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
GregCr 0:e6ceb13d2d05 243 Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
GregCr 0:e6ceb13d2d05 244
GregCr 0:e6ceb13d2d05 245 Write( REG_RXBW, GetFskBandwidthRegValue( bandwidth ) );
GregCr 0:e6ceb13d2d05 246 Write( REG_AFCBW, GetFskBandwidthRegValue( bandwidthAfc ) );
GregCr 0:e6ceb13d2d05 247
mluis 14:8552d0b840be 248 Write( REG_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
mluis 14:8552d0b840be 249 Write( REG_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
mluis 25:3778e6204cc1 250
mluis 22:7f3aab69cca9 251 if( fixLen == 1 )
mluis 22:7f3aab69cca9 252 {
mluis 22:7f3aab69cca9 253 Write( REG_PAYLOADLENGTH, payloadLen );
mluis 22:7f3aab69cca9 254 }
GregCr 23:1e143575df0f 255 else
GregCr 23:1e143575df0f 256 {
mluis 25:3778e6204cc1 257 Write( REG_PAYLOADLENGTH, 0xFF ); // Set payload length to the maximum
GregCr 23:1e143575df0f 258 }
GregCr 23:1e143575df0f 259
GregCr 0:e6ceb13d2d05 260 Write( REG_PACKETCONFIG1,
Helmut Tschemernjak 31:e50929bd3f32 261 ( Read( REG_PACKETCONFIG1 ) &
GregCr 0:e6ceb13d2d05 262 RF_PACKETCONFIG1_CRC_MASK &
GregCr 0:e6ceb13d2d05 263 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
GregCr 0:e6ceb13d2d05 264 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
GregCr 0:e6ceb13d2d05 265 ( crcOn << 4 ) );
Helmut Tschemernjak 31:e50929bd3f32 266 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
GregCr 0:e6ceb13d2d05 267 }
GregCr 0:e6ceb13d2d05 268 break;
GregCr 0:e6ceb13d2d05 269 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 270 {
Helmut Tschemernjak 33:5db0d1e716b1 271 if( bandwidth > LORA_BANKWIDTH_500kHz )
GregCr 0:e6ceb13d2d05 272 {
GregCr 0:e6ceb13d2d05 273 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
GregCr 0:e6ceb13d2d05 274 while( 1 );
GregCr 0:e6ceb13d2d05 275 }
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
Helmut Tschemernjak 33:5db0d1e716b1 288 if( datarate > LORA_SF12 )
GregCr 0:e6ceb13d2d05 289 {
Helmut Tschemernjak 33:5db0d1e716b1 290 datarate = LORA_SF12;
GregCr 0:e6ceb13d2d05 291 }
Helmut Tschemernjak 33:5db0d1e716b1 292 else if( datarate < LORA_SF6 )
GregCr 0:e6ceb13d2d05 293 {
Helmut Tschemernjak 33:5db0d1e716b1 294 datarate = LORA_SF6;
GregCr 0:e6ceb13d2d05 295 }
mluis 25:3778e6204cc1 296
Helmut Tschemernjak 33:5db0d1e716b1 297 if( ( ( bandwidth == LORA_BANKWIDTH_125kHz ) && ( ( datarate == LORA_SF11 ) || ( datarate == LORA_SF12 ) ) ) ||
Helmut Tschemernjak 33:5db0d1e716b1 298 ( ( bandwidth == LORA_BANKWIDTH_250kHz ) && ( datarate == LORA_SF12 ) ) )
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
Helmut Tschemernjak 31:e50929bd3f32 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 25:3778e6204cc1 312 ( bandwidth << 4 ) | ( coderate << 1 ) |
GregCr 0:e6ceb13d2d05 313 fixLen );
mluis 25:3778e6204cc1 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
Helmut Tschemernjak 31:e50929bd3f32 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 25:3778e6204cc1 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
Helmut Tschemernjak 33:5db0d1e716b1 344 if( ( bandwidth == LORA_BANKWIDTH_500kHz ) && ( this->settings.Channel > RF_MID_BAND_THRESH ) )
mluis 22:7f3aab69cca9 345 {
mluis 25:3778e6204cc1 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 }
Helmut Tschemernjak 33:5db0d1e716b1 350 else if( bandwidth == LORA_BANKWIDTH_500kHz )
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 25:3778e6204cc1 361
Helmut Tschemernjak 33:5db0d1e716b1 362 if( datarate == LORA_SF6 )
GregCr 0:e6ceb13d2d05 363 {
Helmut Tschemernjak 31:e50929bd3f32 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 25:3778e6204cc1 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 );
Helmut Tschemernjak 31:e50929bd3f32 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 25:3778e6204cc1 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 25:3778e6204cc1 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 );
Helmut Tschemernjak 31:e50929bd3f32 392 SetRfTxPower( power );
GregCr 0:e6ceb13d2d05 393
Helmut Tschemernjak 31:e50929bd3f32 394 switch( modem )
GregCr 0:e6ceb13d2d05 395 {
GregCr 0:e6ceb13d2d05 396 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 397 {
GregCr 0:e6ceb13d2d05 398 this->settings.Fsk.Power = power;
GregCr 0:e6ceb13d2d05 399 this->settings.Fsk.Fdev = fdev;
GregCr 0:e6ceb13d2d05 400 this->settings.Fsk.Bandwidth = bandwidth;
GregCr 0:e6ceb13d2d05 401 this->settings.Fsk.Datarate = datarate;
GregCr 0:e6ceb13d2d05 402 this->settings.Fsk.PreambleLen = preambleLen;
GregCr 0:e6ceb13d2d05 403 this->settings.Fsk.FixLen = fixLen;
GregCr 0:e6ceb13d2d05 404 this->settings.Fsk.CrcOn = crcOn;
GregCr 0:e6ceb13d2d05 405 this->settings.Fsk.IqInverted = iqInverted;
GregCr 0:e6ceb13d2d05 406 this->settings.Fsk.TxTimeout = timeout;
mluis 25:3778e6204cc1 407
GregCr 0:e6ceb13d2d05 408 fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
GregCr 0:e6ceb13d2d05 409 Write( REG_FDEVMSB, ( uint8_t )( fdev >> 8 ) );
GregCr 0:e6ceb13d2d05 410 Write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) );
GregCr 0:e6ceb13d2d05 411
GregCr 0:e6ceb13d2d05 412 datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
GregCr 0:e6ceb13d2d05 413 Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
GregCr 0:e6ceb13d2d05 414 Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
GregCr 0:e6ceb13d2d05 415
GregCr 0:e6ceb13d2d05 416 Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
GregCr 0:e6ceb13d2d05 417 Write( REG_PREAMBLELSB, preambleLen & 0xFF );
GregCr 0:e6ceb13d2d05 418
GregCr 0:e6ceb13d2d05 419 Write( REG_PACKETCONFIG1,
mluis 25:3778e6204cc1 420 ( Read( REG_PACKETCONFIG1 ) &
GregCr 0:e6ceb13d2d05 421 RF_PACKETCONFIG1_CRC_MASK &
GregCr 0:e6ceb13d2d05 422 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
GregCr 0:e6ceb13d2d05 423 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
GregCr 0:e6ceb13d2d05 424 ( crcOn << 4 ) );
Helmut Tschemernjak 31:e50929bd3f32 425 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) | RF_PACKETCONFIG2_DATAMODE_PACKET ) );
GregCr 0:e6ceb13d2d05 426 }
GregCr 0:e6ceb13d2d05 427 break;
GregCr 0:e6ceb13d2d05 428 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 429 {
GregCr 0:e6ceb13d2d05 430 this->settings.LoRa.Power = power;
Helmut Tschemernjak 33:5db0d1e716b1 431 if( bandwidth > LORA_BANKWIDTH_500kHz )
GregCr 0:e6ceb13d2d05 432 {
GregCr 0:e6ceb13d2d05 433 // Fatal error: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
GregCr 0:e6ceb13d2d05 434 while( 1 );
GregCr 0:e6ceb13d2d05 435 }
GregCr 0:e6ceb13d2d05 436 this->settings.LoRa.Bandwidth = bandwidth;
GregCr 0:e6ceb13d2d05 437 this->settings.LoRa.Datarate = datarate;
GregCr 0:e6ceb13d2d05 438 this->settings.LoRa.Coderate = coderate;
GregCr 0:e6ceb13d2d05 439 this->settings.LoRa.PreambleLen = preambleLen;
GregCr 0:e6ceb13d2d05 440 this->settings.LoRa.FixLen = fixLen;
mluis 13:618826a997e2 441 this->settings.LoRa.FreqHopOn = freqHopOn;
mluis 13:618826a997e2 442 this->settings.LoRa.HopPeriod = hopPeriod;
mluis 22:7f3aab69cca9 443 this->settings.LoRa.CrcOn = crcOn;
GregCr 0:e6ceb13d2d05 444 this->settings.LoRa.IqInverted = iqInverted;
GregCr 0:e6ceb13d2d05 445 this->settings.LoRa.TxTimeout = timeout;
GregCr 0:e6ceb13d2d05 446
Helmut Tschemernjak 33:5db0d1e716b1 447 if( datarate > LORA_SF12 )
GregCr 0:e6ceb13d2d05 448 {
Helmut Tschemernjak 33:5db0d1e716b1 449 datarate = LORA_SF12;
GregCr 0:e6ceb13d2d05 450 }
Helmut Tschemernjak 33:5db0d1e716b1 451 else if( datarate < LORA_SF6 )
GregCr 0:e6ceb13d2d05 452 {
Helmut Tschemernjak 33:5db0d1e716b1 453 datarate = LORA_SF6;
GregCr 0:e6ceb13d2d05 454 }
Helmut Tschemernjak 33:5db0d1e716b1 455 if( ( ( bandwidth == LORA_BANKWIDTH_125kHz ) && ( ( datarate == LORA_SF11 ) || ( datarate == LORA_SF12 ) ) ) ||
Helmut Tschemernjak 33:5db0d1e716b1 456 ( ( bandwidth == LORA_BANKWIDTH_250kHz ) && ( datarate == LORA_SF12 ) ) )
GregCr 0:e6ceb13d2d05 457 {
GregCr 0:e6ceb13d2d05 458 this->settings.LoRa.LowDatarateOptimize = 0x01;
GregCr 0:e6ceb13d2d05 459 }
GregCr 0:e6ceb13d2d05 460 else
GregCr 0:e6ceb13d2d05 461 {
GregCr 0:e6ceb13d2d05 462 this->settings.LoRa.LowDatarateOptimize = 0x00;
GregCr 0:e6ceb13d2d05 463 }
mluis 22:7f3aab69cca9 464
GregCr 6:e7f02929cd3d 465 if( this->settings.LoRa.FreqHopOn == true )
GregCr 6:e7f02929cd3d 466 {
GregCr 6:e7f02929cd3d 467 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
GregCr 6:e7f02929cd3d 468 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
GregCr 6:e7f02929cd3d 469 }
mluis 22:7f3aab69cca9 470
mluis 25:3778e6204cc1 471 Write( REG_LR_MODEMCONFIG1,
GregCr 0:e6ceb13d2d05 472 ( Read( REG_LR_MODEMCONFIG1 ) &
GregCr 0:e6ceb13d2d05 473 RFLR_MODEMCONFIG1_BW_MASK &
GregCr 0:e6ceb13d2d05 474 RFLR_MODEMCONFIG1_CODINGRATE_MASK &
GregCr 0:e6ceb13d2d05 475 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) |
mluis 25:3778e6204cc1 476 ( bandwidth << 4 ) | ( coderate << 1 ) |
GregCr 0:e6ceb13d2d05 477 fixLen );
GregCr 0:e6ceb13d2d05 478
GregCr 0:e6ceb13d2d05 479 Write( REG_LR_MODEMCONFIG2,
GregCr 0:e6ceb13d2d05 480 ( Read( REG_LR_MODEMCONFIG2 ) &
GregCr 0:e6ceb13d2d05 481 RFLR_MODEMCONFIG2_SF_MASK &
GregCr 0:e6ceb13d2d05 482 RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) |
GregCr 0:e6ceb13d2d05 483 ( datarate << 4 ) | ( crcOn << 2 ) );
GregCr 0:e6ceb13d2d05 484
Helmut Tschemernjak 31:e50929bd3f32 485 Write( REG_LR_MODEMCONFIG3,
GregCr 0:e6ceb13d2d05 486 ( Read( REG_LR_MODEMCONFIG3 ) &
GregCr 0:e6ceb13d2d05 487 RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) |
GregCr 0:e6ceb13d2d05 488 ( this->settings.LoRa.LowDatarateOptimize << 3 ) );
mluis 25:3778e6204cc1 489
GregCr 0:e6ceb13d2d05 490 Write( REG_LR_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
GregCr 0:e6ceb13d2d05 491 Write( REG_LR_PREAMBLELSB, preambleLen & 0xFF );
mluis 25:3778e6204cc1 492
Helmut Tschemernjak 33:5db0d1e716b1 493 if( datarate == LORA_SF6 )
GregCr 0:e6ceb13d2d05 494 {
mluis 25:3778e6204cc1 495 Write( REG_LR_DETECTOPTIMIZE,
GregCr 0:e6ceb13d2d05 496 ( Read( REG_LR_DETECTOPTIMIZE ) &
GregCr 0:e6ceb13d2d05 497 RFLR_DETECTIONOPTIMIZE_MASK ) |
GregCr 0:e6ceb13d2d05 498 RFLR_DETECTIONOPTIMIZE_SF6 );
mluis 25:3778e6204cc1 499 Write( REG_LR_DETECTIONTHRESHOLD,
GregCr 0:e6ceb13d2d05 500 RFLR_DETECTIONTHRESH_SF6 );
GregCr 0:e6ceb13d2d05 501 }
GregCr 0:e6ceb13d2d05 502 else
GregCr 0:e6ceb13d2d05 503 {
GregCr 0:e6ceb13d2d05 504 Write( REG_LR_DETECTOPTIMIZE,
GregCr 0:e6ceb13d2d05 505 ( Read( REG_LR_DETECTOPTIMIZE ) &
GregCr 0:e6ceb13d2d05 506 RFLR_DETECTIONOPTIMIZE_MASK ) |
GregCr 0:e6ceb13d2d05 507 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
mluis 25:3778e6204cc1 508 Write( REG_LR_DETECTIONTHRESHOLD,
GregCr 0:e6ceb13d2d05 509 RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
GregCr 0:e6ceb13d2d05 510 }
GregCr 0:e6ceb13d2d05 511 }
GregCr 0:e6ceb13d2d05 512 break;
GregCr 0:e6ceb13d2d05 513 }
GregCr 0:e6ceb13d2d05 514 }
GregCr 0:e6ceb13d2d05 515
Helmut Tschemernjak 31:e50929bd3f32 516 uint32_t SX1276::TimeOnAir( RadioModems_t modem, uint8_t pktLen )
GregCr 0:e6ceb13d2d05 517 {
mluis 22:7f3aab69cca9 518 uint32_t airTime = 0;
GregCr 0:e6ceb13d2d05 519
GregCr 0:e6ceb13d2d05 520 switch( modem )
GregCr 0:e6ceb13d2d05 521 {
GregCr 0:e6ceb13d2d05 522 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 523 {
mluis 22:7f3aab69cca9 524 airTime = rint( ( 8 * ( this->settings.Fsk.PreambleLen +
GregCr 0:e6ceb13d2d05 525 ( ( Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
GregCr 0:e6ceb13d2d05 526 ( ( this->settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
GregCr 0:e6ceb13d2d05 527 ( ( ( Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
GregCr 0:e6ceb13d2d05 528 pktLen +
GregCr 0:e6ceb13d2d05 529 ( ( this->settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) /
Helmut Tschemernjak 31:e50929bd3f32 530 this->settings.Fsk.Datarate ) * 1e3 );
GregCr 0:e6ceb13d2d05 531 }
GregCr 0:e6ceb13d2d05 532 break;
GregCr 0:e6ceb13d2d05 533 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 534 {
GregCr 0:e6ceb13d2d05 535 double bw = 0.0;
GregCr 0:e6ceb13d2d05 536 // REMARK: When using LoRa modem only bandwidths 125, 250 and 500 kHz are supported
GregCr 0:e6ceb13d2d05 537 switch( this->settings.LoRa.Bandwidth )
GregCr 0:e6ceb13d2d05 538 {
Helmut Tschemernjak 33:5db0d1e716b1 539 case LORA_BANKWIDTH_7kHz: // 7.8 kHz
Helmut Tschemernjak 33:5db0d1e716b1 540 bw = 78e2;
Helmut Tschemernjak 33:5db0d1e716b1 541 break;
Helmut Tschemernjak 33:5db0d1e716b1 542 case LORA_BANKWIDTH_10kHz: // 10.4 kHz
Helmut Tschemernjak 33:5db0d1e716b1 543 bw = 104e2;
Helmut Tschemernjak 33:5db0d1e716b1 544 break;
Helmut Tschemernjak 33:5db0d1e716b1 545 case LORA_BANKWIDTH_15kHz: // 15.6 kHz
Helmut Tschemernjak 33:5db0d1e716b1 546 bw = 156e2;
Helmut Tschemernjak 33:5db0d1e716b1 547 break;
Helmut Tschemernjak 33:5db0d1e716b1 548 case LORA_BANKWIDTH_20kHz: // 20.8 kHz
Helmut Tschemernjak 33:5db0d1e716b1 549 bw = 208e2;
Helmut Tschemernjak 33:5db0d1e716b1 550 break;
Helmut Tschemernjak 33:5db0d1e716b1 551 case LORA_BANKWIDTH_31kHz: // 31.2 kHz
Helmut Tschemernjak 33:5db0d1e716b1 552 bw = 312e2;
Helmut Tschemernjak 33:5db0d1e716b1 553 break;
Helmut Tschemernjak 33:5db0d1e716b1 554 case LORA_BANKWIDTH_41kHz: // 41.4 kHz
Helmut Tschemernjak 33:5db0d1e716b1 555 bw = 414e2;
Helmut Tschemernjak 33:5db0d1e716b1 556 break;
Helmut Tschemernjak 33:5db0d1e716b1 557 case LORA_BANKWIDTH_62kHz: // 62.5 kHz
Helmut Tschemernjak 33:5db0d1e716b1 558 bw = 625e2;
Helmut Tschemernjak 33:5db0d1e716b1 559 break;
Helmut Tschemernjak 33:5db0d1e716b1 560 case LORA_BANKWIDTH_125kHz: // 125 kHz
GregCr 0:e6ceb13d2d05 561 bw = 125e3;
GregCr 0:e6ceb13d2d05 562 break;
Helmut Tschemernjak 33:5db0d1e716b1 563 case LORA_BANKWIDTH_250kHz: // 250 kHz
GregCr 0:e6ceb13d2d05 564 bw = 250e3;
GregCr 0:e6ceb13d2d05 565 break;
Helmut Tschemernjak 33:5db0d1e716b1 566 case LORA_BANKWIDTH_500kHz: // 500 kHz
GregCr 0:e6ceb13d2d05 567 bw = 500e3;
GregCr 0:e6ceb13d2d05 568 break;
GregCr 0:e6ceb13d2d05 569 }
GregCr 0:e6ceb13d2d05 570
GregCr 0:e6ceb13d2d05 571 // Symbol rate : time for one symbol (secs)
GregCr 0:e6ceb13d2d05 572 double rs = bw / ( 1 << this->settings.LoRa.Datarate );
GregCr 0:e6ceb13d2d05 573 double ts = 1 / rs;
GregCr 0:e6ceb13d2d05 574 // time of preamble
GregCr 0:e6ceb13d2d05 575 double tPreamble = ( this->settings.LoRa.PreambleLen + 4.25 ) * ts;
GregCr 0:e6ceb13d2d05 576 // Symbol length of payload and time
GregCr 0:e6ceb13d2d05 577 double tmp = ceil( ( 8 * pktLen - 4 * this->settings.LoRa.Datarate +
GregCr 0:e6ceb13d2d05 578 28 + 16 * this->settings.LoRa.CrcOn -
GregCr 0:e6ceb13d2d05 579 ( this->settings.LoRa.FixLen ? 20 : 0 ) ) /
Helmut Tschemernjak 31:e50929bd3f32 580 ( double )( 4 * ( this->settings.LoRa.Datarate -
Helmut Tschemernjak 31:e50929bd3f32 581 ( ( this->settings.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
GregCr 0:e6ceb13d2d05 582 ( this->settings.LoRa.Coderate + 4 );
GregCr 0:e6ceb13d2d05 583 double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
GregCr 0:e6ceb13d2d05 584 double tPayload = nPayload * ts;
mluis 25:3778e6204cc1 585 // Time on air
GregCr 0:e6ceb13d2d05 586 double tOnAir = tPreamble + tPayload;
Helmut Tschemernjak 31:e50929bd3f32 587 // return ms secs
Helmut Tschemernjak 31:e50929bd3f32 588 airTime = floor( tOnAir * 1e3 + 0.999 );
GregCr 0:e6ceb13d2d05 589 }
GregCr 0:e6ceb13d2d05 590 break;
GregCr 0:e6ceb13d2d05 591 }
GregCr 0:e6ceb13d2d05 592 return airTime;
GregCr 0:e6ceb13d2d05 593 }
GregCr 0:e6ceb13d2d05 594
GregCr 0:e6ceb13d2d05 595 void SX1276::Send( uint8_t *buffer, uint8_t size )
GregCr 0:e6ceb13d2d05 596 {
GregCr 0:e6ceb13d2d05 597 uint32_t txTimeout = 0;
GregCr 0:e6ceb13d2d05 598
GregCr 0:e6ceb13d2d05 599 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 600 {
GregCr 0:e6ceb13d2d05 601 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 602 {
GregCr 0:e6ceb13d2d05 603 this->settings.FskPacketHandler.NbBytes = 0;
GregCr 0:e6ceb13d2d05 604 this->settings.FskPacketHandler.Size = size;
GregCr 0:e6ceb13d2d05 605
GregCr 0:e6ceb13d2d05 606 if( this->settings.Fsk.FixLen == false )
GregCr 0:e6ceb13d2d05 607 {
GregCr 0:e6ceb13d2d05 608 WriteFifo( ( uint8_t* )&size, 1 );
GregCr 0:e6ceb13d2d05 609 }
GregCr 0:e6ceb13d2d05 610 else
GregCr 0:e6ceb13d2d05 611 {
GregCr 0:e6ceb13d2d05 612 Write( REG_PAYLOADLENGTH, size );
Helmut Tschemernjak 31:e50929bd3f32 613 }
mluis 25:3778e6204cc1 614
GregCr 0:e6ceb13d2d05 615 if( ( size > 0 ) && ( size <= 64 ) )
GregCr 0:e6ceb13d2d05 616 {
GregCr 0:e6ceb13d2d05 617 this->settings.FskPacketHandler.ChunkSize = size;
GregCr 0:e6ceb13d2d05 618 }
GregCr 0:e6ceb13d2d05 619 else
GregCr 0:e6ceb13d2d05 620 {
Helmut Tschemernjak 31:e50929bd3f32 621 memcpy( rxtxBuffer, buffer, size );
GregCr 0:e6ceb13d2d05 622 this->settings.FskPacketHandler.ChunkSize = 32;
GregCr 0:e6ceb13d2d05 623 }
GregCr 0:e6ceb13d2d05 624
GregCr 0:e6ceb13d2d05 625 // Write payload buffer
GregCr 0:e6ceb13d2d05 626 WriteFifo( buffer, this->settings.FskPacketHandler.ChunkSize );
GregCr 0:e6ceb13d2d05 627 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
GregCr 0:e6ceb13d2d05 628 txTimeout = this->settings.Fsk.TxTimeout;
GregCr 0:e6ceb13d2d05 629 }
GregCr 0:e6ceb13d2d05 630 break;
GregCr 0:e6ceb13d2d05 631 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 632 {
GregCr 0:e6ceb13d2d05 633 if( this->settings.LoRa.IqInverted == true )
GregCr 0:e6ceb13d2d05 634 {
GregCr 0:e6ceb13d2d05 635 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 636 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
GregCr 0:e6ceb13d2d05 637 }
GregCr 0:e6ceb13d2d05 638 else
GregCr 0:e6ceb13d2d05 639 {
GregCr 0:e6ceb13d2d05 640 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 641 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
mluis 25:3778e6204cc1 642 }
mluis 25:3778e6204cc1 643
GregCr 0:e6ceb13d2d05 644 this->settings.LoRaPacketHandler.Size = size;
GregCr 0:e6ceb13d2d05 645
GregCr 0:e6ceb13d2d05 646 // Initializes the payload size
GregCr 0:e6ceb13d2d05 647 Write( REG_LR_PAYLOADLENGTH, size );
GregCr 0:e6ceb13d2d05 648
mluis 25:3778e6204cc1 649 // Full buffer used for Tx
GregCr 0:e6ceb13d2d05 650 Write( REG_LR_FIFOTXBASEADDR, 0 );
GregCr 0:e6ceb13d2d05 651 Write( REG_LR_FIFOADDRPTR, 0 );
GregCr 0:e6ceb13d2d05 652
GregCr 0:e6ceb13d2d05 653 // FIFO operations can not take place in Sleep mode
GregCr 0:e6ceb13d2d05 654 if( ( Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP )
GregCr 0:e6ceb13d2d05 655 {
GregCr 0:e6ceb13d2d05 656 Standby( );
GregCr 4:f0ce52e94d3f 657 wait_ms( 1 );
GregCr 0:e6ceb13d2d05 658 }
GregCr 0:e6ceb13d2d05 659 // Write payload buffer
GregCr 0:e6ceb13d2d05 660 WriteFifo( buffer, size );
GregCr 0:e6ceb13d2d05 661 txTimeout = this->settings.LoRa.TxTimeout;
GregCr 0:e6ceb13d2d05 662 }
GregCr 0:e6ceb13d2d05 663 break;
GregCr 0:e6ceb13d2d05 664 }
GregCr 0:e6ceb13d2d05 665
GregCr 0:e6ceb13d2d05 666 Tx( txTimeout );
GregCr 0:e6ceb13d2d05 667 }
GregCr 0:e6ceb13d2d05 668
GregCr 0:e6ceb13d2d05 669 void SX1276::Sleep( void )
GregCr 0:e6ceb13d2d05 670 {
Helmut Tschemernjak 31:e50929bd3f32 671 txTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 672 rxTimeoutTimer.detach( );
mluis 22:7f3aab69cca9 673
GregCr 0:e6ceb13d2d05 674 SetOpMode( RF_OPMODE_SLEEP );
mluis 22:7f3aab69cca9 675 this->settings.State = RF_IDLE;
GregCr 0:e6ceb13d2d05 676 }
GregCr 0:e6ceb13d2d05 677
GregCr 0:e6ceb13d2d05 678 void SX1276::Standby( void )
GregCr 0:e6ceb13d2d05 679 {
Helmut Tschemernjak 31:e50929bd3f32 680 txTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 681 rxTimeoutTimer.detach( );
mluis 22:7f3aab69cca9 682
GregCr 0:e6ceb13d2d05 683 SetOpMode( RF_OPMODE_STANDBY );
mluis 22:7f3aab69cca9 684 this->settings.State = RF_IDLE;
GregCr 0:e6ceb13d2d05 685 }
GregCr 0:e6ceb13d2d05 686
GregCr 0:e6ceb13d2d05 687 void SX1276::Rx( uint32_t timeout )
GregCr 0:e6ceb13d2d05 688 {
GregCr 0:e6ceb13d2d05 689 bool rxContinuous = false;
mluis 22:7f3aab69cca9 690
GregCr 0:e6ceb13d2d05 691 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 692 {
GregCr 0:e6ceb13d2d05 693 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 694 {
GregCr 0:e6ceb13d2d05 695 rxContinuous = this->settings.Fsk.RxContinuous;
mluis 25:3778e6204cc1 696
GregCr 0:e6ceb13d2d05 697 // DIO0=PayloadReady
GregCr 0:e6ceb13d2d05 698 // DIO1=FifoLevel
GregCr 0:e6ceb13d2d05 699 // DIO2=SyncAddr
GregCr 0:e6ceb13d2d05 700 // DIO3=FifoEmpty
GregCr 0:e6ceb13d2d05 701 // DIO4=Preamble
GregCr 0:e6ceb13d2d05 702 // DIO5=ModeReady
mluis 22:7f3aab69cca9 703 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
GregCr 23:1e143575df0f 704 RF_DIOMAPPING1_DIO1_MASK &
GregCr 0:e6ceb13d2d05 705 RF_DIOMAPPING1_DIO2_MASK ) |
GregCr 0:e6ceb13d2d05 706 RF_DIOMAPPING1_DIO0_00 |
mluis 25:3778e6204cc1 707 RF_DIOMAPPING1_DIO1_00 |
GregCr 0:e6ceb13d2d05 708 RF_DIOMAPPING1_DIO2_11 );
mluis 25:3778e6204cc1 709
GregCr 0:e6ceb13d2d05 710 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
mluis 25:3778e6204cc1 711 RF_DIOMAPPING2_MAP_MASK ) |
GregCr 0:e6ceb13d2d05 712 RF_DIOMAPPING2_DIO4_11 |
GregCr 0:e6ceb13d2d05 713 RF_DIOMAPPING2_MAP_PREAMBLEDETECT );
mluis 25:3778e6204cc1 714
GregCr 0:e6ceb13d2d05 715 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
mluis 25:3778e6204cc1 716
mluis 25:3778e6204cc1 717 Write( REG_RXCONFIG, RF_RXCONFIG_AFCAUTO_ON | RF_RXCONFIG_AGCAUTO_ON | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT );
mluis 25:3778e6204cc1 718
GregCr 0:e6ceb13d2d05 719 this->settings.FskPacketHandler.PreambleDetected = false;
GregCr 0:e6ceb13d2d05 720 this->settings.FskPacketHandler.SyncWordDetected = false;
GregCr 0:e6ceb13d2d05 721 this->settings.FskPacketHandler.NbBytes = 0;
GregCr 0:e6ceb13d2d05 722 this->settings.FskPacketHandler.Size = 0;
GregCr 0:e6ceb13d2d05 723 }
GregCr 0:e6ceb13d2d05 724 break;
GregCr 0:e6ceb13d2d05 725 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 726 {
GregCr 0:e6ceb13d2d05 727 if( this->settings.LoRa.IqInverted == true )
GregCr 0:e6ceb13d2d05 728 {
GregCr 0:e6ceb13d2d05 729 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 730 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
GregCr 0:e6ceb13d2d05 731 }
GregCr 0:e6ceb13d2d05 732 else
GregCr 0:e6ceb13d2d05 733 {
GregCr 0:e6ceb13d2d05 734 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 735 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
Helmut Tschemernjak 31:e50929bd3f32 736 }
mluis 22:7f3aab69cca9 737
mluis 22:7f3aab69cca9 738 // ERRATA 2.3 - Receiver Spurious Reception of a LoRa Signal
Helmut Tschemernjak 33:5db0d1e716b1 739 if( this->settings.LoRa.Bandwidth < LORA_BANKWIDTH_500kHz )
mluis 22:7f3aab69cca9 740 {
mluis 22:7f3aab69cca9 741 Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) & 0x7F );
mluis 22:7f3aab69cca9 742 Write( REG_LR_TEST30, 0x00 );
mluis 22:7f3aab69cca9 743 switch( this->settings.LoRa.Bandwidth )
mluis 22:7f3aab69cca9 744 {
Helmut Tschemernjak 33:5db0d1e716b1 745 case LORA_BANKWIDTH_7kHz: // 7.8 kHz
mluis 22:7f3aab69cca9 746 Write( REG_LR_TEST2F, 0x48 );
mluis 22:7f3aab69cca9 747 SetChannel(this->settings.Channel + 7.81e3 );
mluis 22:7f3aab69cca9 748 break;
Helmut Tschemernjak 33:5db0d1e716b1 749 case LORA_BANKWIDTH_10kHz: // 10.4 kHz
mluis 22:7f3aab69cca9 750 Write( REG_LR_TEST2F, 0x44 );
mluis 22:7f3aab69cca9 751 SetChannel(this->settings.Channel + 10.42e3 );
mluis 22:7f3aab69cca9 752 break;
Helmut Tschemernjak 33:5db0d1e716b1 753 case LORA_BANKWIDTH_15kHz: // 15.6 kHz
mluis 22:7f3aab69cca9 754 Write( REG_LR_TEST2F, 0x44 );
mluis 22:7f3aab69cca9 755 SetChannel(this->settings.Channel + 15.62e3 );
mluis 22:7f3aab69cca9 756 break;
Helmut Tschemernjak 33:5db0d1e716b1 757 case LORA_BANKWIDTH_20kHz: // 20.8 kHz
mluis 22:7f3aab69cca9 758 Write( REG_LR_TEST2F, 0x44 );
mluis 22:7f3aab69cca9 759 SetChannel(this->settings.Channel + 20.83e3 );
mluis 22:7f3aab69cca9 760 break;
Helmut Tschemernjak 33:5db0d1e716b1 761 case LORA_BANKWIDTH_31kHz: // 31.2 kHz
mluis 22:7f3aab69cca9 762 Write( REG_LR_TEST2F, 0x44 );
mluis 22:7f3aab69cca9 763 SetChannel(this->settings.Channel + 31.25e3 );
mluis 22:7f3aab69cca9 764 break;
Helmut Tschemernjak 33:5db0d1e716b1 765 case LORA_BANKWIDTH_41kHz: // 41.4 kHz
mluis 22:7f3aab69cca9 766 Write( REG_LR_TEST2F, 0x44 );
mluis 22:7f3aab69cca9 767 SetChannel(this->settings.Channel + 41.67e3 );
mluis 22:7f3aab69cca9 768 break;
Helmut Tschemernjak 33:5db0d1e716b1 769 case LORA_BANKWIDTH_62kHz: // 62.5 kHz
mluis 22:7f3aab69cca9 770 Write( REG_LR_TEST2F, 0x40 );
mluis 22:7f3aab69cca9 771 break;
Helmut Tschemernjak 33:5db0d1e716b1 772 case LORA_BANKWIDTH_125kHz: // 125 kHz
mluis 22:7f3aab69cca9 773 Write( REG_LR_TEST2F, 0x40 );
mluis 22:7f3aab69cca9 774 break;
Helmut Tschemernjak 33:5db0d1e716b1 775 case LORA_BANKWIDTH_250kHz: // 250 kHz
mluis 22:7f3aab69cca9 776 Write( REG_LR_TEST2F, 0x40 );
mluis 22:7f3aab69cca9 777 break;
mluis 22:7f3aab69cca9 778 }
mluis 22:7f3aab69cca9 779 }
mluis 22:7f3aab69cca9 780 else
mluis 22:7f3aab69cca9 781 {
mluis 22:7f3aab69cca9 782 Write( REG_LR_DETECTOPTIMIZE, Read( REG_LR_DETECTOPTIMIZE ) | 0x80 );
mluis 22:7f3aab69cca9 783 }
mluis 22:7f3aab69cca9 784
GregCr 0:e6ceb13d2d05 785 rxContinuous = this->settings.LoRa.RxContinuous;
mluis 25:3778e6204cc1 786
GregCr 6:e7f02929cd3d 787 if( this->settings.LoRa.FreqHopOn == true )
GregCr 6:e7f02929cd3d 788 {
GregCr 6:e7f02929cd3d 789 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
mluis 22:7f3aab69cca9 790 //RFLR_IRQFLAGS_RXDONE |
mluis 22:7f3aab69cca9 791 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
mluis 22:7f3aab69cca9 792 RFLR_IRQFLAGS_VALIDHEADER |
mluis 22:7f3aab69cca9 793 RFLR_IRQFLAGS_TXDONE |
mluis 22:7f3aab69cca9 794 RFLR_IRQFLAGS_CADDONE |
mluis 22:7f3aab69cca9 795 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
mluis 22:7f3aab69cca9 796 RFLR_IRQFLAGS_CADDETECTED );
mluis 25:3778e6204cc1 797
mluis 13:618826a997e2 798 // DIO0=RxDone, DIO2=FhssChangeChannel
mluis 13:618826a997e2 799 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 800 }
GregCr 6:e7f02929cd3d 801 else
GregCr 6:e7f02929cd3d 802 {
GregCr 6:e7f02929cd3d 803 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
mluis 22:7f3aab69cca9 804 //RFLR_IRQFLAGS_RXDONE |
mluis 22:7f3aab69cca9 805 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
mluis 22:7f3aab69cca9 806 RFLR_IRQFLAGS_VALIDHEADER |
mluis 22:7f3aab69cca9 807 RFLR_IRQFLAGS_TXDONE |
mluis 22:7f3aab69cca9 808 RFLR_IRQFLAGS_CADDONE |
mluis 22:7f3aab69cca9 809 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
mluis 22:7f3aab69cca9 810 RFLR_IRQFLAGS_CADDETECTED );
mluis 25:3778e6204cc1 811
GregCr 6:e7f02929cd3d 812 // DIO0=RxDone
GregCr 6:e7f02929cd3d 813 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
GregCr 6:e7f02929cd3d 814 }
GregCr 0:e6ceb13d2d05 815 Write( REG_LR_FIFORXBASEADDR, 0 );
GregCr 0:e6ceb13d2d05 816 Write( REG_LR_FIFOADDRPTR, 0 );
GregCr 0:e6ceb13d2d05 817 }
GregCr 0:e6ceb13d2d05 818 break;
GregCr 0:e6ceb13d2d05 819 }
GregCr 0:e6ceb13d2d05 820
GregCr 23:1e143575df0f 821 memset( rxtxBuffer, 0, ( size_t )RX_BUFFER_SIZE );
GregCr 0:e6ceb13d2d05 822
mluis 21:2e496deb7858 823 this->settings.State = RF_RX_RUNNING;
GregCr 0:e6ceb13d2d05 824 if( timeout != 0 )
GregCr 0:e6ceb13d2d05 825 {
Helmut Tschemernjak 31:e50929bd3f32 826 rxTimeoutTimer.attach_us(callback( this, &SX1276::OnTimeoutIrq ), timeout * 1e3 );
GregCr 0:e6ceb13d2d05 827 }
GregCr 0:e6ceb13d2d05 828
GregCr 0:e6ceb13d2d05 829 if( this->settings.Modem == MODEM_FSK )
GregCr 0:e6ceb13d2d05 830 {
GregCr 0:e6ceb13d2d05 831 SetOpMode( RF_OPMODE_RECEIVER );
mluis 25:3778e6204cc1 832
GregCr 0:e6ceb13d2d05 833 if( rxContinuous == false )
GregCr 0:e6ceb13d2d05 834 {
Helmut Tschemernjak 31:e50929bd3f32 835 rxTimeoutSyncWord.attach_us(callback( this, &SX1276::OnTimeoutIrq ),
Helmut Tschemernjak 31:e50929bd3f32 836 this->settings.Fsk.RxSingleTimeout * 1e3 );
GregCr 0:e6ceb13d2d05 837 }
GregCr 0:e6ceb13d2d05 838 }
GregCr 0:e6ceb13d2d05 839 else
GregCr 0:e6ceb13d2d05 840 {
GregCr 0:e6ceb13d2d05 841 if( rxContinuous == true )
GregCr 0:e6ceb13d2d05 842 {
GregCr 0:e6ceb13d2d05 843 SetOpMode( RFLR_OPMODE_RECEIVER );
GregCr 0:e6ceb13d2d05 844 }
GregCr 0:e6ceb13d2d05 845 else
GregCr 0:e6ceb13d2d05 846 {
GregCr 0:e6ceb13d2d05 847 SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
GregCr 0:e6ceb13d2d05 848 }
GregCr 0:e6ceb13d2d05 849 }
GregCr 0:e6ceb13d2d05 850 }
GregCr 0:e6ceb13d2d05 851
GregCr 0:e6ceb13d2d05 852 void SX1276::Tx( uint32_t timeout )
mluis 22:7f3aab69cca9 853 {
mluis 22:7f3aab69cca9 854
GregCr 0:e6ceb13d2d05 855 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 856 {
GregCr 0:e6ceb13d2d05 857 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 858 {
GregCr 0:e6ceb13d2d05 859 // DIO0=PacketSent
GregCr 23:1e143575df0f 860 // DIO1=FifoEmpty
GregCr 0:e6ceb13d2d05 861 // DIO2=FifoFull
GregCr 0:e6ceb13d2d05 862 // DIO3=FifoEmpty
GregCr 0:e6ceb13d2d05 863 // DIO4=LowBat
GregCr 0:e6ceb13d2d05 864 // DIO5=ModeReady
mluis 22:7f3aab69cca9 865 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
Helmut Tschemernjak 31:e50929bd3f32 866 RF_DIOMAPPING1_DIO1_MASK &
Helmut Tschemernjak 31:e50929bd3f32 867 RF_DIOMAPPING1_DIO2_MASK ) |
Helmut Tschemernjak 31:e50929bd3f32 868 RF_DIOMAPPING1_DIO1_01 );
GregCr 0:e6ceb13d2d05 869
GregCr 0:e6ceb13d2d05 870 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
GregCr 0:e6ceb13d2d05 871 RF_DIOMAPPING2_MAP_MASK ) );
GregCr 0:e6ceb13d2d05 872 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
GregCr 0:e6ceb13d2d05 873 }
GregCr 0:e6ceb13d2d05 874 break;
GregCr 0:e6ceb13d2d05 875 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 876 {
GregCr 6:e7f02929cd3d 877 if( this->settings.LoRa.FreqHopOn == true )
GregCr 6:e7f02929cd3d 878 {
GregCr 6:e7f02929cd3d 879 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
mluis 22:7f3aab69cca9 880 RFLR_IRQFLAGS_RXDONE |
mluis 22:7f3aab69cca9 881 RFLR_IRQFLAGS_PAYLOADCRCERROR |
mluis 22:7f3aab69cca9 882 RFLR_IRQFLAGS_VALIDHEADER |
mluis 22:7f3aab69cca9 883 //RFLR_IRQFLAGS_TXDONE |
mluis 22:7f3aab69cca9 884 RFLR_IRQFLAGS_CADDONE |
mluis 22:7f3aab69cca9 885 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
mluis 22:7f3aab69cca9 886 RFLR_IRQFLAGS_CADDETECTED );
mluis 25:3778e6204cc1 887
mluis 22:7f3aab69cca9 888 // DIO0=TxDone, DIO2=FhssChangeChannel
mluis 22:7f3aab69cca9 889 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 890 }
GregCr 6:e7f02929cd3d 891 else
GregCr 6:e7f02929cd3d 892 {
GregCr 6:e7f02929cd3d 893 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
mluis 22:7f3aab69cca9 894 RFLR_IRQFLAGS_RXDONE |
mluis 22:7f3aab69cca9 895 RFLR_IRQFLAGS_PAYLOADCRCERROR |
mluis 22:7f3aab69cca9 896 RFLR_IRQFLAGS_VALIDHEADER |
mluis 22:7f3aab69cca9 897 //RFLR_IRQFLAGS_TXDONE |
mluis 22:7f3aab69cca9 898 RFLR_IRQFLAGS_CADDONE |
mluis 22:7f3aab69cca9 899 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
mluis 22:7f3aab69cca9 900 RFLR_IRQFLAGS_CADDETECTED );
mluis 22:7f3aab69cca9 901
GregCr 6:e7f02929cd3d 902 // DIO0=TxDone
mluis 22:7f3aab69cca9 903 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
GregCr 6:e7f02929cd3d 904 }
GregCr 0:e6ceb13d2d05 905 }
GregCr 0:e6ceb13d2d05 906 break;
GregCr 0:e6ceb13d2d05 907 }
GregCr 0:e6ceb13d2d05 908
mluis 21:2e496deb7858 909 this->settings.State = RF_TX_RUNNING;
Helmut Tschemernjak 31:e50929bd3f32 910 txTimeoutTimer.attach_us(callback( this, &SX1276::OnTimeoutIrq ), timeout * 1e3 );
GregCr 0:e6ceb13d2d05 911 SetOpMode( RF_OPMODE_TRANSMITTER );
GregCr 0:e6ceb13d2d05 912 }
GregCr 0:e6ceb13d2d05 913
GregCr 7:2b555111463f 914 void SX1276::StartCad( void )
GregCr 0:e6ceb13d2d05 915 {
GregCr 7:2b555111463f 916 switch( this->settings.Modem )
GregCr 7:2b555111463f 917 {
GregCr 7:2b555111463f 918 case MODEM_FSK:
GregCr 7:2b555111463f 919 {
mluis 25:3778e6204cc1 920
GregCr 7:2b555111463f 921 }
GregCr 7:2b555111463f 922 break;
GregCr 7:2b555111463f 923 case MODEM_LORA:
GregCr 7:2b555111463f 924 {
GregCr 7:2b555111463f 925 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
GregCr 7:2b555111463f 926 RFLR_IRQFLAGS_RXDONE |
GregCr 7:2b555111463f 927 RFLR_IRQFLAGS_PAYLOADCRCERROR |
GregCr 7:2b555111463f 928 RFLR_IRQFLAGS_VALIDHEADER |
GregCr 7:2b555111463f 929 RFLR_IRQFLAGS_TXDONE |
GregCr 7:2b555111463f 930 //RFLR_IRQFLAGS_CADDONE |
GregCr 12:aa5b3bf7fdf4 931 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
Helmut Tschemernjak 31:e50929bd3f32 932 //RFLR_IRQFLAGS_CADDETECTED
GregCr 12:aa5b3bf7fdf4 933 );
mluis 25:3778e6204cc1 934
GregCr 7:2b555111463f 935 // DIO3=CADDone
Helmut Tschemernjak 31:e50929bd3f32 936 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO3_MASK ) | RFLR_DIOMAPPING1_DIO3_00 );
mluis 25:3778e6204cc1 937
mluis 21:2e496deb7858 938 this->settings.State = RF_CAD;
GregCr 7:2b555111463f 939 SetOpMode( RFLR_OPMODE_CAD );
GregCr 7:2b555111463f 940 }
GregCr 7:2b555111463f 941 break;
GregCr 7:2b555111463f 942 default:
GregCr 7:2b555111463f 943 break;
GregCr 7:2b555111463f 944 }
GregCr 7:2b555111463f 945 }
GregCr 7:2b555111463f 946
Helmut Tschemernjak 31:e50929bd3f32 947 void SX1276::SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
Helmut Tschemernjak 31:e50929bd3f32 948 {
Helmut Tschemernjak 31:e50929bd3f32 949 uint32_t timeout = ( uint32_t )( time * 1e6 );
Helmut Tschemernjak 31:e50929bd3f32 950
Helmut Tschemernjak 31:e50929bd3f32 951 SetChannel( freq );
Helmut Tschemernjak 31:e50929bd3f32 952
Helmut Tschemernjak 31:e50929bd3f32 953 SetTxConfig( MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, timeout );
Helmut Tschemernjak 31:e50929bd3f32 954
Helmut Tschemernjak 31:e50929bd3f32 955 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) & RF_PACKETCONFIG2_DATAMODE_MASK ) );
Helmut Tschemernjak 31:e50929bd3f32 956 // Disable radio interrupts
Helmut Tschemernjak 31:e50929bd3f32 957 Write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 );
Helmut Tschemernjak 31:e50929bd3f32 958 Write( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 );
Helmut Tschemernjak 31:e50929bd3f32 959
Helmut Tschemernjak 31:e50929bd3f32 960 this->settings.State = RF_TX_RUNNING;
Helmut Tschemernjak 31:e50929bd3f32 961 txTimeoutTimer.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout );
Helmut Tschemernjak 31:e50929bd3f32 962 SetOpMode( RF_OPMODE_TRANSMITTER );
Helmut Tschemernjak 31:e50929bd3f32 963 }
Helmut Tschemernjak 31:e50929bd3f32 964
mluis 22:7f3aab69cca9 965 int16_t SX1276::GetRssi( RadioModems_t modem )
GregCr 7:2b555111463f 966 {
GregCr 7:2b555111463f 967 int16_t rssi = 0;
GregCr 0:e6ceb13d2d05 968
GregCr 0:e6ceb13d2d05 969 switch( modem )
GregCr 0:e6ceb13d2d05 970 {
GregCr 0:e6ceb13d2d05 971 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 972 rssi = -( Read( REG_RSSIVALUE ) >> 1 );
GregCr 0:e6ceb13d2d05 973 break;
GregCr 0:e6ceb13d2d05 974 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 975 if( this->settings.Channel > RF_MID_BAND_THRESH )
GregCr 0:e6ceb13d2d05 976 {
GregCr 0:e6ceb13d2d05 977 rssi = RSSI_OFFSET_HF + Read( REG_LR_RSSIVALUE );
GregCr 0:e6ceb13d2d05 978 }
GregCr 0:e6ceb13d2d05 979 else
GregCr 0:e6ceb13d2d05 980 {
GregCr 0:e6ceb13d2d05 981 rssi = RSSI_OFFSET_LF + Read( REG_LR_RSSIVALUE );
GregCr 0:e6ceb13d2d05 982 }
GregCr 0:e6ceb13d2d05 983 break;
GregCr 0:e6ceb13d2d05 984 default:
GregCr 0:e6ceb13d2d05 985 rssi = -1;
GregCr 0:e6ceb13d2d05 986 break;
GregCr 0:e6ceb13d2d05 987 }
GregCr 0:e6ceb13d2d05 988 return rssi;
GregCr 0:e6ceb13d2d05 989 }
GregCr 0:e6ceb13d2d05 990
GregCr 0:e6ceb13d2d05 991 void SX1276::SetOpMode( uint8_t opMode )
GregCr 0:e6ceb13d2d05 992 {
mluis 25:3778e6204cc1 993 if( opMode == RF_OPMODE_SLEEP )
GregCr 0:e6ceb13d2d05 994 {
mluis 25:3778e6204cc1 995 SetAntSwLowPower( true );
mluis 25:3778e6204cc1 996 }
mluis 25:3778e6204cc1 997 else
mluis 25:3778e6204cc1 998 {
mluis 25:3778e6204cc1 999 SetAntSwLowPower( false );
Helmut Tschemernjak 31:e50929bd3f32 1000 SetAntSw( opMode );
GregCr 0:e6ceb13d2d05 1001 }
mluis 25:3778e6204cc1 1002 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
GregCr 0:e6ceb13d2d05 1003 }
GregCr 0:e6ceb13d2d05 1004
mluis 22:7f3aab69cca9 1005 void SX1276::SetModem( RadioModems_t modem )
GregCr 0:e6ceb13d2d05 1006 {
Helmut Tschemernjak 31:e50929bd3f32 1007 if( ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_ON ) != 0 )
Helmut Tschemernjak 31:e50929bd3f32 1008 {
Helmut Tschemernjak 31:e50929bd3f32 1009 this->settings.Modem = MODEM_LORA;
Helmut Tschemernjak 31:e50929bd3f32 1010 }
Helmut Tschemernjak 31:e50929bd3f32 1011 else
Helmut Tschemernjak 31:e50929bd3f32 1012 {
Helmut Tschemernjak 31:e50929bd3f32 1013 this->settings.Modem = MODEM_FSK;
Helmut Tschemernjak 31:e50929bd3f32 1014 }
Helmut Tschemernjak 31:e50929bd3f32 1015
mluis 22:7f3aab69cca9 1016 if( this->settings.Modem == modem )
mluis 22:7f3aab69cca9 1017 {
mluis 22:7f3aab69cca9 1018 return;
mluis 22:7f3aab69cca9 1019 }
mluis 22:7f3aab69cca9 1020
mluis 22:7f3aab69cca9 1021 this->settings.Modem = modem;
mluis 22:7f3aab69cca9 1022 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1023 {
mluis 22:7f3aab69cca9 1024 default:
mluis 22:7f3aab69cca9 1025 case MODEM_FSK:
Helmut Tschemernjak 31:e50929bd3f32 1026 Sleep( );
mluis 22:7f3aab69cca9 1027 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
mluis 22:7f3aab69cca9 1028
mluis 22:7f3aab69cca9 1029 Write( REG_DIOMAPPING1, 0x00 );
mluis 22:7f3aab69cca9 1030 Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
mluis 22:7f3aab69cca9 1031 break;
mluis 22:7f3aab69cca9 1032 case MODEM_LORA:
Helmut Tschemernjak 31:e50929bd3f32 1033 Sleep( );
mluis 22:7f3aab69cca9 1034 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
mluis 22:7f3aab69cca9 1035
mluis 22:7f3aab69cca9 1036 Write( REG_DIOMAPPING1, 0x00 );
mluis 22:7f3aab69cca9 1037 Write( REG_DIOMAPPING2, 0x00 );
mluis 22:7f3aab69cca9 1038 break;
GregCr 0:e6ceb13d2d05 1039 }
GregCr 0:e6ceb13d2d05 1040 }
GregCr 0:e6ceb13d2d05 1041
mluis 22:7f3aab69cca9 1042 void SX1276::SetMaxPayloadLength( RadioModems_t modem, uint8_t max )
mluis 20:e05596ba4166 1043 {
mluis 20:e05596ba4166 1044 this->SetModem( modem );
mluis 20:e05596ba4166 1045
mluis 20:e05596ba4166 1046 switch( modem )
mluis 20:e05596ba4166 1047 {
mluis 20:e05596ba4166 1048 case MODEM_FSK:
mluis 20:e05596ba4166 1049 if( this->settings.Fsk.FixLen == false )
mluis 20:e05596ba4166 1050 {
mluis 20:e05596ba4166 1051 this->Write( REG_PAYLOADLENGTH, max );
mluis 20:e05596ba4166 1052 }
mluis 20:e05596ba4166 1053 break;
mluis 20:e05596ba4166 1054 case MODEM_LORA:
mluis 20:e05596ba4166 1055 this->Write( REG_LR_PAYLOADMAXLENGTH, max );
mluis 20:e05596ba4166 1056 break;
mluis 20:e05596ba4166 1057 }
mluis 20:e05596ba4166 1058 }
mluis 20:e05596ba4166 1059
Helmut Tschemernjak 31:e50929bd3f32 1060 void SX1276::SetPublicNetwork( bool enable )
Helmut Tschemernjak 31:e50929bd3f32 1061 {
Helmut Tschemernjak 31:e50929bd3f32 1062 SetModem( MODEM_LORA );
Helmut Tschemernjak 31:e50929bd3f32 1063 this->settings.LoRa.PublicNetwork = enable;
Helmut Tschemernjak 31:e50929bd3f32 1064 if( enable == true )
Helmut Tschemernjak 31:e50929bd3f32 1065 {
Helmut Tschemernjak 31:e50929bd3f32 1066 // Change LoRa modem SyncWord
Helmut Tschemernjak 31:e50929bd3f32 1067 Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
Helmut Tschemernjak 31:e50929bd3f32 1068 }
Helmut Tschemernjak 31:e50929bd3f32 1069 else
Helmut Tschemernjak 31:e50929bd3f32 1070 {
Helmut Tschemernjak 31:e50929bd3f32 1071 // Change LoRa modem SyncWord
Helmut Tschemernjak 31:e50929bd3f32 1072 Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );
Helmut Tschemernjak 31:e50929bd3f32 1073 }
Helmut Tschemernjak 31:e50929bd3f32 1074 }
Helmut Tschemernjak 31:e50929bd3f32 1075
Helmut Tschemernjak 31:e50929bd3f32 1076
GregCr 0:e6ceb13d2d05 1077 void SX1276::OnTimeoutIrq( void )
GregCr 0:e6ceb13d2d05 1078 {
GregCr 0:e6ceb13d2d05 1079 switch( this->settings.State )
GregCr 0:e6ceb13d2d05 1080 {
mluis 21:2e496deb7858 1081 case RF_RX_RUNNING:
GregCr 0:e6ceb13d2d05 1082 if( this->settings.Modem == MODEM_FSK )
GregCr 0:e6ceb13d2d05 1083 {
GregCr 0:e6ceb13d2d05 1084 this->settings.FskPacketHandler.PreambleDetected = false;
GregCr 0:e6ceb13d2d05 1085 this->settings.FskPacketHandler.SyncWordDetected = false;
GregCr 0:e6ceb13d2d05 1086 this->settings.FskPacketHandler.NbBytes = 0;
GregCr 0:e6ceb13d2d05 1087 this->settings.FskPacketHandler.Size = 0;
GregCr 0:e6ceb13d2d05 1088
GregCr 0:e6ceb13d2d05 1089 // Clear Irqs
Helmut Tschemernjak 31:e50929bd3f32 1090 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
GregCr 0:e6ceb13d2d05 1091 RF_IRQFLAGS1_PREAMBLEDETECT |
GregCr 0:e6ceb13d2d05 1092 RF_IRQFLAGS1_SYNCADDRESSMATCH );
GregCr 0:e6ceb13d2d05 1093 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
GregCr 0:e6ceb13d2d05 1094
GregCr 0:e6ceb13d2d05 1095 if( this->settings.Fsk.RxContinuous == true )
GregCr 0:e6ceb13d2d05 1096 {
GregCr 0:e6ceb13d2d05 1097 // Continuous mode restart Rx chain
GregCr 0:e6ceb13d2d05 1098 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
Helmut Tschemernjak 31:e50929bd3f32 1099 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
Helmut Tschemernjak 31:e50929bd3f32 1100 this->settings.Fsk.RxSingleTimeout * 1e3 );
GregCr 0:e6ceb13d2d05 1101 }
GregCr 0:e6ceb13d2d05 1102 else
GregCr 0:e6ceb13d2d05 1103 {
mluis 21:2e496deb7858 1104 this->settings.State = RF_IDLE;
GregCr 5:11ec8a6ba4f0 1105 rxTimeoutSyncWord.detach( );
GregCr 0:e6ceb13d2d05 1106 }
GregCr 0:e6ceb13d2d05 1107 }
mluis 22:7f3aab69cca9 1108 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
GregCr 0:e6ceb13d2d05 1109 {
mluis 21:2e496deb7858 1110 this->RadioEvents->RxTimeout( );
GregCr 0:e6ceb13d2d05 1111 }
GregCr 0:e6ceb13d2d05 1112 break;
mluis 21:2e496deb7858 1113 case RF_TX_RUNNING:
Helmut Tschemernjak 31:e50929bd3f32 1114 // Tx timeout shouldn't happen.
Helmut Tschemernjak 31:e50929bd3f32 1115 // But it has been observed that when it happens it is a result of a corrupted SPI transfer
Helmut Tschemernjak 31:e50929bd3f32 1116 // it depends on the platform design.
Helmut Tschemernjak 31:e50929bd3f32 1117 //
Helmut Tschemernjak 31:e50929bd3f32 1118 // The workaround is to put the radio in a known state. Thus, we re-initialize it.
Helmut Tschemernjak 31:e50929bd3f32 1119 // BEGIN WORKAROUND
Helmut Tschemernjak 31:e50929bd3f32 1120
Helmut Tschemernjak 31:e50929bd3f32 1121 // Reset the radio
Helmut Tschemernjak 31:e50929bd3f32 1122 Reset( );
Helmut Tschemernjak 31:e50929bd3f32 1123
Helmut Tschemernjak 31:e50929bd3f32 1124 // Calibrate Rx chain
Helmut Tschemernjak 31:e50929bd3f32 1125 RxChainCalibration( );
Helmut Tschemernjak 31:e50929bd3f32 1126
Helmut Tschemernjak 31:e50929bd3f32 1127 // Initialize radio default values
Helmut Tschemernjak 31:e50929bd3f32 1128 SetOpMode( RF_OPMODE_SLEEP );
Helmut Tschemernjak 31:e50929bd3f32 1129
Helmut Tschemernjak 31:e50929bd3f32 1130 RadioRegistersInit( );
Helmut Tschemernjak 31:e50929bd3f32 1131
Helmut Tschemernjak 31:e50929bd3f32 1132 SetModem( MODEM_FSK );
Helmut Tschemernjak 31:e50929bd3f32 1133
Helmut Tschemernjak 31:e50929bd3f32 1134 // Restore previous network type setting.
Helmut Tschemernjak 31:e50929bd3f32 1135 SetPublicNetwork( this->settings.LoRa.PublicNetwork );
Helmut Tschemernjak 31:e50929bd3f32 1136 // END WORKAROUND
Helmut Tschemernjak 31:e50929bd3f32 1137
mluis 21:2e496deb7858 1138 this->settings.State = RF_IDLE;
mluis 22:7f3aab69cca9 1139 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxTimeout != NULL ) )
GregCr 0:e6ceb13d2d05 1140 {
mluis 21:2e496deb7858 1141 this->RadioEvents->TxTimeout( );
GregCr 0:e6ceb13d2d05 1142 }
GregCr 0:e6ceb13d2d05 1143 break;
GregCr 0:e6ceb13d2d05 1144 default:
GregCr 0:e6ceb13d2d05 1145 break;
GregCr 0:e6ceb13d2d05 1146 }
GregCr 0:e6ceb13d2d05 1147 }
GregCr 0:e6ceb13d2d05 1148
GregCr 0:e6ceb13d2d05 1149 void SX1276::OnDio0Irq( void )
GregCr 0:e6ceb13d2d05 1150 {
mluis 20:e05596ba4166 1151 volatile uint8_t irqFlags = 0;
mluis 22:7f3aab69cca9 1152
GregCr 0:e6ceb13d2d05 1153 switch( this->settings.State )
mluis 25:3778e6204cc1 1154 {
mluis 21:2e496deb7858 1155 case RF_RX_RUNNING:
GregCr 0:e6ceb13d2d05 1156 //TimerStop( &RxTimeoutTimer );
GregCr 0:e6ceb13d2d05 1157 // RxDone interrupt
GregCr 0:e6ceb13d2d05 1158 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1159 {
GregCr 0:e6ceb13d2d05 1160 case MODEM_FSK:
GregCr 18:99c6e44c1672 1161 if( this->settings.Fsk.CrcOn == true )
GregCr 0:e6ceb13d2d05 1162 {
GregCr 18:99c6e44c1672 1163 irqFlags = Read( REG_IRQFLAGS2 );
GregCr 18:99c6e44c1672 1164 if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
GregCr 0:e6ceb13d2d05 1165 {
GregCr 18:99c6e44c1672 1166 // Clear Irqs
mluis 25:3778e6204cc1 1167 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
GregCr 18:99c6e44c1672 1168 RF_IRQFLAGS1_PREAMBLEDETECT |
GregCr 18:99c6e44c1672 1169 RF_IRQFLAGS1_SYNCADDRESSMATCH );
GregCr 18:99c6e44c1672 1170 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
mluis 25:3778e6204cc1 1171
mluis 25:3778e6204cc1 1172 rxTimeoutTimer.detach( );
mluis 25:3778e6204cc1 1173
GregCr 18:99c6e44c1672 1174 if( this->settings.Fsk.RxContinuous == false )
GregCr 18:99c6e44c1672 1175 {
mluis 25:3778e6204cc1 1176 rxTimeoutSyncWord.detach( );
mluis 21:2e496deb7858 1177 this->settings.State = RF_IDLE;
GregCr 18:99c6e44c1672 1178 }
GregCr 18:99c6e44c1672 1179 else
GregCr 18:99c6e44c1672 1180 {
GregCr 18:99c6e44c1672 1181 // Continuous mode restart Rx chain
GregCr 18:99c6e44c1672 1182 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
Helmut Tschemernjak 31:e50929bd3f32 1183 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
Helmut Tschemernjak 31:e50929bd3f32 1184 this->settings.Fsk.RxSingleTimeout * 1e3 );
GregCr 18:99c6e44c1672 1185 }
mluis 25:3778e6204cc1 1186
mluis 22:7f3aab69cca9 1187 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
GregCr 18:99c6e44c1672 1188 {
mluis 22:7f3aab69cca9 1189 this->RadioEvents->RxError( );
GregCr 18:99c6e44c1672 1190 }
GregCr 18:99c6e44c1672 1191 this->settings.FskPacketHandler.PreambleDetected = false;
GregCr 18:99c6e44c1672 1192 this->settings.FskPacketHandler.SyncWordDetected = false;
GregCr 18:99c6e44c1672 1193 this->settings.FskPacketHandler.NbBytes = 0;
GregCr 18:99c6e44c1672 1194 this->settings.FskPacketHandler.Size = 0;
GregCr 18:99c6e44c1672 1195 break;
GregCr 0:e6ceb13d2d05 1196 }
GregCr 0:e6ceb13d2d05 1197 }
mluis 25:3778e6204cc1 1198
GregCr 0:e6ceb13d2d05 1199 // Read received packet size
GregCr 0:e6ceb13d2d05 1200 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
GregCr 0:e6ceb13d2d05 1201 {
GregCr 0:e6ceb13d2d05 1202 if( this->settings.Fsk.FixLen == false )
GregCr 0:e6ceb13d2d05 1203 {
GregCr 0:e6ceb13d2d05 1204 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
GregCr 0:e6ceb13d2d05 1205 }
GregCr 0:e6ceb13d2d05 1206 else
GregCr 0:e6ceb13d2d05 1207 {
GregCr 0:e6ceb13d2d05 1208 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
GregCr 0:e6ceb13d2d05 1209 }
GregCr 23:1e143575df0f 1210 ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1211 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1212 }
GregCr 0:e6ceb13d2d05 1213 else
GregCr 0:e6ceb13d2d05 1214 {
GregCr 23:1e143575df0f 1215 ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1216 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1217 }
GregCr 0:e6ceb13d2d05 1218
mluis 25:3778e6204cc1 1219 rxTimeoutTimer.detach( );
mluis 25:3778e6204cc1 1220
GregCr 0:e6ceb13d2d05 1221 if( this->settings.Fsk.RxContinuous == false )
GregCr 0:e6ceb13d2d05 1222 {
mluis 21:2e496deb7858 1223 this->settings.State = RF_IDLE;
mluis 25:3778e6204cc1 1224 rxTimeoutSyncWord.detach( );
GregCr 0:e6ceb13d2d05 1225 }
GregCr 0:e6ceb13d2d05 1226 else
GregCr 0:e6ceb13d2d05 1227 {
GregCr 0:e6ceb13d2d05 1228 // Continuous mode restart Rx chain
GregCr 0:e6ceb13d2d05 1229 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
Helmut Tschemernjak 31:e50929bd3f32 1230 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
Helmut Tschemernjak 31:e50929bd3f32 1231 this->settings.Fsk.RxSingleTimeout * 1e3 );
Helmut Tschemernjak 31:e50929bd3f32 1232 }
GregCr 0:e6ceb13d2d05 1233
mluis 22:7f3aab69cca9 1234 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
GregCr 0:e6ceb13d2d05 1235 {
mluis 25:3778e6204cc1 1236 this->RadioEvents->RxDone( rxtxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 );
mluis 25:3778e6204cc1 1237 }
GregCr 0:e6ceb13d2d05 1238 this->settings.FskPacketHandler.PreambleDetected = false;
GregCr 0:e6ceb13d2d05 1239 this->settings.FskPacketHandler.SyncWordDetected = false;
GregCr 0:e6ceb13d2d05 1240 this->settings.FskPacketHandler.NbBytes = 0;
GregCr 0:e6ceb13d2d05 1241 this->settings.FskPacketHandler.Size = 0;
GregCr 0:e6ceb13d2d05 1242 break;
GregCr 0:e6ceb13d2d05 1243 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1244 {
mluis 22:7f3aab69cca9 1245 int8_t snr = 0;
GregCr 0:e6ceb13d2d05 1246
GregCr 0:e6ceb13d2d05 1247 // Clear Irq
GregCr 0:e6ceb13d2d05 1248 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
GregCr 0:e6ceb13d2d05 1249
GregCr 0:e6ceb13d2d05 1250 irqFlags = Read( REG_LR_IRQFLAGS );
GregCr 0:e6ceb13d2d05 1251 if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
GregCr 0:e6ceb13d2d05 1252 {
GregCr 0:e6ceb13d2d05 1253 // Clear Irq
GregCr 0:e6ceb13d2d05 1254 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
GregCr 0:e6ceb13d2d05 1255
GregCr 0:e6ceb13d2d05 1256 if( this->settings.LoRa.RxContinuous == false )
GregCr 0:e6ceb13d2d05 1257 {
mluis 21:2e496deb7858 1258 this->settings.State = RF_IDLE;
GregCr 0:e6ceb13d2d05 1259 }
GregCr 0:e6ceb13d2d05 1260 rxTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 1261
mluis 22:7f3aab69cca9 1262 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
GregCr 0:e6ceb13d2d05 1263 {
mluis 22:7f3aab69cca9 1264 this->RadioEvents->RxError( );
GregCr 0:e6ceb13d2d05 1265 }
GregCr 0:e6ceb13d2d05 1266 break;
GregCr 0:e6ceb13d2d05 1267 }
GregCr 0:e6ceb13d2d05 1268
GregCr 0:e6ceb13d2d05 1269 this->settings.LoRaPacketHandler.SnrValue = Read( REG_LR_PKTSNRVALUE );
GregCr 0:e6ceb13d2d05 1270 if( this->settings.LoRaPacketHandler.SnrValue & 0x80 ) // The SNR sign bit is 1
GregCr 0:e6ceb13d2d05 1271 {
GregCr 0:e6ceb13d2d05 1272 // Invert and divide by 4
GregCr 0:e6ceb13d2d05 1273 snr = ( ( ~this->settings.LoRaPacketHandler.SnrValue + 1 ) & 0xFF ) >> 2;
GregCr 0:e6ceb13d2d05 1274 snr = -snr;
GregCr 0:e6ceb13d2d05 1275 }
GregCr 0:e6ceb13d2d05 1276 else
GregCr 0:e6ceb13d2d05 1277 {
GregCr 0:e6ceb13d2d05 1278 // Divide by 4
GregCr 0:e6ceb13d2d05 1279 snr = ( this->settings.LoRaPacketHandler.SnrValue & 0xFF ) >> 2;
GregCr 0:e6ceb13d2d05 1280 }
GregCr 0:e6ceb13d2d05 1281
GregCr 7:2b555111463f 1282 int16_t rssi = Read( REG_LR_PKTRSSIVALUE );
mluis 22:7f3aab69cca9 1283 if( snr < 0 )
GregCr 0:e6ceb13d2d05 1284 {
GregCr 0:e6ceb13d2d05 1285 if( this->settings.Channel > RF_MID_BAND_THRESH )
GregCr 0:e6ceb13d2d05 1286 {
GregCr 0:e6ceb13d2d05 1287 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 ) +
GregCr 0:e6ceb13d2d05 1288 snr;
GregCr 0:e6ceb13d2d05 1289 }
GregCr 0:e6ceb13d2d05 1290 else
GregCr 0:e6ceb13d2d05 1291 {
GregCr 0:e6ceb13d2d05 1292 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 ) +
GregCr 0:e6ceb13d2d05 1293 snr;
GregCr 0:e6ceb13d2d05 1294 }
GregCr 0:e6ceb13d2d05 1295 }
GregCr 0:e6ceb13d2d05 1296 else
mluis 25:3778e6204cc1 1297 {
GregCr 0:e6ceb13d2d05 1298 if( this->settings.Channel > RF_MID_BAND_THRESH )
GregCr 0:e6ceb13d2d05 1299 {
GregCr 0:e6ceb13d2d05 1300 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 );
GregCr 0:e6ceb13d2d05 1301 }
GregCr 0:e6ceb13d2d05 1302 else
GregCr 0:e6ceb13d2d05 1303 {
GregCr 0:e6ceb13d2d05 1304 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 );
GregCr 0:e6ceb13d2d05 1305 }
GregCr 0:e6ceb13d2d05 1306 }
GregCr 0:e6ceb13d2d05 1307
GregCr 0:e6ceb13d2d05 1308 this->settings.LoRaPacketHandler.Size = Read( REG_LR_RXNBBYTES );
GregCr 23:1e143575df0f 1309 ReadFifo( rxtxBuffer, this->settings.LoRaPacketHandler.Size );
mluis 25:3778e6204cc1 1310
GregCr 0:e6ceb13d2d05 1311 if( this->settings.LoRa.RxContinuous == false )
GregCr 0:e6ceb13d2d05 1312 {
mluis 21:2e496deb7858 1313 this->settings.State = RF_IDLE;
GregCr 0:e6ceb13d2d05 1314 }
GregCr 0:e6ceb13d2d05 1315 rxTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 1316
mluis 22:7f3aab69cca9 1317 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
GregCr 0:e6ceb13d2d05 1318 {
GregCr 23:1e143575df0f 1319 this->RadioEvents->RxDone( rxtxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue );
GregCr 0:e6ceb13d2d05 1320 }
GregCr 0:e6ceb13d2d05 1321 }
GregCr 0:e6ceb13d2d05 1322 break;
GregCr 0:e6ceb13d2d05 1323 default:
GregCr 0:e6ceb13d2d05 1324 break;
GregCr 0:e6ceb13d2d05 1325 }
GregCr 0:e6ceb13d2d05 1326 break;
mluis 21:2e496deb7858 1327 case RF_TX_RUNNING:
Helmut Tschemernjak 31:e50929bd3f32 1328 txTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 1329 // TxDone interrupt
GregCr 0:e6ceb13d2d05 1330 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1331 {
GregCr 0:e6ceb13d2d05 1332 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1333 // Clear Irq
GregCr 0:e6ceb13d2d05 1334 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
GregCr 0:e6ceb13d2d05 1335 // Intentional fall through
GregCr 0:e6ceb13d2d05 1336 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1337 default:
mluis 21:2e496deb7858 1338 this->settings.State = RF_IDLE;
mluis 22:7f3aab69cca9 1339 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxDone != NULL ) )
GregCr 0:e6ceb13d2d05 1340 {
mluis 22:7f3aab69cca9 1341 this->RadioEvents->TxDone( );
mluis 25:3778e6204cc1 1342 }
GregCr 0:e6ceb13d2d05 1343 break;
GregCr 0:e6ceb13d2d05 1344 }
GregCr 0:e6ceb13d2d05 1345 break;
GregCr 0:e6ceb13d2d05 1346 default:
GregCr 0:e6ceb13d2d05 1347 break;
GregCr 0:e6ceb13d2d05 1348 }
GregCr 0:e6ceb13d2d05 1349 }
GregCr 0:e6ceb13d2d05 1350
GregCr 0:e6ceb13d2d05 1351 void SX1276::OnDio1Irq( void )
GregCr 0:e6ceb13d2d05 1352 {
GregCr 0:e6ceb13d2d05 1353 switch( this->settings.State )
mluis 25:3778e6204cc1 1354 {
mluis 21:2e496deb7858 1355 case RF_RX_RUNNING:
GregCr 0:e6ceb13d2d05 1356 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1357 {
GregCr 0:e6ceb13d2d05 1358 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1359 // FifoLevel interrupt
GregCr 0:e6ceb13d2d05 1360 // Read received packet size
GregCr 0:e6ceb13d2d05 1361 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
GregCr 0:e6ceb13d2d05 1362 {
GregCr 0:e6ceb13d2d05 1363 if( this->settings.Fsk.FixLen == false )
GregCr 0:e6ceb13d2d05 1364 {
GregCr 0:e6ceb13d2d05 1365 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
GregCr 0:e6ceb13d2d05 1366 }
GregCr 0:e6ceb13d2d05 1367 else
GregCr 0:e6ceb13d2d05 1368 {
GregCr 0:e6ceb13d2d05 1369 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
GregCr 0:e6ceb13d2d05 1370 }
GregCr 0:e6ceb13d2d05 1371 }
GregCr 0:e6ceb13d2d05 1372
GregCr 0:e6ceb13d2d05 1373 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.FifoThresh )
GregCr 0:e6ceb13d2d05 1374 {
GregCr 23:1e143575df0f 1375 ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.FifoThresh );
GregCr 0:e6ceb13d2d05 1376 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.FifoThresh;
GregCr 0:e6ceb13d2d05 1377 }
GregCr 0:e6ceb13d2d05 1378 else
GregCr 0:e6ceb13d2d05 1379 {
GregCr 23:1e143575df0f 1380 ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1381 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1382 }
GregCr 0:e6ceb13d2d05 1383 break;
GregCr 0:e6ceb13d2d05 1384 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1385 // Sync time out
GregCr 0:e6ceb13d2d05 1386 rxTimeoutTimer.detach( );
Helmut Tschemernjak 31:e50929bd3f32 1387 // Clear Irq
Helmut Tschemernjak 31:e50929bd3f32 1388 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT );
Helmut Tschemernjak 31:e50929bd3f32 1389
mluis 21:2e496deb7858 1390 this->settings.State = RF_IDLE;
mluis 22:7f3aab69cca9 1391 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
GregCr 0:e6ceb13d2d05 1392 {
mluis 21:2e496deb7858 1393 this->RadioEvents->RxTimeout( );
GregCr 0:e6ceb13d2d05 1394 }
GregCr 0:e6ceb13d2d05 1395 break;
GregCr 0:e6ceb13d2d05 1396 default:
GregCr 0:e6ceb13d2d05 1397 break;
GregCr 0:e6ceb13d2d05 1398 }
GregCr 0:e6ceb13d2d05 1399 break;
mluis 21:2e496deb7858 1400 case RF_TX_RUNNING:
GregCr 0:e6ceb13d2d05 1401 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1402 {
GregCr 0:e6ceb13d2d05 1403 case MODEM_FSK:
mluis 25:3778e6204cc1 1404 // FifoEmpty interrupt
GregCr 0:e6ceb13d2d05 1405 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.ChunkSize )
GregCr 0:e6ceb13d2d05 1406 {
GregCr 23:1e143575df0f 1407 WriteFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.ChunkSize );
GregCr 0:e6ceb13d2d05 1408 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
GregCr 0:e6ceb13d2d05 1409 }
mluis 25:3778e6204cc1 1410 else
GregCr 0:e6ceb13d2d05 1411 {
GregCr 0:e6ceb13d2d05 1412 // Write the last chunk of data
GregCr 23:1e143575df0f 1413 WriteFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1414 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes;
GregCr 0:e6ceb13d2d05 1415 }
GregCr 0:e6ceb13d2d05 1416 break;
GregCr 0:e6ceb13d2d05 1417 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1418 break;
GregCr 0:e6ceb13d2d05 1419 default:
GregCr 0:e6ceb13d2d05 1420 break;
GregCr 0:e6ceb13d2d05 1421 }
mluis 22:7f3aab69cca9 1422 break;
GregCr 0:e6ceb13d2d05 1423 default:
GregCr 0:e6ceb13d2d05 1424 break;
GregCr 0:e6ceb13d2d05 1425 }
GregCr 0:e6ceb13d2d05 1426 }
GregCr 0:e6ceb13d2d05 1427
GregCr 0:e6ceb13d2d05 1428 void SX1276::OnDio2Irq( void )
GregCr 0:e6ceb13d2d05 1429 {
GregCr 0:e6ceb13d2d05 1430 switch( this->settings.State )
mluis 25:3778e6204cc1 1431 {
mluis 21:2e496deb7858 1432 case RF_RX_RUNNING:
GregCr 0:e6ceb13d2d05 1433 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1434 {
GregCr 0:e6ceb13d2d05 1435 case MODEM_FSK:
Helmut Tschemernjak 31:e50929bd3f32 1436 // Checks if DIO4 is connected. If it is not PreambleDtected is set to true.
Helmut Tschemernjak 31:e50929bd3f32 1437 if( this->dioIrq[4] == NULL )
Helmut Tschemernjak 31:e50929bd3f32 1438 {
Helmut Tschemernjak 31:e50929bd3f32 1439 this->settings.FskPacketHandler.PreambleDetected = true;
Helmut Tschemernjak 31:e50929bd3f32 1440 }
Helmut Tschemernjak 31:e50929bd3f32 1441
GregCr 0:e6ceb13d2d05 1442 if( ( this->settings.FskPacketHandler.PreambleDetected == true ) && ( this->settings.FskPacketHandler.SyncWordDetected == false ) )
GregCr 0:e6ceb13d2d05 1443 {
GregCr 0:e6ceb13d2d05 1444 rxTimeoutSyncWord.detach( );
mluis 25:3778e6204cc1 1445
GregCr 0:e6ceb13d2d05 1446 this->settings.FskPacketHandler.SyncWordDetected = true;
mluis 25:3778e6204cc1 1447
GregCr 0:e6ceb13d2d05 1448 this->settings.FskPacketHandler.RssiValue = -( Read( REG_RSSIVALUE ) >> 1 );
GregCr 0:e6ceb13d2d05 1449
GregCr 0:e6ceb13d2d05 1450 this->settings.FskPacketHandler.AfcValue = ( int32_t )( double )( ( ( uint16_t )Read( REG_AFCMSB ) << 8 ) |
GregCr 0:e6ceb13d2d05 1451 ( uint16_t )Read( REG_AFCLSB ) ) *
GregCr 0:e6ceb13d2d05 1452 ( double )FREQ_STEP;
GregCr 0:e6ceb13d2d05 1453 this->settings.FskPacketHandler.RxGain = ( Read( REG_LNA ) >> 5 ) & 0x07;
GregCr 0:e6ceb13d2d05 1454 }
GregCr 0:e6ceb13d2d05 1455 break;
GregCr 0:e6ceb13d2d05 1456 case MODEM_LORA:
GregCr 6:e7f02929cd3d 1457 if( this->settings.LoRa.FreqHopOn == true )
GregCr 6:e7f02929cd3d 1458 {
GregCr 6:e7f02929cd3d 1459 // Clear Irq
GregCr 6:e7f02929cd3d 1460 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
mluis 25:3778e6204cc1 1461
mluis 22:7f3aab69cca9 1462 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
mluis 13:618826a997e2 1463 {
mluis 21:2e496deb7858 1464 this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
mluis 13:618826a997e2 1465 }
mluis 22:7f3aab69cca9 1466 }
GregCr 0:e6ceb13d2d05 1467 break;
GregCr 0:e6ceb13d2d05 1468 default:
GregCr 0:e6ceb13d2d05 1469 break;
GregCr 0:e6ceb13d2d05 1470 }
GregCr 0:e6ceb13d2d05 1471 break;
mluis 21:2e496deb7858 1472 case RF_TX_RUNNING:
GregCr 0:e6ceb13d2d05 1473 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1474 {
GregCr 0:e6ceb13d2d05 1475 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1476 break;
GregCr 0:e6ceb13d2d05 1477 case MODEM_LORA:
GregCr 6:e7f02929cd3d 1478 if( this->settings.LoRa.FreqHopOn == true )
GregCr 6:e7f02929cd3d 1479 {
GregCr 6:e7f02929cd3d 1480 // Clear Irq
GregCr 6:e7f02929cd3d 1481 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
mluis 25:3778e6204cc1 1482
mluis 22:7f3aab69cca9 1483 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
mluis 13:618826a997e2 1484 {
mluis 21:2e496deb7858 1485 this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
mluis 13:618826a997e2 1486 }
mluis 22:7f3aab69cca9 1487 }
GregCr 0:e6ceb13d2d05 1488 break;
GregCr 0:e6ceb13d2d05 1489 default:
GregCr 0:e6ceb13d2d05 1490 break;
GregCr 0:e6ceb13d2d05 1491 }
mluis 22:7f3aab69cca9 1492 break;
GregCr 0:e6ceb13d2d05 1493 default:
GregCr 0:e6ceb13d2d05 1494 break;
GregCr 0:e6ceb13d2d05 1495 }
GregCr 0:e6ceb13d2d05 1496 }
GregCr 0:e6ceb13d2d05 1497
GregCr 0:e6ceb13d2d05 1498 void SX1276::OnDio3Irq( void )
GregCr 0:e6ceb13d2d05 1499 {
GregCr 0:e6ceb13d2d05 1500 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1501 {
GregCr 0:e6ceb13d2d05 1502 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1503 break;
GregCr 0:e6ceb13d2d05 1504 case MODEM_LORA:
mluis 22:7f3aab69cca9 1505 if( ( Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
mluis 13:618826a997e2 1506 {
mluis 13:618826a997e2 1507 // Clear Irq
mluis 22:7f3aab69cca9 1508 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
mluis 22:7f3aab69cca9 1509 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
mluis 13:618826a997e2 1510 {
mluis 21:2e496deb7858 1511 this->RadioEvents->CadDone( true );
mluis 13:618826a997e2 1512 }
GregCr 12:aa5b3bf7fdf4 1513 }
GregCr 12:aa5b3bf7fdf4 1514 else
mluis 25:3778e6204cc1 1515 {
mluis 13:618826a997e2 1516 // Clear Irq
mluis 13:618826a997e2 1517 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
mluis 22:7f3aab69cca9 1518 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
mluis 13:618826a997e2 1519 {
mluis 21:2e496deb7858 1520 this->RadioEvents->CadDone( false );
mluis 13:618826a997e2 1521 }
GregCr 7:2b555111463f 1522 }
GregCr 0:e6ceb13d2d05 1523 break;
GregCr 0:e6ceb13d2d05 1524 default:
GregCr 0:e6ceb13d2d05 1525 break;
GregCr 0:e6ceb13d2d05 1526 }
GregCr 0:e6ceb13d2d05 1527 }
GregCr 0:e6ceb13d2d05 1528
GregCr 0:e6ceb13d2d05 1529 void SX1276::OnDio4Irq( void )
GregCr 0:e6ceb13d2d05 1530 {
GregCr 0:e6ceb13d2d05 1531 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1532 {
GregCr 0:e6ceb13d2d05 1533 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1534 {
GregCr 0:e6ceb13d2d05 1535 if( this->settings.FskPacketHandler.PreambleDetected == false )
GregCr 0:e6ceb13d2d05 1536 {
GregCr 0:e6ceb13d2d05 1537 this->settings.FskPacketHandler.PreambleDetected = true;
mluis 25:3778e6204cc1 1538 }
GregCr 0:e6ceb13d2d05 1539 }
GregCr 0:e6ceb13d2d05 1540 break;
GregCr 0:e6ceb13d2d05 1541 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1542 break;
GregCr 0:e6ceb13d2d05 1543 default:
GregCr 0:e6ceb13d2d05 1544 break;
GregCr 0:e6ceb13d2d05 1545 }
GregCr 0:e6ceb13d2d05 1546 }
GregCr 0:e6ceb13d2d05 1547
GregCr 0:e6ceb13d2d05 1548 void SX1276::OnDio5Irq( void )
GregCr 0:e6ceb13d2d05 1549 {
GregCr 0:e6ceb13d2d05 1550 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1551 {
GregCr 0:e6ceb13d2d05 1552 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1553 break;
GregCr 0:e6ceb13d2d05 1554 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1555 break;
GregCr 0:e6ceb13d2d05 1556 default:
GregCr 0:e6ceb13d2d05 1557 break;
GregCr 0:e6ceb13d2d05 1558 }
mluis 13:618826a997e2 1559 }