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:
Helmut64
Date:
Sun May 14 14:22:02 2017 +0000
Revision:
48:62af1e692f00
Parent:
44:544add59b26d
Child:
50:43f7160e869c
Added a Radio pointer parameter to the event callback functions, this allows to know the context where the event coming from, specially of interest when using multiple Radios. It also avoids the use of global variables.

Who changed what in which revision?

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