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:
Sat May 06 11:52:23 2017 +0200
Revision:
34:07e89f23c734
Parent:
33:5db0d1e716b1
Child:
38:d9189d958db8
Updated the SX1276 driver to be way more generic.
Common support for Murata, RFM95 and Semtech SX1276MB1MAS
and SX1276MB1LAS modules.
Operating system dependent code is now the the _hal files.

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