SX1276GenericLib to support sx1276 bassed LoRa modules, including HopeRF RFM95, Murata CMWX1ZZABZ and Semtech SX1276MB1MAS/SX1276MB1LAS modules

Dependents:   DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_USB_Rx ... more

Fork of SX1276Lib by Semtech

Committer:
Helmut Tschemernjak
Date:
Tue May 09 16:41:16 2017 +0200
Revision:
44:544add59b26d
Parent:
42:72deced1a4c4
Child:
48:62af1e692f00
Updated SetTimeout to include a function pointer for the timeout
Changed SetTimeout parameters function NULL means cancel timer.

Who changed what in which revision?

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