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:
Mon Jun 05 01:35:40 2017 +0200
Revision:
62:835c5e20834e
Parent:
59:38e56c85fa44
Child:
63:5b9d391244dc
Fixed wrong LoRaBandwidths for 500kHz entry, this is somehow odd
to use a higher value for EOF, anyways it is fixed

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 62:835c5e20834e 64 { 600000, 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 59:38e56c85fa44 601 uint32_t SX1276::TimeOnAir( RadioModems_t modem, int16_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 }