ST-DEVKIT-LRWAN

Dependents:   DISCO-L072CZ-LRWAN1-base

Fork of SX1276GenericLib by Helmut Tschemernjak

Committer:
Helmut Tschemernjak
Date:
Thu May 25 21:56:39 2017 +0200
Revision:
58:113d2ef978d2
Parent:
57:d9aba0f40823
Child:
59:38e56c85fa44
Removed duplicate timer definitions (left over from previous cleanup)
zapping the receive buffer makes no sense, keeping the content is better
and allows coping the data while we are receiving the next packet.
The State = RF_IDLE is already done in the sx1276 constructor,
no need to do it in the HAL layer.

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