wayne roberts / Mbed OS LoRaWAN_singlechannel_endnode

Dependencies:   SX127x sx12xx_hal TSL2561

Committer:
dudmuck
Date:
Fri May 26 11:00:03 2017 -0700
Revision:
3:aead8f8fdc1f
Parent:
0:8f0d0ae0a077
Child:
10:00997daeb0c0
add choice of radio chip

Who changed what in which revision?

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