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:
Tue Oct 20 17:47:24 2015 +1100
Revision:
6:d542b5a44d5a
Parent:
5:1a255cc8d54a
Child:
9:9a77e2c7c5e8
Added LORA_BW_xx defines to inair.h

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