wayne roberts / Mbed OS LoRaWAN_singlechannel_endnode

Dependencies:   SX127x sx12xx_hal TSL2561

Committer:
dudmuck
Date:
Thu May 18 15:11:53 2017 -0700
Revision:
0:8f0d0ae0a077
Child:
3:aead8f8fdc1f
initial commit

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