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:
Fri May 19 11:50:12 2017 +0200
Revision:
54:0d8ea87fbab9
Parent:
53:6d3adad59633
Child:
55:00c1f5b83920
Added return value to Init, we check for a radio availability.
Added a RxSignalPending which verifies if we have a signal pending.

Who changed what in which revision?

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