This library update contains changes according to the HW-modification.

Dependents:   LoRaWAN_Serial_port_driven_and_configurable_ELMO_based_on_TxRx_Template

Fork of SX1272lib by Espotel

Changes compared to original SX1272lib:

HW modification was made to remove RFO-output and replaced with PABOOST-output. PASELECT changed accordingly.

Committer:
KosTee
Date:
Fri Oct 07 11:35:50 2016 +0000
Revision:
13:1af18cdef696
Parent:
11:3133174407a2
RFO & PABOOST transmit modification has been done to some devices.; Selection can be made on sx1272-hal.cpp.; The new transmit route is currently commented on sx1272-hal.cpp, cause majority of devices still use the old route.;

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;
mleksio 9:f53b11725565 58 this->rxTxBuffer = 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 {
mleksio 9:f53b11725565 80 delete this->rxTxBuffer;
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
mleksio 9:f53b11725565 220 if( fixLen == 1 )
mleksio 9:f53b11725565 221 {
mleksio 9:f53b11725565 222 Write( REG_PAYLOADLENGTH, payloadLen );
mleksio 9:f53b11725565 223 }
mleksio 9:f53b11725565 224 else
mleksio 9:f53b11725565 225 {
mleksio 9:f53b11725565 226 Write( REG_PAYLOADLENGTH, 0xFF ); // Set payload length to the maximum
mleksio 9:f53b11725565 227 }
WGorniak 0:669f3b0e91c8 228 Write( REG_PACKETCONFIG1,
WGorniak 0:669f3b0e91c8 229 ( Read( REG_PACKETCONFIG1 ) &
WGorniak 0:669f3b0e91c8 230 RF_PACKETCONFIG1_CRC_MASK &
WGorniak 0:669f3b0e91c8 231 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
WGorniak 0:669f3b0e91c8 232 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
WGorniak 0:669f3b0e91c8 233 ( crcOn << 4 ) );
WGorniak 0:669f3b0e91c8 234 }
WGorniak 0:669f3b0e91c8 235 break;
WGorniak 0:669f3b0e91c8 236 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 237 {
WGorniak 0:669f3b0e91c8 238 this->settings.LoRa.Bandwidth = bandwidth;
WGorniak 0:669f3b0e91c8 239 this->settings.LoRa.Datarate = datarate;
WGorniak 0:669f3b0e91c8 240 this->settings.LoRa.Coderate = coderate;
mleksio 9:f53b11725565 241 this->settings.LoRa.PreambleLen = preambleLen;
WGorniak 0:669f3b0e91c8 242 this->settings.LoRa.FixLen = fixLen;
WGorniak 0:669f3b0e91c8 243 this->settings.LoRa.PayloadLen = payloadLen;
WGorniak 0:669f3b0e91c8 244 this->settings.LoRa.CrcOn = crcOn;
WGorniak 0:669f3b0e91c8 245 this->settings.LoRa.FreqHopOn = freqHopOn;
WGorniak 0:669f3b0e91c8 246 this->settings.LoRa.HopPeriod = hopPeriod;
WGorniak 0:669f3b0e91c8 247 this->settings.LoRa.IqInverted = iqInverted;
WGorniak 0:669f3b0e91c8 248 this->settings.LoRa.RxContinuous = rxContinuous;
WGorniak 0:669f3b0e91c8 249
WGorniak 0:669f3b0e91c8 250 if( datarate > 12 )
WGorniak 0:669f3b0e91c8 251 {
WGorniak 0:669f3b0e91c8 252 datarate = 12;
WGorniak 0:669f3b0e91c8 253 }
WGorniak 0:669f3b0e91c8 254 else if( datarate < 6 )
WGorniak 0:669f3b0e91c8 255 {
WGorniak 0:669f3b0e91c8 256 datarate = 6;
WGorniak 0:669f3b0e91c8 257 }
WGorniak 0:669f3b0e91c8 258
WGorniak 0:669f3b0e91c8 259 if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
WGorniak 0:669f3b0e91c8 260 ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
WGorniak 0:669f3b0e91c8 261 {
WGorniak 0:669f3b0e91c8 262 this->settings.LoRa.LowDatarateOptimize = 0x01;
WGorniak 0:669f3b0e91c8 263 }
WGorniak 0:669f3b0e91c8 264 else
WGorniak 0:669f3b0e91c8 265 {
WGorniak 0:669f3b0e91c8 266 this->settings.LoRa.LowDatarateOptimize = 0x00;
WGorniak 0:669f3b0e91c8 267 }
WGorniak 0:669f3b0e91c8 268
WGorniak 0:669f3b0e91c8 269 Write( REG_LR_MODEMCONFIG1,
WGorniak 0:669f3b0e91c8 270 ( Read( REG_LR_MODEMCONFIG1 ) &
WGorniak 0:669f3b0e91c8 271 RFLR_MODEMCONFIG1_BW_MASK &
WGorniak 0:669f3b0e91c8 272 RFLR_MODEMCONFIG1_CODINGRATE_MASK &
WGorniak 0:669f3b0e91c8 273 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK &
WGorniak 0:669f3b0e91c8 274 RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK &
WGorniak 0:669f3b0e91c8 275 RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK ) |
WGorniak 0:669f3b0e91c8 276 ( bandwidth << 6 ) | ( coderate << 3 ) |
WGorniak 0:669f3b0e91c8 277 ( fixLen << 2 ) | ( crcOn << 1 ) |
WGorniak 0:669f3b0e91c8 278 this->settings.LoRa.LowDatarateOptimize );
WGorniak 0:669f3b0e91c8 279
WGorniak 0:669f3b0e91c8 280 Write( REG_LR_MODEMCONFIG2,
WGorniak 0:669f3b0e91c8 281 ( Read( REG_LR_MODEMCONFIG2 ) &
WGorniak 0:669f3b0e91c8 282 RFLR_MODEMCONFIG2_SF_MASK &
WGorniak 0:669f3b0e91c8 283 RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) |
WGorniak 0:669f3b0e91c8 284 ( datarate << 4 ) |
WGorniak 0:669f3b0e91c8 285 ( ( symbTimeout >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) );
WGorniak 0:669f3b0e91c8 286
WGorniak 0:669f3b0e91c8 287 Write( REG_LR_SYMBTIMEOUTLSB, ( uint8_t )( symbTimeout & 0xFF ) );
WGorniak 0:669f3b0e91c8 288
WGorniak 0:669f3b0e91c8 289 Write( REG_LR_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
WGorniak 0:669f3b0e91c8 290 Write( REG_LR_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
WGorniak 0:669f3b0e91c8 291
WGorniak 0:669f3b0e91c8 292 if( fixLen == 1 )
WGorniak 0:669f3b0e91c8 293 {
WGorniak 0:669f3b0e91c8 294 Write( REG_LR_PAYLOADLENGTH, payloadLen );
WGorniak 0:669f3b0e91c8 295 }
WGorniak 0:669f3b0e91c8 296
WGorniak 0:669f3b0e91c8 297 if( this->settings.LoRa.FreqHopOn == true )
WGorniak 0:669f3b0e91c8 298 {
WGorniak 0:669f3b0e91c8 299 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
WGorniak 0:669f3b0e91c8 300 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
WGorniak 0:669f3b0e91c8 301 }
WGorniak 0:669f3b0e91c8 302
WGorniak 0:669f3b0e91c8 303 if( datarate == 6 )
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_SF6 );
WGorniak 0:669f3b0e91c8 309 Write( REG_LR_DETECTIONTHRESHOLD,
WGorniak 0:669f3b0e91c8 310 RFLR_DETECTIONTHRESH_SF6 );
WGorniak 0:669f3b0e91c8 311 }
WGorniak 0:669f3b0e91c8 312 else
WGorniak 0:669f3b0e91c8 313 {
WGorniak 0:669f3b0e91c8 314 Write( REG_LR_DETECTOPTIMIZE,
WGorniak 0:669f3b0e91c8 315 ( Read( REG_LR_DETECTOPTIMIZE ) &
WGorniak 0:669f3b0e91c8 316 RFLR_DETECTIONOPTIMIZE_MASK ) |
WGorniak 0:669f3b0e91c8 317 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
WGorniak 0:669f3b0e91c8 318 Write( REG_LR_DETECTIONTHRESHOLD,
WGorniak 0:669f3b0e91c8 319 RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
WGorniak 0:669f3b0e91c8 320 }
WGorniak 0:669f3b0e91c8 321 }
WGorniak 0:669f3b0e91c8 322 break;
WGorniak 0:669f3b0e91c8 323 }
WGorniak 0:669f3b0e91c8 324 }
WGorniak 0:669f3b0e91c8 325
WGorniak 0:669f3b0e91c8 326
WGorniak 3:81cc2c384b1b 327
WGorniak 3:81cc2c384b1b 328 void SX1272::SetTxConfig( ModemType modem, int8_t power, uint32_t fdev,
WGorniak 3:81cc2c384b1b 329 uint32_t bandwidth, uint32_t datarate,
WGorniak 3:81cc2c384b1b 330 uint8_t coderate, uint16_t preambleLen,
WGorniak 3:81cc2c384b1b 331 bool fixLen, bool crcOn, bool freqHopOn,
WGorniak 3:81cc2c384b1b 332 uint8_t hopPeriod, bool iqInverted, uint32_t timeout )
WGorniak 3:81cc2c384b1b 333 {
WGorniak 3:81cc2c384b1b 334 SetTxConfig(modem, power, fdev, bandwidth, datarate, coderate, preambleLen,
WGorniak 3:81cc2c384b1b 335 fixLen, crcOn, freqHopOn, hopPeriod, iqInverted, timeout,
WGorniak 3:81cc2c384b1b 336 GetPaSelect( this->settings.Channel ) == RF_PACONFIG_PASELECT_PABOOST);
WGorniak 3:81cc2c384b1b 337 }
WGorniak 3:81cc2c384b1b 338
WGorniak 0:669f3b0e91c8 339 void SX1272::SetTxConfig( ModemType modem, int8_t power, uint32_t fdev,
WGorniak 0:669f3b0e91c8 340 uint32_t bandwidth, uint32_t datarate,
WGorniak 0:669f3b0e91c8 341 uint8_t coderate, uint16_t preambleLen,
WGorniak 0:669f3b0e91c8 342 bool fixLen, bool crcOn, bool freqHopOn,
WGorniak 3:81cc2c384b1b 343 uint8_t hopPeriod, bool iqInverted, uint32_t timeout, bool paBoost )
WGorniak 0:669f3b0e91c8 344 {
WGorniak 0:669f3b0e91c8 345 uint8_t paConfig = 0;
WGorniak 0:669f3b0e91c8 346 uint8_t paDac = 0;
WGorniak 0:669f3b0e91c8 347
WGorniak 0:669f3b0e91c8 348 SetModem( modem );
WGorniak 0:669f3b0e91c8 349
WGorniak 0:669f3b0e91c8 350 paConfig = Read( REG_PACONFIG );
WGorniak 0:669f3b0e91c8 351 paDac = Read( REG_PADAC );
WGorniak 0:669f3b0e91c8 352
mleksio 9:f53b11725565 353 paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | GetPaSelect( this->settings.Channel );
WGorniak 0:669f3b0e91c8 354
WGorniak 0:669f3b0e91c8 355 if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
WGorniak 0:669f3b0e91c8 356 {
WGorniak 0:669f3b0e91c8 357 if( power > 17 )
WGorniak 0:669f3b0e91c8 358 {
WGorniak 0:669f3b0e91c8 359 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON;
WGorniak 0:669f3b0e91c8 360 }
WGorniak 0:669f3b0e91c8 361 else
WGorniak 0:669f3b0e91c8 362 {
WGorniak 0:669f3b0e91c8 363 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF;
WGorniak 0:669f3b0e91c8 364 }
WGorniak 0:669f3b0e91c8 365 if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON )
WGorniak 0:669f3b0e91c8 366 {
WGorniak 0:669f3b0e91c8 367 if( power < 5 )
WGorniak 0:669f3b0e91c8 368 {
WGorniak 0:669f3b0e91c8 369 power = 5;
WGorniak 0:669f3b0e91c8 370 }
WGorniak 0:669f3b0e91c8 371 if( power > 20 )
WGorniak 0:669f3b0e91c8 372 {
WGorniak 0:669f3b0e91c8 373 power = 20;
WGorniak 0:669f3b0e91c8 374 }
WGorniak 0:669f3b0e91c8 375 paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
WGorniak 0:669f3b0e91c8 376 }
WGorniak 0:669f3b0e91c8 377 else
WGorniak 0:669f3b0e91c8 378 {
WGorniak 0:669f3b0e91c8 379 if( power < 2 )
WGorniak 0:669f3b0e91c8 380 {
WGorniak 0:669f3b0e91c8 381 power = 2;
WGorniak 0:669f3b0e91c8 382 }
WGorniak 0:669f3b0e91c8 383 if( power > 17 )
WGorniak 0:669f3b0e91c8 384 {
WGorniak 0:669f3b0e91c8 385 power = 17;
WGorniak 0:669f3b0e91c8 386 }
WGorniak 0:669f3b0e91c8 387 paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
WGorniak 0:669f3b0e91c8 388 }
WGorniak 0:669f3b0e91c8 389 }
WGorniak 0:669f3b0e91c8 390 else
WGorniak 0:669f3b0e91c8 391 {
WGorniak 0:669f3b0e91c8 392 if( power < -1 )
WGorniak 0:669f3b0e91c8 393 {
WGorniak 0:669f3b0e91c8 394 power = -1;
WGorniak 0:669f3b0e91c8 395 }
WGorniak 0:669f3b0e91c8 396 if( power > 14 )
WGorniak 0:669f3b0e91c8 397 {
WGorniak 0:669f3b0e91c8 398 power = 14;
WGorniak 0:669f3b0e91c8 399 }
WGorniak 0:669f3b0e91c8 400 paConfig = ( paConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
WGorniak 0:669f3b0e91c8 401 }
WGorniak 0:669f3b0e91c8 402 Write( REG_PACONFIG, paConfig );
WGorniak 0:669f3b0e91c8 403 Write( REG_PADAC, paDac );
WGorniak 0:669f3b0e91c8 404
WGorniak 0:669f3b0e91c8 405 switch( modem )
WGorniak 0:669f3b0e91c8 406 {
WGorniak 0:669f3b0e91c8 407 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 408 {
WGorniak 0:669f3b0e91c8 409 this->settings.Fsk.Power = power;
WGorniak 0:669f3b0e91c8 410 this->settings.Fsk.Fdev = fdev;
WGorniak 0:669f3b0e91c8 411 this->settings.Fsk.Bandwidth = bandwidth;
WGorniak 0:669f3b0e91c8 412 this->settings.Fsk.Datarate = datarate;
WGorniak 0:669f3b0e91c8 413 this->settings.Fsk.PreambleLen = preambleLen;
WGorniak 0:669f3b0e91c8 414 this->settings.Fsk.FixLen = fixLen;
WGorniak 0:669f3b0e91c8 415 this->settings.Fsk.CrcOn = crcOn;
WGorniak 0:669f3b0e91c8 416 this->settings.Fsk.IqInverted = iqInverted;
WGorniak 0:669f3b0e91c8 417 this->settings.Fsk.TxTimeout = timeout;
WGorniak 0:669f3b0e91c8 418
WGorniak 0:669f3b0e91c8 419 fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
WGorniak 0:669f3b0e91c8 420 Write( REG_FDEVMSB, ( uint8_t )( fdev >> 8 ) );
WGorniak 0:669f3b0e91c8 421 Write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) );
WGorniak 0:669f3b0e91c8 422
WGorniak 0:669f3b0e91c8 423 datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
WGorniak 0:669f3b0e91c8 424 Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
WGorniak 0:669f3b0e91c8 425 Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
WGorniak 0:669f3b0e91c8 426
WGorniak 0:669f3b0e91c8 427 Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
WGorniak 0:669f3b0e91c8 428 Write( REG_PREAMBLELSB, preambleLen & 0xFF );
WGorniak 0:669f3b0e91c8 429
WGorniak 0:669f3b0e91c8 430 Write( REG_PACKETCONFIG1,
WGorniak 0:669f3b0e91c8 431 ( Read( REG_PACKETCONFIG1 ) &
WGorniak 0:669f3b0e91c8 432 RF_PACKETCONFIG1_CRC_MASK &
WGorniak 0:669f3b0e91c8 433 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
WGorniak 0:669f3b0e91c8 434 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
WGorniak 0:669f3b0e91c8 435 ( crcOn << 4 ) );
WGorniak 0:669f3b0e91c8 436
WGorniak 0:669f3b0e91c8 437 }
WGorniak 0:669f3b0e91c8 438 break;
WGorniak 0:669f3b0e91c8 439 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 440 {
WGorniak 0:669f3b0e91c8 441 this->settings.LoRa.Power = power;
WGorniak 0:669f3b0e91c8 442 this->settings.LoRa.Bandwidth = bandwidth;
WGorniak 0:669f3b0e91c8 443 this->settings.LoRa.Datarate = datarate;
WGorniak 0:669f3b0e91c8 444 this->settings.LoRa.Coderate = coderate;
WGorniak 0:669f3b0e91c8 445 this->settings.LoRa.PreambleLen = preambleLen;
WGorniak 0:669f3b0e91c8 446 this->settings.LoRa.FixLen = fixLen;
WGorniak 0:669f3b0e91c8 447 this->settings.LoRa.FreqHopOn = freqHopOn;
WGorniak 0:669f3b0e91c8 448 this->settings.LoRa.HopPeriod = hopPeriod;
WGorniak 0:669f3b0e91c8 449 this->settings.LoRa.CrcOn = crcOn;
WGorniak 0:669f3b0e91c8 450 this->settings.LoRa.IqInverted = iqInverted;
WGorniak 0:669f3b0e91c8 451 this->settings.LoRa.TxTimeout = timeout;
WGorniak 0:669f3b0e91c8 452
WGorniak 0:669f3b0e91c8 453 if( datarate > 12 )
WGorniak 0:669f3b0e91c8 454 {
WGorniak 0:669f3b0e91c8 455 datarate = 12;
WGorniak 0:669f3b0e91c8 456 }
WGorniak 0:669f3b0e91c8 457 else if( datarate < 6 )
WGorniak 0:669f3b0e91c8 458 {
WGorniak 0:669f3b0e91c8 459 datarate = 6;
WGorniak 0:669f3b0e91c8 460 }
WGorniak 0:669f3b0e91c8 461 if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
WGorniak 0:669f3b0e91c8 462 ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
WGorniak 0:669f3b0e91c8 463 {
WGorniak 0:669f3b0e91c8 464 this->settings.LoRa.LowDatarateOptimize = 0x01;
WGorniak 0:669f3b0e91c8 465 }
WGorniak 0:669f3b0e91c8 466 else
WGorniak 0:669f3b0e91c8 467 {
WGorniak 0:669f3b0e91c8 468 this->settings.LoRa.LowDatarateOptimize = 0x00;
WGorniak 0:669f3b0e91c8 469 }
WGorniak 0:669f3b0e91c8 470
WGorniak 0:669f3b0e91c8 471 if( this->settings.LoRa.FreqHopOn == true )
WGorniak 0:669f3b0e91c8 472 {
WGorniak 0:669f3b0e91c8 473 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
WGorniak 0:669f3b0e91c8 474 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
WGorniak 0:669f3b0e91c8 475 }
WGorniak 0:669f3b0e91c8 476
WGorniak 0:669f3b0e91c8 477 Write( REG_LR_MODEMCONFIG1,
WGorniak 0:669f3b0e91c8 478 ( Read( REG_LR_MODEMCONFIG1 ) &
WGorniak 0:669f3b0e91c8 479 RFLR_MODEMCONFIG1_BW_MASK &
WGorniak 0:669f3b0e91c8 480 RFLR_MODEMCONFIG1_CODINGRATE_MASK &
WGorniak 0:669f3b0e91c8 481 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK &
WGorniak 0:669f3b0e91c8 482 RFLR_MODEMCONFIG1_RXPAYLOADCRC_MASK &
WGorniak 0:669f3b0e91c8 483 RFLR_MODEMCONFIG1_LOWDATARATEOPTIMIZE_MASK ) |
WGorniak 0:669f3b0e91c8 484 ( bandwidth << 6 ) | ( coderate << 3 ) |
WGorniak 0:669f3b0e91c8 485 ( fixLen << 2 ) | ( crcOn << 1 ) |
WGorniak 0:669f3b0e91c8 486 this->settings.LoRa.LowDatarateOptimize );
WGorniak 0:669f3b0e91c8 487
WGorniak 0:669f3b0e91c8 488 Write( REG_LR_MODEMCONFIG2,
WGorniak 0:669f3b0e91c8 489 ( Read( REG_LR_MODEMCONFIG2 ) &
WGorniak 0:669f3b0e91c8 490 RFLR_MODEMCONFIG2_SF_MASK ) |
WGorniak 0:669f3b0e91c8 491 ( datarate << 4 ) );
WGorniak 0:669f3b0e91c8 492
WGorniak 0:669f3b0e91c8 493
WGorniak 0:669f3b0e91c8 494 Write( REG_LR_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
WGorniak 0:669f3b0e91c8 495 Write( REG_LR_PREAMBLELSB, preambleLen & 0xFF );
WGorniak 0:669f3b0e91c8 496
WGorniak 0:669f3b0e91c8 497 if( datarate == 6 )
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_SF6 );
WGorniak 0:669f3b0e91c8 503 Write( REG_LR_DETECTIONTHRESHOLD,
WGorniak 0:669f3b0e91c8 504 RFLR_DETECTIONTHRESH_SF6 );
WGorniak 0:669f3b0e91c8 505 }
WGorniak 0:669f3b0e91c8 506 else
WGorniak 0:669f3b0e91c8 507 {
WGorniak 0:669f3b0e91c8 508 Write( REG_LR_DETECTOPTIMIZE,
WGorniak 0:669f3b0e91c8 509 ( Read( REG_LR_DETECTOPTIMIZE ) &
WGorniak 0:669f3b0e91c8 510 RFLR_DETECTIONOPTIMIZE_MASK ) |
WGorniak 0:669f3b0e91c8 511 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
WGorniak 0:669f3b0e91c8 512 Write( REG_LR_DETECTIONTHRESHOLD,
WGorniak 0:669f3b0e91c8 513 RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
WGorniak 0:669f3b0e91c8 514 }
WGorniak 0:669f3b0e91c8 515 }
WGorniak 0:669f3b0e91c8 516 break;
WGorniak 0:669f3b0e91c8 517 }
WGorniak 0:669f3b0e91c8 518 }
WGorniak 0:669f3b0e91c8 519
WGorniak 0:669f3b0e91c8 520
WGorniak 0:669f3b0e91c8 521 double SX1272::TimeOnAir( ModemType modem, uint8_t pktLen )
WGorniak 0:669f3b0e91c8 522 {
WGorniak 0:669f3b0e91c8 523 uint32_t airTime = 0;
WGorniak 0:669f3b0e91c8 524
WGorniak 0:669f3b0e91c8 525 switch( modem )
WGorniak 0:669f3b0e91c8 526 {
WGorniak 0:669f3b0e91c8 527 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 528 {
WGorniak 0:669f3b0e91c8 529 airTime = ceil( ( 8 * ( this->settings.Fsk.PreambleLen +
WGorniak 0:669f3b0e91c8 530 ( ( Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
WGorniak 0:669f3b0e91c8 531 ( ( this->settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
WGorniak 0:669f3b0e91c8 532 ( ( ( Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
WGorniak 0:669f3b0e91c8 533 pktLen +
WGorniak 0:669f3b0e91c8 534 ( ( this->settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) /
WGorniak 0:669f3b0e91c8 535 this->settings.Fsk.Datarate ) * 1e6 );
WGorniak 0:669f3b0e91c8 536 }
WGorniak 0:669f3b0e91c8 537 break;
WGorniak 0:669f3b0e91c8 538 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 539 {
WGorniak 0:669f3b0e91c8 540 double bw = 0.0;
WGorniak 0:669f3b0e91c8 541 switch( this->settings.LoRa.Bandwidth )
WGorniak 0:669f3b0e91c8 542 {
WGorniak 0:669f3b0e91c8 543 case 0: // 125 kHz
WGorniak 0:669f3b0e91c8 544 bw = 125e3;
WGorniak 0:669f3b0e91c8 545 break;
WGorniak 0:669f3b0e91c8 546 case 1: // 250 kHz
WGorniak 0:669f3b0e91c8 547 bw = 250e3;
WGorniak 0:669f3b0e91c8 548 break;
WGorniak 0:669f3b0e91c8 549 case 2: // 500 kHz
WGorniak 0:669f3b0e91c8 550 bw = 500e3;
WGorniak 0:669f3b0e91c8 551 break;
WGorniak 0:669f3b0e91c8 552 }
WGorniak 0:669f3b0e91c8 553
WGorniak 0:669f3b0e91c8 554 // Symbol rate : time for one symbol (secs)
WGorniak 0:669f3b0e91c8 555 double rs = bw / ( 1 << this->settings.LoRa.Datarate );
WGorniak 0:669f3b0e91c8 556 double ts = 1 / rs;
WGorniak 0:669f3b0e91c8 557 // time of preamble
WGorniak 0:669f3b0e91c8 558 double tPreamble = ( this->settings.LoRa.PreambleLen + 4.25 ) * ts;
WGorniak 0:669f3b0e91c8 559 // Symbol length of payload and time
WGorniak 0:669f3b0e91c8 560 double tmp = ceil( ( 8 * pktLen - 4 * this->settings.LoRa.Datarate +
WGorniak 0:669f3b0e91c8 561 28 + 16 * this->settings.LoRa.CrcOn -
WGorniak 0:669f3b0e91c8 562 ( this->settings.LoRa.FixLen ? 20 : 0 ) ) /
WGorniak 0:669f3b0e91c8 563 ( double )( 4 * this->settings.LoRa.Datarate -
mleksio 9:f53b11725565 564 ( ( this->settings.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) *
WGorniak 0:669f3b0e91c8 565 ( this->settings.LoRa.Coderate + 4 );
WGorniak 0:669f3b0e91c8 566 double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
WGorniak 0:669f3b0e91c8 567 double tPayload = nPayload * ts;
WGorniak 0:669f3b0e91c8 568 // Time on air
WGorniak 0:669f3b0e91c8 569 double tOnAir = tPreamble + tPayload;
WGorniak 0:669f3b0e91c8 570 // return us secs
WGorniak 0:669f3b0e91c8 571 airTime = floor( tOnAir * 1e6 + 0.999 );
WGorniak 0:669f3b0e91c8 572 }
WGorniak 0:669f3b0e91c8 573 break;
WGorniak 0:669f3b0e91c8 574 }
WGorniak 0:669f3b0e91c8 575 return airTime;
WGorniak 0:669f3b0e91c8 576 }
WGorniak 0:669f3b0e91c8 577
WGorniak 0:669f3b0e91c8 578 void SX1272::Send( uint8_t *buffer, uint8_t size )
WGorniak 0:669f3b0e91c8 579 {
WGorniak 0:669f3b0e91c8 580 uint32_t txTimeout = 0;
WGorniak 0:669f3b0e91c8 581
WGorniak 0:669f3b0e91c8 582 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 583 {
WGorniak 0:669f3b0e91c8 584 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 585 {
WGorniak 0:669f3b0e91c8 586 this->settings.FskPacketHandler.NbBytes = 0;
WGorniak 0:669f3b0e91c8 587 this->settings.FskPacketHandler.Size = size;
WGorniak 0:669f3b0e91c8 588
WGorniak 0:669f3b0e91c8 589 if( this->settings.Fsk.FixLen == false )
WGorniak 0:669f3b0e91c8 590 {
WGorniak 0:669f3b0e91c8 591 WriteFifo( ( uint8_t* )&size, 1 );
WGorniak 0:669f3b0e91c8 592 }
WGorniak 0:669f3b0e91c8 593 else
WGorniak 0:669f3b0e91c8 594 {
WGorniak 0:669f3b0e91c8 595 Write( REG_PAYLOADLENGTH, size );
WGorniak 0:669f3b0e91c8 596 }
WGorniak 0:669f3b0e91c8 597
WGorniak 0:669f3b0e91c8 598 if( ( size > 0 ) && ( size <= 64 ) )
WGorniak 0:669f3b0e91c8 599 {
WGorniak 0:669f3b0e91c8 600 this->settings.FskPacketHandler.ChunkSize = size;
WGorniak 0:669f3b0e91c8 601 }
WGorniak 0:669f3b0e91c8 602 else
WGorniak 0:669f3b0e91c8 603 {
Daniel_espo 11:3133174407a2 604 memcpy( rxTxBuffer, buffer, size );
WGorniak 0:669f3b0e91c8 605 this->settings.FskPacketHandler.ChunkSize = 32;
WGorniak 0:669f3b0e91c8 606 }
WGorniak 0:669f3b0e91c8 607
WGorniak 0:669f3b0e91c8 608 // Write payload buffer
WGorniak 0:669f3b0e91c8 609 WriteFifo( buffer, this->settings.FskPacketHandler.ChunkSize );
WGorniak 0:669f3b0e91c8 610 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
WGorniak 0:669f3b0e91c8 611 txTimeout = this->settings.Fsk.TxTimeout;
WGorniak 0:669f3b0e91c8 612 }
WGorniak 0:669f3b0e91c8 613 break;
WGorniak 0:669f3b0e91c8 614 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 615 {
WGorniak 0:669f3b0e91c8 616 if( this->settings.LoRa.IqInverted == true )
WGorniak 0:669f3b0e91c8 617 {
WGorniak 0:669f3b0e91c8 618 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) );
mleksio 9:f53b11725565 619 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
WGorniak 0:669f3b0e91c8 620 }
WGorniak 0:669f3b0e91c8 621 else
WGorniak 0:669f3b0e91c8 622 {
WGorniak 0:669f3b0e91c8 623 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
mleksio 9:f53b11725565 624 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
WGorniak 0:669f3b0e91c8 625 }
WGorniak 0:669f3b0e91c8 626
WGorniak 0:669f3b0e91c8 627 this->settings.LoRaPacketHandler.Size = size;
WGorniak 0:669f3b0e91c8 628
WGorniak 0:669f3b0e91c8 629 // Initializes the payload size
WGorniak 0:669f3b0e91c8 630 Write( REG_LR_PAYLOADLENGTH, size );
WGorniak 0:669f3b0e91c8 631
WGorniak 0:669f3b0e91c8 632 // Full buffer used for Tx
WGorniak 0:669f3b0e91c8 633 Write( REG_LR_FIFOTXBASEADDR, 0 );
WGorniak 0:669f3b0e91c8 634 Write( REG_LR_FIFOADDRPTR, 0 );
WGorniak 0:669f3b0e91c8 635
WGorniak 0:669f3b0e91c8 636 // FIFO operations can not take place in Sleep mode
WGorniak 0:669f3b0e91c8 637 if( ( Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP )
WGorniak 0:669f3b0e91c8 638 {
WGorniak 0:669f3b0e91c8 639 Standby( );
WGorniak 0:669f3b0e91c8 640 wait_ms( 1 );
WGorniak 0:669f3b0e91c8 641 }
WGorniak 0:669f3b0e91c8 642 // Write payload buffer
WGorniak 0:669f3b0e91c8 643 WriteFifo( buffer, size );
WGorniak 0:669f3b0e91c8 644 txTimeout = this->settings.LoRa.TxTimeout;
WGorniak 0:669f3b0e91c8 645 }
WGorniak 0:669f3b0e91c8 646 break;
WGorniak 0:669f3b0e91c8 647 }
WGorniak 0:669f3b0e91c8 648
WGorniak 0:669f3b0e91c8 649 Tx( txTimeout );
WGorniak 0:669f3b0e91c8 650 }
WGorniak 0:669f3b0e91c8 651
WGorniak 0:669f3b0e91c8 652 void SX1272::Sleep( void )
WGorniak 0:669f3b0e91c8 653 {
WGorniak 0:669f3b0e91c8 654 // Initialize driver timeout timers
WGorniak 0:669f3b0e91c8 655 txTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 656 rxTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 657 SetOpMode( RF_OPMODE_SLEEP );
WGorniak 0:669f3b0e91c8 658 //SX1272.Settings.State = RF_IDLE;
WGorniak 0:669f3b0e91c8 659 }
WGorniak 0:669f3b0e91c8 660
WGorniak 0:669f3b0e91c8 661 void SX1272::Standby( void )
WGorniak 0:669f3b0e91c8 662 {
WGorniak 0:669f3b0e91c8 663 txTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 664 rxTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 665 SetOpMode( RF_OPMODE_STANDBY );
WGorniak 0:669f3b0e91c8 666 //SX1272.Settings.State = RF_IDLE;
WGorniak 0:669f3b0e91c8 667 }
WGorniak 0:669f3b0e91c8 668
WGorniak 0:669f3b0e91c8 669 void SX1272::Rx( uint32_t timeout )
WGorniak 0:669f3b0e91c8 670 {
WGorniak 0:669f3b0e91c8 671 bool rxContinuous = false;
WGorniak 0:669f3b0e91c8 672
WGorniak 0:669f3b0e91c8 673 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 674 {
WGorniak 0:669f3b0e91c8 675 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 676 {
WGorniak 0:669f3b0e91c8 677 rxContinuous = this->settings.Fsk.RxContinuous;
WGorniak 0:669f3b0e91c8 678
WGorniak 0:669f3b0e91c8 679 // DIO0=PayloadReady
WGorniak 0:669f3b0e91c8 680 // DIO1=FifoLevel
WGorniak 0:669f3b0e91c8 681 // DIO2=SyncAddr
WGorniak 0:669f3b0e91c8 682 // DIO3=FifoEmpty
WGorniak 0:669f3b0e91c8 683 // DIO4=Preamble
WGorniak 0:669f3b0e91c8 684 // DIO5=ModeReady
WGorniak 0:669f3b0e91c8 685 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
mleksio 9:f53b11725565 686 RF_DIOMAPPING1_DIO1_MASK &
WGorniak 0:669f3b0e91c8 687 RF_DIOMAPPING1_DIO2_MASK ) |
WGorniak 0:669f3b0e91c8 688 RF_DIOMAPPING1_DIO0_00 |
mleksio 9:f53b11725565 689 RF_DIOMAPPING1_DIO1_00 |
WGorniak 0:669f3b0e91c8 690 RF_DIOMAPPING1_DIO2_11 );
WGorniak 0:669f3b0e91c8 691
WGorniak 0:669f3b0e91c8 692 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
WGorniak 0:669f3b0e91c8 693 RF_DIOMAPPING2_MAP_MASK ) |
WGorniak 0:669f3b0e91c8 694 RF_DIOMAPPING2_DIO4_11 |
WGorniak 0:669f3b0e91c8 695 RF_DIOMAPPING2_MAP_PREAMBLEDETECT );
WGorniak 0:669f3b0e91c8 696
WGorniak 0:669f3b0e91c8 697 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
WGorniak 0:669f3b0e91c8 698
WGorniak 0:669f3b0e91c8 699 this->settings.FskPacketHandler.PreambleDetected = false;
WGorniak 0:669f3b0e91c8 700 this->settings.FskPacketHandler.SyncWordDetected = false;
WGorniak 0:669f3b0e91c8 701 this->settings.FskPacketHandler.NbBytes = 0;
WGorniak 0:669f3b0e91c8 702 this->settings.FskPacketHandler.Size = 0;
WGorniak 0:669f3b0e91c8 703 }
WGorniak 0:669f3b0e91c8 704 break;
WGorniak 0:669f3b0e91c8 705 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 706 {
WGorniak 0:669f3b0e91c8 707 if( this->settings.LoRa.IqInverted == true )
WGorniak 0:669f3b0e91c8 708 {
WGorniak 0:669f3b0e91c8 709 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF ) );
mleksio 9:f53b11725565 710 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_ON );
WGorniak 0:669f3b0e91c8 711 }
WGorniak 0:669f3b0e91c8 712 else
WGorniak 0:669f3b0e91c8 713 {
WGorniak 0:669f3b0e91c8 714 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
mleksio 9:f53b11725565 715 Write( REG_LR_INVERTIQ2, RFLR_INVERTIQ2_OFF );
WGorniak 0:669f3b0e91c8 716 }
WGorniak 0:669f3b0e91c8 717
WGorniak 0:669f3b0e91c8 718 rxContinuous = this->settings.LoRa.RxContinuous;
WGorniak 0:669f3b0e91c8 719
WGorniak 0:669f3b0e91c8 720 if( this->settings.LoRa.FreqHopOn == true )
WGorniak 0:669f3b0e91c8 721 {
WGorniak 0:669f3b0e91c8 722 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
WGorniak 0:669f3b0e91c8 723 //RFLR_IRQFLAGS_RXDONE |
WGorniak 0:669f3b0e91c8 724 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
WGorniak 0:669f3b0e91c8 725 RFLR_IRQFLAGS_VALIDHEADER |
WGorniak 0:669f3b0e91c8 726 RFLR_IRQFLAGS_TXDONE |
WGorniak 0:669f3b0e91c8 727 RFLR_IRQFLAGS_CADDONE |
WGorniak 0:669f3b0e91c8 728 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
WGorniak 0:669f3b0e91c8 729 RFLR_IRQFLAGS_CADDETECTED );
WGorniak 0:669f3b0e91c8 730
WGorniak 0:669f3b0e91c8 731 // DIO0=RxDone, DIO2=FhssChangeChannel
WGorniak 0:669f3b0e91c8 732 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 733 }
WGorniak 0:669f3b0e91c8 734 else
WGorniak 0:669f3b0e91c8 735 {
WGorniak 0:669f3b0e91c8 736 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
WGorniak 0:669f3b0e91c8 737 //RFLR_IRQFLAGS_RXDONE |
WGorniak 0:669f3b0e91c8 738 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
WGorniak 0:669f3b0e91c8 739 RFLR_IRQFLAGS_VALIDHEADER |
WGorniak 0:669f3b0e91c8 740 RFLR_IRQFLAGS_TXDONE |
WGorniak 0:669f3b0e91c8 741 RFLR_IRQFLAGS_CADDONE |
WGorniak 0:669f3b0e91c8 742 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
WGorniak 0:669f3b0e91c8 743 RFLR_IRQFLAGS_CADDETECTED );
WGorniak 0:669f3b0e91c8 744
WGorniak 0:669f3b0e91c8 745 // DIO0=RxDone
WGorniak 0:669f3b0e91c8 746 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
WGorniak 0:669f3b0e91c8 747 }
WGorniak 0:669f3b0e91c8 748 Write( REG_LR_FIFORXBASEADDR, 0 );
WGorniak 0:669f3b0e91c8 749 Write( REG_LR_FIFOADDRPTR, 0 );
WGorniak 0:669f3b0e91c8 750 }
WGorniak 0:669f3b0e91c8 751 break;
WGorniak 0:669f3b0e91c8 752 }
WGorniak 0:669f3b0e91c8 753
mleksio 9:f53b11725565 754 memset( rxTxBuffer, 0, ( size_t )RX_BUFFER_SIZE );
WGorniak 0:669f3b0e91c8 755
WGorniak 0:669f3b0e91c8 756 this->settings.State = RX;
WGorniak 0:669f3b0e91c8 757 if( timeout != 0 )
WGorniak 0:669f3b0e91c8 758 {
WGorniak 0:669f3b0e91c8 759 rxTimeoutTimer.attach_us( this, &SX1272::OnTimeoutIrq, timeout );
WGorniak 0:669f3b0e91c8 760 }
WGorniak 0:669f3b0e91c8 761
WGorniak 0:669f3b0e91c8 762 if( this->settings.Modem == MODEM_FSK )
WGorniak 0:669f3b0e91c8 763 {
WGorniak 0:669f3b0e91c8 764 SetOpMode( RF_OPMODE_RECEIVER );
WGorniak 0:669f3b0e91c8 765
WGorniak 0:669f3b0e91c8 766 if( rxContinuous == false )
WGorniak 0:669f3b0e91c8 767 {
WGorniak 0:669f3b0e91c8 768 rxTimeoutSyncWord.attach_us( this, &SX1272::OnTimeoutIrq, ( 8.0 * ( this->settings.Fsk.PreambleLen +
WGorniak 0:669f3b0e91c8 769 ( ( Read( REG_SYNCCONFIG ) &
WGorniak 0:669f3b0e91c8 770 ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
mleksio 9:f53b11725565 771 1.0 ) + 10.0 ) /
WGorniak 0:669f3b0e91c8 772 ( double )this->settings.Fsk.Datarate ) * 1e6 ) ;
WGorniak 0:669f3b0e91c8 773 }
WGorniak 0:669f3b0e91c8 774
WGorniak 0:669f3b0e91c8 775 }
WGorniak 0:669f3b0e91c8 776 else
WGorniak 0:669f3b0e91c8 777 {
WGorniak 0:669f3b0e91c8 778 if( rxContinuous == true )
WGorniak 0:669f3b0e91c8 779 {
WGorniak 0:669f3b0e91c8 780 SetOpMode( RFLR_OPMODE_RECEIVER );
WGorniak 0:669f3b0e91c8 781 }
WGorniak 0:669f3b0e91c8 782 else
WGorniak 0:669f3b0e91c8 783 {
WGorniak 0:669f3b0e91c8 784 SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
WGorniak 0:669f3b0e91c8 785 }
WGorniak 0:669f3b0e91c8 786 }
WGorniak 0:669f3b0e91c8 787 }
WGorniak 0:669f3b0e91c8 788
WGorniak 0:669f3b0e91c8 789 void SX1272::Tx( uint32_t timeout )
WGorniak 0:669f3b0e91c8 790 {
WGorniak 0:669f3b0e91c8 791
WGorniak 0:669f3b0e91c8 792 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 793 {
WGorniak 0:669f3b0e91c8 794 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 795 {
WGorniak 0:669f3b0e91c8 796 // DIO0=PacketSent
WGorniak 0:669f3b0e91c8 797 // DIO1=FifoLevel
WGorniak 0:669f3b0e91c8 798 // DIO2=FifoFull
WGorniak 0:669f3b0e91c8 799 // DIO3=FifoEmpty
WGorniak 0:669f3b0e91c8 800 // DIO4=LowBat
WGorniak 0:669f3b0e91c8 801 // DIO5=ModeReady
WGorniak 0:669f3b0e91c8 802 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
mleksio 9:f53b11725565 803 RF_DIOMAPPING1_DIO1_MASK &
mleksio 9:f53b11725565 804 RF_DIOMAPPING1_DIO2_MASK ) |
mleksio 9:f53b11725565 805 RF_DIOMAPPING1_DIO1_01 );
WGorniak 0:669f3b0e91c8 806
WGorniak 0:669f3b0e91c8 807 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
WGorniak 0:669f3b0e91c8 808 RF_DIOMAPPING2_MAP_MASK ) );
WGorniak 0:669f3b0e91c8 809 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
WGorniak 0:669f3b0e91c8 810 }
WGorniak 0:669f3b0e91c8 811 break;
WGorniak 0:669f3b0e91c8 812 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 813 {
WGorniak 0:669f3b0e91c8 814 if( this->settings.LoRa.FreqHopOn == true )
WGorniak 0:669f3b0e91c8 815 {
WGorniak 0:669f3b0e91c8 816 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
WGorniak 0:669f3b0e91c8 817 RFLR_IRQFLAGS_RXDONE |
WGorniak 0:669f3b0e91c8 818 RFLR_IRQFLAGS_PAYLOADCRCERROR |
WGorniak 0:669f3b0e91c8 819 RFLR_IRQFLAGS_VALIDHEADER |
WGorniak 0:669f3b0e91c8 820 //RFLR_IRQFLAGS_TXDONE |
WGorniak 0:669f3b0e91c8 821 RFLR_IRQFLAGS_CADDONE |
WGorniak 0:669f3b0e91c8 822 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
WGorniak 0:669f3b0e91c8 823 RFLR_IRQFLAGS_CADDETECTED );
WGorniak 0:669f3b0e91c8 824
WGorniak 0:669f3b0e91c8 825 // DIO0=TxDone, DIO2=FhssChangeChannel
WGorniak 0:669f3b0e91c8 826 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 827 }
WGorniak 0:669f3b0e91c8 828 else
WGorniak 0:669f3b0e91c8 829 {
WGorniak 0:669f3b0e91c8 830 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
WGorniak 0:669f3b0e91c8 831 RFLR_IRQFLAGS_RXDONE |
WGorniak 0:669f3b0e91c8 832 RFLR_IRQFLAGS_PAYLOADCRCERROR |
WGorniak 0:669f3b0e91c8 833 RFLR_IRQFLAGS_VALIDHEADER |
WGorniak 0:669f3b0e91c8 834 //RFLR_IRQFLAGS_TXDONE |
WGorniak 0:669f3b0e91c8 835 RFLR_IRQFLAGS_CADDONE |
WGorniak 0:669f3b0e91c8 836 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
WGorniak 0:669f3b0e91c8 837 RFLR_IRQFLAGS_CADDETECTED );
WGorniak 0:669f3b0e91c8 838
WGorniak 0:669f3b0e91c8 839 // DIO0=TxDone
WGorniak 0:669f3b0e91c8 840 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
WGorniak 0:669f3b0e91c8 841 }
WGorniak 0:669f3b0e91c8 842 }
WGorniak 0:669f3b0e91c8 843 break;
WGorniak 0:669f3b0e91c8 844 }
WGorniak 0:669f3b0e91c8 845
WGorniak 0:669f3b0e91c8 846 this->settings.State = TX;
WGorniak 0:669f3b0e91c8 847 txTimeoutTimer.attach_us( this, &SX1272::OnTimeoutIrq, timeout );
WGorniak 0:669f3b0e91c8 848 SetOpMode( RF_OPMODE_TRANSMITTER );
WGorniak 0:669f3b0e91c8 849
WGorniak 0:669f3b0e91c8 850 }
WGorniak 0:669f3b0e91c8 851
WGorniak 0:669f3b0e91c8 852 void SX1272::StartCad( void )
WGorniak 0:669f3b0e91c8 853 {
WGorniak 0:669f3b0e91c8 854 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 855 {
WGorniak 0:669f3b0e91c8 856 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 857 {
WGorniak 0:669f3b0e91c8 858
WGorniak 0:669f3b0e91c8 859 }
WGorniak 0:669f3b0e91c8 860 break;
WGorniak 0:669f3b0e91c8 861 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 862 {
WGorniak 0:669f3b0e91c8 863 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
WGorniak 0:669f3b0e91c8 864 RFLR_IRQFLAGS_RXDONE |
WGorniak 0:669f3b0e91c8 865 RFLR_IRQFLAGS_PAYLOADCRCERROR |
WGorniak 0:669f3b0e91c8 866 RFLR_IRQFLAGS_VALIDHEADER |
WGorniak 0:669f3b0e91c8 867 RFLR_IRQFLAGS_TXDONE |
WGorniak 0:669f3b0e91c8 868 //RFLR_IRQFLAGS_CADDONE |
WGorniak 0:669f3b0e91c8 869 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
WGorniak 0:669f3b0e91c8 870 //RFLR_IRQFLAGS_CADDETECTED
WGorniak 0:669f3b0e91c8 871 );
WGorniak 0:669f3b0e91c8 872
WGorniak 0:669f3b0e91c8 873 // DIO3=CADDone
WGorniak 0:669f3b0e91c8 874 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
WGorniak 0:669f3b0e91c8 875
WGorniak 0:669f3b0e91c8 876 this->settings.State = CAD;
WGorniak 0:669f3b0e91c8 877 SetOpMode( RFLR_OPMODE_CAD );
WGorniak 0:669f3b0e91c8 878 }
WGorniak 0:669f3b0e91c8 879 break;
WGorniak 0:669f3b0e91c8 880 default:
WGorniak 0:669f3b0e91c8 881 break;
WGorniak 0:669f3b0e91c8 882 }
WGorniak 0:669f3b0e91c8 883 }
WGorniak 0:669f3b0e91c8 884
WGorniak 0:669f3b0e91c8 885
WGorniak 0:669f3b0e91c8 886 int16_t SX1272::GetRssi( ModemType modem )
WGorniak 0:669f3b0e91c8 887 {
WGorniak 0:669f3b0e91c8 888 int16_t rssi = 0;
WGorniak 0:669f3b0e91c8 889
WGorniak 0:669f3b0e91c8 890 switch( modem )
WGorniak 0:669f3b0e91c8 891 {
WGorniak 0:669f3b0e91c8 892 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 893 rssi = -( Read( REG_RSSIVALUE ) >> 1 );
WGorniak 0:669f3b0e91c8 894 break;
WGorniak 0:669f3b0e91c8 895 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 896 rssi = RSSI_OFFSET + Read( REG_LR_RSSIVALUE );
WGorniak 0:669f3b0e91c8 897 break;
WGorniak 0:669f3b0e91c8 898 default:
WGorniak 0:669f3b0e91c8 899 rssi = -1;
WGorniak 0:669f3b0e91c8 900 break;
WGorniak 0:669f3b0e91c8 901 }
WGorniak 0:669f3b0e91c8 902 return rssi;
WGorniak 0:669f3b0e91c8 903 }
WGorniak 0:669f3b0e91c8 904
WGorniak 0:669f3b0e91c8 905 void SX1272::SetOpMode( uint8_t opMode )
WGorniak 0:669f3b0e91c8 906 {
WGorniak 0:669f3b0e91c8 907 if( opMode != previousOpMode )
WGorniak 0:669f3b0e91c8 908 {
WGorniak 0:669f3b0e91c8 909 previousOpMode = opMode;
WGorniak 0:669f3b0e91c8 910 if( opMode == RF_OPMODE_SLEEP )
WGorniak 0:669f3b0e91c8 911 {
WGorniak 0:669f3b0e91c8 912 SetAntSwLowPower( true );
WGorniak 0:669f3b0e91c8 913 }
WGorniak 0:669f3b0e91c8 914 else
WGorniak 0:669f3b0e91c8 915 {
WGorniak 0:669f3b0e91c8 916 SetAntSwLowPower( false );
WGorniak 0:669f3b0e91c8 917 if( opMode == RF_OPMODE_TRANSMITTER )
WGorniak 0:669f3b0e91c8 918 {
WGorniak 0:669f3b0e91c8 919 SetAntSw( 1 );
WGorniak 0:669f3b0e91c8 920 }
WGorniak 0:669f3b0e91c8 921 else
WGorniak 0:669f3b0e91c8 922 {
WGorniak 0:669f3b0e91c8 923 SetAntSw( 0 );
WGorniak 0:669f3b0e91c8 924 }
WGorniak 0:669f3b0e91c8 925 }
WGorniak 0:669f3b0e91c8 926 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
WGorniak 0:669f3b0e91c8 927 }
WGorniak 0:669f3b0e91c8 928 }
WGorniak 0:669f3b0e91c8 929
WGorniak 0:669f3b0e91c8 930 void SX1272::SetModem( ModemType modem )
WGorniak 0:669f3b0e91c8 931 {
WGorniak 0:669f3b0e91c8 932 if( this->settings.Modem == modem )
WGorniak 0:669f3b0e91c8 933 {
WGorniak 0:669f3b0e91c8 934 return;
WGorniak 0:669f3b0e91c8 935 }
WGorniak 0:669f3b0e91c8 936
WGorniak 0:669f3b0e91c8 937 this->settings.Modem = modem;
WGorniak 0:669f3b0e91c8 938 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 939 {
WGorniak 0:669f3b0e91c8 940 default:
WGorniak 0:669f3b0e91c8 941 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 942 SetOpMode( RF_OPMODE_SLEEP );
WGorniak 0:669f3b0e91c8 943 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
WGorniak 0:669f3b0e91c8 944
WGorniak 0:669f3b0e91c8 945 Write( REG_DIOMAPPING1, 0x00 );
WGorniak 0:669f3b0e91c8 946 Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
WGorniak 0:669f3b0e91c8 947 break;
WGorniak 0:669f3b0e91c8 948 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 949 SetOpMode( RF_OPMODE_SLEEP );
WGorniak 0:669f3b0e91c8 950 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
WGorniak 0:669f3b0e91c8 951
WGorniak 0:669f3b0e91c8 952 Write( REG_DIOMAPPING1, 0x00 );
WGorniak 0:669f3b0e91c8 953 Write( REG_DIOMAPPING2, 0x00 );
WGorniak 0:669f3b0e91c8 954 break;
WGorniak 0:669f3b0e91c8 955 }
WGorniak 0:669f3b0e91c8 956 }
WGorniak 0:669f3b0e91c8 957
WGorniak 0:669f3b0e91c8 958 void SX1272::OnTimeoutIrq( void )
WGorniak 0:669f3b0e91c8 959 {
WGorniak 0:669f3b0e91c8 960 switch( this->settings.State )
WGorniak 0:669f3b0e91c8 961 {
WGorniak 0:669f3b0e91c8 962 case RX:
WGorniak 0:669f3b0e91c8 963 if( this->settings.Modem == MODEM_FSK )
WGorniak 0:669f3b0e91c8 964 {
WGorniak 0:669f3b0e91c8 965 this->settings.FskPacketHandler.PreambleDetected = false;
WGorniak 0:669f3b0e91c8 966 this->settings.FskPacketHandler.SyncWordDetected = false;
WGorniak 0:669f3b0e91c8 967 this->settings.FskPacketHandler.NbBytes = 0;
WGorniak 0:669f3b0e91c8 968 this->settings.FskPacketHandler.Size = 0;
WGorniak 0:669f3b0e91c8 969
WGorniak 0:669f3b0e91c8 970 // Clear Irqs
WGorniak 0:669f3b0e91c8 971 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
WGorniak 0:669f3b0e91c8 972 RF_IRQFLAGS1_PREAMBLEDETECT |
WGorniak 0:669f3b0e91c8 973 RF_IRQFLAGS1_SYNCADDRESSMATCH );
WGorniak 0:669f3b0e91c8 974 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
WGorniak 0:669f3b0e91c8 975
WGorniak 0:669f3b0e91c8 976 if( this->settings.Fsk.RxContinuous == true )
WGorniak 0:669f3b0e91c8 977 {
WGorniak 0:669f3b0e91c8 978 // Continuous mode restart Rx chain
WGorniak 0:669f3b0e91c8 979 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
WGorniak 0:669f3b0e91c8 980 }
WGorniak 0:669f3b0e91c8 981 else
WGorniak 0:669f3b0e91c8 982 {
WGorniak 0:669f3b0e91c8 983 this->settings.State = IDLE;
WGorniak 0:669f3b0e91c8 984 rxTimeoutSyncWord.detach( );
WGorniak 0:669f3b0e91c8 985 }
WGorniak 0:669f3b0e91c8 986 }
WGorniak 0:669f3b0e91c8 987 if( ( rxTimeout != NULL ) )
WGorniak 0:669f3b0e91c8 988 {
WGorniak 0:669f3b0e91c8 989 rxTimeout( );
WGorniak 0:669f3b0e91c8 990 }
WGorniak 0:669f3b0e91c8 991 break;
WGorniak 0:669f3b0e91c8 992 case TX:
WGorniak 0:669f3b0e91c8 993 this->settings.State = IDLE;
WGorniak 0:669f3b0e91c8 994 if( ( txTimeout != NULL ) )
WGorniak 0:669f3b0e91c8 995 {
WGorniak 0:669f3b0e91c8 996 txTimeout( );
WGorniak 0:669f3b0e91c8 997 }
WGorniak 0:669f3b0e91c8 998 break;
WGorniak 0:669f3b0e91c8 999 default:
WGorniak 0:669f3b0e91c8 1000 break;
WGorniak 0:669f3b0e91c8 1001 }
WGorniak 0:669f3b0e91c8 1002 }
WGorniak 0:669f3b0e91c8 1003
WGorniak 0:669f3b0e91c8 1004 void SX1272::OnDio0Irq( void )
WGorniak 0:669f3b0e91c8 1005 {
WGorniak 0:669f3b0e91c8 1006 __IO uint8_t irqFlags = 0;
WGorniak 0:669f3b0e91c8 1007
WGorniak 0:669f3b0e91c8 1008 switch( this->settings.State )
WGorniak 0:669f3b0e91c8 1009 {
WGorniak 0:669f3b0e91c8 1010 case RX:
WGorniak 0:669f3b0e91c8 1011 //TimerStop( &RxTimeoutTimer );
WGorniak 0:669f3b0e91c8 1012 // RxDone interrupt
WGorniak 0:669f3b0e91c8 1013 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 1014 {
WGorniak 0:669f3b0e91c8 1015 case MODEM_FSK:
mleksio 9:f53b11725565 1016 if( this->settings.Fsk.CrcOn == true )
WGorniak 0:669f3b0e91c8 1017 {
mleksio 9:f53b11725565 1018 irqFlags = Read( REG_IRQFLAGS2 );
mleksio 9:f53b11725565 1019 if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
mleksio 9:f53b11725565 1020 {
mleksio 9:f53b11725565 1021 // Clear Irqs
mleksio 9:f53b11725565 1022 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
mleksio 9:f53b11725565 1023 RF_IRQFLAGS1_PREAMBLEDETECT |
mleksio 9:f53b11725565 1024 RF_IRQFLAGS1_SYNCADDRESSMATCH );
mleksio 9:f53b11725565 1025 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
WGorniak 0:669f3b0e91c8 1026
mleksio 9:f53b11725565 1027 if( this->settings.Fsk.RxContinuous == false )
mleksio 9:f53b11725565 1028 {
mleksio 9:f53b11725565 1029 //this->settings.State = RF_IDLE;
mleksio 9:f53b11725565 1030 //TimerStart( &RxTimeoutSyncWord );
mleksio 9:f53b11725565 1031 this->settings.State = IDLE;
mleksio 9:f53b11725565 1032 rxTimeoutSyncWord.attach_us( this, &SX1272::OnTimeoutIrq, ( 8.0 * ( this->settings.Fsk.PreambleLen +
mleksio 9:f53b11725565 1033 ( ( Read( REG_SYNCCONFIG ) &
mleksio 9:f53b11725565 1034 ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
mleksio 9:f53b11725565 1035 1.0 ) + 1.0 ) /
mleksio 9:f53b11725565 1036 ( double )this->settings.Fsk.Datarate ) * 1e6 ) ;
WGorniak 0:669f3b0e91c8 1037
mleksio 9:f53b11725565 1038 }
mleksio 9:f53b11725565 1039 else
mleksio 9:f53b11725565 1040 {
mleksio 9:f53b11725565 1041 // Continuous mode restart Rx chain
mleksio 9:f53b11725565 1042 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
mleksio 9:f53b11725565 1043 }
WGorniak 0:669f3b0e91c8 1044
mleksio 9:f53b11725565 1045 //TimerStop( &RxTimeoutTimer );
mleksio 9:f53b11725565 1046 rxTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 1047
mleksio 9:f53b11725565 1048 if( ( rxError != NULL ) )
mleksio 9:f53b11725565 1049 {
mleksio 9:f53b11725565 1050 rxError( );
mleksio 9:f53b11725565 1051 }
WGorniak 0:669f3b0e91c8 1052
mleksio 9:f53b11725565 1053 this->settings.FskPacketHandler.PreambleDetected = false;
mleksio 9:f53b11725565 1054 this->settings.FskPacketHandler.SyncWordDetected = false;
mleksio 9:f53b11725565 1055 this->settings.FskPacketHandler.NbBytes = 0;
mleksio 9:f53b11725565 1056 this->settings.FskPacketHandler.Size = 0;
mleksio 9:f53b11725565 1057 break;
mleksio 9:f53b11725565 1058 }
WGorniak 0:669f3b0e91c8 1059 }
WGorniak 0:669f3b0e91c8 1060
WGorniak 0:669f3b0e91c8 1061 // Read received packet size
WGorniak 0:669f3b0e91c8 1062 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
WGorniak 0:669f3b0e91c8 1063 {
WGorniak 0:669f3b0e91c8 1064 if( this->settings.Fsk.FixLen == false )
WGorniak 0:669f3b0e91c8 1065 {
WGorniak 0:669f3b0e91c8 1066 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
WGorniak 0:669f3b0e91c8 1067 }
WGorniak 0:669f3b0e91c8 1068 else
WGorniak 0:669f3b0e91c8 1069 {
WGorniak 0:669f3b0e91c8 1070 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
WGorniak 0:669f3b0e91c8 1071 }
mleksio 9:f53b11725565 1072 ReadFifo( rxTxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
WGorniak 0:669f3b0e91c8 1073 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
WGorniak 0:669f3b0e91c8 1074 }
WGorniak 0:669f3b0e91c8 1075 else
WGorniak 0:669f3b0e91c8 1076 {
mleksio 9:f53b11725565 1077 ReadFifo( rxTxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
WGorniak 0:669f3b0e91c8 1078 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
WGorniak 0:669f3b0e91c8 1079 }
WGorniak 0:669f3b0e91c8 1080
WGorniak 0:669f3b0e91c8 1081 if( this->settings.Fsk.RxContinuous == false )
WGorniak 0:669f3b0e91c8 1082 {
WGorniak 0:669f3b0e91c8 1083 this->settings.State = IDLE;
WGorniak 0:669f3b0e91c8 1084 rxTimeoutSyncWord.attach_us( this, &SX1272::OnTimeoutIrq, ( 8.0 * ( this->settings.Fsk.PreambleLen +
WGorniak 0:669f3b0e91c8 1085 ( ( Read( REG_SYNCCONFIG ) &
WGorniak 0:669f3b0e91c8 1086 ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
WGorniak 0:669f3b0e91c8 1087 1.0 ) + 1.0 ) /
WGorniak 0:669f3b0e91c8 1088 ( double )this->settings.Fsk.Datarate ) * 1e6 ) ;
WGorniak 0:669f3b0e91c8 1089 }
WGorniak 0:669f3b0e91c8 1090 else
WGorniak 0:669f3b0e91c8 1091 {
WGorniak 0:669f3b0e91c8 1092 // Continuous mode restart Rx chain
WGorniak 0:669f3b0e91c8 1093 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
WGorniak 0:669f3b0e91c8 1094 }
WGorniak 0:669f3b0e91c8 1095 rxTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 1096
WGorniak 0:669f3b0e91c8 1097 if( (rxDone != NULL ) )
WGorniak 0:669f3b0e91c8 1098 {
mleksio 9:f53b11725565 1099 rxDone( rxTxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 );
WGorniak 0:669f3b0e91c8 1100 }
WGorniak 0:669f3b0e91c8 1101 this->settings.FskPacketHandler.PreambleDetected = false;
WGorniak 0:669f3b0e91c8 1102 this->settings.FskPacketHandler.SyncWordDetected = false;
WGorniak 0:669f3b0e91c8 1103 this->settings.FskPacketHandler.NbBytes = 0;
WGorniak 0:669f3b0e91c8 1104 this->settings.FskPacketHandler.Size = 0;
WGorniak 0:669f3b0e91c8 1105 break;
WGorniak 0:669f3b0e91c8 1106
WGorniak 0:669f3b0e91c8 1107 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 1108 {
WGorniak 0:669f3b0e91c8 1109 int8_t snr = 0;
WGorniak 0:669f3b0e91c8 1110
WGorniak 0:669f3b0e91c8 1111 // Clear Irq
WGorniak 0:669f3b0e91c8 1112 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
WGorniak 0:669f3b0e91c8 1113
WGorniak 0:669f3b0e91c8 1114 irqFlags = Read( REG_LR_IRQFLAGS );
WGorniak 0:669f3b0e91c8 1115 if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
WGorniak 0:669f3b0e91c8 1116 {
WGorniak 0:669f3b0e91c8 1117 // Clear Irq
WGorniak 0:669f3b0e91c8 1118 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
WGorniak 0:669f3b0e91c8 1119
WGorniak 0:669f3b0e91c8 1120 if( this->settings.LoRa.RxContinuous == false )
WGorniak 0:669f3b0e91c8 1121 {
WGorniak 0:669f3b0e91c8 1122 this->settings.State = IDLE;
WGorniak 0:669f3b0e91c8 1123 }
WGorniak 0:669f3b0e91c8 1124 rxTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 1125
WGorniak 0:669f3b0e91c8 1126 if( ( rxError != NULL ) )
WGorniak 0:669f3b0e91c8 1127 {
WGorniak 0:669f3b0e91c8 1128 rxError( );
WGorniak 0:669f3b0e91c8 1129 }
WGorniak 0:669f3b0e91c8 1130
WGorniak 0:669f3b0e91c8 1131 break;
WGorniak 0:669f3b0e91c8 1132 }
WGorniak 0:669f3b0e91c8 1133
WGorniak 0:669f3b0e91c8 1134 this->settings.LoRaPacketHandler.SnrValue = Read( REG_LR_PKTSNRVALUE );
WGorniak 0:669f3b0e91c8 1135 if( this->settings.LoRaPacketHandler.SnrValue & 0x80 ) // The SNR sign bit is 1
WGorniak 0:669f3b0e91c8 1136 {
WGorniak 0:669f3b0e91c8 1137 // Invert and divide by 4
WGorniak 0:669f3b0e91c8 1138 snr = ( ( ~this->settings.LoRaPacketHandler.SnrValue + 1 ) & 0xFF ) >> 2;
WGorniak 0:669f3b0e91c8 1139 snr = -snr;
WGorniak 0:669f3b0e91c8 1140 }
WGorniak 0:669f3b0e91c8 1141 else
WGorniak 0:669f3b0e91c8 1142 {
WGorniak 0:669f3b0e91c8 1143 // Divide by 4
WGorniak 0:669f3b0e91c8 1144 snr = ( this->settings.LoRaPacketHandler.SnrValue & 0xFF ) >> 2;
WGorniak 0:669f3b0e91c8 1145 }
WGorniak 0:669f3b0e91c8 1146
WGorniak 0:669f3b0e91c8 1147 int16_t rssi = Read( REG_LR_PKTRSSIVALUE );
WGorniak 3:81cc2c384b1b 1148 rssi_last_received_packet = rssi;
WGorniak 3:81cc2c384b1b 1149 rssi_current_packet = GetRssi(MODEM_LORA);
WGorniak 3:81cc2c384b1b 1150 snr_value = snr;
WGorniak 3:81cc2c384b1b 1151
WGorniak 0:669f3b0e91c8 1152 if( snr < 0 )
WGorniak 0:669f3b0e91c8 1153 {
WGorniak 0:669f3b0e91c8 1154 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET + rssi + ( rssi >> 4 ) +
WGorniak 0:669f3b0e91c8 1155 snr;
WGorniak 0:669f3b0e91c8 1156 }
WGorniak 0:669f3b0e91c8 1157 else
WGorniak 0:669f3b0e91c8 1158 {
WGorniak 0:669f3b0e91c8 1159 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET + rssi + ( rssi >> 4 );
WGorniak 0:669f3b0e91c8 1160 }
WGorniak 0:669f3b0e91c8 1161
WGorniak 0:669f3b0e91c8 1162 this->settings.LoRaPacketHandler.Size = Read( REG_LR_RXNBBYTES );
mleksio 9:f53b11725565 1163 ReadFifo( rxTxBuffer, this->settings.LoRaPacketHandler.Size );
WGorniak 0:669f3b0e91c8 1164
WGorniak 0:669f3b0e91c8 1165
WGorniak 0:669f3b0e91c8 1166 if( this->settings.LoRa.RxContinuous == false )
WGorniak 0:669f3b0e91c8 1167 {
WGorniak 0:669f3b0e91c8 1168 this->settings.State = IDLE;
WGorniak 0:669f3b0e91c8 1169 }
WGorniak 0:669f3b0e91c8 1170 rxTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 1171
WGorniak 0:669f3b0e91c8 1172 if( ( rxDone != NULL ) )
WGorniak 0:669f3b0e91c8 1173 {
mleksio 9:f53b11725565 1174 rxDone( rxTxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue );
WGorniak 0:669f3b0e91c8 1175 }
WGorniak 0:669f3b0e91c8 1176 }
WGorniak 0:669f3b0e91c8 1177 break;
WGorniak 0:669f3b0e91c8 1178 default:
WGorniak 0:669f3b0e91c8 1179 break;
WGorniak 0:669f3b0e91c8 1180 }
WGorniak 0:669f3b0e91c8 1181 break;
WGorniak 0:669f3b0e91c8 1182 case TX:
WGorniak 0:669f3b0e91c8 1183 txTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 1184 // TxDone interrupt
WGorniak 0:669f3b0e91c8 1185 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 1186 {
WGorniak 0:669f3b0e91c8 1187 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 1188 // Clear Irq
WGorniak 0:669f3b0e91c8 1189 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
WGorniak 0:669f3b0e91c8 1190 // Intentional fall through
WGorniak 0:669f3b0e91c8 1191 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 1192 default:
WGorniak 0:669f3b0e91c8 1193 this->settings.State = IDLE;
WGorniak 0:669f3b0e91c8 1194 if( ( txDone != NULL ) )
WGorniak 0:669f3b0e91c8 1195 {
WGorniak 0:669f3b0e91c8 1196 txDone( );
WGorniak 0:669f3b0e91c8 1197 }
WGorniak 0:669f3b0e91c8 1198 break;
WGorniak 0:669f3b0e91c8 1199 }
WGorniak 0:669f3b0e91c8 1200
WGorniak 0:669f3b0e91c8 1201 break;
WGorniak 0:669f3b0e91c8 1202 default:
WGorniak 0:669f3b0e91c8 1203 break;
WGorniak 0:669f3b0e91c8 1204 }
WGorniak 0:669f3b0e91c8 1205 }
WGorniak 0:669f3b0e91c8 1206
WGorniak 0:669f3b0e91c8 1207 void SX1272::OnDio1Irq( void )
WGorniak 0:669f3b0e91c8 1208 {
WGorniak 0:669f3b0e91c8 1209 switch( this->settings.State )
WGorniak 0:669f3b0e91c8 1210 {
WGorniak 0:669f3b0e91c8 1211 case RX:
WGorniak 0:669f3b0e91c8 1212 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 1213 {
WGorniak 0:669f3b0e91c8 1214 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 1215 // FifoLevel interrupt
WGorniak 0:669f3b0e91c8 1216 // Read received packet size
WGorniak 0:669f3b0e91c8 1217 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
WGorniak 0:669f3b0e91c8 1218 {
WGorniak 0:669f3b0e91c8 1219 if( this->settings.Fsk.FixLen == false )
WGorniak 0:669f3b0e91c8 1220 {
WGorniak 0:669f3b0e91c8 1221 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
WGorniak 0:669f3b0e91c8 1222 }
WGorniak 0:669f3b0e91c8 1223 else
WGorniak 0:669f3b0e91c8 1224 {
WGorniak 0:669f3b0e91c8 1225 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
WGorniak 0:669f3b0e91c8 1226 }
WGorniak 0:669f3b0e91c8 1227 }
WGorniak 0:669f3b0e91c8 1228
WGorniak 0:669f3b0e91c8 1229 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.FifoThresh )
WGorniak 0:669f3b0e91c8 1230 {
mleksio 9:f53b11725565 1231 ReadFifo( ( rxTxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.FifoThresh );
WGorniak 0:669f3b0e91c8 1232 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.FifoThresh;
WGorniak 0:669f3b0e91c8 1233 }
WGorniak 0:669f3b0e91c8 1234 else
WGorniak 0:669f3b0e91c8 1235 {
mleksio 9:f53b11725565 1236 ReadFifo( ( rxTxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
WGorniak 0:669f3b0e91c8 1237 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
WGorniak 0:669f3b0e91c8 1238 }
WGorniak 0:669f3b0e91c8 1239 break;
WGorniak 0:669f3b0e91c8 1240 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 1241 // Sync time out
WGorniak 0:669f3b0e91c8 1242 rxTimeoutTimer.detach( );
WGorniak 0:669f3b0e91c8 1243 this->settings.State = IDLE;
WGorniak 0:669f3b0e91c8 1244 if( ( rxTimeout != NULL ) )
WGorniak 0:669f3b0e91c8 1245 {
WGorniak 0:669f3b0e91c8 1246 rxTimeout( );
WGorniak 0:669f3b0e91c8 1247 }
WGorniak 0:669f3b0e91c8 1248 break;
WGorniak 0:669f3b0e91c8 1249 default:
WGorniak 0:669f3b0e91c8 1250 break;
WGorniak 0:669f3b0e91c8 1251 }
WGorniak 0:669f3b0e91c8 1252 break;
WGorniak 0:669f3b0e91c8 1253 case TX:
WGorniak 0:669f3b0e91c8 1254 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 1255 {
WGorniak 0:669f3b0e91c8 1256 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 1257 // FifoLevel interrupt
WGorniak 0:669f3b0e91c8 1258 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.ChunkSize )
WGorniak 0:669f3b0e91c8 1259 {
mleksio 9:f53b11725565 1260 WriteFifo( ( rxTxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.ChunkSize );
WGorniak 0:669f3b0e91c8 1261 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
WGorniak 0:669f3b0e91c8 1262 }
WGorniak 0:669f3b0e91c8 1263 else
WGorniak 0:669f3b0e91c8 1264 {
WGorniak 0:669f3b0e91c8 1265 // Write the last chunk of data
mleksio 9:f53b11725565 1266 WriteFifo( rxTxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
WGorniak 0:669f3b0e91c8 1267 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes;
WGorniak 0:669f3b0e91c8 1268 }
WGorniak 0:669f3b0e91c8 1269 break;
WGorniak 0:669f3b0e91c8 1270 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 1271 break;
WGorniak 0:669f3b0e91c8 1272 default:
WGorniak 0:669f3b0e91c8 1273 break;
WGorniak 0:669f3b0e91c8 1274 }
WGorniak 0:669f3b0e91c8 1275 break;
WGorniak 0:669f3b0e91c8 1276 default:
WGorniak 0:669f3b0e91c8 1277 break;
WGorniak 0:669f3b0e91c8 1278 }
WGorniak 0:669f3b0e91c8 1279 }
WGorniak 0:669f3b0e91c8 1280
WGorniak 0:669f3b0e91c8 1281 void SX1272::OnDio2Irq( void )
WGorniak 0:669f3b0e91c8 1282 {
WGorniak 0:669f3b0e91c8 1283 switch( this->settings.State )
WGorniak 0:669f3b0e91c8 1284 {
WGorniak 0:669f3b0e91c8 1285 case RX:
WGorniak 0:669f3b0e91c8 1286 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 1287 {
WGorniak 0:669f3b0e91c8 1288 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 1289 if( ( this->settings.FskPacketHandler.PreambleDetected == true ) && ( this->settings.FskPacketHandler.SyncWordDetected == false ) )
WGorniak 0:669f3b0e91c8 1290 {
WGorniak 0:669f3b0e91c8 1291 rxTimeoutSyncWord.detach( );
WGorniak 0:669f3b0e91c8 1292
WGorniak 0:669f3b0e91c8 1293 this->settings.FskPacketHandler.SyncWordDetected = true;
WGorniak 0:669f3b0e91c8 1294
WGorniak 0:669f3b0e91c8 1295 this->settings.FskPacketHandler.RssiValue = -( Read( REG_RSSIVALUE ) >> 1 );
WGorniak 0:669f3b0e91c8 1296
WGorniak 0:669f3b0e91c8 1297 this->settings.FskPacketHandler.AfcValue = ( int32_t )( double )( ( ( uint16_t )Read( REG_AFCMSB ) << 8 ) |
WGorniak 0:669f3b0e91c8 1298 ( uint16_t )Read( REG_AFCLSB ) ) *
WGorniak 0:669f3b0e91c8 1299 ( double )FREQ_STEP;
WGorniak 0:669f3b0e91c8 1300 this->settings.FskPacketHandler.RxGain = ( Read( REG_LNA ) >> 5 ) & 0x07;
WGorniak 0:669f3b0e91c8 1301 }
WGorniak 0:669f3b0e91c8 1302 break;
WGorniak 0:669f3b0e91c8 1303 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 1304 if( this->settings.LoRa.FreqHopOn == true )
WGorniak 0:669f3b0e91c8 1305 {
WGorniak 0:669f3b0e91c8 1306 // Clear Irq
WGorniak 0:669f3b0e91c8 1307 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
WGorniak 0:669f3b0e91c8 1308
WGorniak 0:669f3b0e91c8 1309 if( ( fhssChangeChannel != NULL ) )
WGorniak 0:669f3b0e91c8 1310 {
WGorniak 0:669f3b0e91c8 1311 fhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
WGorniak 0:669f3b0e91c8 1312 }
WGorniak 0:669f3b0e91c8 1313 }
WGorniak 0:669f3b0e91c8 1314 break;
WGorniak 0:669f3b0e91c8 1315 default:
WGorniak 0:669f3b0e91c8 1316 break;
WGorniak 0:669f3b0e91c8 1317 }
WGorniak 0:669f3b0e91c8 1318 break;
WGorniak 0:669f3b0e91c8 1319 case TX:
WGorniak 0:669f3b0e91c8 1320 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 1321 {
WGorniak 0:669f3b0e91c8 1322 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 1323 break;
WGorniak 0:669f3b0e91c8 1324 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 1325 if( this->settings.LoRa.FreqHopOn == true )
WGorniak 0:669f3b0e91c8 1326 {
WGorniak 0:669f3b0e91c8 1327 // Clear Irq
WGorniak 0:669f3b0e91c8 1328 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
WGorniak 0:669f3b0e91c8 1329
WGorniak 0:669f3b0e91c8 1330 if( ( fhssChangeChannel != NULL ) )
WGorniak 0:669f3b0e91c8 1331 {
WGorniak 0:669f3b0e91c8 1332 fhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
WGorniak 0:669f3b0e91c8 1333 }
WGorniak 0:669f3b0e91c8 1334 }
WGorniak 0:669f3b0e91c8 1335 break;
WGorniak 0:669f3b0e91c8 1336 default:
WGorniak 0:669f3b0e91c8 1337 break;
WGorniak 0:669f3b0e91c8 1338 }
WGorniak 0:669f3b0e91c8 1339 break;
WGorniak 0:669f3b0e91c8 1340 default:
WGorniak 0:669f3b0e91c8 1341 break;
WGorniak 0:669f3b0e91c8 1342 }
WGorniak 0:669f3b0e91c8 1343 }
WGorniak 0:669f3b0e91c8 1344
WGorniak 0:669f3b0e91c8 1345 void SX1272::OnDio3Irq( void )
WGorniak 0:669f3b0e91c8 1346 {
WGorniak 0:669f3b0e91c8 1347 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 1348 {
WGorniak 0:669f3b0e91c8 1349 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 1350 break;
WGorniak 0:669f3b0e91c8 1351 case MODEM_LORA:
mleksio 9:f53b11725565 1352 if( ( Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
WGorniak 0:669f3b0e91c8 1353 {
WGorniak 0:669f3b0e91c8 1354 // Clear Irq
WGorniak 0:669f3b0e91c8 1355 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED_MASK | RFLR_IRQFLAGS_CADDONE);
WGorniak 0:669f3b0e91c8 1356 if( ( cadDone != NULL ) )
WGorniak 0:669f3b0e91c8 1357 {
WGorniak 0:669f3b0e91c8 1358 cadDone( true );
WGorniak 0:669f3b0e91c8 1359 }
WGorniak 0:669f3b0e91c8 1360 }
WGorniak 0:669f3b0e91c8 1361 else
WGorniak 0:669f3b0e91c8 1362 {
WGorniak 0:669f3b0e91c8 1363 // Clear Irq
WGorniak 0:669f3b0e91c8 1364 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
WGorniak 0:669f3b0e91c8 1365 if( ( cadDone != NULL ) )
WGorniak 0:669f3b0e91c8 1366 {
WGorniak 0:669f3b0e91c8 1367 cadDone( false );
WGorniak 0:669f3b0e91c8 1368 }
WGorniak 0:669f3b0e91c8 1369 }
WGorniak 0:669f3b0e91c8 1370 break;
WGorniak 0:669f3b0e91c8 1371 default:
WGorniak 0:669f3b0e91c8 1372 break;
WGorniak 0:669f3b0e91c8 1373 }
WGorniak 0:669f3b0e91c8 1374 }
WGorniak 0:669f3b0e91c8 1375
WGorniak 0:669f3b0e91c8 1376 void SX1272::OnDio4Irq( void )
WGorniak 0:669f3b0e91c8 1377 {
WGorniak 0:669f3b0e91c8 1378 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 1379 {
WGorniak 0:669f3b0e91c8 1380 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 1381 {
WGorniak 0:669f3b0e91c8 1382 if( this->settings.FskPacketHandler.PreambleDetected == false )
WGorniak 0:669f3b0e91c8 1383 {
WGorniak 0:669f3b0e91c8 1384 this->settings.FskPacketHandler.PreambleDetected = true;
WGorniak 0:669f3b0e91c8 1385 }
WGorniak 0:669f3b0e91c8 1386 }
WGorniak 0:669f3b0e91c8 1387 break;
WGorniak 0:669f3b0e91c8 1388 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 1389 break;
WGorniak 0:669f3b0e91c8 1390 default:
WGorniak 0:669f3b0e91c8 1391 break;
WGorniak 0:669f3b0e91c8 1392 }
WGorniak 0:669f3b0e91c8 1393 }
WGorniak 0:669f3b0e91c8 1394
WGorniak 0:669f3b0e91c8 1395 void SX1272::OnDio5Irq( void )
WGorniak 0:669f3b0e91c8 1396 {
WGorniak 0:669f3b0e91c8 1397 switch( this->settings.Modem )
WGorniak 0:669f3b0e91c8 1398 {
WGorniak 0:669f3b0e91c8 1399 case MODEM_FSK:
WGorniak 0:669f3b0e91c8 1400 break;
WGorniak 0:669f3b0e91c8 1401 case MODEM_LORA:
WGorniak 0:669f3b0e91c8 1402 break;
WGorniak 0:669f3b0e91c8 1403 default:
WGorniak 0:669f3b0e91c8 1404 break;
WGorniak 0:669f3b0e91c8 1405 }
WGorniak 0:669f3b0e91c8 1406 }
mleksio 8:ead3f4cc5923 1407
mleksio 8:ead3f4cc5923 1408 void SX1272::SetMaxPayloadLength( ModemType modem, uint8_t max )
mleksio 8:ead3f4cc5923 1409 {
mleksio 8:ead3f4cc5923 1410 this->SetModem( modem );
mleksio 8:ead3f4cc5923 1411
mleksio 8:ead3f4cc5923 1412 switch( modem )
mleksio 8:ead3f4cc5923 1413 {
mleksio 8:ead3f4cc5923 1414 case MODEM_FSK:
mleksio 8:ead3f4cc5923 1415 if( this->settings.Fsk.FixLen == false )
mleksio 8:ead3f4cc5923 1416 {
mleksio 8:ead3f4cc5923 1417 this->Write( REG_PAYLOADLENGTH, max );
mleksio 8:ead3f4cc5923 1418 }
mleksio 8:ead3f4cc5923 1419 break;
mleksio 8:ead3f4cc5923 1420 case MODEM_LORA:
mleksio 8:ead3f4cc5923 1421 this->Write( REG_LR_PAYLOADMAXLENGTH, max );
mleksio 8:ead3f4cc5923 1422 break;
mleksio 8:ead3f4cc5923 1423 }
mleksio 8:ead3f4cc5923 1424 }