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:
Sun May 07 18:09:10 2017 +0200
Revision:
38:d9189d958db8
Parent:
34:07e89f23c734
Child:
42:72deced1a4c4
Migrated typedefs.h into the sx1276 source.
Migrated radio init register values and settings into sx1276.cpp
where it belongs to.

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 31:e50929bd3f32 712 txTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 713 rxTimeoutTimer.detach( );
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 31:e50929bd3f32 721 txTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 722 rxTimeoutTimer.detach( );
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 31:e50929bd3f32 867 rxTimeoutTimer.attach_us(callback( this, &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 31:e50929bd3f32 876 rxTimeoutSyncWord.attach_us(callback( this, &SX1276::OnTimeoutIrq ),
Helmut Tschemernjak 31:e50929bd3f32 877 this->settings.Fsk.RxSingleTimeout * 1e3 );
GregCr 0:e6ceb13d2d05 878 }
GregCr 0:e6ceb13d2d05 879 }
GregCr 0:e6ceb13d2d05 880 else
GregCr 0:e6ceb13d2d05 881 {
GregCr 0:e6ceb13d2d05 882 if( rxContinuous == true )
GregCr 0:e6ceb13d2d05 883 {
GregCr 0:e6ceb13d2d05 884 SetOpMode( RFLR_OPMODE_RECEIVER );
GregCr 0:e6ceb13d2d05 885 }
GregCr 0:e6ceb13d2d05 886 else
GregCr 0:e6ceb13d2d05 887 {
GregCr 0:e6ceb13d2d05 888 SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
GregCr 0:e6ceb13d2d05 889 }
GregCr 0:e6ceb13d2d05 890 }
GregCr 0:e6ceb13d2d05 891 }
GregCr 0:e6ceb13d2d05 892
GregCr 0:e6ceb13d2d05 893 void SX1276::Tx( uint32_t timeout )
mluis 22:7f3aab69cca9 894 {
mluis 22:7f3aab69cca9 895
GregCr 0:e6ceb13d2d05 896 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 897 {
GregCr 0:e6ceb13d2d05 898 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 899 {
GregCr 0:e6ceb13d2d05 900 // DIO0=PacketSent
GregCr 23:1e143575df0f 901 // DIO1=FifoEmpty
GregCr 0:e6ceb13d2d05 902 // DIO2=FifoFull
GregCr 0:e6ceb13d2d05 903 // DIO3=FifoEmpty
GregCr 0:e6ceb13d2d05 904 // DIO4=LowBat
GregCr 0:e6ceb13d2d05 905 // DIO5=ModeReady
mluis 22:7f3aab69cca9 906 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK &
Helmut Tschemernjak 31:e50929bd3f32 907 RF_DIOMAPPING1_DIO1_MASK &
Helmut Tschemernjak 31:e50929bd3f32 908 RF_DIOMAPPING1_DIO2_MASK ) |
Helmut Tschemernjak 31:e50929bd3f32 909 RF_DIOMAPPING1_DIO1_01 );
GregCr 0:e6ceb13d2d05 910
GregCr 0:e6ceb13d2d05 911 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
GregCr 0:e6ceb13d2d05 912 RF_DIOMAPPING2_MAP_MASK ) );
GregCr 0:e6ceb13d2d05 913 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
GregCr 0:e6ceb13d2d05 914 }
GregCr 0:e6ceb13d2d05 915 break;
GregCr 0:e6ceb13d2d05 916 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 917 {
GregCr 6:e7f02929cd3d 918 if( this->settings.LoRa.FreqHopOn == true )
GregCr 6:e7f02929cd3d 919 {
GregCr 6:e7f02929cd3d 920 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
mluis 22:7f3aab69cca9 921 RFLR_IRQFLAGS_RXDONE |
mluis 22:7f3aab69cca9 922 RFLR_IRQFLAGS_PAYLOADCRCERROR |
mluis 22:7f3aab69cca9 923 RFLR_IRQFLAGS_VALIDHEADER |
mluis 22:7f3aab69cca9 924 //RFLR_IRQFLAGS_TXDONE |
mluis 22:7f3aab69cca9 925 RFLR_IRQFLAGS_CADDONE |
mluis 22:7f3aab69cca9 926 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
mluis 22:7f3aab69cca9 927 RFLR_IRQFLAGS_CADDETECTED );
mluis 25:3778e6204cc1 928
mluis 22:7f3aab69cca9 929 // DIO0=TxDone, DIO2=FhssChangeChannel
mluis 22:7f3aab69cca9 930 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 931 }
GregCr 6:e7f02929cd3d 932 else
GregCr 6:e7f02929cd3d 933 {
GregCr 6:e7f02929cd3d 934 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
mluis 22:7f3aab69cca9 935 RFLR_IRQFLAGS_RXDONE |
mluis 22:7f3aab69cca9 936 RFLR_IRQFLAGS_PAYLOADCRCERROR |
mluis 22:7f3aab69cca9 937 RFLR_IRQFLAGS_VALIDHEADER |
mluis 22:7f3aab69cca9 938 //RFLR_IRQFLAGS_TXDONE |
mluis 22:7f3aab69cca9 939 RFLR_IRQFLAGS_CADDONE |
mluis 22:7f3aab69cca9 940 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
mluis 22:7f3aab69cca9 941 RFLR_IRQFLAGS_CADDETECTED );
mluis 22:7f3aab69cca9 942
GregCr 6:e7f02929cd3d 943 // DIO0=TxDone
mluis 22:7f3aab69cca9 944 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
GregCr 6:e7f02929cd3d 945 }
GregCr 0:e6ceb13d2d05 946 }
GregCr 0:e6ceb13d2d05 947 break;
GregCr 0:e6ceb13d2d05 948 }
GregCr 0:e6ceb13d2d05 949
mluis 21:2e496deb7858 950 this->settings.State = RF_TX_RUNNING;
Helmut Tschemernjak 31:e50929bd3f32 951 txTimeoutTimer.attach_us(callback( this, &SX1276::OnTimeoutIrq ), timeout * 1e3 );
GregCr 0:e6ceb13d2d05 952 SetOpMode( RF_OPMODE_TRANSMITTER );
GregCr 0:e6ceb13d2d05 953 }
GregCr 0:e6ceb13d2d05 954
GregCr 7:2b555111463f 955 void SX1276::StartCad( void )
GregCr 0:e6ceb13d2d05 956 {
GregCr 7:2b555111463f 957 switch( this->settings.Modem )
GregCr 7:2b555111463f 958 {
GregCr 7:2b555111463f 959 case MODEM_FSK:
GregCr 7:2b555111463f 960 {
mluis 25:3778e6204cc1 961
GregCr 7:2b555111463f 962 }
GregCr 7:2b555111463f 963 break;
GregCr 7:2b555111463f 964 case MODEM_LORA:
GregCr 7:2b555111463f 965 {
GregCr 7:2b555111463f 966 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
GregCr 7:2b555111463f 967 RFLR_IRQFLAGS_RXDONE |
GregCr 7:2b555111463f 968 RFLR_IRQFLAGS_PAYLOADCRCERROR |
GregCr 7:2b555111463f 969 RFLR_IRQFLAGS_VALIDHEADER |
GregCr 7:2b555111463f 970 RFLR_IRQFLAGS_TXDONE |
GregCr 7:2b555111463f 971 //RFLR_IRQFLAGS_CADDONE |
GregCr 12:aa5b3bf7fdf4 972 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
Helmut Tschemernjak 31:e50929bd3f32 973 //RFLR_IRQFLAGS_CADDETECTED
GregCr 12:aa5b3bf7fdf4 974 );
mluis 25:3778e6204cc1 975
GregCr 7:2b555111463f 976 // DIO3=CADDone
Helmut Tschemernjak 31:e50929bd3f32 977 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO3_MASK ) | RFLR_DIOMAPPING1_DIO3_00 );
mluis 25:3778e6204cc1 978
mluis 21:2e496deb7858 979 this->settings.State = RF_CAD;
GregCr 7:2b555111463f 980 SetOpMode( RFLR_OPMODE_CAD );
GregCr 7:2b555111463f 981 }
GregCr 7:2b555111463f 982 break;
GregCr 7:2b555111463f 983 default:
GregCr 7:2b555111463f 984 break;
GregCr 7:2b555111463f 985 }
GregCr 7:2b555111463f 986 }
GregCr 7:2b555111463f 987
Helmut Tschemernjak 31:e50929bd3f32 988 void SX1276::SetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
Helmut Tschemernjak 31:e50929bd3f32 989 {
Helmut Tschemernjak 31:e50929bd3f32 990 uint32_t timeout = ( uint32_t )( time * 1e6 );
Helmut Tschemernjak 31:e50929bd3f32 991
Helmut Tschemernjak 31:e50929bd3f32 992 SetChannel( freq );
Helmut Tschemernjak 31:e50929bd3f32 993
Helmut Tschemernjak 31:e50929bd3f32 994 SetTxConfig( MODEM_FSK, power, 0, 0, 4800, 0, 5, false, false, 0, 0, 0, timeout );
Helmut Tschemernjak 31:e50929bd3f32 995
Helmut Tschemernjak 31:e50929bd3f32 996 Write( REG_PACKETCONFIG2, ( Read( REG_PACKETCONFIG2 ) & RF_PACKETCONFIG2_DATAMODE_MASK ) );
Helmut Tschemernjak 31:e50929bd3f32 997 // Disable radio interrupts
Helmut Tschemernjak 31:e50929bd3f32 998 Write( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_11 );
Helmut Tschemernjak 31:e50929bd3f32 999 Write( REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | RF_DIOMAPPING2_DIO5_10 );
Helmut Tschemernjak 31:e50929bd3f32 1000
Helmut Tschemernjak 31:e50929bd3f32 1001 this->settings.State = RF_TX_RUNNING;
Helmut Tschemernjak 31:e50929bd3f32 1002 txTimeoutTimer.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ), timeout );
Helmut Tschemernjak 31:e50929bd3f32 1003 SetOpMode( RF_OPMODE_TRANSMITTER );
Helmut Tschemernjak 31:e50929bd3f32 1004 }
Helmut Tschemernjak 31:e50929bd3f32 1005
mluis 22:7f3aab69cca9 1006 int16_t SX1276::GetRssi( RadioModems_t modem )
GregCr 7:2b555111463f 1007 {
GregCr 7:2b555111463f 1008 int16_t rssi = 0;
GregCr 0:e6ceb13d2d05 1009
GregCr 0:e6ceb13d2d05 1010 switch( modem )
GregCr 0:e6ceb13d2d05 1011 {
GregCr 0:e6ceb13d2d05 1012 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1013 rssi = -( Read( REG_RSSIVALUE ) >> 1 );
GregCr 0:e6ceb13d2d05 1014 break;
GregCr 0:e6ceb13d2d05 1015 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1016 if( this->settings.Channel > RF_MID_BAND_THRESH )
GregCr 0:e6ceb13d2d05 1017 {
GregCr 0:e6ceb13d2d05 1018 rssi = RSSI_OFFSET_HF + Read( REG_LR_RSSIVALUE );
GregCr 0:e6ceb13d2d05 1019 }
GregCr 0:e6ceb13d2d05 1020 else
GregCr 0:e6ceb13d2d05 1021 {
GregCr 0:e6ceb13d2d05 1022 rssi = RSSI_OFFSET_LF + Read( REG_LR_RSSIVALUE );
GregCr 0:e6ceb13d2d05 1023 }
GregCr 0:e6ceb13d2d05 1024 break;
GregCr 0:e6ceb13d2d05 1025 default:
GregCr 0:e6ceb13d2d05 1026 rssi = -1;
GregCr 0:e6ceb13d2d05 1027 break;
GregCr 0:e6ceb13d2d05 1028 }
GregCr 0:e6ceb13d2d05 1029 return rssi;
GregCr 0:e6ceb13d2d05 1030 }
GregCr 0:e6ceb13d2d05 1031
GregCr 0:e6ceb13d2d05 1032 void SX1276::SetOpMode( uint8_t opMode )
GregCr 0:e6ceb13d2d05 1033 {
mluis 25:3778e6204cc1 1034 if( opMode == RF_OPMODE_SLEEP )
GregCr 0:e6ceb13d2d05 1035 {
mluis 25:3778e6204cc1 1036 SetAntSwLowPower( true );
mluis 25:3778e6204cc1 1037 }
mluis 25:3778e6204cc1 1038 else
mluis 25:3778e6204cc1 1039 {
mluis 25:3778e6204cc1 1040 SetAntSwLowPower( false );
Helmut Tschemernjak 31:e50929bd3f32 1041 SetAntSw( opMode );
GregCr 0:e6ceb13d2d05 1042 }
mluis 25:3778e6204cc1 1043 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
GregCr 0:e6ceb13d2d05 1044 }
GregCr 0:e6ceb13d2d05 1045
mluis 22:7f3aab69cca9 1046 void SX1276::SetModem( RadioModems_t modem )
GregCr 0:e6ceb13d2d05 1047 {
Helmut Tschemernjak 31:e50929bd3f32 1048 if( ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_ON ) != 0 )
Helmut Tschemernjak 31:e50929bd3f32 1049 {
Helmut Tschemernjak 31:e50929bd3f32 1050 this->settings.Modem = MODEM_LORA;
Helmut Tschemernjak 31:e50929bd3f32 1051 }
Helmut Tschemernjak 31:e50929bd3f32 1052 else
Helmut Tschemernjak 31:e50929bd3f32 1053 {
Helmut Tschemernjak 31:e50929bd3f32 1054 this->settings.Modem = MODEM_FSK;
Helmut Tschemernjak 31:e50929bd3f32 1055 }
Helmut Tschemernjak 31:e50929bd3f32 1056
mluis 22:7f3aab69cca9 1057 if( this->settings.Modem == modem )
mluis 22:7f3aab69cca9 1058 {
mluis 22:7f3aab69cca9 1059 return;
mluis 22:7f3aab69cca9 1060 }
mluis 22:7f3aab69cca9 1061
mluis 22:7f3aab69cca9 1062 this->settings.Modem = modem;
mluis 22:7f3aab69cca9 1063 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1064 {
mluis 22:7f3aab69cca9 1065 default:
mluis 22:7f3aab69cca9 1066 case MODEM_FSK:
Helmut Tschemernjak 31:e50929bd3f32 1067 Sleep( );
mluis 22:7f3aab69cca9 1068 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
mluis 22:7f3aab69cca9 1069
mluis 22:7f3aab69cca9 1070 Write( REG_DIOMAPPING1, 0x00 );
mluis 22:7f3aab69cca9 1071 Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
mluis 22:7f3aab69cca9 1072 break;
mluis 22:7f3aab69cca9 1073 case MODEM_LORA:
Helmut Tschemernjak 31:e50929bd3f32 1074 Sleep( );
mluis 22:7f3aab69cca9 1075 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
mluis 22:7f3aab69cca9 1076
mluis 22:7f3aab69cca9 1077 Write( REG_DIOMAPPING1, 0x00 );
mluis 22:7f3aab69cca9 1078 Write( REG_DIOMAPPING2, 0x00 );
mluis 22:7f3aab69cca9 1079 break;
GregCr 0:e6ceb13d2d05 1080 }
GregCr 0:e6ceb13d2d05 1081 }
GregCr 0:e6ceb13d2d05 1082
mluis 22:7f3aab69cca9 1083 void SX1276::SetMaxPayloadLength( RadioModems_t modem, uint8_t max )
mluis 20:e05596ba4166 1084 {
mluis 20:e05596ba4166 1085 this->SetModem( modem );
mluis 20:e05596ba4166 1086
mluis 20:e05596ba4166 1087 switch( modem )
mluis 20:e05596ba4166 1088 {
mluis 20:e05596ba4166 1089 case MODEM_FSK:
mluis 20:e05596ba4166 1090 if( this->settings.Fsk.FixLen == false )
mluis 20:e05596ba4166 1091 {
mluis 20:e05596ba4166 1092 this->Write( REG_PAYLOADLENGTH, max );
mluis 20:e05596ba4166 1093 }
mluis 20:e05596ba4166 1094 break;
mluis 20:e05596ba4166 1095 case MODEM_LORA:
mluis 20:e05596ba4166 1096 this->Write( REG_LR_PAYLOADMAXLENGTH, max );
mluis 20:e05596ba4166 1097 break;
mluis 20:e05596ba4166 1098 }
mluis 20:e05596ba4166 1099 }
mluis 20:e05596ba4166 1100
Helmut Tschemernjak 31:e50929bd3f32 1101 void SX1276::SetPublicNetwork( bool enable )
Helmut Tschemernjak 31:e50929bd3f32 1102 {
Helmut Tschemernjak 31:e50929bd3f32 1103 SetModem( MODEM_LORA );
Helmut Tschemernjak 31:e50929bd3f32 1104 this->settings.LoRa.PublicNetwork = enable;
Helmut Tschemernjak 31:e50929bd3f32 1105 if( enable == true )
Helmut Tschemernjak 31:e50929bd3f32 1106 {
Helmut Tschemernjak 31:e50929bd3f32 1107 // Change LoRa modem SyncWord
Helmut Tschemernjak 31:e50929bd3f32 1108 Write( REG_LR_SYNCWORD, LORA_MAC_PUBLIC_SYNCWORD );
Helmut Tschemernjak 31:e50929bd3f32 1109 }
Helmut Tschemernjak 31:e50929bd3f32 1110 else
Helmut Tschemernjak 31:e50929bd3f32 1111 {
Helmut Tschemernjak 31:e50929bd3f32 1112 // Change LoRa modem SyncWord
Helmut Tschemernjak 31:e50929bd3f32 1113 Write( REG_LR_SYNCWORD, LORA_MAC_PRIVATE_SYNCWORD );
Helmut Tschemernjak 31:e50929bd3f32 1114 }
Helmut Tschemernjak 31:e50929bd3f32 1115 }
Helmut Tschemernjak 31:e50929bd3f32 1116
Helmut Tschemernjak 31:e50929bd3f32 1117
GregCr 0:e6ceb13d2d05 1118 void SX1276::OnTimeoutIrq( void )
GregCr 0:e6ceb13d2d05 1119 {
GregCr 0:e6ceb13d2d05 1120 switch( this->settings.State )
GregCr 0:e6ceb13d2d05 1121 {
mluis 21:2e496deb7858 1122 case RF_RX_RUNNING:
GregCr 0:e6ceb13d2d05 1123 if( this->settings.Modem == MODEM_FSK )
GregCr 0:e6ceb13d2d05 1124 {
GregCr 0:e6ceb13d2d05 1125 this->settings.FskPacketHandler.PreambleDetected = false;
GregCr 0:e6ceb13d2d05 1126 this->settings.FskPacketHandler.SyncWordDetected = false;
GregCr 0:e6ceb13d2d05 1127 this->settings.FskPacketHandler.NbBytes = 0;
GregCr 0:e6ceb13d2d05 1128 this->settings.FskPacketHandler.Size = 0;
GregCr 0:e6ceb13d2d05 1129
GregCr 0:e6ceb13d2d05 1130 // Clear Irqs
Helmut Tschemernjak 31:e50929bd3f32 1131 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
GregCr 0:e6ceb13d2d05 1132 RF_IRQFLAGS1_PREAMBLEDETECT |
GregCr 0:e6ceb13d2d05 1133 RF_IRQFLAGS1_SYNCADDRESSMATCH );
GregCr 0:e6ceb13d2d05 1134 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
GregCr 0:e6ceb13d2d05 1135
GregCr 0:e6ceb13d2d05 1136 if( this->settings.Fsk.RxContinuous == true )
GregCr 0:e6ceb13d2d05 1137 {
GregCr 0:e6ceb13d2d05 1138 // Continuous mode restart Rx chain
GregCr 0:e6ceb13d2d05 1139 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
Helmut Tschemernjak 31:e50929bd3f32 1140 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
Helmut Tschemernjak 31:e50929bd3f32 1141 this->settings.Fsk.RxSingleTimeout * 1e3 );
GregCr 0:e6ceb13d2d05 1142 }
GregCr 0:e6ceb13d2d05 1143 else
GregCr 0:e6ceb13d2d05 1144 {
mluis 21:2e496deb7858 1145 this->settings.State = RF_IDLE;
GregCr 5:11ec8a6ba4f0 1146 rxTimeoutSyncWord.detach( );
GregCr 0:e6ceb13d2d05 1147 }
GregCr 0:e6ceb13d2d05 1148 }
mluis 22:7f3aab69cca9 1149 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
GregCr 0:e6ceb13d2d05 1150 {
mluis 21:2e496deb7858 1151 this->RadioEvents->RxTimeout( );
GregCr 0:e6ceb13d2d05 1152 }
GregCr 0:e6ceb13d2d05 1153 break;
mluis 21:2e496deb7858 1154 case RF_TX_RUNNING:
Helmut Tschemernjak 31:e50929bd3f32 1155 // Tx timeout shouldn't happen.
Helmut Tschemernjak 31:e50929bd3f32 1156 // But it has been observed that when it happens it is a result of a corrupted SPI transfer
Helmut Tschemernjak 31:e50929bd3f32 1157 // it depends on the platform design.
Helmut Tschemernjak 31:e50929bd3f32 1158 //
Helmut Tschemernjak 31:e50929bd3f32 1159 // The workaround is to put the radio in a known state. Thus, we re-initialize it.
Helmut Tschemernjak 31:e50929bd3f32 1160 // BEGIN WORKAROUND
Helmut Tschemernjak 31:e50929bd3f32 1161
Helmut Tschemernjak 31:e50929bd3f32 1162 // Reset the radio
Helmut Tschemernjak 31:e50929bd3f32 1163 Reset( );
Helmut Tschemernjak 31:e50929bd3f32 1164
Helmut Tschemernjak 31:e50929bd3f32 1165 // Calibrate Rx chain
Helmut Tschemernjak 31:e50929bd3f32 1166 RxChainCalibration( );
Helmut Tschemernjak 31:e50929bd3f32 1167
Helmut Tschemernjak 31:e50929bd3f32 1168 // Initialize radio default values
Helmut Tschemernjak 31:e50929bd3f32 1169 SetOpMode( RF_OPMODE_SLEEP );
Helmut Tschemernjak 31:e50929bd3f32 1170
Helmut Tschemernjak 31:e50929bd3f32 1171 RadioRegistersInit( );
Helmut Tschemernjak 31:e50929bd3f32 1172
Helmut Tschemernjak 31:e50929bd3f32 1173 SetModem( MODEM_FSK );
Helmut Tschemernjak 31:e50929bd3f32 1174
Helmut Tschemernjak 31:e50929bd3f32 1175 // Restore previous network type setting.
Helmut Tschemernjak 31:e50929bd3f32 1176 SetPublicNetwork( this->settings.LoRa.PublicNetwork );
Helmut Tschemernjak 31:e50929bd3f32 1177 // END WORKAROUND
Helmut Tschemernjak 31:e50929bd3f32 1178
mluis 21:2e496deb7858 1179 this->settings.State = RF_IDLE;
mluis 22:7f3aab69cca9 1180 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxTimeout != NULL ) )
GregCr 0:e6ceb13d2d05 1181 {
mluis 21:2e496deb7858 1182 this->RadioEvents->TxTimeout( );
GregCr 0:e6ceb13d2d05 1183 }
GregCr 0:e6ceb13d2d05 1184 break;
GregCr 0:e6ceb13d2d05 1185 default:
GregCr 0:e6ceb13d2d05 1186 break;
GregCr 0:e6ceb13d2d05 1187 }
GregCr 0:e6ceb13d2d05 1188 }
GregCr 0:e6ceb13d2d05 1189
GregCr 0:e6ceb13d2d05 1190 void SX1276::OnDio0Irq( void )
GregCr 0:e6ceb13d2d05 1191 {
mluis 20:e05596ba4166 1192 volatile uint8_t irqFlags = 0;
mluis 22:7f3aab69cca9 1193
GregCr 0:e6ceb13d2d05 1194 switch( this->settings.State )
mluis 25:3778e6204cc1 1195 {
mluis 21:2e496deb7858 1196 case RF_RX_RUNNING:
GregCr 0:e6ceb13d2d05 1197 //TimerStop( &RxTimeoutTimer );
GregCr 0:e6ceb13d2d05 1198 // RxDone interrupt
GregCr 0:e6ceb13d2d05 1199 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1200 {
GregCr 0:e6ceb13d2d05 1201 case MODEM_FSK:
GregCr 18:99c6e44c1672 1202 if( this->settings.Fsk.CrcOn == true )
GregCr 0:e6ceb13d2d05 1203 {
GregCr 18:99c6e44c1672 1204 irqFlags = Read( REG_IRQFLAGS2 );
GregCr 18:99c6e44c1672 1205 if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
GregCr 0:e6ceb13d2d05 1206 {
GregCr 18:99c6e44c1672 1207 // Clear Irqs
mluis 25:3778e6204cc1 1208 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
GregCr 18:99c6e44c1672 1209 RF_IRQFLAGS1_PREAMBLEDETECT |
GregCr 18:99c6e44c1672 1210 RF_IRQFLAGS1_SYNCADDRESSMATCH );
GregCr 18:99c6e44c1672 1211 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
mluis 25:3778e6204cc1 1212
mluis 25:3778e6204cc1 1213 rxTimeoutTimer.detach( );
mluis 25:3778e6204cc1 1214
GregCr 18:99c6e44c1672 1215 if( this->settings.Fsk.RxContinuous == false )
GregCr 18:99c6e44c1672 1216 {
mluis 25:3778e6204cc1 1217 rxTimeoutSyncWord.detach( );
mluis 21:2e496deb7858 1218 this->settings.State = RF_IDLE;
GregCr 18:99c6e44c1672 1219 }
GregCr 18:99c6e44c1672 1220 else
GregCr 18:99c6e44c1672 1221 {
GregCr 18:99c6e44c1672 1222 // Continuous mode restart Rx chain
GregCr 18:99c6e44c1672 1223 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
Helmut Tschemernjak 31:e50929bd3f32 1224 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
Helmut Tschemernjak 31:e50929bd3f32 1225 this->settings.Fsk.RxSingleTimeout * 1e3 );
GregCr 18:99c6e44c1672 1226 }
mluis 25:3778e6204cc1 1227
mluis 22:7f3aab69cca9 1228 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
GregCr 18:99c6e44c1672 1229 {
mluis 22:7f3aab69cca9 1230 this->RadioEvents->RxError( );
GregCr 18:99c6e44c1672 1231 }
GregCr 18:99c6e44c1672 1232 this->settings.FskPacketHandler.PreambleDetected = false;
GregCr 18:99c6e44c1672 1233 this->settings.FskPacketHandler.SyncWordDetected = false;
GregCr 18:99c6e44c1672 1234 this->settings.FskPacketHandler.NbBytes = 0;
GregCr 18:99c6e44c1672 1235 this->settings.FskPacketHandler.Size = 0;
GregCr 18:99c6e44c1672 1236 break;
GregCr 0:e6ceb13d2d05 1237 }
GregCr 0:e6ceb13d2d05 1238 }
mluis 25:3778e6204cc1 1239
GregCr 0:e6ceb13d2d05 1240 // Read received packet size
GregCr 0:e6ceb13d2d05 1241 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
GregCr 0:e6ceb13d2d05 1242 {
GregCr 0:e6ceb13d2d05 1243 if( this->settings.Fsk.FixLen == false )
GregCr 0:e6ceb13d2d05 1244 {
GregCr 0:e6ceb13d2d05 1245 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
GregCr 0:e6ceb13d2d05 1246 }
GregCr 0:e6ceb13d2d05 1247 else
GregCr 0:e6ceb13d2d05 1248 {
GregCr 0:e6ceb13d2d05 1249 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
GregCr 0:e6ceb13d2d05 1250 }
GregCr 23:1e143575df0f 1251 ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1252 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1253 }
GregCr 0:e6ceb13d2d05 1254 else
GregCr 0:e6ceb13d2d05 1255 {
GregCr 23:1e143575df0f 1256 ReadFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1257 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1258 }
GregCr 0:e6ceb13d2d05 1259
mluis 25:3778e6204cc1 1260 rxTimeoutTimer.detach( );
mluis 25:3778e6204cc1 1261
GregCr 0:e6ceb13d2d05 1262 if( this->settings.Fsk.RxContinuous == false )
GregCr 0:e6ceb13d2d05 1263 {
mluis 21:2e496deb7858 1264 this->settings.State = RF_IDLE;
mluis 25:3778e6204cc1 1265 rxTimeoutSyncWord.detach( );
GregCr 0:e6ceb13d2d05 1266 }
GregCr 0:e6ceb13d2d05 1267 else
GregCr 0:e6ceb13d2d05 1268 {
GregCr 0:e6ceb13d2d05 1269 // Continuous mode restart Rx chain
GregCr 0:e6ceb13d2d05 1270 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
Helmut Tschemernjak 31:e50929bd3f32 1271 rxTimeoutSyncWord.attach_us( mbed::callback( this, &SX1276::OnTimeoutIrq ),
Helmut Tschemernjak 31:e50929bd3f32 1272 this->settings.Fsk.RxSingleTimeout * 1e3 );
Helmut Tschemernjak 31:e50929bd3f32 1273 }
GregCr 0:e6ceb13d2d05 1274
mluis 22:7f3aab69cca9 1275 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
GregCr 0:e6ceb13d2d05 1276 {
mluis 25:3778e6204cc1 1277 this->RadioEvents->RxDone( rxtxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 );
mluis 25:3778e6204cc1 1278 }
GregCr 0:e6ceb13d2d05 1279 this->settings.FskPacketHandler.PreambleDetected = false;
GregCr 0:e6ceb13d2d05 1280 this->settings.FskPacketHandler.SyncWordDetected = false;
GregCr 0:e6ceb13d2d05 1281 this->settings.FskPacketHandler.NbBytes = 0;
GregCr 0:e6ceb13d2d05 1282 this->settings.FskPacketHandler.Size = 0;
GregCr 0:e6ceb13d2d05 1283 break;
GregCr 0:e6ceb13d2d05 1284 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1285 {
mluis 22:7f3aab69cca9 1286 int8_t snr = 0;
GregCr 0:e6ceb13d2d05 1287
GregCr 0:e6ceb13d2d05 1288 // Clear Irq
GregCr 0:e6ceb13d2d05 1289 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
GregCr 0:e6ceb13d2d05 1290
GregCr 0:e6ceb13d2d05 1291 irqFlags = Read( REG_LR_IRQFLAGS );
GregCr 0:e6ceb13d2d05 1292 if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
GregCr 0:e6ceb13d2d05 1293 {
GregCr 0:e6ceb13d2d05 1294 // Clear Irq
GregCr 0:e6ceb13d2d05 1295 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
GregCr 0:e6ceb13d2d05 1296
GregCr 0:e6ceb13d2d05 1297 if( this->settings.LoRa.RxContinuous == false )
GregCr 0:e6ceb13d2d05 1298 {
mluis 21:2e496deb7858 1299 this->settings.State = RF_IDLE;
GregCr 0:e6ceb13d2d05 1300 }
GregCr 0:e6ceb13d2d05 1301 rxTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 1302
mluis 22:7f3aab69cca9 1303 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxError != NULL ) )
GregCr 0:e6ceb13d2d05 1304 {
mluis 22:7f3aab69cca9 1305 this->RadioEvents->RxError( );
GregCr 0:e6ceb13d2d05 1306 }
GregCr 0:e6ceb13d2d05 1307 break;
GregCr 0:e6ceb13d2d05 1308 }
GregCr 0:e6ceb13d2d05 1309
GregCr 0:e6ceb13d2d05 1310 this->settings.LoRaPacketHandler.SnrValue = Read( REG_LR_PKTSNRVALUE );
GregCr 0:e6ceb13d2d05 1311 if( this->settings.LoRaPacketHandler.SnrValue & 0x80 ) // The SNR sign bit is 1
GregCr 0:e6ceb13d2d05 1312 {
GregCr 0:e6ceb13d2d05 1313 // Invert and divide by 4
GregCr 0:e6ceb13d2d05 1314 snr = ( ( ~this->settings.LoRaPacketHandler.SnrValue + 1 ) & 0xFF ) >> 2;
GregCr 0:e6ceb13d2d05 1315 snr = -snr;
GregCr 0:e6ceb13d2d05 1316 }
GregCr 0:e6ceb13d2d05 1317 else
GregCr 0:e6ceb13d2d05 1318 {
GregCr 0:e6ceb13d2d05 1319 // Divide by 4
GregCr 0:e6ceb13d2d05 1320 snr = ( this->settings.LoRaPacketHandler.SnrValue & 0xFF ) >> 2;
GregCr 0:e6ceb13d2d05 1321 }
GregCr 0:e6ceb13d2d05 1322
GregCr 7:2b555111463f 1323 int16_t rssi = Read( REG_LR_PKTRSSIVALUE );
mluis 22:7f3aab69cca9 1324 if( snr < 0 )
GregCr 0:e6ceb13d2d05 1325 {
GregCr 0:e6ceb13d2d05 1326 if( this->settings.Channel > RF_MID_BAND_THRESH )
GregCr 0:e6ceb13d2d05 1327 {
GregCr 0:e6ceb13d2d05 1328 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 ) +
GregCr 0:e6ceb13d2d05 1329 snr;
GregCr 0:e6ceb13d2d05 1330 }
GregCr 0:e6ceb13d2d05 1331 else
GregCr 0:e6ceb13d2d05 1332 {
GregCr 0:e6ceb13d2d05 1333 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 ) +
GregCr 0:e6ceb13d2d05 1334 snr;
GregCr 0:e6ceb13d2d05 1335 }
GregCr 0:e6ceb13d2d05 1336 }
GregCr 0:e6ceb13d2d05 1337 else
mluis 25:3778e6204cc1 1338 {
GregCr 0:e6ceb13d2d05 1339 if( this->settings.Channel > RF_MID_BAND_THRESH )
GregCr 0:e6ceb13d2d05 1340 {
GregCr 0:e6ceb13d2d05 1341 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF + rssi + ( rssi >> 4 );
GregCr 0:e6ceb13d2d05 1342 }
GregCr 0:e6ceb13d2d05 1343 else
GregCr 0:e6ceb13d2d05 1344 {
GregCr 0:e6ceb13d2d05 1345 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF + rssi + ( rssi >> 4 );
GregCr 0:e6ceb13d2d05 1346 }
GregCr 0:e6ceb13d2d05 1347 }
GregCr 0:e6ceb13d2d05 1348
GregCr 0:e6ceb13d2d05 1349 this->settings.LoRaPacketHandler.Size = Read( REG_LR_RXNBBYTES );
GregCr 23:1e143575df0f 1350 ReadFifo( rxtxBuffer, this->settings.LoRaPacketHandler.Size );
mluis 25:3778e6204cc1 1351
GregCr 0:e6ceb13d2d05 1352 if( this->settings.LoRa.RxContinuous == false )
GregCr 0:e6ceb13d2d05 1353 {
mluis 21:2e496deb7858 1354 this->settings.State = RF_IDLE;
GregCr 0:e6ceb13d2d05 1355 }
GregCr 0:e6ceb13d2d05 1356 rxTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 1357
mluis 22:7f3aab69cca9 1358 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxDone != NULL ) )
GregCr 0:e6ceb13d2d05 1359 {
GregCr 23:1e143575df0f 1360 this->RadioEvents->RxDone( rxtxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue );
GregCr 0:e6ceb13d2d05 1361 }
GregCr 0:e6ceb13d2d05 1362 }
GregCr 0:e6ceb13d2d05 1363 break;
GregCr 0:e6ceb13d2d05 1364 default:
GregCr 0:e6ceb13d2d05 1365 break;
GregCr 0:e6ceb13d2d05 1366 }
GregCr 0:e6ceb13d2d05 1367 break;
mluis 21:2e496deb7858 1368 case RF_TX_RUNNING:
Helmut Tschemernjak 31:e50929bd3f32 1369 txTimeoutTimer.detach( );
GregCr 0:e6ceb13d2d05 1370 // TxDone interrupt
GregCr 0:e6ceb13d2d05 1371 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1372 {
GregCr 0:e6ceb13d2d05 1373 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1374 // Clear Irq
GregCr 0:e6ceb13d2d05 1375 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
GregCr 0:e6ceb13d2d05 1376 // Intentional fall through
GregCr 0:e6ceb13d2d05 1377 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1378 default:
mluis 21:2e496deb7858 1379 this->settings.State = RF_IDLE;
mluis 22:7f3aab69cca9 1380 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->TxDone != NULL ) )
GregCr 0:e6ceb13d2d05 1381 {
mluis 22:7f3aab69cca9 1382 this->RadioEvents->TxDone( );
mluis 25:3778e6204cc1 1383 }
GregCr 0:e6ceb13d2d05 1384 break;
GregCr 0:e6ceb13d2d05 1385 }
GregCr 0:e6ceb13d2d05 1386 break;
GregCr 0:e6ceb13d2d05 1387 default:
GregCr 0:e6ceb13d2d05 1388 break;
GregCr 0:e6ceb13d2d05 1389 }
GregCr 0:e6ceb13d2d05 1390 }
GregCr 0:e6ceb13d2d05 1391
GregCr 0:e6ceb13d2d05 1392 void SX1276::OnDio1Irq( void )
GregCr 0:e6ceb13d2d05 1393 {
GregCr 0:e6ceb13d2d05 1394 switch( this->settings.State )
mluis 25:3778e6204cc1 1395 {
mluis 21:2e496deb7858 1396 case RF_RX_RUNNING:
GregCr 0:e6ceb13d2d05 1397 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1398 {
GregCr 0:e6ceb13d2d05 1399 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1400 // FifoLevel interrupt
GregCr 0:e6ceb13d2d05 1401 // Read received packet size
GregCr 0:e6ceb13d2d05 1402 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
GregCr 0:e6ceb13d2d05 1403 {
GregCr 0:e6ceb13d2d05 1404 if( this->settings.Fsk.FixLen == false )
GregCr 0:e6ceb13d2d05 1405 {
GregCr 0:e6ceb13d2d05 1406 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
GregCr 0:e6ceb13d2d05 1407 }
GregCr 0:e6ceb13d2d05 1408 else
GregCr 0:e6ceb13d2d05 1409 {
GregCr 0:e6ceb13d2d05 1410 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
GregCr 0:e6ceb13d2d05 1411 }
GregCr 0:e6ceb13d2d05 1412 }
GregCr 0:e6ceb13d2d05 1413
GregCr 0:e6ceb13d2d05 1414 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.FifoThresh )
GregCr 0:e6ceb13d2d05 1415 {
GregCr 23:1e143575df0f 1416 ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.FifoThresh );
GregCr 0:e6ceb13d2d05 1417 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.FifoThresh;
GregCr 0:e6ceb13d2d05 1418 }
GregCr 0:e6ceb13d2d05 1419 else
GregCr 0:e6ceb13d2d05 1420 {
GregCr 23:1e143575df0f 1421 ReadFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1422 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1423 }
GregCr 0:e6ceb13d2d05 1424 break;
GregCr 0:e6ceb13d2d05 1425 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1426 // Sync time out
GregCr 0:e6ceb13d2d05 1427 rxTimeoutTimer.detach( );
Helmut Tschemernjak 31:e50929bd3f32 1428 // Clear Irq
Helmut Tschemernjak 31:e50929bd3f32 1429 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT );
Helmut Tschemernjak 31:e50929bd3f32 1430
mluis 21:2e496deb7858 1431 this->settings.State = RF_IDLE;
mluis 22:7f3aab69cca9 1432 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->RxTimeout != NULL ) )
GregCr 0:e6ceb13d2d05 1433 {
mluis 21:2e496deb7858 1434 this->RadioEvents->RxTimeout( );
GregCr 0:e6ceb13d2d05 1435 }
GregCr 0:e6ceb13d2d05 1436 break;
GregCr 0:e6ceb13d2d05 1437 default:
GregCr 0:e6ceb13d2d05 1438 break;
GregCr 0:e6ceb13d2d05 1439 }
GregCr 0:e6ceb13d2d05 1440 break;
mluis 21:2e496deb7858 1441 case RF_TX_RUNNING:
GregCr 0:e6ceb13d2d05 1442 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1443 {
GregCr 0:e6ceb13d2d05 1444 case MODEM_FSK:
mluis 25:3778e6204cc1 1445 // FifoEmpty interrupt
GregCr 0:e6ceb13d2d05 1446 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.ChunkSize )
GregCr 0:e6ceb13d2d05 1447 {
GregCr 23:1e143575df0f 1448 WriteFifo( ( rxtxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.ChunkSize );
GregCr 0:e6ceb13d2d05 1449 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
GregCr 0:e6ceb13d2d05 1450 }
mluis 25:3778e6204cc1 1451 else
GregCr 0:e6ceb13d2d05 1452 {
GregCr 0:e6ceb13d2d05 1453 // Write the last chunk of data
GregCr 23:1e143575df0f 1454 WriteFifo( rxtxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
GregCr 0:e6ceb13d2d05 1455 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes;
GregCr 0:e6ceb13d2d05 1456 }
GregCr 0:e6ceb13d2d05 1457 break;
GregCr 0:e6ceb13d2d05 1458 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1459 break;
GregCr 0:e6ceb13d2d05 1460 default:
GregCr 0:e6ceb13d2d05 1461 break;
GregCr 0:e6ceb13d2d05 1462 }
mluis 22:7f3aab69cca9 1463 break;
GregCr 0:e6ceb13d2d05 1464 default:
GregCr 0:e6ceb13d2d05 1465 break;
GregCr 0:e6ceb13d2d05 1466 }
GregCr 0:e6ceb13d2d05 1467 }
GregCr 0:e6ceb13d2d05 1468
GregCr 0:e6ceb13d2d05 1469 void SX1276::OnDio2Irq( void )
GregCr 0:e6ceb13d2d05 1470 {
GregCr 0:e6ceb13d2d05 1471 switch( this->settings.State )
mluis 25:3778e6204cc1 1472 {
mluis 21:2e496deb7858 1473 case RF_RX_RUNNING:
GregCr 0:e6ceb13d2d05 1474 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1475 {
GregCr 0:e6ceb13d2d05 1476 case MODEM_FSK:
Helmut Tschemernjak 31:e50929bd3f32 1477 // Checks if DIO4 is connected. If it is not PreambleDtected is set to true.
Helmut Tschemernjak 31:e50929bd3f32 1478 if( this->dioIrq[4] == NULL )
Helmut Tschemernjak 31:e50929bd3f32 1479 {
Helmut Tschemernjak 31:e50929bd3f32 1480 this->settings.FskPacketHandler.PreambleDetected = true;
Helmut Tschemernjak 31:e50929bd3f32 1481 }
Helmut Tschemernjak 31:e50929bd3f32 1482
GregCr 0:e6ceb13d2d05 1483 if( ( this->settings.FskPacketHandler.PreambleDetected == true ) && ( this->settings.FskPacketHandler.SyncWordDetected == false ) )
GregCr 0:e6ceb13d2d05 1484 {
GregCr 0:e6ceb13d2d05 1485 rxTimeoutSyncWord.detach( );
mluis 25:3778e6204cc1 1486
GregCr 0:e6ceb13d2d05 1487 this->settings.FskPacketHandler.SyncWordDetected = true;
mluis 25:3778e6204cc1 1488
GregCr 0:e6ceb13d2d05 1489 this->settings.FskPacketHandler.RssiValue = -( Read( REG_RSSIVALUE ) >> 1 );
GregCr 0:e6ceb13d2d05 1490
GregCr 0:e6ceb13d2d05 1491 this->settings.FskPacketHandler.AfcValue = ( int32_t )( double )( ( ( uint16_t )Read( REG_AFCMSB ) << 8 ) |
GregCr 0:e6ceb13d2d05 1492 ( uint16_t )Read( REG_AFCLSB ) ) *
GregCr 0:e6ceb13d2d05 1493 ( double )FREQ_STEP;
GregCr 0:e6ceb13d2d05 1494 this->settings.FskPacketHandler.RxGain = ( Read( REG_LNA ) >> 5 ) & 0x07;
GregCr 0:e6ceb13d2d05 1495 }
GregCr 0:e6ceb13d2d05 1496 break;
GregCr 0:e6ceb13d2d05 1497 case MODEM_LORA:
GregCr 6:e7f02929cd3d 1498 if( this->settings.LoRa.FreqHopOn == true )
GregCr 6:e7f02929cd3d 1499 {
GregCr 6:e7f02929cd3d 1500 // Clear Irq
GregCr 6:e7f02929cd3d 1501 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
mluis 25:3778e6204cc1 1502
mluis 22:7f3aab69cca9 1503 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
mluis 13:618826a997e2 1504 {
mluis 21:2e496deb7858 1505 this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
mluis 13:618826a997e2 1506 }
mluis 22:7f3aab69cca9 1507 }
GregCr 0:e6ceb13d2d05 1508 break;
GregCr 0:e6ceb13d2d05 1509 default:
GregCr 0:e6ceb13d2d05 1510 break;
GregCr 0:e6ceb13d2d05 1511 }
GregCr 0:e6ceb13d2d05 1512 break;
mluis 21:2e496deb7858 1513 case RF_TX_RUNNING:
GregCr 0:e6ceb13d2d05 1514 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1515 {
GregCr 0:e6ceb13d2d05 1516 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1517 break;
GregCr 0:e6ceb13d2d05 1518 case MODEM_LORA:
GregCr 6:e7f02929cd3d 1519 if( this->settings.LoRa.FreqHopOn == true )
GregCr 6:e7f02929cd3d 1520 {
GregCr 6:e7f02929cd3d 1521 // Clear Irq
GregCr 6:e7f02929cd3d 1522 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
mluis 25:3778e6204cc1 1523
mluis 22:7f3aab69cca9 1524 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->FhssChangeChannel != NULL ) )
mluis 13:618826a997e2 1525 {
mluis 21:2e496deb7858 1526 this->RadioEvents->FhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
mluis 13:618826a997e2 1527 }
mluis 22:7f3aab69cca9 1528 }
GregCr 0:e6ceb13d2d05 1529 break;
GregCr 0:e6ceb13d2d05 1530 default:
GregCr 0:e6ceb13d2d05 1531 break;
GregCr 0:e6ceb13d2d05 1532 }
mluis 22:7f3aab69cca9 1533 break;
GregCr 0:e6ceb13d2d05 1534 default:
GregCr 0:e6ceb13d2d05 1535 break;
GregCr 0:e6ceb13d2d05 1536 }
GregCr 0:e6ceb13d2d05 1537 }
GregCr 0:e6ceb13d2d05 1538
GregCr 0:e6ceb13d2d05 1539 void SX1276::OnDio3Irq( void )
GregCr 0:e6ceb13d2d05 1540 {
GregCr 0:e6ceb13d2d05 1541 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1542 {
GregCr 0:e6ceb13d2d05 1543 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1544 break;
GregCr 0:e6ceb13d2d05 1545 case MODEM_LORA:
mluis 22:7f3aab69cca9 1546 if( ( Read( REG_LR_IRQFLAGS ) & RFLR_IRQFLAGS_CADDETECTED ) == RFLR_IRQFLAGS_CADDETECTED )
mluis 13:618826a997e2 1547 {
mluis 13:618826a997e2 1548 // Clear Irq
mluis 22:7f3aab69cca9 1549 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE );
mluis 22:7f3aab69cca9 1550 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
mluis 13:618826a997e2 1551 {
mluis 21:2e496deb7858 1552 this->RadioEvents->CadDone( true );
mluis 13:618826a997e2 1553 }
GregCr 12:aa5b3bf7fdf4 1554 }
GregCr 12:aa5b3bf7fdf4 1555 else
mluis 25:3778e6204cc1 1556 {
mluis 13:618826a997e2 1557 // Clear Irq
mluis 13:618826a997e2 1558 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
mluis 22:7f3aab69cca9 1559 if( ( this->RadioEvents != NULL ) && ( this->RadioEvents->CadDone != NULL ) )
mluis 13:618826a997e2 1560 {
mluis 21:2e496deb7858 1561 this->RadioEvents->CadDone( false );
mluis 13:618826a997e2 1562 }
GregCr 7:2b555111463f 1563 }
GregCr 0:e6ceb13d2d05 1564 break;
GregCr 0:e6ceb13d2d05 1565 default:
GregCr 0:e6ceb13d2d05 1566 break;
GregCr 0:e6ceb13d2d05 1567 }
GregCr 0:e6ceb13d2d05 1568 }
GregCr 0:e6ceb13d2d05 1569
GregCr 0:e6ceb13d2d05 1570 void SX1276::OnDio4Irq( void )
GregCr 0:e6ceb13d2d05 1571 {
GregCr 0:e6ceb13d2d05 1572 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1573 {
GregCr 0:e6ceb13d2d05 1574 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1575 {
GregCr 0:e6ceb13d2d05 1576 if( this->settings.FskPacketHandler.PreambleDetected == false )
GregCr 0:e6ceb13d2d05 1577 {
GregCr 0:e6ceb13d2d05 1578 this->settings.FskPacketHandler.PreambleDetected = true;
mluis 25:3778e6204cc1 1579 }
GregCr 0:e6ceb13d2d05 1580 }
GregCr 0:e6ceb13d2d05 1581 break;
GregCr 0:e6ceb13d2d05 1582 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1583 break;
GregCr 0:e6ceb13d2d05 1584 default:
GregCr 0:e6ceb13d2d05 1585 break;
GregCr 0:e6ceb13d2d05 1586 }
GregCr 0:e6ceb13d2d05 1587 }
GregCr 0:e6ceb13d2d05 1588
GregCr 0:e6ceb13d2d05 1589 void SX1276::OnDio5Irq( void )
GregCr 0:e6ceb13d2d05 1590 {
GregCr 0:e6ceb13d2d05 1591 switch( this->settings.Modem )
GregCr 0:e6ceb13d2d05 1592 {
GregCr 0:e6ceb13d2d05 1593 case MODEM_FSK:
GregCr 0:e6ceb13d2d05 1594 break;
GregCr 0:e6ceb13d2d05 1595 case MODEM_LORA:
GregCr 0:e6ceb13d2d05 1596 break;
GregCr 0:e6ceb13d2d05 1597 default:
GregCr 0:e6ceb13d2d05 1598 break;
GregCr 0:e6ceb13d2d05 1599 }
mluis 13:618826a997e2 1600 }