Semtech SX1272 radio chipset driver - ported based on Semtech SX1276 driver.

Dependents:   Elmo-Terminal LoRaWAN-test-app Elmo-Terminal-App LoRaWAN_Semtech_stack ... more

Committer:
mleksio
Date:
Wed Dec 16 14:25:04 2015 +0000
Revision:
8:ead3f4cc5923
Parent:
3:81cc2c384b1b
Child:
9:f53b11725565
firt commit.

Who changed what in which revision?

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