Based on SX1276Lib. Simplified and targeted for Modtronix inAir modules. All pins can now be specified to use interrupts or general purpose I/O pins.

Committer:
modtronix-com
Date:
Fri Aug 19 15:50:01 2016 +1000
Revision:
9:9a77e2c7c5e8
Parent:
6:d542b5a44d5a
Cleaned up includes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
modtronix 1:64a9c4a03244 1 /*
modtronix 1:64a9c4a03244 2 / _____) _ | |
modtronix 1:64a9c4a03244 3 ( (____ _____ ____ _| |_ _____ ____| |__
modtronix 1:64a9c4a03244 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
modtronix 1:64a9c4a03244 5 _____) ) ____| | | || |_| ____( (___| | | |
modtronix 1:64a9c4a03244 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
modtronix 1:64a9c4a03244 7 ( C )2014 Semtech
modtronix 1:64a9c4a03244 8
modtronix 1:64a9c4a03244 9 Description: Actual implementation of a SX1276 radio, inherits Radio
modtronix 1:64a9c4a03244 10
modtronix 1:64a9c4a03244 11 License: Revised BSD License, see LICENSE.TXT file include in the project
modtronix 1:64a9c4a03244 12
modtronix 1:64a9c4a03244 13 Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
modtronix 1:64a9c4a03244 14 */
modtronix-com 9:9a77e2c7c5e8 15 #include "mbed.h"
modtronix 1:64a9c4a03244 16 #include "inair.h"
modtronix 1:64a9c4a03244 17
modtronix-com 4:0086deec9cac 18 //MODTRONIX BEGIN /////////////////////////////////////////////////////////////
modtronix-com 4:0086deec9cac 19 #define DEBUG_ENABLE 0
modtronix-com 4:0086deec9cac 20 #if (DEBUG_ENABLE == 1)
modtronix-com 4:0086deec9cac 21 extern Stream* pMxDebug; //Define Stream for debug output in user code called pMxDebug
modtronix-com 4:0086deec9cac 22 #define MX_DEBUG pMxDebug->printf
modtronix-com 4:0086deec9cac 23 #else
modtronix-com 4:0086deec9cac 24 #define MX_DEBUG(format, args...) ((void)0)
modtronix-com 4:0086deec9cac 25 #endif
modtronix-com 4:0086deec9cac 26 //MODTRONIX END ///////////////////////////////////////////////////////////////
modtronix-com 4:0086deec9cac 27
modtronix 1:64a9c4a03244 28 #define INAIR_ENABLE_FSK 0
modtronix 1:64a9c4a03244 29
modtronix 1:64a9c4a03244 30 const FskBandwidth_t InAir::FskBandwidths[] =
modtronix 1:64a9c4a03244 31 {
modtronix 1:64a9c4a03244 32 { 2600 , 0x17 },
modtronix 1:64a9c4a03244 33 { 3100 , 0x0F },
modtronix 1:64a9c4a03244 34 { 3900 , 0x07 },
modtronix 1:64a9c4a03244 35 { 5200 , 0x16 },
modtronix 1:64a9c4a03244 36 { 6300 , 0x0E },
modtronix 1:64a9c4a03244 37 { 7800 , 0x06 },
modtronix 1:64a9c4a03244 38 { 10400 , 0x15 },
modtronix 1:64a9c4a03244 39 { 12500 , 0x0D },
modtronix 1:64a9c4a03244 40 { 15600 , 0x05 },
modtronix 1:64a9c4a03244 41 { 20800 , 0x14 },
modtronix 1:64a9c4a03244 42 { 25000 , 0x0C },
modtronix 1:64a9c4a03244 43 { 31300 , 0x04 },
modtronix 1:64a9c4a03244 44 { 41700 , 0x13 },
modtronix 1:64a9c4a03244 45 { 50000 , 0x0B },
modtronix 1:64a9c4a03244 46 { 62500 , 0x03 },
modtronix 1:64a9c4a03244 47 { 83333 , 0x12 },
modtronix 1:64a9c4a03244 48 { 100000, 0x0A },
modtronix 1:64a9c4a03244 49 { 125000, 0x02 },
modtronix 1:64a9c4a03244 50 { 166700, 0x11 },
modtronix 1:64a9c4a03244 51 { 200000, 0x09 },
modtronix 1:64a9c4a03244 52 { 250000, 0x01 },
modtronix 1:64a9c4a03244 53 { 300000, 0x00 }, // Invalid Badwidth
modtronix 1:64a9c4a03244 54 };
modtronix 1:64a9c4a03244 55
modtronix 1:64a9c4a03244 56
modtronix 1:64a9c4a03244 57 InAir::InAir( void ( *txDone )( ), void ( *txTimeout ) ( ), void ( *rxDone ) ( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ),
modtronix 1:64a9c4a03244 58 void ( *rxTimeout ) ( ), void ( *rxError ) ( ), void ( *fhssChangeChannel ) ( uint8_t channelIndex ), void ( *cadDone ) ( bool channelActivityDetected ),
modtronix 1:64a9c4a03244 59 PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
modtronix 1:64a9c4a03244 60 PinName dio0, PinName dio1, PinName dio2, PinName dio3)
modtronix 1:64a9c4a03244 61 : Radio( txDone, txTimeout, rxDone, rxTimeout, rxError, fhssChangeChannel, cadDone ),
modtronix 1:64a9c4a03244 62 spi( mosi, miso, sclk ),
modtronix 1:64a9c4a03244 63 nss( nss ),
modtronix 1:64a9c4a03244 64 reset( reset ),
modtronix 1:64a9c4a03244 65 dio0( dio0 ), dio1( dio1 ), dio2( dio2 ), dio3( dio3 ),
modtronix 1:64a9c4a03244 66 isRadioActive( false )
modtronix 1:64a9c4a03244 67 {
modtronix 1:64a9c4a03244 68 wait_ms( 10 );
modtronix 1:64a9c4a03244 69 this->rxTx = 0;
modtronix 1:64a9c4a03244 70 this->rxBuffer = new uint8_t[RX_BUFFER_SIZE];
modtronix 1:64a9c4a03244 71 previousOpMode = RF_OPMODE_STANDBY;
modtronix 1:64a9c4a03244 72
modtronix 1:64a9c4a03244 73 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 74
modtronix 1:64a9c4a03244 75 // From sx1276-inAir Constructor //////////////////////////////////////////
modtronix 1:64a9c4a03244 76 Reset( );
modtronix 1:64a9c4a03244 77
modtronix 1:64a9c4a03244 78 boardConnected = BOARD_UNKNOWN;
modtronix 1:64a9c4a03244 79
modtronix 1:64a9c4a03244 80 RxChainCalibration( );
modtronix 1:64a9c4a03244 81
modtronix 1:64a9c4a03244 82 IoInit( );
modtronix 1:64a9c4a03244 83
modtronix 1:64a9c4a03244 84 SetOpMode( RF_OPMODE_SLEEP );
modtronix 1:64a9c4a03244 85
modtronix 1:64a9c4a03244 86 IoIrqInit();
modtronix 1:64a9c4a03244 87
modtronix 1:64a9c4a03244 88 RadioRegistersInit( );
modtronix 1:64a9c4a03244 89
modtronix 1:64a9c4a03244 90 SetModem( MODEM_LORA );
modtronix 1:64a9c4a03244 91
modtronix 1:64a9c4a03244 92 this->settings.State = IDLE ;
modtronix 1:64a9c4a03244 93 }
modtronix 1:64a9c4a03244 94
modtronix 1:64a9c4a03244 95 InAir::~InAir( )
modtronix 1:64a9c4a03244 96 {
modtronix 1:64a9c4a03244 97 delete this->rxBuffer;
modtronix 1:64a9c4a03244 98 }
modtronix 1:64a9c4a03244 99
modtronix 1:64a9c4a03244 100 void InAir::task(void)
modtronix 1:64a9c4a03244 101 {
modtronix 1:64a9c4a03244 102 #if(INAIR_DIO0_IS_INTERRUPT==0)
modtronix 1:64a9c4a03244 103 static bool dio0Was0 = false;
modtronix 1:64a9c4a03244 104 #endif
modtronix 1:64a9c4a03244 105 #if(INAIR_DIO1_IS_INTERRUPT==0)
modtronix 1:64a9c4a03244 106 static bool dio1Was0 = false;
modtronix 1:64a9c4a03244 107 #endif
modtronix 1:64a9c4a03244 108 #if(INAIR_DIO2_IS_INTERRUPT==0)
modtronix 1:64a9c4a03244 109 static bool dio2Was0 = false;
modtronix 1:64a9c4a03244 110 #endif
modtronix 1:64a9c4a03244 111 #if(INAIR_DIO3_IS_INTERRUPT==0)
modtronix 1:64a9c4a03244 112 static bool dio3Was0 = false;
modtronix 1:64a9c4a03244 113 #endif
modtronix 1:64a9c4a03244 114
modtronix 1:64a9c4a03244 115 #if(INAIR_DIO0_IS_INTERRUPT==0)
modtronix 1:64a9c4a03244 116 if (dio0.read() == 0) {
modtronix 1:64a9c4a03244 117 dio0Was0 = true;
modtronix 1:64a9c4a03244 118 }
modtronix 1:64a9c4a03244 119 else {
modtronix 1:64a9c4a03244 120 //Only do once on rising edge of 0-to-1 transition
modtronix 1:64a9c4a03244 121 if (dio0Was0 == true) {
modtronix 1:64a9c4a03244 122 dio0Was0 = false;
modtronix 1:64a9c4a03244 123 OnDio0Irq();
modtronix 1:64a9c4a03244 124 }
modtronix 1:64a9c4a03244 125 }
modtronix 1:64a9c4a03244 126 #endif
modtronix 1:64a9c4a03244 127
modtronix 1:64a9c4a03244 128 #if(INAIR_DIO1_IS_INTERRUPT==0)
modtronix 1:64a9c4a03244 129 if (dio1.read() == 0) {
modtronix 1:64a9c4a03244 130 dio1Was0 = true;
modtronix 1:64a9c4a03244 131 }
modtronix 1:64a9c4a03244 132 else {
modtronix 1:64a9c4a03244 133 //Only do once on rising edge of 0-to-1 transition
modtronix 1:64a9c4a03244 134 if (dio1Was0 == true) {
modtronix 1:64a9c4a03244 135 dio1Was0 = false;
modtronix 1:64a9c4a03244 136 OnDio1Irq();
modtronix 1:64a9c4a03244 137 }
modtronix 1:64a9c4a03244 138 }
modtronix 1:64a9c4a03244 139 #endif
modtronix 1:64a9c4a03244 140
modtronix 1:64a9c4a03244 141 #if(INAIR_DIO2_IS_INTERRUPT==0)
modtronix 1:64a9c4a03244 142 if (dio2.read() == 0) {
modtronix 1:64a9c4a03244 143 dio2Was0 = true;
modtronix 1:64a9c4a03244 144 }
modtronix 1:64a9c4a03244 145 else {
modtronix 1:64a9c4a03244 146 //Only do once on rising edge of 0-to-1 transition
modtronix 1:64a9c4a03244 147 if (dio2Was0 == true) {
modtronix 1:64a9c4a03244 148 dio2Was0 = false;
modtronix 1:64a9c4a03244 149 OnDio2Irq();
modtronix 1:64a9c4a03244 150 }
modtronix 1:64a9c4a03244 151 }
modtronix 1:64a9c4a03244 152 #endif
modtronix 1:64a9c4a03244 153
modtronix 1:64a9c4a03244 154 #if(INAIR_DIO3_IS_INTERRUPT==0)
modtronix 1:64a9c4a03244 155 if (dio3.read() == 0) {
modtronix 1:64a9c4a03244 156 dio3Was0 = true;
modtronix 1:64a9c4a03244 157 }
modtronix 1:64a9c4a03244 158 else {
modtronix 1:64a9c4a03244 159 //Only do once on rising edge of 0-to-1 transition
modtronix 1:64a9c4a03244 160 if (dio3Was0 == true) {
modtronix 1:64a9c4a03244 161 dio3Was0 = false;
modtronix 1:64a9c4a03244 162 OnDio3Irq();
modtronix 1:64a9c4a03244 163 }
modtronix 1:64a9c4a03244 164 }
modtronix 1:64a9c4a03244 165 #endif
modtronix 1:64a9c4a03244 166
modtronix 1:64a9c4a03244 167 }
modtronix 1:64a9c4a03244 168
modtronix 1:64a9c4a03244 169
modtronix 1:64a9c4a03244 170 uint8_t InAir::GetBoardType( void )
modtronix 1:64a9c4a03244 171 {
modtronix 1:64a9c4a03244 172 return boardConnected;
modtronix 1:64a9c4a03244 173 }
modtronix 1:64a9c4a03244 174
modtronix 1:64a9c4a03244 175 void InAir::SetBoardType( uint8_t boardType)
modtronix 1:64a9c4a03244 176 {
modtronix 1:64a9c4a03244 177 boardConnected = boardType;
modtronix 1:64a9c4a03244 178 }
modtronix 1:64a9c4a03244 179
modtronix 1:64a9c4a03244 180 void InAir::RxChainCalibration( void )
modtronix 1:64a9c4a03244 181 {
modtronix 1:64a9c4a03244 182 uint8_t regPaConfigInitVal;
modtronix 1:64a9c4a03244 183 uint32_t initialFreq;
modtronix 1:64a9c4a03244 184
modtronix 1:64a9c4a03244 185 // Save context
modtronix 1:64a9c4a03244 186 regPaConfigInitVal = this->Read( REG_PACONFIG );
modtronix 1:64a9c4a03244 187 initialFreq = ( double )( ( ( uint32_t )this->Read( REG_FRFMSB ) << 16 ) |
modtronix 1:64a9c4a03244 188 ( ( uint32_t )this->Read( REG_FRFMID ) << 8 ) |
modtronix 1:64a9c4a03244 189 ( ( uint32_t )this->Read( REG_FRFLSB ) ) ) * ( double )FREQ_STEP;
modtronix 1:64a9c4a03244 190
modtronix 1:64a9c4a03244 191 // Cut the PA just in case, RFO output, power = -1 dBm
modtronix 1:64a9c4a03244 192 this->Write( REG_PACONFIG, 0x00 );
modtronix 1:64a9c4a03244 193
modtronix 1:64a9c4a03244 194 // Launch Rx chain calibration for LF band
modtronix 1:64a9c4a03244 195 Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
modtronix 1:64a9c4a03244 196 while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
modtronix 1:64a9c4a03244 197 {
modtronix 1:64a9c4a03244 198 }
modtronix 1:64a9c4a03244 199
modtronix 1:64a9c4a03244 200 // Sets a Frequency in HF band
modtronix 1:64a9c4a03244 201 settings.Channel= 868000000 ;
modtronix 1:64a9c4a03244 202
modtronix 1:64a9c4a03244 203 // Launch Rx chain calibration for HF band
modtronix 1:64a9c4a03244 204 Write ( REG_IMAGECAL, ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START );
modtronix 1:64a9c4a03244 205 while( ( Read( REG_IMAGECAL ) & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
modtronix 1:64a9c4a03244 206 {
modtronix 1:64a9c4a03244 207 }
modtronix 1:64a9c4a03244 208
modtronix 1:64a9c4a03244 209 // Restore context
modtronix 1:64a9c4a03244 210 this->Write( REG_PACONFIG, regPaConfigInitVal );
modtronix 1:64a9c4a03244 211 SetChannel( initialFreq );
modtronix 1:64a9c4a03244 212 }
modtronix 1:64a9c4a03244 213
modtronix-com 2:93cf5cb235ee 214 RadioState InAir::GetStatus( void )
modtronix 1:64a9c4a03244 215 {
modtronix 1:64a9c4a03244 216 return this->settings.State;
modtronix 1:64a9c4a03244 217 }
modtronix 1:64a9c4a03244 218
modtronix 1:64a9c4a03244 219 void InAir::SetChannel( uint32_t freq )
modtronix 1:64a9c4a03244 220 {
modtronix 1:64a9c4a03244 221 this->settings.Channel = freq;
modtronix 1:64a9c4a03244 222 freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
modtronix 1:64a9c4a03244 223 Write( REG_FRFMSB, ( uint8_t )( ( freq >> 16 ) & 0xFF ) );
modtronix 1:64a9c4a03244 224 Write( REG_FRFMID, ( uint8_t )( ( freq >> 8 ) & 0xFF ) );
modtronix 1:64a9c4a03244 225 Write( REG_FRFLSB, ( uint8_t )( freq & 0xFF ) );
modtronix 1:64a9c4a03244 226 }
modtronix 1:64a9c4a03244 227
modtronix 1:64a9c4a03244 228 bool InAir::IsChannelFree( ModemType modem, uint32_t freq, int8_t rssiThresh )
modtronix 1:64a9c4a03244 229 {
modtronix 1:64a9c4a03244 230 int16_t rssi = 0;
modtronix 1:64a9c4a03244 231
modtronix 1:64a9c4a03244 232 SetModem( modem );
modtronix 1:64a9c4a03244 233
modtronix 1:64a9c4a03244 234 SetChannel( freq );
modtronix 1:64a9c4a03244 235
modtronix 1:64a9c4a03244 236 SetOpMode( RF_OPMODE_RECEIVER );
modtronix 1:64a9c4a03244 237
modtronix 1:64a9c4a03244 238 wait_ms( 1 );
modtronix 1:64a9c4a03244 239
modtronix 1:64a9c4a03244 240 rssi = GetRssi( modem );
modtronix 1:64a9c4a03244 241
modtronix 1:64a9c4a03244 242 Sleep( );
modtronix 1:64a9c4a03244 243
modtronix 1:64a9c4a03244 244 if( rssi > ( int16_t )rssiThresh )
modtronix 1:64a9c4a03244 245 {
modtronix 1:64a9c4a03244 246 return false;
modtronix 1:64a9c4a03244 247 }
modtronix 1:64a9c4a03244 248 return true;
modtronix 1:64a9c4a03244 249 }
modtronix 1:64a9c4a03244 250
modtronix 1:64a9c4a03244 251 uint32_t InAir::Random( void )
modtronix 1:64a9c4a03244 252 {
modtronix 1:64a9c4a03244 253 uint8_t i;
modtronix 1:64a9c4a03244 254 uint32_t rnd = 0;
modtronix 1:64a9c4a03244 255
modtronix 1:64a9c4a03244 256 /*
modtronix 1:64a9c4a03244 257 * Radio setup for random number generation
modtronix 1:64a9c4a03244 258 */
modtronix 1:64a9c4a03244 259 // Set LoRa modem ON
modtronix 1:64a9c4a03244 260 SetModem( MODEM_LORA );
modtronix 1:64a9c4a03244 261
modtronix 1:64a9c4a03244 262 // Disable LoRa modem interrupts
modtronix 1:64a9c4a03244 263 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
modtronix 1:64a9c4a03244 264 RFLR_IRQFLAGS_RXDONE |
modtronix 1:64a9c4a03244 265 RFLR_IRQFLAGS_PAYLOADCRCERROR |
modtronix 1:64a9c4a03244 266 RFLR_IRQFLAGS_VALIDHEADER |
modtronix 1:64a9c4a03244 267 RFLR_IRQFLAGS_TXDONE |
modtronix 1:64a9c4a03244 268 RFLR_IRQFLAGS_CADDONE |
modtronix 1:64a9c4a03244 269 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
modtronix 1:64a9c4a03244 270 RFLR_IRQFLAGS_CADDETECTED );
modtronix 1:64a9c4a03244 271
modtronix 1:64a9c4a03244 272 // Set radio in continuous reception
modtronix 1:64a9c4a03244 273 SetOpMode( RF_OPMODE_RECEIVER );
modtronix 1:64a9c4a03244 274
modtronix 1:64a9c4a03244 275 for( i = 0; i < 32; i++ )
modtronix 1:64a9c4a03244 276 {
modtronix 1:64a9c4a03244 277 wait_ms( 1 );
modtronix 1:64a9c4a03244 278 // Unfiltered RSSI value reading. Only takes the LSB value
modtronix 1:64a9c4a03244 279 rnd |= ( ( uint32_t )Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) << i;
modtronix 1:64a9c4a03244 280 }
modtronix 1:64a9c4a03244 281
modtronix 1:64a9c4a03244 282 Sleep( );
modtronix 1:64a9c4a03244 283
modtronix 1:64a9c4a03244 284 return rnd;
modtronix 1:64a9c4a03244 285 }
modtronix 1:64a9c4a03244 286
modtronix 1:64a9c4a03244 287 /*!
modtronix 1:64a9c4a03244 288 * Returns the known FSK bandwidth registers value
modtronix 1:64a9c4a03244 289 *
modtronix 1:64a9c4a03244 290 * \param [IN] bandwidth Bandwidth value in Hz
modtronix 1:64a9c4a03244 291 * \retval regValue Bandwidth register value.
modtronix 1:64a9c4a03244 292 */
modtronix 1:64a9c4a03244 293 uint8_t InAir::GetFskBandwidthRegValue( uint32_t bandwidth )
modtronix 1:64a9c4a03244 294 {
modtronix 1:64a9c4a03244 295 uint8_t i;
modtronix 1:64a9c4a03244 296
modtronix 1:64a9c4a03244 297 for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ )
modtronix 1:64a9c4a03244 298 {
modtronix 1:64a9c4a03244 299 if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) )
modtronix 1:64a9c4a03244 300 {
modtronix 1:64a9c4a03244 301 return FskBandwidths[i].RegValue;
modtronix 1:64a9c4a03244 302 }
modtronix 1:64a9c4a03244 303 }
modtronix 1:64a9c4a03244 304 // ERROR: Value not found
modtronix 1:64a9c4a03244 305 while( 1 );
modtronix 1:64a9c4a03244 306 }
modtronix 1:64a9c4a03244 307
modtronix 1:64a9c4a03244 308 void InAir::SetRxConfig( ModemType modem, uint32_t bandwidth,
modtronix 1:64a9c4a03244 309 uint32_t datarate, uint8_t coderate,
modtronix 1:64a9c4a03244 310 uint32_t bandwidthAfc, uint16_t preambleLen,
modtronix 1:64a9c4a03244 311 uint16_t symbTimeout, bool fixLen,
modtronix 1:64a9c4a03244 312 uint8_t payloadLen,
modtronix 1:64a9c4a03244 313 bool crcOn, bool freqHopOn, uint8_t hopPeriod,
modtronix 1:64a9c4a03244 314 bool iqInverted, bool rxContinuous )
modtronix 1:64a9c4a03244 315 {
modtronix 1:64a9c4a03244 316 SetModem( modem );
modtronix 1:64a9c4a03244 317
modtronix 1:64a9c4a03244 318 switch( modem )
modtronix 1:64a9c4a03244 319 {
modtronix 1:64a9c4a03244 320 case MODEM_FSK:
modtronix 1:64a9c4a03244 321 {
modtronix 1:64a9c4a03244 322 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 323 this->settings.Fsk.Bandwidth = bandwidth;
modtronix 1:64a9c4a03244 324 this->settings.Fsk.Datarate = datarate;
modtronix 1:64a9c4a03244 325 this->settings.Fsk.BandwidthAfc = bandwidthAfc;
modtronix 1:64a9c4a03244 326 this->settings.Fsk.FixLen = fixLen;
modtronix 1:64a9c4a03244 327 this->settings.Fsk.PayloadLen = payloadLen;
modtronix 1:64a9c4a03244 328 this->settings.Fsk.CrcOn = crcOn;
modtronix 1:64a9c4a03244 329 this->settings.Fsk.IqInverted = iqInverted;
modtronix 1:64a9c4a03244 330 this->settings.Fsk.RxContinuous = rxContinuous;
modtronix 1:64a9c4a03244 331 this->settings.Fsk.PreambleLen = preambleLen;
modtronix 1:64a9c4a03244 332
modtronix 1:64a9c4a03244 333 datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
modtronix 1:64a9c4a03244 334 Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
modtronix 1:64a9c4a03244 335 Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
modtronix 1:64a9c4a03244 336
modtronix 1:64a9c4a03244 337 Write( REG_RXBW, GetFskBandwidthRegValue( bandwidth ) );
modtronix 1:64a9c4a03244 338 Write( REG_AFCBW, GetFskBandwidthRegValue( bandwidthAfc ) );
modtronix 1:64a9c4a03244 339
modtronix 1:64a9c4a03244 340 Write( REG_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
modtronix 1:64a9c4a03244 341 Write( REG_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
modtronix 1:64a9c4a03244 342
modtronix 1:64a9c4a03244 343 Write( REG_PACKETCONFIG1,
modtronix 1:64a9c4a03244 344 ( Read( REG_PACKETCONFIG1 ) &
modtronix 1:64a9c4a03244 345 RF_PACKETCONFIG1_CRC_MASK &
modtronix 1:64a9c4a03244 346 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
modtronix 1:64a9c4a03244 347 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
modtronix 1:64a9c4a03244 348 ( crcOn << 4 ) );
modtronix 1:64a9c4a03244 349 if( fixLen == 1 )
modtronix 1:64a9c4a03244 350 {
modtronix 1:64a9c4a03244 351 Write( REG_PAYLOADLENGTH, payloadLen );
modtronix 1:64a9c4a03244 352 }
modtronix 1:64a9c4a03244 353 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 354 }
modtronix 1:64a9c4a03244 355 break;
modtronix 1:64a9c4a03244 356 case MODEM_LORA:
modtronix 1:64a9c4a03244 357 {
modtronix 1:64a9c4a03244 358 if( bandwidth > 9 )
modtronix 1:64a9c4a03244 359 {
modtronix 1:64a9c4a03244 360 // Fatal error: Bandwidth must be 0-9 (7.8 - 500khz)
modtronix 1:64a9c4a03244 361 while( 1 );
modtronix 1:64a9c4a03244 362 }
modtronix 1:64a9c4a03244 363 //bandwidth += 7; //Changed bandwidth from 0-2 to 0-10
modtronix 1:64a9c4a03244 364 this->settings.LoRa.Bandwidth = bandwidth;
modtronix 1:64a9c4a03244 365 this->settings.LoRa.Datarate = datarate;
modtronix 1:64a9c4a03244 366 this->settings.LoRa.Coderate = coderate;
modtronix 1:64a9c4a03244 367 this->settings.LoRa.FixLen = fixLen;
modtronix 1:64a9c4a03244 368 this->settings.LoRa.PayloadLen = payloadLen;
modtronix 1:64a9c4a03244 369 this->settings.LoRa.CrcOn = crcOn;
modtronix 1:64a9c4a03244 370 this->settings.LoRa.FreqHopOn = freqHopOn;
modtronix 1:64a9c4a03244 371 this->settings.LoRa.HopPeriod = hopPeriod;
modtronix 1:64a9c4a03244 372 this->settings.LoRa.IqInverted = iqInverted;
modtronix 1:64a9c4a03244 373 this->settings.LoRa.RxContinuous = rxContinuous;
modtronix 1:64a9c4a03244 374
modtronix 1:64a9c4a03244 375 if( datarate > 12 )
modtronix 1:64a9c4a03244 376 {
modtronix 1:64a9c4a03244 377 datarate = 12;
modtronix 1:64a9c4a03244 378 }
modtronix 1:64a9c4a03244 379 else if( datarate < 6 )
modtronix 1:64a9c4a03244 380 {
modtronix 1:64a9c4a03244 381 datarate = 6;
modtronix 1:64a9c4a03244 382 }
modtronix 1:64a9c4a03244 383
modtronix 1:64a9c4a03244 384 //bandwidth 6=62.5, 7=125, 8=250, 9=500, datarate=SF. LowDatarateOptimize is mandatory when symbol length > 16ms
modtronix 1:64a9c4a03244 385 //LowDatarateOptimize = 0 when (BW=500) or (BW=250 and SF=12), else it is ON (Tsym > 16ms)
modtronix 1:64a9c4a03244 386 if( ( ( bandwidth == 8 ) && ( datarate == 12 ) ) ||
modtronix 1:64a9c4a03244 387 ( ( bandwidth == 7 ) && ( datarate > 10 ) ) ||
modtronix 1:64a9c4a03244 388 ( ( bandwidth == 6 ) && ( datarate > 9 ) ) ||
modtronix 1:64a9c4a03244 389 ( ( bandwidth == 5 ) && ( datarate > 9 ) ) ||
modtronix 1:64a9c4a03244 390 ( ( bandwidth == 4 ) && ( datarate > 8 ) ) || ( bandwidth < 4 )
modtronix 1:64a9c4a03244 391 //The below is actually correct method, but assume BW = 20.8 and lower will always have SF > 8
modtronix 1:64a9c4a03244 392 // ( ( bandwidth == 3 ) && ( datarate > 8 ) ) ||
modtronix 1:64a9c4a03244 393 // ( ( bandwidth == 2 ) && ( datarate > 7 ) ) ||
modtronix 1:64a9c4a03244 394 // ( ( bandwidth == 1 ) && ( datarate > 7 ) ) ||
modtronix 1:64a9c4a03244 395 // ( ( bandwidth == 0 ) && ( datarate > 6 ) )
modtronix 1:64a9c4a03244 396 )
modtronix 1:64a9c4a03244 397 {
modtronix 1:64a9c4a03244 398 this->settings.LoRa.LowDatarateOptimize = 0x01;
modtronix 1:64a9c4a03244 399 }
modtronix 1:64a9c4a03244 400 else
modtronix 1:64a9c4a03244 401 {
modtronix 1:64a9c4a03244 402 this->settings.LoRa.LowDatarateOptimize = 0x00;
modtronix 1:64a9c4a03244 403 }
modtronix 1:64a9c4a03244 404
modtronix 1:64a9c4a03244 405 Write( REG_LR_MODEMCONFIG1,
modtronix 1:64a9c4a03244 406 ( Read( REG_LR_MODEMCONFIG1 ) &
modtronix 1:64a9c4a03244 407 RFLR_MODEMCONFIG1_BW_MASK &
modtronix 1:64a9c4a03244 408 RFLR_MODEMCONFIG1_CODINGRATE_MASK &
modtronix 1:64a9c4a03244 409 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) |
modtronix 1:64a9c4a03244 410 ( bandwidth << 4 ) | ( coderate << 1 ) |
modtronix 1:64a9c4a03244 411 fixLen );
modtronix 1:64a9c4a03244 412
modtronix 1:64a9c4a03244 413 Write( REG_LR_MODEMCONFIG2,
modtronix 1:64a9c4a03244 414 ( Read( REG_LR_MODEMCONFIG2 ) &
modtronix 1:64a9c4a03244 415 RFLR_MODEMCONFIG2_SF_MASK &
modtronix 1:64a9c4a03244 416 RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK &
modtronix 1:64a9c4a03244 417 RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) |
modtronix 1:64a9c4a03244 418 ( datarate << 4 ) | ( crcOn << 2 ) |
modtronix 1:64a9c4a03244 419 ( ( symbTimeout >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) );
modtronix 1:64a9c4a03244 420
modtronix 1:64a9c4a03244 421 Write( REG_LR_MODEMCONFIG3,
modtronix 1:64a9c4a03244 422 ( Read( REG_LR_MODEMCONFIG3 ) &
modtronix 1:64a9c4a03244 423 RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) |
modtronix 1:64a9c4a03244 424 ( this->settings.LoRa.LowDatarateOptimize << 3 ) );
modtronix 1:64a9c4a03244 425
modtronix 1:64a9c4a03244 426 Write( REG_LR_SYMBTIMEOUTLSB, ( uint8_t )( symbTimeout & 0xFF ) );
modtronix 1:64a9c4a03244 427
modtronix 1:64a9c4a03244 428 Write( REG_LR_PREAMBLEMSB, ( uint8_t )( ( preambleLen >> 8 ) & 0xFF ) );
modtronix 1:64a9c4a03244 429 Write( REG_LR_PREAMBLELSB, ( uint8_t )( preambleLen & 0xFF ) );
modtronix 1:64a9c4a03244 430
modtronix 1:64a9c4a03244 431 if( fixLen == 1 )
modtronix 1:64a9c4a03244 432 {
modtronix 1:64a9c4a03244 433 Write( REG_LR_PAYLOADLENGTH, payloadLen );
modtronix 1:64a9c4a03244 434 }
modtronix 1:64a9c4a03244 435
modtronix 1:64a9c4a03244 436 if( this->settings.LoRa.FreqHopOn == true )
modtronix 1:64a9c4a03244 437 {
modtronix 1:64a9c4a03244 438 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
modtronix 1:64a9c4a03244 439 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
modtronix 1:64a9c4a03244 440 }
modtronix 1:64a9c4a03244 441
modtronix 1:64a9c4a03244 442 if( datarate == 6 )
modtronix 1:64a9c4a03244 443 {
modtronix 1:64a9c4a03244 444 Write( REG_LR_DETECTOPTIMIZE,
modtronix 1:64a9c4a03244 445 ( Read( REG_LR_DETECTOPTIMIZE ) &
modtronix 1:64a9c4a03244 446 RFLR_DETECTIONOPTIMIZE_MASK ) |
modtronix 1:64a9c4a03244 447 RFLR_DETECTIONOPTIMIZE_SF6 );
modtronix 1:64a9c4a03244 448 Write( REG_LR_DETECTIONTHRESHOLD,
modtronix 1:64a9c4a03244 449 RFLR_DETECTIONTHRESH_SF6 );
modtronix 1:64a9c4a03244 450 }
modtronix 1:64a9c4a03244 451 else
modtronix 1:64a9c4a03244 452 {
modtronix 1:64a9c4a03244 453 Write( REG_LR_DETECTOPTIMIZE,
modtronix 1:64a9c4a03244 454 ( Read( REG_LR_DETECTOPTIMIZE ) &
modtronix 1:64a9c4a03244 455 RFLR_DETECTIONOPTIMIZE_MASK ) |
modtronix 1:64a9c4a03244 456 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
modtronix 1:64a9c4a03244 457 Write( REG_LR_DETECTIONTHRESHOLD,
modtronix 1:64a9c4a03244 458 RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
modtronix 1:64a9c4a03244 459 }
modtronix 1:64a9c4a03244 460 }
modtronix 1:64a9c4a03244 461 break;
modtronix 1:64a9c4a03244 462 }
modtronix 1:64a9c4a03244 463 }
modtronix 1:64a9c4a03244 464
modtronix 1:64a9c4a03244 465 void InAir::SetTxConfig( ModemType modem, int8_t power, uint32_t fdev,
modtronix 1:64a9c4a03244 466 uint32_t bandwidth, uint32_t datarate,
modtronix 1:64a9c4a03244 467 uint8_t coderate, uint16_t preambleLen,
modtronix 1:64a9c4a03244 468 bool fixLen, bool crcOn, bool freqHopOn,
modtronix 1:64a9c4a03244 469 uint8_t hopPeriod, bool iqInverted, uint32_t timeout )
modtronix 1:64a9c4a03244 470 {
modtronix 1:64a9c4a03244 471 uint8_t paConfig = 0;
modtronix 1:64a9c4a03244 472 uint8_t paDac = 0;
modtronix 1:64a9c4a03244 473
modtronix 1:64a9c4a03244 474 SetModem( modem );
modtronix 1:64a9c4a03244 475
modtronix 1:64a9c4a03244 476 paConfig = Read( REG_PACONFIG );
modtronix 1:64a9c4a03244 477 paDac = Read( REG_PADAC );
modtronix 1:64a9c4a03244 478
modtronix 1:64a9c4a03244 479 paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | GetPaSelect( this->settings.Channel );
modtronix 1:64a9c4a03244 480 paConfig = ( paConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
modtronix 1:64a9c4a03244 481
modtronix 1:64a9c4a03244 482 if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
modtronix 1:64a9c4a03244 483 {
modtronix 1:64a9c4a03244 484 if( power > 17 )
modtronix 1:64a9c4a03244 485 {
modtronix 1:64a9c4a03244 486 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON;
modtronix 1:64a9c4a03244 487 }
modtronix 1:64a9c4a03244 488 else
modtronix 1:64a9c4a03244 489 {
modtronix 1:64a9c4a03244 490 paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF;
modtronix 1:64a9c4a03244 491 }
modtronix 1:64a9c4a03244 492 if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON )
modtronix 1:64a9c4a03244 493 {
modtronix 1:64a9c4a03244 494 if( power < 5 )
modtronix 1:64a9c4a03244 495 {
modtronix 1:64a9c4a03244 496 power = 5;
modtronix 1:64a9c4a03244 497 }
modtronix 1:64a9c4a03244 498 if( power > 20 )
modtronix 1:64a9c4a03244 499 {
modtronix 1:64a9c4a03244 500 power = 20;
modtronix 1:64a9c4a03244 501 }
modtronix 1:64a9c4a03244 502 paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
modtronix 1:64a9c4a03244 503 }
modtronix 1:64a9c4a03244 504 else
modtronix 1:64a9c4a03244 505 {
modtronix 1:64a9c4a03244 506 if( power < 2 )
modtronix 1:64a9c4a03244 507 {
modtronix 1:64a9c4a03244 508 power = 2;
modtronix 1:64a9c4a03244 509 }
modtronix 1:64a9c4a03244 510 if( power > 17 )
modtronix 1:64a9c4a03244 511 {
modtronix 1:64a9c4a03244 512 power = 17;
modtronix 1:64a9c4a03244 513 }
modtronix 1:64a9c4a03244 514 paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
modtronix 1:64a9c4a03244 515 }
modtronix 1:64a9c4a03244 516 }
modtronix 1:64a9c4a03244 517 else
modtronix 1:64a9c4a03244 518 {
modtronix 1:64a9c4a03244 519 if( power < -1 )
modtronix 1:64a9c4a03244 520 {
modtronix 1:64a9c4a03244 521 power = -1;
modtronix 1:64a9c4a03244 522 }
modtronix 1:64a9c4a03244 523 if( power > 14 )
modtronix 1:64a9c4a03244 524 {
modtronix 1:64a9c4a03244 525 power = 14;
modtronix 1:64a9c4a03244 526 }
modtronix 1:64a9c4a03244 527 paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
modtronix 1:64a9c4a03244 528 }
modtronix 1:64a9c4a03244 529 Write( REG_PACONFIG, paConfig );
modtronix 1:64a9c4a03244 530 Write( REG_PADAC, paDac );
modtronix 1:64a9c4a03244 531
modtronix 1:64a9c4a03244 532 switch( modem )
modtronix 1:64a9c4a03244 533 {
modtronix 1:64a9c4a03244 534 case MODEM_FSK:
modtronix 1:64a9c4a03244 535 {
modtronix 1:64a9c4a03244 536 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 537 this->settings.Fsk.Power = power;
modtronix 1:64a9c4a03244 538 this->settings.Fsk.Fdev = fdev;
modtronix 1:64a9c4a03244 539 this->settings.Fsk.Bandwidth = bandwidth;
modtronix 1:64a9c4a03244 540 this->settings.Fsk.Datarate = datarate;
modtronix 1:64a9c4a03244 541 this->settings.Fsk.PreambleLen = preambleLen;
modtronix 1:64a9c4a03244 542 this->settings.Fsk.FixLen = fixLen;
modtronix 1:64a9c4a03244 543 this->settings.Fsk.CrcOn = crcOn;
modtronix 1:64a9c4a03244 544 this->settings.Fsk.IqInverted = iqInverted;
modtronix 1:64a9c4a03244 545 this->settings.Fsk.TxTimeout = timeout;
modtronix 1:64a9c4a03244 546
modtronix 1:64a9c4a03244 547 fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
modtronix 1:64a9c4a03244 548 Write( REG_FDEVMSB, ( uint8_t )( fdev >> 8 ) );
modtronix 1:64a9c4a03244 549 Write( REG_FDEVLSB, ( uint8_t )( fdev & 0xFF ) );
modtronix 1:64a9c4a03244 550
modtronix 1:64a9c4a03244 551 datarate = ( uint16_t )( ( double )XTAL_FREQ / ( double )datarate );
modtronix 1:64a9c4a03244 552 Write( REG_BITRATEMSB, ( uint8_t )( datarate >> 8 ) );
modtronix 1:64a9c4a03244 553 Write( REG_BITRATELSB, ( uint8_t )( datarate & 0xFF ) );
modtronix 1:64a9c4a03244 554
modtronix 1:64a9c4a03244 555 Write( REG_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
modtronix 1:64a9c4a03244 556 Write( REG_PREAMBLELSB, preambleLen & 0xFF );
modtronix 1:64a9c4a03244 557
modtronix 1:64a9c4a03244 558 Write( REG_PACKETCONFIG1,
modtronix 1:64a9c4a03244 559 ( Read( REG_PACKETCONFIG1 ) &
modtronix 1:64a9c4a03244 560 RF_PACKETCONFIG1_CRC_MASK &
modtronix 1:64a9c4a03244 561 RF_PACKETCONFIG1_PACKETFORMAT_MASK ) |
modtronix 1:64a9c4a03244 562 ( ( fixLen == 1 ) ? RF_PACKETCONFIG1_PACKETFORMAT_FIXED : RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE ) |
modtronix 1:64a9c4a03244 563 ( crcOn << 4 ) );
modtronix 1:64a9c4a03244 564 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 565 }
modtronix 1:64a9c4a03244 566 break;
modtronix 1:64a9c4a03244 567 case MODEM_LORA:
modtronix 1:64a9c4a03244 568 {
modtronix 1:64a9c4a03244 569 this->settings.LoRa.Power = power;
modtronix 1:64a9c4a03244 570 if( bandwidth > 9 )
modtronix 1:64a9c4a03244 571 {
modtronix 1:64a9c4a03244 572 // Fatal error: Bandwidth must be 0-9 (7.8 - 500khz)
modtronix 1:64a9c4a03244 573 while( 1 );
modtronix 1:64a9c4a03244 574 }
modtronix 1:64a9c4a03244 575 //bandwidth += 7;
modtronix 1:64a9c4a03244 576 this->settings.LoRa.Bandwidth = bandwidth;
modtronix 1:64a9c4a03244 577 this->settings.LoRa.Datarate = datarate;
modtronix 1:64a9c4a03244 578 this->settings.LoRa.Coderate = coderate;
modtronix 1:64a9c4a03244 579 this->settings.LoRa.PreambleLen = preambleLen;
modtronix 1:64a9c4a03244 580 this->settings.LoRa.FixLen = fixLen;
modtronix 1:64a9c4a03244 581 this->settings.LoRa.CrcOn = crcOn;
modtronix 1:64a9c4a03244 582 this->settings.LoRa.FreqHopOn = freqHopOn;
modtronix 1:64a9c4a03244 583 this->settings.LoRa.HopPeriod = hopPeriod;
modtronix 1:64a9c4a03244 584 this->settings.LoRa.IqInverted = iqInverted;
modtronix 1:64a9c4a03244 585 this->settings.LoRa.TxTimeout = timeout;
modtronix 1:64a9c4a03244 586
modtronix 1:64a9c4a03244 587 if( datarate > 12 )
modtronix 1:64a9c4a03244 588 {
modtronix 1:64a9c4a03244 589 datarate = 12;
modtronix 1:64a9c4a03244 590 }
modtronix 1:64a9c4a03244 591 else if( datarate < 6 )
modtronix 1:64a9c4a03244 592 {
modtronix 1:64a9c4a03244 593 datarate = 6;
modtronix 1:64a9c4a03244 594 }
modtronix 1:64a9c4a03244 595 //bandwidth 6=62.5, 7=125, 8=250, 9=500, datarate=SF. LowDatarateOptimize is mandatory when symbol length > 16ms
modtronix 1:64a9c4a03244 596 //LowDatarateOptimize = 0 when (BW=500) or (BW=250 and SF=12), else it is ON (Tsym > 16ms)
modtronix 1:64a9c4a03244 597 if( ( ( bandwidth == 8 ) && ( datarate == 12 ) ) ||
modtronix 1:64a9c4a03244 598 ( ( bandwidth == 7 ) && ( datarate > 10 ) ) ||
modtronix 1:64a9c4a03244 599 ( ( bandwidth == 6 ) && ( datarate > 9 ) ) ||
modtronix 1:64a9c4a03244 600 ( ( bandwidth == 5 ) && ( datarate > 9 ) ) ||
modtronix 1:64a9c4a03244 601 ( ( bandwidth == 4 ) && ( datarate > 8 ) ) || ( bandwidth < 4 )
modtronix 1:64a9c4a03244 602 //The below is actually correct method, but assume BW = 20.8 and lower will always have SF > 8
modtronix 1:64a9c4a03244 603 // ( ( bandwidth == 3 ) && ( datarate > 8 ) ) ||
modtronix 1:64a9c4a03244 604 // ( ( bandwidth == 2 ) && ( datarate > 7 ) ) ||
modtronix 1:64a9c4a03244 605 // ( ( bandwidth == 1 ) && ( datarate > 7 ) ) ||
modtronix 1:64a9c4a03244 606 // ( ( bandwidth == 0 ) && ( datarate > 6 ) )
modtronix 1:64a9c4a03244 607 )
modtronix 1:64a9c4a03244 608 {
modtronix 1:64a9c4a03244 609 this->settings.LoRa.LowDatarateOptimize = 0x01;
modtronix 1:64a9c4a03244 610 }
modtronix 1:64a9c4a03244 611 else
modtronix 1:64a9c4a03244 612 {
modtronix 1:64a9c4a03244 613 this->settings.LoRa.LowDatarateOptimize = 0x00;
modtronix 1:64a9c4a03244 614 }
modtronix 1:64a9c4a03244 615
modtronix 1:64a9c4a03244 616 if( this->settings.LoRa.FreqHopOn == true )
modtronix 1:64a9c4a03244 617 {
modtronix 1:64a9c4a03244 618 Write( REG_LR_PLLHOP, ( Read( REG_LR_PLLHOP ) & RFLR_PLLHOP_FASTHOP_MASK ) | RFLR_PLLHOP_FASTHOP_ON );
modtronix 1:64a9c4a03244 619 Write( REG_LR_HOPPERIOD, this->settings.LoRa.HopPeriod );
modtronix 1:64a9c4a03244 620 }
modtronix 1:64a9c4a03244 621
modtronix 1:64a9c4a03244 622 Write( REG_LR_MODEMCONFIG1,
modtronix 1:64a9c4a03244 623 ( Read( REG_LR_MODEMCONFIG1 ) &
modtronix 1:64a9c4a03244 624 RFLR_MODEMCONFIG1_BW_MASK &
modtronix 1:64a9c4a03244 625 RFLR_MODEMCONFIG1_CODINGRATE_MASK &
modtronix 1:64a9c4a03244 626 RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) |
modtronix 1:64a9c4a03244 627 ( bandwidth << 4 ) | ( coderate << 1 ) |
modtronix 1:64a9c4a03244 628 fixLen );
modtronix 1:64a9c4a03244 629
modtronix 1:64a9c4a03244 630 Write( REG_LR_MODEMCONFIG2,
modtronix 1:64a9c4a03244 631 ( Read( REG_LR_MODEMCONFIG2 ) &
modtronix 1:64a9c4a03244 632 RFLR_MODEMCONFIG2_SF_MASK &
modtronix 1:64a9c4a03244 633 RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) |
modtronix 1:64a9c4a03244 634 ( datarate << 4 ) | ( crcOn << 2 ) );
modtronix 1:64a9c4a03244 635
modtronix 1:64a9c4a03244 636 Write( REG_LR_MODEMCONFIG3,
modtronix 1:64a9c4a03244 637 ( Read( REG_LR_MODEMCONFIG3 ) &
modtronix 1:64a9c4a03244 638 RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) |
modtronix 1:64a9c4a03244 639 ( this->settings.LoRa.LowDatarateOptimize << 3 ) );
modtronix 1:64a9c4a03244 640
modtronix 1:64a9c4a03244 641 Write( REG_LR_PREAMBLEMSB, ( preambleLen >> 8 ) & 0x00FF );
modtronix 1:64a9c4a03244 642 Write( REG_LR_PREAMBLELSB, preambleLen & 0xFF );
modtronix 1:64a9c4a03244 643
modtronix 1:64a9c4a03244 644 if( datarate == 6 )
modtronix 1:64a9c4a03244 645 {
modtronix 1:64a9c4a03244 646 Write( REG_LR_DETECTOPTIMIZE,
modtronix 1:64a9c4a03244 647 ( Read( REG_LR_DETECTOPTIMIZE ) &
modtronix 1:64a9c4a03244 648 RFLR_DETECTIONOPTIMIZE_MASK ) |
modtronix 1:64a9c4a03244 649 RFLR_DETECTIONOPTIMIZE_SF6 );
modtronix 1:64a9c4a03244 650 Write( REG_LR_DETECTIONTHRESHOLD,
modtronix 1:64a9c4a03244 651 RFLR_DETECTIONTHRESH_SF6 );
modtronix 1:64a9c4a03244 652 }
modtronix 1:64a9c4a03244 653 else
modtronix 1:64a9c4a03244 654 {
modtronix 1:64a9c4a03244 655 Write( REG_LR_DETECTOPTIMIZE,
modtronix 1:64a9c4a03244 656 ( Read( REG_LR_DETECTOPTIMIZE ) &
modtronix 1:64a9c4a03244 657 RFLR_DETECTIONOPTIMIZE_MASK ) |
modtronix 1:64a9c4a03244 658 RFLR_DETECTIONOPTIMIZE_SF7_TO_SF12 );
modtronix 1:64a9c4a03244 659 Write( REG_LR_DETECTIONTHRESHOLD,
modtronix 1:64a9c4a03244 660 RFLR_DETECTIONTHRESH_SF7_TO_SF12 );
modtronix 1:64a9c4a03244 661 }
modtronix 1:64a9c4a03244 662 }
modtronix 1:64a9c4a03244 663 break;
modtronix 1:64a9c4a03244 664 }
modtronix 1:64a9c4a03244 665 }
modtronix 1:64a9c4a03244 666
modtronix 1:64a9c4a03244 667 double InAir::TimeOnAir( ModemType modem, uint8_t pktLen )
modtronix 1:64a9c4a03244 668 {
modtronix 1:64a9c4a03244 669 double airTime = 0.0;
modtronix 1:64a9c4a03244 670
modtronix 1:64a9c4a03244 671 switch( modem )
modtronix 1:64a9c4a03244 672 {
modtronix 1:64a9c4a03244 673 case MODEM_FSK:
modtronix 1:64a9c4a03244 674 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 675 {
modtronix 1:64a9c4a03244 676 airTime = ceil( ( 8 * ( this->settings.Fsk.PreambleLen +
modtronix 1:64a9c4a03244 677 ( ( Read( REG_SYNCCONFIG ) & ~RF_SYNCCONFIG_SYNCSIZE_MASK ) + 1 ) +
modtronix 1:64a9c4a03244 678 ( ( this->settings.Fsk.FixLen == 0x01 ) ? 0.0 : 1.0 ) +
modtronix 1:64a9c4a03244 679 ( ( ( Read( REG_PACKETCONFIG1 ) & ~RF_PACKETCONFIG1_ADDRSFILTERING_MASK ) != 0x00 ) ? 1.0 : 0 ) +
modtronix 1:64a9c4a03244 680 pktLen +
modtronix 1:64a9c4a03244 681 ( ( this->settings.Fsk.CrcOn == 0x01 ) ? 2.0 : 0 ) ) /
modtronix 1:64a9c4a03244 682 this->settings.Fsk.Datarate ) * 1e6 );
modtronix 1:64a9c4a03244 683 }
modtronix 1:64a9c4a03244 684 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 685 break;
modtronix 1:64a9c4a03244 686 case MODEM_LORA:
modtronix 1:64a9c4a03244 687 {
modtronix 1:64a9c4a03244 688 double bw = 0.0;
modtronix 1:64a9c4a03244 689 switch( this->settings.LoRa.Bandwidth )
modtronix 1:64a9c4a03244 690 {
modtronix 1:64a9c4a03244 691 case 0: // 7.8 kHz
modtronix 1:64a9c4a03244 692 bw = 78e2;
modtronix 1:64a9c4a03244 693 break;
modtronix 1:64a9c4a03244 694 case 1: // 10.4 kHz
modtronix 1:64a9c4a03244 695 bw = 104e2;
modtronix 1:64a9c4a03244 696 break;
modtronix 1:64a9c4a03244 697 case 2: // 15.6 kHz
modtronix 1:64a9c4a03244 698 bw = 156e2;
modtronix 1:64a9c4a03244 699 break;
modtronix 1:64a9c4a03244 700 case 3: // 20.8 kHz
modtronix 1:64a9c4a03244 701 bw = 208e2;
modtronix 1:64a9c4a03244 702 break;
modtronix 1:64a9c4a03244 703 case 4: // 31.2 kHz
modtronix 1:64a9c4a03244 704 bw = 312e2;
modtronix 1:64a9c4a03244 705 break;
modtronix 1:64a9c4a03244 706 case 5: // 41.4 kHz
modtronix 1:64a9c4a03244 707 bw = 414e2;
modtronix 1:64a9c4a03244 708 break;
modtronix 1:64a9c4a03244 709 case 6: // 62.5 kHz
modtronix 1:64a9c4a03244 710 bw = 625e2;
modtronix 1:64a9c4a03244 711 break;
modtronix 1:64a9c4a03244 712 case 7: // 125 kHz
modtronix 1:64a9c4a03244 713 bw = 125e3;
modtronix 1:64a9c4a03244 714 break;
modtronix 1:64a9c4a03244 715 case 8: // 250 kHz
modtronix 1:64a9c4a03244 716 bw = 250e3;
modtronix 1:64a9c4a03244 717 break;
modtronix 1:64a9c4a03244 718 case 9: // 500 kHz
modtronix 1:64a9c4a03244 719 bw = 500e3;
modtronix 1:64a9c4a03244 720 break;
modtronix 1:64a9c4a03244 721 }
modtronix 1:64a9c4a03244 722
modtronix 1:64a9c4a03244 723 // Symbol rate : time for one symbol (secs)
modtronix 1:64a9c4a03244 724 double rs = bw / ( 1 << this->settings.LoRa.Datarate );
modtronix 1:64a9c4a03244 725 double ts = 1 / rs;
modtronix 1:64a9c4a03244 726 // time of preamble
modtronix 1:64a9c4a03244 727 double tPreamble = ( this->settings.LoRa.PreambleLen + 4.25 ) * ts;
modtronix 1:64a9c4a03244 728 // Symbol length of payload and time
modtronix 1:64a9c4a03244 729 double tmp = ceil( ( 8 * pktLen - 4 * this->settings.LoRa.Datarate +
modtronix 1:64a9c4a03244 730 28 + 16 * this->settings.LoRa.CrcOn -
modtronix 1:64a9c4a03244 731 ( this->settings.LoRa.FixLen ? 20 : 0 ) ) /
modtronix 1:64a9c4a03244 732 ( double )( 4 * this->settings.LoRa.Datarate -
modtronix 1:64a9c4a03244 733 ( ( this->settings.LoRa.LowDatarateOptimize > 0 ) ? 8 : 0 ) ) ) *
modtronix 1:64a9c4a03244 734 ( this->settings.LoRa.Coderate + 4 );
modtronix 1:64a9c4a03244 735 double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
modtronix 1:64a9c4a03244 736 double tPayload = nPayload * ts;
modtronix 1:64a9c4a03244 737 // Time on air
modtronix 1:64a9c4a03244 738 double tOnAir = tPreamble + tPayload;
modtronix 1:64a9c4a03244 739 // return us secs
modtronix 1:64a9c4a03244 740 airTime = floor( tOnAir * 1e6 + 0.999 );
modtronix 1:64a9c4a03244 741 }
modtronix 1:64a9c4a03244 742 break;
modtronix 1:64a9c4a03244 743 }
modtronix 1:64a9c4a03244 744 return airTime;
modtronix 1:64a9c4a03244 745 }
modtronix 1:64a9c4a03244 746
modtronix 1:64a9c4a03244 747 void InAir::Send( uint8_t *buffer, uint8_t size )
modtronix 1:64a9c4a03244 748 {
modtronix 1:64a9c4a03244 749 uint32_t txTimeout = 0;
modtronix 1:64a9c4a03244 750
modtronix 1:64a9c4a03244 751 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 752
modtronix 1:64a9c4a03244 753 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 754 {
modtronix 1:64a9c4a03244 755 case MODEM_FSK:
modtronix 1:64a9c4a03244 756 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 757 {
modtronix 1:64a9c4a03244 758 this->settings.FskPacketHandler.NbBytes = 0;
modtronix 1:64a9c4a03244 759 this->settings.FskPacketHandler.Size = size;
modtronix 1:64a9c4a03244 760
modtronix 1:64a9c4a03244 761 if( this->settings.Fsk.FixLen == false )
modtronix 1:64a9c4a03244 762 {
modtronix 1:64a9c4a03244 763 WriteFifo( ( uint8_t* )&size, 1 );
modtronix 1:64a9c4a03244 764 }
modtronix 1:64a9c4a03244 765 else
modtronix 1:64a9c4a03244 766 {
modtronix 1:64a9c4a03244 767 Write( REG_PAYLOADLENGTH, size );
modtronix 1:64a9c4a03244 768 }
modtronix 1:64a9c4a03244 769
modtronix 1:64a9c4a03244 770 if( ( size > 0 ) && ( size <= 64 ) )
modtronix 1:64a9c4a03244 771 {
modtronix 1:64a9c4a03244 772 this->settings.FskPacketHandler.ChunkSize = size;
modtronix 1:64a9c4a03244 773 }
modtronix 1:64a9c4a03244 774 else
modtronix 1:64a9c4a03244 775 {
modtronix 1:64a9c4a03244 776 this->settings.FskPacketHandler.ChunkSize = 32;
modtronix 1:64a9c4a03244 777 }
modtronix 1:64a9c4a03244 778
modtronix 1:64a9c4a03244 779 // Write payload buffer
modtronix 1:64a9c4a03244 780 WriteFifo( buffer, this->settings.FskPacketHandler.ChunkSize );
modtronix 1:64a9c4a03244 781 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
modtronix 1:64a9c4a03244 782 txTimeout = this->settings.Fsk.TxTimeout;
modtronix 1:64a9c4a03244 783 }
modtronix 1:64a9c4a03244 784 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 785 break;
modtronix 1:64a9c4a03244 786 case MODEM_LORA:
modtronix 1:64a9c4a03244 787 {
modtronix 1:64a9c4a03244 788 if( this->settings.LoRa.IqInverted == true )
modtronix 1:64a9c4a03244 789 {
modtronix 1:64a9c4a03244 790 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_ON ) );
modtronix 1:64a9c4a03244 791 }
modtronix 1:64a9c4a03244 792 else
modtronix 1:64a9c4a03244 793 {
modtronix 1:64a9c4a03244 794 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
modtronix 1:64a9c4a03244 795 }
modtronix 1:64a9c4a03244 796
modtronix 1:64a9c4a03244 797 this->settings.LoRaPacketHandler.Size = size;
modtronix 1:64a9c4a03244 798
modtronix 1:64a9c4a03244 799 // Initializes the payload size
modtronix 1:64a9c4a03244 800 Write( REG_LR_PAYLOADLENGTH, size );
modtronix 1:64a9c4a03244 801
modtronix 1:64a9c4a03244 802 // Full buffer used for Tx
modtronix 1:64a9c4a03244 803 Write( REG_LR_FIFOTXBASEADDR, 0 );
modtronix 1:64a9c4a03244 804 Write( REG_LR_FIFOADDRPTR, 0 );
modtronix 1:64a9c4a03244 805
modtronix 1:64a9c4a03244 806 // FIFO operations can not take place in Sleep mode
modtronix 1:64a9c4a03244 807 if( ( Read( REG_OPMODE ) & ~RF_OPMODE_MASK ) == RF_OPMODE_SLEEP )
modtronix 1:64a9c4a03244 808 {
modtronix 1:64a9c4a03244 809 Standby( );
modtronix 1:64a9c4a03244 810 wait_ms( 1 );
modtronix 1:64a9c4a03244 811 }
modtronix 1:64a9c4a03244 812 // Write payload buffer
modtronix 1:64a9c4a03244 813 WriteFifo( buffer, size );
modtronix 1:64a9c4a03244 814 txTimeout = this->settings.LoRa.TxTimeout;
modtronix 1:64a9c4a03244 815 }
modtronix 1:64a9c4a03244 816 break;
modtronix 1:64a9c4a03244 817 }
modtronix 1:64a9c4a03244 818
modtronix 1:64a9c4a03244 819 Tx( txTimeout );
modtronix 1:64a9c4a03244 820 }
modtronix 1:64a9c4a03244 821
modtronix 1:64a9c4a03244 822 void InAir::Sleep( void )
modtronix 1:64a9c4a03244 823 {
modtronix 1:64a9c4a03244 824 // Initialize driver timeout timers
modtronix 1:64a9c4a03244 825 txTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 826 rxTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 827 SetOpMode( RF_OPMODE_SLEEP );
modtronix 1:64a9c4a03244 828 }
modtronix 1:64a9c4a03244 829
modtronix 1:64a9c4a03244 830 void InAir::Standby( void )
modtronix 1:64a9c4a03244 831 {
modtronix 1:64a9c4a03244 832 txTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 833 rxTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 834 SetOpMode( RF_OPMODE_STANDBY );
modtronix 1:64a9c4a03244 835 }
modtronix 1:64a9c4a03244 836
modtronix 1:64a9c4a03244 837 void InAir::Rx( uint32_t timeout )
modtronix 1:64a9c4a03244 838 {
modtronix 1:64a9c4a03244 839 bool rxContinuous = false;
modtronix 1:64a9c4a03244 840
modtronix 1:64a9c4a03244 841 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 842 {
modtronix 1:64a9c4a03244 843 case MODEM_FSK:
modtronix 1:64a9c4a03244 844 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 845 {
modtronix 1:64a9c4a03244 846 rxContinuous = this->settings.Fsk.RxContinuous;
modtronix 1:64a9c4a03244 847
modtronix 1:64a9c4a03244 848 // DIO0=PayloadReady
modtronix 1:64a9c4a03244 849 // DIO1=FifoLevel
modtronix 1:64a9c4a03244 850 // DIO2=SyncAddr
modtronix 1:64a9c4a03244 851 // DIO3=FifoEmpty
modtronix 1:64a9c4a03244 852 // DIO4=Preamble
modtronix 1:64a9c4a03244 853 // DIO5=ModeReady
modtronix 1:64a9c4a03244 854 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK & RF_DIOMAPPING1_DIO1_MASK &
modtronix 1:64a9c4a03244 855 RF_DIOMAPPING1_DIO2_MASK ) |
modtronix 1:64a9c4a03244 856 RF_DIOMAPPING1_DIO0_00 |
modtronix 1:64a9c4a03244 857 RF_DIOMAPPING1_DIO2_11 );
modtronix 1:64a9c4a03244 858
modtronix 1:64a9c4a03244 859 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
modtronix 1:64a9c4a03244 860 RF_DIOMAPPING2_MAP_MASK ) |
modtronix 1:64a9c4a03244 861 RF_DIOMAPPING2_DIO4_11 |
modtronix 1:64a9c4a03244 862 RF_DIOMAPPING2_MAP_PREAMBLEDETECT );
modtronix 1:64a9c4a03244 863
modtronix 1:64a9c4a03244 864 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
modtronix 1:64a9c4a03244 865
modtronix 1:64a9c4a03244 866 this->settings.FskPacketHandler.PreambleDetected = false;
modtronix 1:64a9c4a03244 867 this->settings.FskPacketHandler.SyncWordDetected = false;
modtronix 1:64a9c4a03244 868 this->settings.FskPacketHandler.NbBytes = 0;
modtronix 1:64a9c4a03244 869 this->settings.FskPacketHandler.Size = 0;
modtronix 1:64a9c4a03244 870 }
modtronix 1:64a9c4a03244 871 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 872 break;
modtronix 1:64a9c4a03244 873 case MODEM_LORA:
modtronix 1:64a9c4a03244 874 {
modtronix 1:64a9c4a03244 875 if( this->settings.LoRa.IqInverted == true )
modtronix 1:64a9c4a03244 876 {
modtronix 1:64a9c4a03244 877 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_ON | RFLR_INVERTIQ_TX_OFF ) );
modtronix 1:64a9c4a03244 878 }
modtronix 1:64a9c4a03244 879 else
modtronix 1:64a9c4a03244 880 {
modtronix 1:64a9c4a03244 881 Write( REG_LR_INVERTIQ, ( ( Read( REG_LR_INVERTIQ ) & RFLR_INVERTIQ_TX_MASK & RFLR_INVERTIQ_RX_MASK ) | RFLR_INVERTIQ_RX_OFF | RFLR_INVERTIQ_TX_OFF ) );
modtronix 1:64a9c4a03244 882 }
modtronix 1:64a9c4a03244 883
modtronix 1:64a9c4a03244 884 rxContinuous = this->settings.LoRa.RxContinuous;
modtronix 1:64a9c4a03244 885
modtronix 1:64a9c4a03244 886 if( this->settings.LoRa.FreqHopOn == true )
modtronix 1:64a9c4a03244 887 {
modtronix 1:64a9c4a03244 888 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
modtronix 1:64a9c4a03244 889 //RFLR_IRQFLAGS_RXDONE |
modtronix 1:64a9c4a03244 890 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
modtronix 1:64a9c4a03244 891 RFLR_IRQFLAGS_VALIDHEADER |
modtronix 1:64a9c4a03244 892 RFLR_IRQFLAGS_TXDONE |
modtronix 1:64a9c4a03244 893 RFLR_IRQFLAGS_CADDONE |
modtronix 1:64a9c4a03244 894 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
modtronix 1:64a9c4a03244 895 RFLR_IRQFLAGS_CADDETECTED );
modtronix 1:64a9c4a03244 896
modtronix 1:64a9c4a03244 897 // DIO0=RxDone, DIO2=FhssChangeChannel
modtronix 1:64a9c4a03244 898 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO0_00 | RFLR_DIOMAPPING1_DIO2_00 );
modtronix 1:64a9c4a03244 899 }
modtronix 1:64a9c4a03244 900 else
modtronix 1:64a9c4a03244 901 {
modtronix 1:64a9c4a03244 902 Write( REG_LR_IRQFLAGSMASK, //RFLR_IRQFLAGS_RXTIMEOUT |
modtronix 1:64a9c4a03244 903 //RFLR_IRQFLAGS_RXDONE |
modtronix 1:64a9c4a03244 904 //RFLR_IRQFLAGS_PAYLOADCRCERROR |
modtronix 1:64a9c4a03244 905 RFLR_IRQFLAGS_VALIDHEADER |
modtronix 1:64a9c4a03244 906 RFLR_IRQFLAGS_TXDONE |
modtronix 1:64a9c4a03244 907 RFLR_IRQFLAGS_CADDONE |
modtronix 1:64a9c4a03244 908 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
modtronix 1:64a9c4a03244 909 RFLR_IRQFLAGS_CADDETECTED );
modtronix 1:64a9c4a03244 910
modtronix 1:64a9c4a03244 911 // DIO0=RxDone
modtronix 1:64a9c4a03244 912 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
modtronix 1:64a9c4a03244 913 }
modtronix 1:64a9c4a03244 914
modtronix 1:64a9c4a03244 915 Write( REG_LR_FIFORXBASEADDR, 0 );
modtronix 1:64a9c4a03244 916 Write( REG_LR_FIFOADDRPTR, 0 );
modtronix 1:64a9c4a03244 917 }
modtronix 1:64a9c4a03244 918 break;
modtronix 1:64a9c4a03244 919 }
modtronix 1:64a9c4a03244 920
modtronix 1:64a9c4a03244 921 memset( rxBuffer, 0, ( size_t )RX_BUFFER_SIZE );
modtronix 1:64a9c4a03244 922
modtronix 1:64a9c4a03244 923 this->settings.State = RX_DONE;
modtronix 1:64a9c4a03244 924 if( timeout != 0 )
modtronix 1:64a9c4a03244 925 {
modtronix 1:64a9c4a03244 926 rxTimeoutTimer.attach_us( this, &InAir::OnTimeoutIrq, timeout );
modtronix 1:64a9c4a03244 927 }
modtronix 1:64a9c4a03244 928
modtronix 1:64a9c4a03244 929 if( this->settings.Modem == MODEM_FSK )
modtronix 1:64a9c4a03244 930 {
modtronix 1:64a9c4a03244 931 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 932 SetOpMode( RF_OPMODE_RECEIVER );
modtronix 1:64a9c4a03244 933
modtronix 1:64a9c4a03244 934 if( rxContinuous == false )
modtronix 1:64a9c4a03244 935 {
modtronix 1:64a9c4a03244 936 rxTimeoutSyncWord.attach_us( this, &InAir::OnTimeoutIrq, ( 8.0 * ( this->settings.Fsk.PreambleLen +
modtronix 1:64a9c4a03244 937 ( ( Read( REG_SYNCCONFIG ) &
modtronix 1:64a9c4a03244 938 ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
modtronix 1:64a9c4a03244 939 1.0 ) + 1.0 ) /
modtronix 1:64a9c4a03244 940 ( double )this->settings.Fsk.Datarate ) * 1e6 ) ;
modtronix 1:64a9c4a03244 941 }
modtronix 1:64a9c4a03244 942 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 943 }
modtronix 1:64a9c4a03244 944 else
modtronix 1:64a9c4a03244 945 {
modtronix 1:64a9c4a03244 946 if( rxContinuous == true )
modtronix 1:64a9c4a03244 947 {
modtronix 1:64a9c4a03244 948 SetOpMode( RFLR_OPMODE_RECEIVER );
modtronix 1:64a9c4a03244 949 }
modtronix 1:64a9c4a03244 950 else
modtronix 1:64a9c4a03244 951 {
modtronix 1:64a9c4a03244 952 SetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
modtronix 1:64a9c4a03244 953 }
modtronix 1:64a9c4a03244 954 }
modtronix 1:64a9c4a03244 955 }
modtronix 1:64a9c4a03244 956
modtronix 1:64a9c4a03244 957 void InAir::Tx( uint32_t timeout )
modtronix 1:64a9c4a03244 958 {
modtronix 1:64a9c4a03244 959 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 960 {
modtronix 1:64a9c4a03244 961 case MODEM_FSK:
modtronix 1:64a9c4a03244 962 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 963 {
modtronix 1:64a9c4a03244 964 // DIO0=PacketSent
modtronix 1:64a9c4a03244 965 // DIO1=FifoLevel
modtronix 1:64a9c4a03244 966 // DIO2=FifoFull
modtronix 1:64a9c4a03244 967 // DIO3=FifoEmpty
modtronix 1:64a9c4a03244 968 // DIO4=LowBat
modtronix 1:64a9c4a03244 969 // DIO5=ModeReady
modtronix 1:64a9c4a03244 970 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RF_DIOMAPPING1_DIO0_MASK & RF_DIOMAPPING1_DIO1_MASK &
modtronix 1:64a9c4a03244 971 RF_DIOMAPPING1_DIO2_MASK ) );
modtronix 1:64a9c4a03244 972
modtronix 1:64a9c4a03244 973 Write( REG_DIOMAPPING2, ( Read( REG_DIOMAPPING2 ) & RF_DIOMAPPING2_DIO4_MASK &
modtronix 1:64a9c4a03244 974 RF_DIOMAPPING2_MAP_MASK ) );
modtronix 1:64a9c4a03244 975 this->settings.FskPacketHandler.FifoThresh = Read( REG_FIFOTHRESH ) & 0x3F;
modtronix 1:64a9c4a03244 976 }
modtronix 1:64a9c4a03244 977 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 978 break;
modtronix 1:64a9c4a03244 979 case MODEM_LORA:
modtronix 1:64a9c4a03244 980 {
modtronix 1:64a9c4a03244 981
modtronix 1:64a9c4a03244 982 if( this->settings.LoRa.FreqHopOn == true )
modtronix 1:64a9c4a03244 983 {
modtronix 1:64a9c4a03244 984 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
modtronix 1:64a9c4a03244 985 RFLR_IRQFLAGS_RXDONE |
modtronix 1:64a9c4a03244 986 RFLR_IRQFLAGS_PAYLOADCRCERROR |
modtronix 1:64a9c4a03244 987 RFLR_IRQFLAGS_VALIDHEADER |
modtronix 1:64a9c4a03244 988 //RFLR_IRQFLAGS_TXDONE |
modtronix 1:64a9c4a03244 989 RFLR_IRQFLAGS_CADDONE |
modtronix 1:64a9c4a03244 990 //RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
modtronix 1:64a9c4a03244 991 RFLR_IRQFLAGS_CADDETECTED );
modtronix 1:64a9c4a03244 992
modtronix 1:64a9c4a03244 993 // DIO0=TxDone
modtronix 1:64a9c4a03244 994 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
modtronix 1:64a9c4a03244 995 // DIO2=FhssChangeChannel
modtronix 1:64a9c4a03244 996 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO2_MASK ) | RFLR_DIOMAPPING1_DIO2_00 );
modtronix 1:64a9c4a03244 997 }
modtronix 1:64a9c4a03244 998 else
modtronix 1:64a9c4a03244 999 {
modtronix 1:64a9c4a03244 1000 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
modtronix 1:64a9c4a03244 1001 RFLR_IRQFLAGS_RXDONE |
modtronix 1:64a9c4a03244 1002 RFLR_IRQFLAGS_PAYLOADCRCERROR |
modtronix 1:64a9c4a03244 1003 RFLR_IRQFLAGS_VALIDHEADER |
modtronix 1:64a9c4a03244 1004 //RFLR_IRQFLAGS_TXDONE |
modtronix 1:64a9c4a03244 1005 RFLR_IRQFLAGS_CADDONE |
modtronix 1:64a9c4a03244 1006 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
modtronix 1:64a9c4a03244 1007 RFLR_IRQFLAGS_CADDETECTED );
modtronix 1:64a9c4a03244 1008
modtronix 1:64a9c4a03244 1009 // DIO0=TxDone
modtronix 1:64a9c4a03244 1010 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_01 );
modtronix 1:64a9c4a03244 1011 }
modtronix 1:64a9c4a03244 1012 }
modtronix 1:64a9c4a03244 1013 break;
modtronix 1:64a9c4a03244 1014 }
modtronix 1:64a9c4a03244 1015
modtronix 1:64a9c4a03244 1016 this->settings.State = TX_DONE;
modtronix 1:64a9c4a03244 1017 txTimeoutTimer.attach_us( this, &InAir::OnTimeoutIrq, timeout );
modtronix 1:64a9c4a03244 1018 SetOpMode( RF_OPMODE_TRANSMITTER );
modtronix 1:64a9c4a03244 1019 }
modtronix 1:64a9c4a03244 1020
modtronix 1:64a9c4a03244 1021 void InAir::StartCad( void )
modtronix 1:64a9c4a03244 1022 {
modtronix 1:64a9c4a03244 1023 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1024 {
modtronix 1:64a9c4a03244 1025 case MODEM_FSK:
modtronix 1:64a9c4a03244 1026 {
modtronix 1:64a9c4a03244 1027
modtronix 1:64a9c4a03244 1028 }
modtronix 1:64a9c4a03244 1029 break;
modtronix 1:64a9c4a03244 1030 case MODEM_LORA:
modtronix 1:64a9c4a03244 1031 {
modtronix 1:64a9c4a03244 1032 Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
modtronix 1:64a9c4a03244 1033 RFLR_IRQFLAGS_RXDONE |
modtronix 1:64a9c4a03244 1034 RFLR_IRQFLAGS_PAYLOADCRCERROR |
modtronix 1:64a9c4a03244 1035 RFLR_IRQFLAGS_VALIDHEADER |
modtronix 1:64a9c4a03244 1036 RFLR_IRQFLAGS_TXDONE |
modtronix 1:64a9c4a03244 1037 //RFLR_IRQFLAGS_CADDONE |
modtronix 1:64a9c4a03244 1038 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL // |
modtronix 1:64a9c4a03244 1039 //RFLR_IRQFLAGS_CADDETECTED
modtronix 1:64a9c4a03244 1040 );
modtronix 1:64a9c4a03244 1041
modtronix 1:64a9c4a03244 1042 // DIO3=CADDone
modtronix 1:64a9c4a03244 1043 Write( REG_DIOMAPPING1, ( Read( REG_DIOMAPPING1 ) & RFLR_DIOMAPPING1_DIO0_MASK ) | RFLR_DIOMAPPING1_DIO0_00 );
modtronix 1:64a9c4a03244 1044
modtronix 1:64a9c4a03244 1045 this->settings.State = CAD;
modtronix 1:64a9c4a03244 1046 SetOpMode( RFLR_OPMODE_CAD );
modtronix 1:64a9c4a03244 1047 }
modtronix 1:64a9c4a03244 1048 break;
modtronix 1:64a9c4a03244 1049 default:
modtronix 1:64a9c4a03244 1050 break;
modtronix 1:64a9c4a03244 1051 }
modtronix 1:64a9c4a03244 1052 }
modtronix 1:64a9c4a03244 1053
modtronix 1:64a9c4a03244 1054 int16_t InAir::GetRssi( ModemType modem )
modtronix 1:64a9c4a03244 1055 {
modtronix 1:64a9c4a03244 1056 int16_t rssi = 0;
modtronix 1:64a9c4a03244 1057
modtronix 1:64a9c4a03244 1058 switch( modem )
modtronix 1:64a9c4a03244 1059 {
modtronix 1:64a9c4a03244 1060 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1061 case MODEM_FSK:
modtronix 1:64a9c4a03244 1062 rssi = -( Read( REG_RSSIVALUE ) >> 1 );
modtronix 1:64a9c4a03244 1063 break;
modtronix 1:64a9c4a03244 1064 #endif
modtronix 1:64a9c4a03244 1065 case MODEM_LORA:
modtronix 1:64a9c4a03244 1066 if( this->settings.Channel > RF_MID_BAND_THRESH )
modtronix 1:64a9c4a03244 1067 {
modtronix 1:64a9c4a03244 1068 rssi = RSSI_OFFSET_HF + Read( REG_LR_RSSIVALUE );
modtronix 1:64a9c4a03244 1069 }
modtronix 1:64a9c4a03244 1070 else
modtronix 1:64a9c4a03244 1071 {
modtronix 1:64a9c4a03244 1072 rssi = RSSI_OFFSET_LF + Read( REG_LR_RSSIVALUE );
modtronix 1:64a9c4a03244 1073 }
modtronix 1:64a9c4a03244 1074 break;
modtronix 1:64a9c4a03244 1075 default:
modtronix 1:64a9c4a03244 1076 rssi = -1;
modtronix 1:64a9c4a03244 1077 break;
modtronix 1:64a9c4a03244 1078 }
modtronix 1:64a9c4a03244 1079 return rssi;
modtronix 1:64a9c4a03244 1080 }
modtronix 1:64a9c4a03244 1081
modtronix 1:64a9c4a03244 1082 void InAir::SetOpMode( uint8_t opMode )
modtronix 1:64a9c4a03244 1083 {
modtronix 1:64a9c4a03244 1084 if( opMode != previousOpMode )
modtronix 1:64a9c4a03244 1085 {
modtronix 1:64a9c4a03244 1086 previousOpMode = opMode;
modtronix 1:64a9c4a03244 1087 if( opMode == RF_OPMODE_SLEEP )
modtronix 1:64a9c4a03244 1088 {
modtronix 1:64a9c4a03244 1089 //SetAntSwLowPower( true );
modtronix 1:64a9c4a03244 1090 }
modtronix 1:64a9c4a03244 1091 else
modtronix 1:64a9c4a03244 1092 {
modtronix 1:64a9c4a03244 1093 //SetAntSwLowPower( false );
modtronix 1:64a9c4a03244 1094 }
modtronix 1:64a9c4a03244 1095 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RF_OPMODE_MASK ) | opMode );
modtronix 1:64a9c4a03244 1096 }
modtronix 1:64a9c4a03244 1097 }
modtronix 1:64a9c4a03244 1098
modtronix 1:64a9c4a03244 1099 void InAir::SetModem( ModemType modem )
modtronix 1:64a9c4a03244 1100 {
modtronix 1:64a9c4a03244 1101 if( this->settings.Modem != modem )
modtronix 1:64a9c4a03244 1102 {
modtronix 1:64a9c4a03244 1103 this->settings.Modem = modem;
modtronix 1:64a9c4a03244 1104 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1105 {
modtronix 1:64a9c4a03244 1106 default:
modtronix 1:64a9c4a03244 1107 case MODEM_FSK:
modtronix 1:64a9c4a03244 1108 SetOpMode( RF_OPMODE_SLEEP );
modtronix 1:64a9c4a03244 1109 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_OFF );
modtronix 1:64a9c4a03244 1110
modtronix 1:64a9c4a03244 1111 Write( REG_DIOMAPPING1, 0x00 );
modtronix 1:64a9c4a03244 1112 Write( REG_DIOMAPPING2, 0x30 ); // DIO5=ModeReady
modtronix 1:64a9c4a03244 1113 break;
modtronix 1:64a9c4a03244 1114 case MODEM_LORA:
modtronix 1:64a9c4a03244 1115 SetOpMode( RF_OPMODE_SLEEP );
modtronix 1:64a9c4a03244 1116 Write( REG_OPMODE, ( Read( REG_OPMODE ) & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON );
modtronix 1:64a9c4a03244 1117 Write( 0x30, 0x00 ); // IF = 0
modtronix 1:64a9c4a03244 1118 Write( REG_LR_DETECTOPTIMIZE, ( Read( REG_LR_DETECTOPTIMIZE ) & 0x7F ) ); // Manual IF
modtronix 1:64a9c4a03244 1119 Write( REG_DIOMAPPING1, 0x00 );
modtronix 1:64a9c4a03244 1120 Write( REG_DIOMAPPING2, 0x00 );
modtronix 1:64a9c4a03244 1121 break;
modtronix 1:64a9c4a03244 1122 }
modtronix 1:64a9c4a03244 1123 }
modtronix 1:64a9c4a03244 1124 }
modtronix 1:64a9c4a03244 1125
modtronix 1:64a9c4a03244 1126 void InAir::OnTimeoutIrq( void )
modtronix 1:64a9c4a03244 1127 {
modtronix 1:64a9c4a03244 1128 switch( this->settings.State )
modtronix 1:64a9c4a03244 1129 {
modtronix 1:64a9c4a03244 1130 case RX_DONE:
modtronix 1:64a9c4a03244 1131 if( this->settings.Modem == MODEM_FSK )
modtronix 1:64a9c4a03244 1132 {
modtronix 1:64a9c4a03244 1133 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1134 this->settings.FskPacketHandler.PreambleDetected = false;
modtronix 1:64a9c4a03244 1135 this->settings.FskPacketHandler.SyncWordDetected = false;
modtronix 1:64a9c4a03244 1136 this->settings.FskPacketHandler.NbBytes = 0;
modtronix 1:64a9c4a03244 1137 this->settings.FskPacketHandler.Size = 0;
modtronix 1:64a9c4a03244 1138
modtronix 1:64a9c4a03244 1139 // Clear Irqs
modtronix 1:64a9c4a03244 1140 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
modtronix 1:64a9c4a03244 1141 RF_IRQFLAGS1_PREAMBLEDETECT |
modtronix 1:64a9c4a03244 1142 RF_IRQFLAGS1_SYNCADDRESSMATCH );
modtronix 1:64a9c4a03244 1143 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
modtronix 1:64a9c4a03244 1144
modtronix 1:64a9c4a03244 1145 if( this->settings.Fsk.RxContinuous == true )
modtronix 1:64a9c4a03244 1146 {
modtronix 1:64a9c4a03244 1147 // Continuous mode restart Rx chain
modtronix 1:64a9c4a03244 1148 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
modtronix 1:64a9c4a03244 1149 }
modtronix 1:64a9c4a03244 1150 else
modtronix 1:64a9c4a03244 1151 {
modtronix 1:64a9c4a03244 1152 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 1153 rxTimeoutSyncWord.detach( );
modtronix 1:64a9c4a03244 1154 }
modtronix 1:64a9c4a03244 1155 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1156 }
modtronix 1:64a9c4a03244 1157 if( ( rxTimeout != NULL ) )
modtronix 1:64a9c4a03244 1158 {
modtronix 1:64a9c4a03244 1159 rxTimeout( );
modtronix 1:64a9c4a03244 1160 }
modtronix 1:64a9c4a03244 1161 break;
modtronix 1:64a9c4a03244 1162 case TX_DONE:
modtronix 1:64a9c4a03244 1163 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 1164 if( ( txTimeout != NULL ) )
modtronix 1:64a9c4a03244 1165 {
modtronix 1:64a9c4a03244 1166 txTimeout( );
modtronix 1:64a9c4a03244 1167 }
modtronix 1:64a9c4a03244 1168 break;
modtronix 1:64a9c4a03244 1169 default:
modtronix 1:64a9c4a03244 1170 break;
modtronix 1:64a9c4a03244 1171 }
modtronix 1:64a9c4a03244 1172 }
modtronix 1:64a9c4a03244 1173
modtronix 1:64a9c4a03244 1174 void InAir::OnDio0Irq( void )
modtronix 1:64a9c4a03244 1175 {
modtronix 1:64a9c4a03244 1176 __IO uint8_t irqFlags = 0;
modtronix 1:64a9c4a03244 1177
modtronix 1:64a9c4a03244 1178 switch( this->settings.State )
modtronix 1:64a9c4a03244 1179 {
modtronix 1:64a9c4a03244 1180 case RX_DONE:
modtronix 1:64a9c4a03244 1181 //TimerStop( &RxTimeoutTimer );
modtronix 1:64a9c4a03244 1182 // RxDone interrupt
modtronix 1:64a9c4a03244 1183 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1184 {
modtronix 1:64a9c4a03244 1185 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1186 case MODEM_FSK:
modtronix 1:64a9c4a03244 1187 if( this->settings.Fsk.CrcOn == true )
modtronix 1:64a9c4a03244 1188 {
modtronix 1:64a9c4a03244 1189 irqFlags = Read( REG_IRQFLAGS2 );
modtronix 1:64a9c4a03244 1190 if( ( irqFlags & RF_IRQFLAGS2_CRCOK ) != RF_IRQFLAGS2_CRCOK )
modtronix 1:64a9c4a03244 1191 {
modtronix 1:64a9c4a03244 1192 // Clear Irqs
modtronix 1:64a9c4a03244 1193 Write( REG_IRQFLAGS1, RF_IRQFLAGS1_RSSI |
modtronix 1:64a9c4a03244 1194 RF_IRQFLAGS1_PREAMBLEDETECT |
modtronix 1:64a9c4a03244 1195 RF_IRQFLAGS1_SYNCADDRESSMATCH );
modtronix 1:64a9c4a03244 1196 Write( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );
modtronix 1:64a9c4a03244 1197
modtronix 1:64a9c4a03244 1198 if( this->settings.Fsk.RxContinuous == false )
modtronix 1:64a9c4a03244 1199 {
modtronix 1:64a9c4a03244 1200 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 1201 rxTimeoutSyncWord.attach_us( this, &InAir::OnTimeoutIrq, ( 8.0 * ( this->settings.Fsk.PreambleLen +
modtronix 1:64a9c4a03244 1202 ( ( Read( REG_SYNCCONFIG ) &
modtronix 1:64a9c4a03244 1203 ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
modtronix 1:64a9c4a03244 1204 1.0 ) + 1.0 ) /
modtronix 1:64a9c4a03244 1205 ( double )this->settings.Fsk.Datarate ) * 1e6 ) ;
modtronix 1:64a9c4a03244 1206 }
modtronix 1:64a9c4a03244 1207 else
modtronix 1:64a9c4a03244 1208 {
modtronix 1:64a9c4a03244 1209 // Continuous mode restart Rx chain
modtronix 1:64a9c4a03244 1210 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
modtronix 1:64a9c4a03244 1211 }
modtronix 1:64a9c4a03244 1212 rxTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 1213
modtronix 1:64a9c4a03244 1214 if( ( rxError != NULL ) )
modtronix 1:64a9c4a03244 1215 {
modtronix 1:64a9c4a03244 1216 rxError( );
modtronix 1:64a9c4a03244 1217 }
modtronix 1:64a9c4a03244 1218 this->settings.FskPacketHandler.PreambleDetected = false;
modtronix 1:64a9c4a03244 1219 this->settings.FskPacketHandler.SyncWordDetected = false;
modtronix 1:64a9c4a03244 1220 this->settings.FskPacketHandler.NbBytes = 0;
modtronix 1:64a9c4a03244 1221 this->settings.FskPacketHandler.Size = 0;
modtronix 1:64a9c4a03244 1222 break;
modtronix 1:64a9c4a03244 1223 }
modtronix 1:64a9c4a03244 1224 }
modtronix 1:64a9c4a03244 1225
modtronix 1:64a9c4a03244 1226 // Read received packet size
modtronix 1:64a9c4a03244 1227 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
modtronix 1:64a9c4a03244 1228 {
modtronix 1:64a9c4a03244 1229 if( this->settings.Fsk.FixLen == false )
modtronix 1:64a9c4a03244 1230 {
modtronix 1:64a9c4a03244 1231 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
modtronix 1:64a9c4a03244 1232 }
modtronix 1:64a9c4a03244 1233 else
modtronix 1:64a9c4a03244 1234 {
modtronix 1:64a9c4a03244 1235 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
modtronix 1:64a9c4a03244 1236 }
modtronix 1:64a9c4a03244 1237 ReadFifo( rxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
modtronix 1:64a9c4a03244 1238 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
modtronix 1:64a9c4a03244 1239 }
modtronix 1:64a9c4a03244 1240 else
modtronix 1:64a9c4a03244 1241 {
modtronix 1:64a9c4a03244 1242 ReadFifo( rxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
modtronix 1:64a9c4a03244 1243 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
modtronix 1:64a9c4a03244 1244 }
modtronix 1:64a9c4a03244 1245
modtronix 1:64a9c4a03244 1246 if( this->settings.Fsk.RxContinuous == false )
modtronix 1:64a9c4a03244 1247 {
modtronix 1:64a9c4a03244 1248 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 1249 rxTimeoutSyncWord.attach_us( this, &InAir::OnTimeoutIrq, ( 8.0 * ( this->settings.Fsk.PreambleLen +
modtronix 1:64a9c4a03244 1250 ( ( Read( REG_SYNCCONFIG ) &
modtronix 1:64a9c4a03244 1251 ~RF_SYNCCONFIG_SYNCSIZE_MASK ) +
modtronix 1:64a9c4a03244 1252 1.0 ) + 1.0 ) /
modtronix 1:64a9c4a03244 1253 ( double )this->settings.Fsk.Datarate ) * 1e6 ) ;
modtronix 1:64a9c4a03244 1254 }
modtronix 1:64a9c4a03244 1255 else
modtronix 1:64a9c4a03244 1256 {
modtronix 1:64a9c4a03244 1257 // Continuous mode restart Rx chain
modtronix 1:64a9c4a03244 1258 Write( REG_RXCONFIG, Read( REG_RXCONFIG ) | RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK );
modtronix 1:64a9c4a03244 1259 }
modtronix 1:64a9c4a03244 1260 rxTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 1261
modtronix 1:64a9c4a03244 1262 if( (rxDone != NULL ) )
modtronix 1:64a9c4a03244 1263 {
modtronix 1:64a9c4a03244 1264 rxDone( rxBuffer, this->settings.FskPacketHandler.Size, this->settings.FskPacketHandler.RssiValue, 0 );
modtronix 1:64a9c4a03244 1265 }
modtronix 1:64a9c4a03244 1266 this->settings.FskPacketHandler.PreambleDetected = false;
modtronix 1:64a9c4a03244 1267 this->settings.FskPacketHandler.SyncWordDetected = false;
modtronix 1:64a9c4a03244 1268 this->settings.FskPacketHandler.NbBytes = 0;
modtronix 1:64a9c4a03244 1269 this->settings.FskPacketHandler.Size = 0;
modtronix 1:64a9c4a03244 1270 break;
modtronix 1:64a9c4a03244 1271 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1272 case MODEM_LORA:
modtronix 1:64a9c4a03244 1273 {
modtronix 1:64a9c4a03244 1274 // Clear Irq
modtronix 1:64a9c4a03244 1275 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXDONE );
modtronix 1:64a9c4a03244 1276
modtronix 1:64a9c4a03244 1277 irqFlags = Read( REG_LR_IRQFLAGS );
modtronix 1:64a9c4a03244 1278 if( ( irqFlags & RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK ) == RFLR_IRQFLAGS_PAYLOADCRCERROR )
modtronix 1:64a9c4a03244 1279 {
modtronix 1:64a9c4a03244 1280 // Clear Irq
modtronix 1:64a9c4a03244 1281 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_PAYLOADCRCERROR );
modtronix 1:64a9c4a03244 1282
modtronix 1:64a9c4a03244 1283 if( this->settings.LoRa.RxContinuous == false )
modtronix 1:64a9c4a03244 1284 {
modtronix 1:64a9c4a03244 1285 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 1286 }
modtronix-com 4:0086deec9cac 1287 // For Continuous reception, we remain in Receive mode. Delete current packet!
modtronix-com 4:0086deec9cac 1288 // - RegFifoAddrPtr = FIFO Pointer used for SPI instructions.
modtronix-com 4:0086deec9cac 1289 // - RegFifoRxByteAddr = Address of last byte written to FIFO + 1 = Start address of next receive packet
modtronix-com 4:0086deec9cac 1290 else {
modtronix-com 4:0086deec9cac 1291 //Get start address of next packet
modtronix-com 4:0086deec9cac 1292 uint8_t startAddNxtPckt = Read(REG_LR_FIFORXBYTEADDR);
modtronix-com 4:0086deec9cac 1293 //Set SPI pointer to address of next packet we will receive = delete current packet!
modtronix-com 4:0086deec9cac 1294 Write(REG_LR_FIFOADDRPTR, startAddNxtPckt);
modtronix-com 4:0086deec9cac 1295 }
modtronix 1:64a9c4a03244 1296 rxTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 1297
modtronix 1:64a9c4a03244 1298 if( ( rxError != NULL ) )
modtronix 1:64a9c4a03244 1299 {
modtronix 1:64a9c4a03244 1300 rxError( );
modtronix 1:64a9c4a03244 1301 }
modtronix 1:64a9c4a03244 1302 break;
modtronix 1:64a9c4a03244 1303 }
modtronix 1:64a9c4a03244 1304
modtronix 1:64a9c4a03244 1305 this->settings.LoRaPacketHandler.SnrValue = Read( REG_LR_PKTSNRVALUE );
modtronix 1:64a9c4a03244 1306
modtronix 1:64a9c4a03244 1307 int16_t rssi = Read( REG_LR_PKTRSSIVALUE );
modtronix 1:64a9c4a03244 1308 if( this->settings.LoRaPacketHandler.SnrValue < 0 )
modtronix 1:64a9c4a03244 1309 {
modtronix 1:64a9c4a03244 1310 if( this->settings.Channel > RF_MID_BAND_THRESH )
modtronix 1:64a9c4a03244 1311 {
modtronix-com 5:1a255cc8d54a 1312 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF;
modtronix 1:64a9c4a03244 1313 }
modtronix 1:64a9c4a03244 1314 else
modtronix 1:64a9c4a03244 1315 {
modtronix-com 5:1a255cc8d54a 1316 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF;
modtronix 1:64a9c4a03244 1317 }
modtronix-com 5:1a255cc8d54a 1318 this->settings.LoRaPacketHandler.RssiValue += rssi + ( rssi >> 4 )
modtronix-com 5:1a255cc8d54a 1319 + (this->settings.LoRaPacketHandler.SnrValue / 4);
modtronix 1:64a9c4a03244 1320 }
modtronix 1:64a9c4a03244 1321 else
modtronix 1:64a9c4a03244 1322 {
modtronix 1:64a9c4a03244 1323 if( this->settings.Channel > RF_MID_BAND_THRESH )
modtronix 1:64a9c4a03244 1324 {
modtronix-com 5:1a255cc8d54a 1325 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_HF;
modtronix 1:64a9c4a03244 1326 }
modtronix 1:64a9c4a03244 1327 else
modtronix 1:64a9c4a03244 1328 {
modtronix-com 5:1a255cc8d54a 1329 this->settings.LoRaPacketHandler.RssiValue = RSSI_OFFSET_LF;
modtronix 1:64a9c4a03244 1330 }
modtronix-com 5:1a255cc8d54a 1331 this->settings.LoRaPacketHandler.RssiValue += rssi + ( rssi >> 4 );
modtronix 1:64a9c4a03244 1332 }
modtronix 1:64a9c4a03244 1333
modtronix 1:64a9c4a03244 1334 this->settings.LoRaPacketHandler.Size = Read( REG_LR_RXNBBYTES );
modtronix-com 4:0086deec9cac 1335
modtronix-com 4:0086deec9cac 1336 //Debug Output:
modtronix-com 4:0086deec9cac 1337 // - RegRxNbBytes = Nb bytes RXed
modtronix-com 4:0086deec9cac 1338 // - RegFifoAddrPtr = FIFO Pointer used for SPI instructions.
modtronix-com 4:0086deec9cac 1339 // - RegFifoRxBaseAddr = Set to 0 in Rx() function
modtronix-com 4:0086deec9cac 1340 // - RegFifoRxCurrentAddr = Start address of last packet received
modtronix-com 4:0086deec9cac 1341 // - RegFifoRxByteAddr = Address of last byte written to FIFO + 1 = Start address of next receive packet
modtronix-com 4:0086deec9cac 1342 //
modtronix-com 4:0086deec9cac 1343 MX_DEBUG("\r\nNB=%d AP=%d RB=%d CA=%d BA=%d", this->settings.LoRaPacketHandler.Size,
modtronix-com 4:0086deec9cac 1344 Read(REG_LR_FIFOADDRPTR),
modtronix-com 4:0086deec9cac 1345 Read(REG_LR_FIFORXBASEADDR),
modtronix-com 4:0086deec9cac 1346 Read(REG_LR_FIFORXCURRENTADDR),
modtronix-com 4:0086deec9cac 1347 Read(REG_LR_FIFORXBYTEADDR));
modtronix-com 4:0086deec9cac 1348 //Ensure we read the last packet received. Without doing this, the bytes read can get out of sync
modtronix-com 4:0086deec9cac 1349 //with the last packet received after errors occur!
modtronix-com 4:0086deec9cac 1350 Write(REG_LR_FIFOADDRPTR, Read(REG_LR_FIFORXCURRENTADDR));
modtronix 1:64a9c4a03244 1351 ReadFifo( rxBuffer, this->settings.LoRaPacketHandler.Size );
modtronix 1:64a9c4a03244 1352
modtronix 1:64a9c4a03244 1353 if( this->settings.LoRa.RxContinuous == false )
modtronix 1:64a9c4a03244 1354 {
modtronix 1:64a9c4a03244 1355 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 1356 }
modtronix 1:64a9c4a03244 1357 rxTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 1358
modtronix 1:64a9c4a03244 1359 if( ( rxDone != NULL ) )
modtronix 1:64a9c4a03244 1360 {
modtronix 1:64a9c4a03244 1361 rxDone( rxBuffer, this->settings.LoRaPacketHandler.Size, this->settings.LoRaPacketHandler.RssiValue, this->settings.LoRaPacketHandler.SnrValue );
modtronix 1:64a9c4a03244 1362 }
modtronix 1:64a9c4a03244 1363 }
modtronix 1:64a9c4a03244 1364 break;
modtronix 1:64a9c4a03244 1365 default:
modtronix 1:64a9c4a03244 1366 break;
modtronix 1:64a9c4a03244 1367 }
modtronix 1:64a9c4a03244 1368 break;
modtronix 1:64a9c4a03244 1369 case TX_DONE:
modtronix 1:64a9c4a03244 1370 txTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 1371 // TxDone interrupt
modtronix 1:64a9c4a03244 1372 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1373 {
modtronix 1:64a9c4a03244 1374 case MODEM_LORA:
modtronix 1:64a9c4a03244 1375 // Clear Irq
modtronix 1:64a9c4a03244 1376 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_TXDONE );
modtronix 1:64a9c4a03244 1377 // Intentional fall through
modtronix 1:64a9c4a03244 1378 case MODEM_FSK:
modtronix 1:64a9c4a03244 1379 default:
modtronix 1:64a9c4a03244 1380 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 1381 if( ( txDone != NULL ) )
modtronix 1:64a9c4a03244 1382 {
modtronix 1:64a9c4a03244 1383 txDone( );
modtronix 1:64a9c4a03244 1384 }
modtronix 1:64a9c4a03244 1385 break;
modtronix 1:64a9c4a03244 1386 }
modtronix 1:64a9c4a03244 1387 break;
modtronix 1:64a9c4a03244 1388 default:
modtronix 1:64a9c4a03244 1389 break;
modtronix 1:64a9c4a03244 1390 }
modtronix 1:64a9c4a03244 1391 }
modtronix 1:64a9c4a03244 1392
modtronix 1:64a9c4a03244 1393 void InAir::OnDio1Irq( void )
modtronix 1:64a9c4a03244 1394 {
modtronix 1:64a9c4a03244 1395 switch( this->settings.State )
modtronix 1:64a9c4a03244 1396 {
modtronix 1:64a9c4a03244 1397 case RX_DONE:
modtronix 1:64a9c4a03244 1398 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1399 {
modtronix 1:64a9c4a03244 1400 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1401 case MODEM_FSK:
modtronix 1:64a9c4a03244 1402 // FifoLevel interrupt
modtronix 1:64a9c4a03244 1403 // Read received packet size
modtronix 1:64a9c4a03244 1404 if( ( this->settings.FskPacketHandler.Size == 0 ) && ( this->settings.FskPacketHandler.NbBytes == 0 ) )
modtronix 1:64a9c4a03244 1405 {
modtronix 1:64a9c4a03244 1406 if( this->settings.Fsk.FixLen == false )
modtronix 1:64a9c4a03244 1407 {
modtronix 1:64a9c4a03244 1408 ReadFifo( ( uint8_t* )&this->settings.FskPacketHandler.Size, 1 );
modtronix 1:64a9c4a03244 1409 }
modtronix 1:64a9c4a03244 1410 else
modtronix 1:64a9c4a03244 1411 {
modtronix 1:64a9c4a03244 1412 this->settings.FskPacketHandler.Size = Read( REG_PAYLOADLENGTH );
modtronix 1:64a9c4a03244 1413 }
modtronix 1:64a9c4a03244 1414 }
modtronix 1:64a9c4a03244 1415
modtronix 1:64a9c4a03244 1416 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.FifoThresh )
modtronix 1:64a9c4a03244 1417 {
modtronix 1:64a9c4a03244 1418 ReadFifo( ( rxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.FifoThresh );
modtronix 1:64a9c4a03244 1419 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.FifoThresh;
modtronix 1:64a9c4a03244 1420 }
modtronix 1:64a9c4a03244 1421 else
modtronix 1:64a9c4a03244 1422 {
modtronix 1:64a9c4a03244 1423 ReadFifo( ( rxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
modtronix 1:64a9c4a03244 1424 this->settings.FskPacketHandler.NbBytes += ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
modtronix 1:64a9c4a03244 1425 }
modtronix 1:64a9c4a03244 1426 break;
modtronix 1:64a9c4a03244 1427 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1428 case MODEM_LORA:
modtronix 1:64a9c4a03244 1429 // Sync time out
modtronix 1:64a9c4a03244 1430 rxTimeoutTimer.detach( );
modtronix 1:64a9c4a03244 1431 this->settings.State = IDLE;
modtronix 1:64a9c4a03244 1432 if( ( rxTimeout != NULL ) )
modtronix 1:64a9c4a03244 1433 {
modtronix 1:64a9c4a03244 1434 rxTimeout( );
modtronix 1:64a9c4a03244 1435 }
modtronix 1:64a9c4a03244 1436 break;
modtronix 1:64a9c4a03244 1437 default:
modtronix 1:64a9c4a03244 1438 break;
modtronix 1:64a9c4a03244 1439 }
modtronix 1:64a9c4a03244 1440 break;
modtronix 1:64a9c4a03244 1441 case TX_DONE:
modtronix 1:64a9c4a03244 1442 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1443 {
modtronix 1:64a9c4a03244 1444 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1445 case MODEM_FSK:
modtronix 1:64a9c4a03244 1446 // FifoLevel interrupt
modtronix 1:64a9c4a03244 1447 if( ( this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes ) > this->settings.FskPacketHandler.ChunkSize )
modtronix 1:64a9c4a03244 1448 {
modtronix 1:64a9c4a03244 1449 WriteFifo( ( rxBuffer + this->settings.FskPacketHandler.NbBytes ), this->settings.FskPacketHandler.ChunkSize );
modtronix 1:64a9c4a03244 1450 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.ChunkSize;
modtronix 1:64a9c4a03244 1451 }
modtronix 1:64a9c4a03244 1452 else
modtronix 1:64a9c4a03244 1453 {
modtronix 1:64a9c4a03244 1454 // Write the last chunk of data
modtronix 1:64a9c4a03244 1455 WriteFifo( rxBuffer + this->settings.FskPacketHandler.NbBytes, this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes );
modtronix 1:64a9c4a03244 1456 this->settings.FskPacketHandler.NbBytes += this->settings.FskPacketHandler.Size - this->settings.FskPacketHandler.NbBytes;
modtronix 1:64a9c4a03244 1457 }
modtronix 1:64a9c4a03244 1458 break;
modtronix 1:64a9c4a03244 1459 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1460 case MODEM_LORA:
modtronix 1:64a9c4a03244 1461 break;
modtronix 1:64a9c4a03244 1462 default:
modtronix 1:64a9c4a03244 1463 break;
modtronix 1:64a9c4a03244 1464 }
modtronix 1:64a9c4a03244 1465 break;
modtronix 1:64a9c4a03244 1466 default:
modtronix 1:64a9c4a03244 1467 break;
modtronix 1:64a9c4a03244 1468 }
modtronix 1:64a9c4a03244 1469 }
modtronix 1:64a9c4a03244 1470
modtronix 1:64a9c4a03244 1471 void InAir::OnDio2Irq( void )
modtronix 1:64a9c4a03244 1472 {
modtronix 1:64a9c4a03244 1473 switch( this->settings.State )
modtronix 1:64a9c4a03244 1474 {
modtronix 1:64a9c4a03244 1475 case RX_DONE:
modtronix 1:64a9c4a03244 1476 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1477 {
modtronix 1:64a9c4a03244 1478 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1479 case MODEM_FSK:
modtronix 1:64a9c4a03244 1480 if( ( this->settings.FskPacketHandler.PreambleDetected == true ) && ( this->settings.FskPacketHandler.SyncWordDetected == false ) )
modtronix 1:64a9c4a03244 1481 {
modtronix 1:64a9c4a03244 1482 rxTimeoutSyncWord.detach( );
modtronix 1:64a9c4a03244 1483
modtronix 1:64a9c4a03244 1484 this->settings.FskPacketHandler.SyncWordDetected = true;
modtronix 1:64a9c4a03244 1485
modtronix 1:64a9c4a03244 1486 this->settings.FskPacketHandler.RssiValue = -( Read( REG_RSSIVALUE ) >> 1 );
modtronix 1:64a9c4a03244 1487
modtronix 1:64a9c4a03244 1488 this->settings.FskPacketHandler.AfcValue = ( int32_t )( double )( ( ( uint16_t )Read( REG_AFCMSB ) << 8 ) |
modtronix 1:64a9c4a03244 1489 ( uint16_t )Read( REG_AFCLSB ) ) *
modtronix 1:64a9c4a03244 1490 ( double )FREQ_STEP;
modtronix 1:64a9c4a03244 1491 this->settings.FskPacketHandler.RxGain = ( Read( REG_LNA ) >> 5 ) & 0x07;
modtronix 1:64a9c4a03244 1492 }
modtronix 1:64a9c4a03244 1493 break;
modtronix 1:64a9c4a03244 1494 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1495 case MODEM_LORA:
modtronix 1:64a9c4a03244 1496 if( this->settings.LoRa.FreqHopOn == true )
modtronix 1:64a9c4a03244 1497 {
modtronix 1:64a9c4a03244 1498 // Clear Irq
modtronix 1:64a9c4a03244 1499 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
modtronix 1:64a9c4a03244 1500
modtronix 1:64a9c4a03244 1501 if( ( fhssChangeChannel != NULL ) )
modtronix 1:64a9c4a03244 1502 {
modtronix 1:64a9c4a03244 1503 fhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
modtronix 1:64a9c4a03244 1504 }
modtronix 1:64a9c4a03244 1505 }
modtronix 1:64a9c4a03244 1506 break;
modtronix 1:64a9c4a03244 1507 default:
modtronix 1:64a9c4a03244 1508 break;
modtronix 1:64a9c4a03244 1509 }
modtronix 1:64a9c4a03244 1510 break;
modtronix 1:64a9c4a03244 1511 case TX_DONE:
modtronix 1:64a9c4a03244 1512 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1513 {
modtronix 1:64a9c4a03244 1514 case MODEM_FSK:
modtronix 1:64a9c4a03244 1515 break;
modtronix 1:64a9c4a03244 1516 case MODEM_LORA:
modtronix 1:64a9c4a03244 1517 if( this->settings.LoRa.FreqHopOn == true )
modtronix 1:64a9c4a03244 1518 {
modtronix 1:64a9c4a03244 1519 // Clear Irq
modtronix 1:64a9c4a03244 1520 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
modtronix 1:64a9c4a03244 1521
modtronix 1:64a9c4a03244 1522 if( ( fhssChangeChannel != NULL ) )
modtronix 1:64a9c4a03244 1523 {
modtronix 1:64a9c4a03244 1524 fhssChangeChannel( ( Read( REG_LR_HOPCHANNEL ) & RFLR_HOPCHANNEL_CHANNEL_MASK ) );
modtronix 1:64a9c4a03244 1525 }
modtronix 1:64a9c4a03244 1526 }
modtronix 1:64a9c4a03244 1527 break;
modtronix 1:64a9c4a03244 1528 default:
modtronix 1:64a9c4a03244 1529 break;
modtronix 1:64a9c4a03244 1530 }
modtronix 1:64a9c4a03244 1531 break;
modtronix 1:64a9c4a03244 1532 default:
modtronix 1:64a9c4a03244 1533 break;
modtronix 1:64a9c4a03244 1534 }
modtronix 1:64a9c4a03244 1535 }
modtronix 1:64a9c4a03244 1536
modtronix 1:64a9c4a03244 1537 void InAir::OnDio3Irq( void )
modtronix 1:64a9c4a03244 1538 {
modtronix 1:64a9c4a03244 1539 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1540 {
modtronix 1:64a9c4a03244 1541 case MODEM_FSK:
modtronix 1:64a9c4a03244 1542 break;
modtronix 1:64a9c4a03244 1543 case MODEM_LORA:
modtronix 1:64a9c4a03244 1544 if( ( Read( REG_LR_IRQFLAGS ) & 0x01 ) == 0x01 )
modtronix 1:64a9c4a03244 1545 {
modtronix 1:64a9c4a03244 1546 // Clear Irq
modtronix 1:64a9c4a03244 1547 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDETECTED_MASK | RFLR_IRQFLAGS_CADDONE);
modtronix 1:64a9c4a03244 1548 if( ( cadDone != NULL ) )
modtronix 1:64a9c4a03244 1549 {
modtronix 1:64a9c4a03244 1550 cadDone( true );
modtronix 1:64a9c4a03244 1551 }
modtronix 1:64a9c4a03244 1552 }
modtronix 1:64a9c4a03244 1553 else
modtronix 1:64a9c4a03244 1554 {
modtronix 1:64a9c4a03244 1555 // Clear Irq
modtronix 1:64a9c4a03244 1556 Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_CADDONE );
modtronix 1:64a9c4a03244 1557 if( ( cadDone != NULL ) )
modtronix 1:64a9c4a03244 1558 {
modtronix 1:64a9c4a03244 1559 cadDone( false );
modtronix 1:64a9c4a03244 1560 }
modtronix 1:64a9c4a03244 1561 }
modtronix 1:64a9c4a03244 1562 break;
modtronix 1:64a9c4a03244 1563 default:
modtronix 1:64a9c4a03244 1564 break;
modtronix 1:64a9c4a03244 1565 }
modtronix 1:64a9c4a03244 1566 }
modtronix 1:64a9c4a03244 1567
modtronix 1:64a9c4a03244 1568 /*
modtronix 1:64a9c4a03244 1569 void InAir::OnDio4Irq( void )
modtronix 1:64a9c4a03244 1570 {
modtronix 1:64a9c4a03244 1571 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1572 {
modtronix 1:64a9c4a03244 1573 #if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1574 case MODEM_FSK:
modtronix 1:64a9c4a03244 1575 {
modtronix 1:64a9c4a03244 1576 if( this->settings.FskPacketHandler.PreambleDetected == false )
modtronix 1:64a9c4a03244 1577 {
modtronix 1:64a9c4a03244 1578 this->settings.FskPacketHandler.PreambleDetected = true;
modtronix 1:64a9c4a03244 1579 }
modtronix 1:64a9c4a03244 1580 }
modtronix 1:64a9c4a03244 1581 break;
modtronix 1:64a9c4a03244 1582 #endif //#if (INAIR_ENABLE_FSK==1)
modtronix 1:64a9c4a03244 1583 case MODEM_LORA:
modtronix 1:64a9c4a03244 1584 break;
modtronix 1:64a9c4a03244 1585 default:
modtronix 1:64a9c4a03244 1586 break;
modtronix 1:64a9c4a03244 1587 }
modtronix 1:64a9c4a03244 1588 }
modtronix 1:64a9c4a03244 1589
modtronix 1:64a9c4a03244 1590 void InAir::OnDio5Irq( void )
modtronix 1:64a9c4a03244 1591 {
modtronix 1:64a9c4a03244 1592 switch( this->settings.Modem )
modtronix 1:64a9c4a03244 1593 {
modtronix 1:64a9c4a03244 1594 case MODEM_FSK:
modtronix 1:64a9c4a03244 1595 break;
modtronix 1:64a9c4a03244 1596 case MODEM_LORA:
modtronix 1:64a9c4a03244 1597 break;
modtronix 1:64a9c4a03244 1598 default:
modtronix 1:64a9c4a03244 1599 break;
modtronix 1:64a9c4a03244 1600 }
modtronix 1:64a9c4a03244 1601 }
modtronix 1:64a9c4a03244 1602 */
modtronix 1:64a9c4a03244 1603
modtronix 1:64a9c4a03244 1604 void InAir::Reset( void )
modtronix 1:64a9c4a03244 1605 {
modtronix 1:64a9c4a03244 1606 reset.output();
modtronix 1:64a9c4a03244 1607 reset = 0;
modtronix 1:64a9c4a03244 1608 wait_ms( 1 );
modtronix 1:64a9c4a03244 1609 reset.input();
modtronix 1:64a9c4a03244 1610 wait_ms( 6 );
modtronix 1:64a9c4a03244 1611 }
modtronix 1:64a9c4a03244 1612
modtronix 1:64a9c4a03244 1613 void InAir::Write( uint8_t addr, uint8_t data )
modtronix 1:64a9c4a03244 1614 {
modtronix 1:64a9c4a03244 1615 Write( addr, &data, 1 );
modtronix 1:64a9c4a03244 1616 }
modtronix 1:64a9c4a03244 1617
modtronix 1:64a9c4a03244 1618 uint8_t InAir::Read( uint8_t addr )
modtronix 1:64a9c4a03244 1619 {
modtronix 1:64a9c4a03244 1620 uint8_t data;
modtronix 1:64a9c4a03244 1621 Read( addr, &data, 1 );
modtronix 1:64a9c4a03244 1622 return data;
modtronix 1:64a9c4a03244 1623 }
modtronix 1:64a9c4a03244 1624
modtronix 1:64a9c4a03244 1625 void InAir::Write( uint8_t addr, uint8_t *buffer, uint8_t size )
modtronix 1:64a9c4a03244 1626 {
modtronix 1:64a9c4a03244 1627 uint8_t i;
modtronix 1:64a9c4a03244 1628
modtronix 1:64a9c4a03244 1629 nss = 0;
modtronix 1:64a9c4a03244 1630 spi.write( addr | 0x80 );
modtronix 1:64a9c4a03244 1631 for( i = 0; i < size; i++ )
modtronix 1:64a9c4a03244 1632 {
modtronix 1:64a9c4a03244 1633 spi.write( buffer[i] );
modtronix 1:64a9c4a03244 1634 }
modtronix 1:64a9c4a03244 1635 nss = 1;
modtronix 1:64a9c4a03244 1636 }
modtronix 1:64a9c4a03244 1637
modtronix 1:64a9c4a03244 1638 void InAir::Read( uint8_t addr, uint8_t *buffer, uint8_t size )
modtronix 1:64a9c4a03244 1639 {
modtronix 1:64a9c4a03244 1640 uint8_t i;
modtronix 1:64a9c4a03244 1641
modtronix 1:64a9c4a03244 1642 nss = 0;
modtronix 1:64a9c4a03244 1643 spi.write( addr & 0x7F );
modtronix 1:64a9c4a03244 1644 for( i = 0; i < size; i++ )
modtronix 1:64a9c4a03244 1645 {
modtronix 1:64a9c4a03244 1646 buffer[i] = spi.write( 0 );
modtronix 1:64a9c4a03244 1647 }
modtronix 1:64a9c4a03244 1648 nss = 1;
modtronix 1:64a9c4a03244 1649 }
modtronix 1:64a9c4a03244 1650
modtronix 1:64a9c4a03244 1651 void InAir::WriteFifo( uint8_t *buffer, uint8_t size )
modtronix 1:64a9c4a03244 1652 {
modtronix 1:64a9c4a03244 1653 Write( 0, buffer, size );
modtronix 1:64a9c4a03244 1654 }
modtronix 1:64a9c4a03244 1655
modtronix 1:64a9c4a03244 1656 void InAir::ReadFifo( uint8_t *buffer, uint8_t size )
modtronix 1:64a9c4a03244 1657 {
modtronix 1:64a9c4a03244 1658 Read( 0, buffer, size );
modtronix 1:64a9c4a03244 1659 }
modtronix 1:64a9c4a03244 1660
modtronix 1:64a9c4a03244 1661
modtronix 1:64a9c4a03244 1662 //-------------------------------------------------------------------------
modtronix 1:64a9c4a03244 1663 // Board relative functions
modtronix 1:64a9c4a03244 1664 //-------------------------------------------------------------------------
modtronix 1:64a9c4a03244 1665
modtronix 1:64a9c4a03244 1666 void InAir::IoInit( void )
modtronix 1:64a9c4a03244 1667 {
modtronix 1:64a9c4a03244 1668 SpiInit( );
modtronix 1:64a9c4a03244 1669 }
modtronix 1:64a9c4a03244 1670
modtronix 1:64a9c4a03244 1671 static const RadioRegisters_t RadioRegsInit[] =
modtronix 1:64a9c4a03244 1672 {
modtronix 1:64a9c4a03244 1673 { MODEM_FSK , REG_LNA , 0x23 },
modtronix 1:64a9c4a03244 1674 { MODEM_FSK , REG_RXCONFIG , 0x1E },
modtronix 1:64a9c4a03244 1675 { MODEM_FSK , REG_RSSICONFIG , 0xD2 },
modtronix 1:64a9c4a03244 1676 { MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },
modtronix 1:64a9c4a03244 1677 { MODEM_FSK , REG_OSC , 0x07 },
modtronix 1:64a9c4a03244 1678 { MODEM_FSK , REG_SYNCCONFIG , 0x12 },
modtronix 1:64a9c4a03244 1679 { MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },
modtronix 1:64a9c4a03244 1680 { MODEM_FSK , REG_SYNCVALUE2 , 0x94 },
modtronix 1:64a9c4a03244 1681 { MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },
modtronix 1:64a9c4a03244 1682 { MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },
modtronix 1:64a9c4a03244 1683 { MODEM_FSK , REG_FIFOTHRESH , 0x8F },
modtronix 1:64a9c4a03244 1684 { MODEM_FSK , REG_IMAGECAL , 0x02 },
modtronix 1:64a9c4a03244 1685 { MODEM_FSK , REG_DIOMAPPING1 , 0x00 },
modtronix 1:64a9c4a03244 1686 { MODEM_FSK , REG_DIOMAPPING2 , 0x30 },
modtronix 1:64a9c4a03244 1687 { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },
modtronix 1:64a9c4a03244 1688 };
modtronix 1:64a9c4a03244 1689
modtronix 1:64a9c4a03244 1690 void InAir::RadioRegistersInit( ) {
modtronix 1:64a9c4a03244 1691 uint8_t i = 0;
modtronix 1:64a9c4a03244 1692 for( i = 0; i < sizeof( RadioRegsInit ) / sizeof( RadioRegisters_t ); i++ )
modtronix 1:64a9c4a03244 1693 {
modtronix 1:64a9c4a03244 1694 SetModem( RadioRegsInit[i].Modem );
modtronix 1:64a9c4a03244 1695 Write( RadioRegsInit[i].Addr, RadioRegsInit[i].Value );
modtronix 1:64a9c4a03244 1696 }
modtronix 1:64a9c4a03244 1697 }
modtronix 1:64a9c4a03244 1698
modtronix 1:64a9c4a03244 1699 void InAir::SpiInit( void )
modtronix 1:64a9c4a03244 1700 {
modtronix 1:64a9c4a03244 1701 nss = 1;
modtronix 1:64a9c4a03244 1702 spi.format( 8,0 );
modtronix 1:64a9c4a03244 1703 uint32_t frequencyToSet = 8000000;
modtronix 1:64a9c4a03244 1704 #if( defined ( TARGET_NUCLEO_L152RE ) || defined (TARGET_NUCLEO_F401RE) || defined ( TARGET_LPC11U6X ) || defined (TARGET_K64F) || defined ( TARGET_NZ32ST1L ) || defined(TARGET_NZ32SC151) )
modtronix 1:64a9c4a03244 1705 spi.frequency( frequencyToSet );
modtronix 1:64a9c4a03244 1706 #elif( defined ( TARGET_KL25Z ) ) //busclock frequency is halved -> double the spi frequency to compensate
modtronix 1:64a9c4a03244 1707 spi.frequency( frequencyToSet * 2 );
modtronix 1:64a9c4a03244 1708 #else
modtronix 1:64a9c4a03244 1709 #warning "Check the board's SPI frequency"
modtronix 1:64a9c4a03244 1710 #endif
modtronix 1:64a9c4a03244 1711 wait(0.1);
modtronix 1:64a9c4a03244 1712 }
modtronix 1:64a9c4a03244 1713
modtronix 1:64a9c4a03244 1714 void InAir::IoIrqInit()
modtronix 1:64a9c4a03244 1715 {
modtronix 1:64a9c4a03244 1716 //TARGET_KL25Z board does not have pulldown resistors, seems like TARGET_K64F does have them
modtronix 1:64a9c4a03244 1717 #if( defined ( TARGET_NUCLEO_L152RE ) || defined (TARGET_NUCLEO_F401RE) || defined ( TARGET_LPC11U6X ) || defined (TARGET_K64F) || defined ( TARGET_NZ32ST1L ) || defined(TARGET_NZ32SC151))
modtronix 1:64a9c4a03244 1718 dio0.mode(PullDown);
modtronix 1:64a9c4a03244 1719 dio1.mode(PullDown);
modtronix 1:64a9c4a03244 1720 dio2.mode(PullDown);
modtronix 1:64a9c4a03244 1721 dio3.mode(PullDown);
modtronix 1:64a9c4a03244 1722 #endif
modtronix 1:64a9c4a03244 1723 #if(INAIR_DIO0_IS_INTERRUPT==1)
modtronix 1:64a9c4a03244 1724 dio0.rise(this, &InAir::OnDio0Irq);
modtronix 1:64a9c4a03244 1725 #endif
modtronix 1:64a9c4a03244 1726 #if(INAIR_DIO1_IS_INTERRUPT==1)
modtronix 1:64a9c4a03244 1727 dio1.rise( this, &InAir::OnDio1Irq);
modtronix 1:64a9c4a03244 1728 #endif
modtronix 1:64a9c4a03244 1729 #if(INAIR_DIO2_IS_INTERRUPT==1)
modtronix 1:64a9c4a03244 1730 dio2.rise( this, &InAir::OnDio2Irq);
modtronix 1:64a9c4a03244 1731 #endif
modtronix 1:64a9c4a03244 1732 #if(INAIR_DIO3_IS_INTERRUPT==1)
modtronix 1:64a9c4a03244 1733 dio3.rise( this, &InAir::OnDio3Irq);
modtronix 1:64a9c4a03244 1734 #endif
modtronix 1:64a9c4a03244 1735 }
modtronix 1:64a9c4a03244 1736
modtronix 1:64a9c4a03244 1737 void InAir::IoDeInit( void )
modtronix 1:64a9c4a03244 1738 {
modtronix 1:64a9c4a03244 1739 //nothing
modtronix 1:64a9c4a03244 1740 }
modtronix 1:64a9c4a03244 1741
modtronix 1:64a9c4a03244 1742 uint8_t InAir::GetPaSelect( uint32_t channel )
modtronix 1:64a9c4a03244 1743 {
modtronix 1:64a9c4a03244 1744 if(boardConnected == BOARD_INAIR9B) {
modtronix 1:64a9c4a03244 1745 return RF_PACONFIG_PASELECT_PABOOST;
modtronix 1:64a9c4a03244 1746 }
modtronix 1:64a9c4a03244 1747 else {
modtronix 1:64a9c4a03244 1748 return RF_PACONFIG_PASELECT_RFO;
modtronix 1:64a9c4a03244 1749 }
modtronix 1:64a9c4a03244 1750 }
modtronix 1:64a9c4a03244 1751
modtronix 1:64a9c4a03244 1752 bool InAir::CheckRfFrequency( uint32_t frequency )
modtronix 1:64a9c4a03244 1753 {
modtronix 1:64a9c4a03244 1754 //TODO: Implement check, currently all frequencies are supported
modtronix 1:64a9c4a03244 1755 return true;
modtronix 1:64a9c4a03244 1756 }