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