Version of personalized IMPACT LoRa
Fork of LMiC-10secs by
Embed:
(wiki syntax)
Show/hide line numbers
radio.cpp
00001 /******************************************************************************* 00002 * Copyright (c) 2014-2015 IBM Corporation. 00003 * All rights reserved. This program and the accompanying materials 00004 * are made available under the terms of the Eclipse Public License v1.0 00005 * which accompanies this distribution, and is available at 00006 * http://www.eclipse.org/legal/epl-v10.html 00007 * 00008 * Contributors: 00009 * IBM Zurich Research Lab - initial API, implementation and documentation 00010 * Semtech Apps Team - Modified to support the MBED sx1276 driver 00011 * library. 00012 * Possibility to use original or Semtech's MBED 00013 * radio driver. The selection is done by setting 00014 * USE_SMTC_RADIO_DRIVER preprocessing directive 00015 * in lmic.h 00016 *******************************************************************************/ 00017 00018 #include "lmic.h" 00019 00020 #if USE_SMTC_RADIO_DRIVER 00021 #include "sx1276-hal.h" 00022 00023 /*! 00024 * Syncword for lora networks 00025 */ 00026 #define LORA_MAC_SYNCWORD 0x34 00027 00028 /* 00029 * Callback functions prototypes 00030 */ 00031 /*! 00032 * @brief Function to be executed on Radio Tx Done event 00033 */ 00034 void OnTxDone( void ); 00035 00036 /*! 00037 * @brief Function to be executed on Radio Rx Done event 00038 */ 00039 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); 00040 00041 /*! 00042 * @brief Function executed on Radio Tx Timeout event 00043 */ 00044 void OnTxTimeout( void ); 00045 00046 /*! 00047 * @brief Function executed on Radio Rx Timeout event 00048 */ 00049 void OnRxTimeout( void ); 00050 00051 /*! 00052 * @brief Function executed on Radio Rx Error event 00053 */ 00054 void OnRxError( void ); 00055 00056 /*! 00057 * @brief Function executed on Radio Fhss Change Channel event 00058 */ 00059 void OnFhssChangeChannel( uint8_t channelIndex ); 00060 00061 /*! 00062 * @brief Function executed on CAD Done event 00063 */ 00064 void OnCadDone( void ); 00065 00066 /* 00067 * Radio object declraration 00068 */ 00069 SX1276MB1xAS Radio( OnTxDone, OnTxTimeout, OnRxDone, OnRxTimeout, OnRxError, NULL, NULL ); 00070 00071 static const u2_t LORA_RXDONE_FIXUP[] = { 00072 [FSK] = us2osticks(0), // ( 0 ticks) 00073 [SF7] = us2osticks(0), // ( 0 ticks) 00074 [SF8] = us2osticks(1648), // ( 54 ticks) 00075 [SF9] = us2osticks(3265), // ( 107 ticks) 00076 [SF10] = us2osticks(7049), // ( 231 ticks) 00077 [SF11] = us2osticks(13641), // ( 447 ticks) 00078 [SF12] = us2osticks(31189), // (1022 ticks) 00079 }; 00080 00081 void OnTxDone( void ) 00082 { 00083 ostime_t now = os_getTime( ); 00084 // save exact tx time 00085 LMIC.txend = now - us2osticks( RADIO_WAKEUP_TIME ); // TXDONE FIXUP 00086 00087 // go from stanby to sleep 00088 Radio.Sleep( ); 00089 // run os job (use preset func ptr) 00090 os_setCallback( &LMIC.osjob, LMIC.osjob.func ); 00091 } 00092 00093 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) 00094 { 00095 ostime_t now = os_getTime( ); 00096 // save exact rx time 00097 if( getBw( LMIC.rps ) == BW125 ) 00098 { 00099 now -= LORA_RXDONE_FIXUP[getSf( LMIC.rps )]; 00100 } 00101 LMIC.rxtime = now; 00102 // read the PDU and inform the MAC that we received something 00103 LMIC.dataLen = size; 00104 // now read the FIFO 00105 memcpy( LMIC.frame, payload, size ); 00106 // read rx quality parameters 00107 LMIC.snr = snr; // SNR [dB] * 4 00108 LMIC.rssi = rssi; // RSSI [dBm] (-196...+63) 00109 00110 // go from stanby to sleep 00111 Radio.Sleep( ); 00112 // run os job (use preset func ptr) 00113 os_setCallback( &LMIC.osjob, LMIC.osjob.func ); 00114 } 00115 00116 void OnTxTimeout( void ) 00117 { 00118 ostime_t now = os_getTime( ); 00119 00120 // indicate error 00121 LMIC.dataLen = 0; 00122 00123 // go from stanby to sleep 00124 Radio.Sleep( ); 00125 // run os job (use preset func ptr) 00126 os_setCallback( &LMIC.osjob, LMIC.osjob.func ); 00127 } 00128 00129 void OnRxTimeout( void ) 00130 { 00131 ostime_t now = os_getTime( ); 00132 // indicate timeout 00133 LMIC.dataLen = 0; 00134 00135 // go from stanby to sleep 00136 Radio.Sleep( ); 00137 // run os job (use preset func ptr) 00138 os_setCallback( &LMIC.osjob, LMIC.osjob.func ); 00139 } 00140 00141 void OnRxError( void ) 00142 { 00143 ostime_t now = os_getTime( ); 00144 00145 // indicate error 00146 LMIC.dataLen = 0; 00147 00148 // go from stanby to sleep 00149 Radio.Sleep( ); 00150 // run os job (use preset func ptr) 00151 os_setCallback( &LMIC.osjob, LMIC.osjob.func ); 00152 } 00153 00154 /*! 00155 * LMIC API implementation 00156 */ 00157 // RADIO STATE 00158 // (initialized by radio_init( ), used by radio_rand1( )) 00159 static u1_t randbuf[16]; 00160 00161 // get random seed from wideband noise rssi 00162 void radio_init( void ) 00163 { 00164 hal_disableIRQs( ); 00165 00166 // seed 15-byte randomness via noise rssi 00167 // Set LoRa modem ON 00168 Radio.SetModem( MODEM_LORA ); 00169 // Disable LoRa modem interrupts 00170 Radio.Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT | 00171 RFLR_IRQFLAGS_RXDONE | 00172 RFLR_IRQFLAGS_PAYLOADCRCERROR | 00173 RFLR_IRQFLAGS_VALIDHEADER | 00174 RFLR_IRQFLAGS_TXDONE | 00175 RFLR_IRQFLAGS_CADDONE | 00176 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL | 00177 RFLR_IRQFLAGS_CADDETECTED ); 00178 00179 // Set radio in continuous reception 00180 Radio.Rx( 0 ); 00181 00182 for( int i = 1; i < 16; i++ ) 00183 { 00184 for( int j = 0; j < 8; j++ ) 00185 { 00186 u1_t b; // wait for two non-identical subsequent least-significant bits 00187 while( ( b = Radio.Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) == ( Radio.Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) ); 00188 randbuf[i] = ( randbuf[i] << 1 ) | b; 00189 } 00190 } 00191 randbuf[0] = 16; // set initial index 00192 00193 // Change LoRa modem SyncWord 00194 Radio.Write( REG_LR_SYNCWORD, LORA_MAC_SYNCWORD ); 00195 00196 Radio.Sleep( ); 00197 00198 hal_enableIRQs( ); 00199 } 00200 00201 // return next random byte derived from seed buffer 00202 // (buf[0] holds index of next byte to be returned) 00203 u1_t radio_rand1( void ) 00204 { 00205 u1_t i = randbuf[0]; 00206 ASSERT( i != 0 ); 00207 if( i == 16 ) 00208 { 00209 os_aes( AES_ENC, randbuf, 16 ); // encrypt seed with any key 00210 i = 0; 00211 } 00212 u1_t v = randbuf[i++]; 00213 randbuf[0] = i; 00214 return v; 00215 } 00216 00217 void os_radio( u1_t mode ) 00218 { 00219 hal_disableIRQs( ); 00220 switch( mode ) 00221 { 00222 case RADIO_RST: 00223 // put radio to sleep 00224 Radio.Sleep( ); 00225 break; 00226 00227 case RADIO_TX: 00228 // transmit frame now 00229 //ASSERT( Radio.GetState( ) == IDLE ); 00230 00231 Radio.SetChannel( LMIC.freq ); 00232 if( getSf( LMIC.rps ) == FSK ) 00233 { // FSK modem 00234 Radio.SetTxConfig( MODEM_FSK, LMIC.txpow, 25e3, 0, 50e3, 0, 5, false, true, 0, 0, false, 3e6 ); 00235 } 00236 else 00237 { // LoRa modem 00238 00239 Radio.SetTxConfig( MODEM_LORA, LMIC.txpow, 0, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 8, getIh( LMIC.rps ) ? true : false, ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, false, 3e6 ); 00240 } 00241 00242 //starttx( ); // buf=LMIC.frame, len=LMIC.dataLen 00243 Radio.Send( LMIC.frame, LMIC.dataLen ); 00244 break; 00245 00246 case RADIO_RX: 00247 // receive frame now (exactly at rxtime) 00248 //ASSERT( Radio.GetState( ) == IDLE ); 00249 00250 Radio.SetChannel( LMIC.freq ); 00251 if( getSf( LMIC.rps ) == FSK ) 00252 { // FSK modem 00253 //Radio.SetRxConfig( MODEM_FSK, 50e3, 50e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, false ); 00254 Radio.SetRxConfig( MODEM_FSK, 50e3, 50e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, true ); 00255 } 00256 else 00257 { // LoRa modem 00258 if( ( getSf( LMIC.rps ) <= SF9 ) && ( LMIC.rxsyms < 8 ) ) 00259 { 00260 Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms + 3, getIh( LMIC.rps ) ? true : false, getIh( LMIC.rps ), ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, true, false ); 00261 } 00262 else 00263 { 00264 Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms, getIh( LMIC.rps ) ? true : false, getIh( LMIC.rps ), ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, true, false ); 00265 } 00266 } 00267 00268 // now instruct the radio to receive 00269 hal_waitUntil( LMIC.rxtime ); // busy wait until exact rx time 00270 00271 //startrx( RXMODE_SINGLE ); // buf = LMIC.frame, time = LMIC.rxtime, timeout=LMIC.rxsyms 00272 if( getSf( LMIC.rps ) == FSK ) 00273 { // FSK modem 00274 Radio.Rx( 50e3 ); // Max Rx window 50 ms 00275 } 00276 else 00277 { // LoRa modem 00278 Radio.Rx( 3e6 ); // Max Rx window 3 seconds 00279 } 00280 break; 00281 00282 case RADIO_RXON: 00283 // start scanning for beacon now 00284 00285 //ASSERT( Radio.GetState( ) == IDLE ); 00286 00287 Radio.SetChannel( LMIC.freq ); 00288 if( getSf( LMIC.rps ) == FSK ) 00289 { // FSK modem 00290 Radio.SetRxConfig( MODEM_FSK, 50e3, 50e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, true ); 00291 } 00292 else 00293 { // LoRa modem 00294 Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms, getIh( LMIC.rps ) ? true : false, getIh( LMIC.rps ), ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, true, true ); 00295 } 00296 00297 //startrx( RXMODE_SCAN ); // buf = LMIC.frame 00298 Radio.Rx( 0 ); 00299 break; 00300 } 00301 hal_enableIRQs( ); 00302 } 00303 00304 #else 00305 00306 // ---------------------------------------- 00307 // Registers Mapping 00308 #define RegFifo 0x00 // common 00309 #define RegOpMode 0x01 // common 00310 #define FSKRegBitrateMsb 0x02 00311 #define FSKRegBitrateLsb 0x03 00312 #define FSKRegFdevMsb 0x04 00313 #define FSKRegFdevLsb 0x05 00314 #define RegFrfMsb 0x06 // common 00315 #define RegFrfMid 0x07 // common 00316 #define RegFrfLsb 0x08 // common 00317 #define RegPaConfig 0x09 // common 00318 #define RegPaRamp 0x0A // common 00319 #define RegOcp 0x0B // common 00320 #define RegLna 0x0C // common 00321 #define FSKRegRxConfig 0x0D 00322 #define LORARegFifoAddrPtr 0x0D 00323 #define FSKRegRssiConfig 0x0E 00324 #define LORARegFifoTxBaseAddr 0x0E 00325 #define FSKRegRssiCollision 0x0F 00326 #define LORARegFifoRxBaseAddr 0x0F 00327 #define FSKRegRssiThresh 0x10 00328 #define LORARegFifoRxCurrentAddr 0x10 00329 #define FSKRegRssiValue 0x11 00330 #define LORARegIrqFlagsMask 0x11 00331 #define FSKRegRxBw 0x12 00332 #define LORARegIrqFlags 0x12 00333 #define FSKRegAfcBw 0x13 00334 #define LORARegRxNbBytes 0x13 00335 #define FSKRegOokPeak 0x14 00336 #define LORARegRxHeaderCntValueMsb 0x14 00337 #define FSKRegOokFix 0x15 00338 #define LORARegRxHeaderCntValueLsb 0x15 00339 #define FSKRegOokAvg 0x16 00340 #define LORARegRxPacketCntValueMsb 0x16 00341 #define LORARegRxpacketCntValueLsb 0x17 00342 #define LORARegModemStat 0x18 00343 #define LORARegPktSnrValue 0x19 00344 #define FSKRegAfcFei 0x1A 00345 #define LORARegPktRssiValue 0x1A 00346 #define FSKRegAfcMsb 0x1B 00347 #define LORARegRssiValue 0x1B 00348 #define FSKRegAfcLsb 0x1C 00349 #define LORARegHopChannel 0x1C 00350 #define FSKRegFeiMsb 0x1D 00351 #define LORARegModemConfig1 0x1D 00352 #define FSKRegFeiLsb 0x1E 00353 #define LORARegModemConfig2 0x1E 00354 #define FSKRegPreambleDetect 0x1F 00355 #define LORARegSymbTimeoutLsb 0x1F 00356 #define FSKRegRxTimeout1 0x20 00357 #define LORARegPreambleMsb 0x20 00358 #define FSKRegRxTimeout2 0x21 00359 #define LORARegPreambleLsb 0x21 00360 #define FSKRegRxTimeout3 0x22 00361 #define LORARegPayloadLength 0x22 00362 #define FSKRegRxDelay 0x23 00363 #define LORARegPayloadMaxLength 0x23 00364 #define FSKRegOsc 0x24 00365 #define LORARegHopPeriod 0x24 00366 #define FSKRegPreambleMsb 0x25 00367 #define LORARegFifoRxByteAddr 0x25 00368 #define LORARegModemConfig3 0x26 00369 #define FSKRegPreambleLsb 0x26 00370 #define FSKRegSyncConfig 0x27 00371 #define LORARegFeiMsb 0x28 00372 #define FSKRegSyncValue1 0x28 00373 #define LORAFeiMib 0x29 00374 #define FSKRegSyncValue2 0x29 00375 #define LORARegFeiLsb 0x2A 00376 #define FSKRegSyncValue3 0x2A 00377 #define FSKRegSyncValue4 0x2B 00378 #define LORARegRssiWideband 0x2C 00379 #define FSKRegSyncValue5 0x2C 00380 #define FSKRegSyncValue6 0x2D 00381 #define FSKRegSyncValue7 0x2E 00382 #define FSKRegSyncValue8 0x2F 00383 #define FSKRegPacketConfig1 0x30 00384 #define FSKRegPacketConfig2 0x31 00385 #define LORARegDetectOptimize 0x31 00386 #define FSKRegPayloadLength 0x32 00387 #define FSKRegNodeAdrs 0x33 00388 #define LORARegInvertIQ 0x33 00389 #define FSKRegBroadcastAdrs 0x34 00390 #define FSKRegFifoThresh 0x35 00391 #define FSKRegSeqConfig1 0x36 00392 #define FSKRegSeqConfig2 0x37 00393 #define LORARegDetectionThreshold 0x37 00394 #define FSKRegTimerResol 0x38 00395 #define FSKRegTimer1Coef 0x39 00396 #define LORARegSyncWord 0x39 00397 #define FSKRegTimer2Coef 0x3A 00398 #define FSKRegImageCal 0x3B 00399 #define FSKRegTemp 0x3C 00400 #define FSKRegLowBat 0x3D 00401 #define FSKRegIrqFlags1 0x3E 00402 #define FSKRegIrqFlags2 0x3F 00403 #define RegDioMapping1 0x40 // common 00404 #define RegDioMapping2 0x41 // common 00405 #define RegVersion 0x42 // common 00406 // #define RegAgcRef 0x43 // common 00407 // #define RegAgcThresh1 0x44 // common 00408 // #define RegAgcThresh2 0x45 // common 00409 // #define RegAgcThresh3 0x46 // common 00410 // #define RegPllHop 0x4B // common 00411 // #define RegTcxo 0x58 // common 00412 #define RegPaDac 0x5A // common 00413 // #define RegPll 0x5C // common 00414 // #define RegPllLowPn 0x5E // common 00415 // #define RegFormerTemp 0x6C // common 00416 // #define RegBitRateFrac 0x70 // common 00417 00418 // ---------------------------------------- 00419 // spread factors and mode for RegModemConfig2 00420 #define SX1272_MC2_FSK 0x00 00421 #define SX1272_MC2_SF7 0x70 00422 #define SX1272_MC2_SF8 0x80 00423 #define SX1272_MC2_SF9 0x90 00424 #define SX1272_MC2_SF10 0xA0 00425 #define SX1272_MC2_SF11 0xB0 00426 #define SX1272_MC2_SF12 0xC0 00427 // bandwidth for RegModemConfig1 00428 #define SX1272_MC1_BW_125 0x00 00429 #define SX1272_MC1_BW_250 0x40 00430 #define SX1272_MC1_BW_500 0x80 00431 // coding rate for RegModemConfig1 00432 #define SX1272_MC1_CR_4_5 0x08 00433 #define SX1272_MC1_CR_4_6 0x10 00434 #define SX1272_MC1_CR_4_7 0x18 00435 #define SX1272_MC1_CR_4_8 0x20 00436 #define SX1272_MC1_IMPLICIT_HEADER_MODE_ON 0x04 // required for receive 00437 #define SX1272_MC1_RX_PAYLOAD_CRCON 0x02 00438 #define SX1272_MC1_LOW_DATA_RATE_OPTIMIZE 0x01 // mandated for SF11 and SF12 00439 // transmit power configuration for RegPaConfig 00440 #define SX1272_PAC_PA_SELECT_PA_BOOST 0x80 00441 #define SX1272_PAC_PA_SELECT_RFIO_PIN 0x00 00442 00443 00444 // sx1276 RegModemConfig1 00445 #define SX1276_MC1_BW_125 0x70 00446 #define SX1276_MC1_BW_250 0x80 00447 #define SX1276_MC1_BW_500 0x90 00448 #define SX1276_MC1_CR_4_5 0x02 00449 #define SX1276_MC1_CR_4_6 0x04 00450 #define SX1276_MC1_CR_4_7 0x06 00451 #define SX1276_MC1_CR_4_8 0x08 00452 00453 #define SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01 00454 00455 // sx1276 RegModemConfig2 00456 #define SX1276_MC2_RX_PAYLOAD_CRCON 0x04 00457 00458 // sx1276 RegModemConfig3 00459 #define SX1276_MC3_LOW_DATA_RATE_OPTIMIZE 0x08 00460 #define SX1276_MC3_AGCAUTO 0x04 00461 00462 // preamble for lora networks (nibbles swapped) 00463 #define LORA_MAC_PREAMBLE 0x34 00464 00465 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1 0x0A 00466 #ifdef CFG_sx1276_radio 00467 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x70 00468 #elif CFG_sx1272_radio 00469 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x74 00470 #endif 00471 00472 00473 00474 // ---------------------------------------- 00475 // Constants for radio registers 00476 #define OPMODE_LORA 0x80 00477 #define OPMODE_MASK 0x07 00478 #define OPMODE_SLEEP 0x00 00479 #define OPMODE_STANDBY 0x01 00480 #define OPMODE_FSTX 0x02 00481 #define OPMODE_TX 0x03 00482 #define OPMODE_FSRX 0x04 00483 #define OPMODE_RX 0x05 00484 #define OPMODE_RX_SINGLE 0x06 00485 #define OPMODE_CAD 0x07 00486 00487 // ---------------------------------------- 00488 // Bits masking the corresponding IRQs from the radio 00489 #define IRQ_LORA_RXTOUT_MASK 0x80 00490 #define IRQ_LORA_RXDONE_MASK 0x40 00491 #define IRQ_LORA_CRCERR_MASK 0x20 00492 #define IRQ_LORA_HEADER_MASK 0x10 00493 #define IRQ_LORA_TXDONE_MASK 0x08 00494 #define IRQ_LORA_CDDONE_MASK 0x04 00495 #define IRQ_LORA_FHSSCH_MASK 0x02 00496 #define IRQ_LORA_CDDETD_MASK 0x01 00497 00498 #define IRQ_FSK1_MODEREADY_MASK 0x80 00499 #define IRQ_FSK1_RXREADY_MASK 0x40 00500 #define IRQ_FSK1_TXREADY_MASK 0x20 00501 #define IRQ_FSK1_PLLLOCK_MASK 0x10 00502 #define IRQ_FSK1_RSSI_MASK 0x08 00503 #define IRQ_FSK1_TIMEOUT_MASK 0x04 00504 #define IRQ_FSK1_PREAMBLEDETECT_MASK 0x02 00505 #define IRQ_FSK1_SYNCADDRESSMATCH_MASK 0x01 00506 #define IRQ_FSK2_FIFOFULL_MASK 0x80 00507 #define IRQ_FSK2_FIFOEMPTY_MASK 0x40 00508 #define IRQ_FSK2_FIFOLEVEL_MASK 0x20 00509 #define IRQ_FSK2_FIFOOVERRUN_MASK 0x10 00510 #define IRQ_FSK2_PACKETSENT_MASK 0x08 00511 #define IRQ_FSK2_PAYLOADREADY_MASK 0x04 00512 #define IRQ_FSK2_CRCOK_MASK 0x02 00513 #define IRQ_FSK2_LOWBAT_MASK 0x01 00514 00515 // ---------------------------------------- 00516 // DIO function mappings D0D1D2D3 00517 #define MAP_DIO0_LORA_RXDONE 0x00 // 00------ 00518 #define MAP_DIO0_LORA_TXDONE 0x40 // 01------ 00519 #define MAP_DIO1_LORA_RXTOUT 0x00 // --00---- 00520 #define MAP_DIO1_LORA_NOP 0x30 // --11---- 00521 #define MAP_DIO2_LORA_NOP 0xC0 // ----11-- 00522 00523 #define MAP_DIO0_FSK_READY 0x00 // 00------ (packet sent / payload ready) 00524 #define MAP_DIO1_FSK_NOP 0x30 // --11---- 00525 #define MAP_DIO2_FSK_TXNOP 0x04 // ----01-- 00526 #define MAP_DIO2_FSK_TIMEOUT 0x08 // ----10-- 00527 00528 00529 // FSK IMAGECAL defines 00530 #define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F 00531 #define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80 00532 #define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default 00533 00534 #define RF_IMAGECAL_IMAGECAL_MASK 0xBF 00535 #define RF_IMAGECAL_IMAGECAL_START 0x40 00536 00537 #define RF_IMAGECAL_IMAGECAL_RUNNING 0x20 00538 #define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default 00539 00540 00541 // RADIO STATE 00542 // (initialized by radio_init(), used by radio_rand1()) 00543 static u1_t randbuf[16]; 00544 00545 00546 #ifdef CFG_sx1276_radio 00547 #define LNA_RX_GAIN (0x20|0x1) 00548 #elif CFG_sx1272_radio 00549 #define LNA_RX_GAIN (0x20|0x03) 00550 #else 00551 #error Missing CFG_sx1272_radio/CFG_sx1276_radio 00552 #endif 00553 00554 #define RADIO_DBG 00555 #if defined(RADIO_DBG) 00556 DigitalOut txStateIo( PB_8 ); 00557 DigitalOut rxStateIo( PB_9 ); 00558 #endif 00559 00560 static void writeReg (u1_t addr, u1_t data ) { 00561 hal_pin_nss(0); 00562 hal_spi(addr | 0x80); 00563 hal_spi(data); 00564 hal_pin_nss(1); 00565 } 00566 00567 static u1_t readReg (u1_t addr) { 00568 hal_pin_nss(0); 00569 hal_spi(addr & 0x7F); 00570 u1_t val = hal_spi(0x00); 00571 hal_pin_nss(1); 00572 return val; 00573 } 00574 00575 static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) { 00576 hal_pin_nss(0); 00577 hal_spi(addr | 0x80); 00578 for (u1_t i=0; i<len; i++) { 00579 hal_spi(buf[i]); 00580 } 00581 hal_pin_nss(1); 00582 } 00583 00584 static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) { 00585 hal_pin_nss(0); 00586 hal_spi(addr & 0x7F); 00587 for (u1_t i=0; i<len; i++) { 00588 buf[i] = hal_spi(0x00); 00589 } 00590 hal_pin_nss(1); 00591 } 00592 00593 static void opmode (u1_t mode) { 00594 writeReg(RegOpMode, (readReg(RegOpMode) & ~OPMODE_MASK) | mode); 00595 } 00596 00597 static void opmodeLora() { 00598 u1_t u = OPMODE_LORA; 00599 #ifdef CFG_sx1276_radio 00600 u |= 0x8; // TBD: sx1276 high freq 00601 #endif 00602 writeReg(RegOpMode, u); 00603 } 00604 00605 static void opmodeFSK() { 00606 u1_t u = 0; 00607 #ifdef CFG_sx1276_radio 00608 u |= 0x8; // TBD: sx1276 high freq 00609 #endif 00610 writeReg(RegOpMode, u); 00611 } 00612 00613 // configure LoRa modem (cfg1, cfg2) 00614 static void configLoraModem () { 00615 sf_t sf = getSf(LMIC.rps); 00616 00617 #ifdef CFG_sx1276_radio 00618 u1_t mc1 = 0, mc2 = 0, mc3 = 0; 00619 00620 switch (getBw(LMIC.rps)) { 00621 case BW125: mc1 |= SX1276_MC1_BW_125; break; 00622 case BW250: mc1 |= SX1276_MC1_BW_250; break; 00623 case BW500: mc1 |= SX1276_MC1_BW_500; break; 00624 default: 00625 ASSERT(0); 00626 } 00627 switch( getCr(LMIC.rps) ) { 00628 case CR_4_5: mc1 |= SX1276_MC1_CR_4_5; break; 00629 case CR_4_6: mc1 |= SX1276_MC1_CR_4_6; break; 00630 case CR_4_7: mc1 |= SX1276_MC1_CR_4_7; break; 00631 case CR_4_8: mc1 |= SX1276_MC1_CR_4_8; break; 00632 default: 00633 ASSERT(0); 00634 } 00635 00636 if (getIh(LMIC.rps)) { 00637 mc1 |= SX1276_MC1_IMPLICIT_HEADER_MODE_ON; 00638 writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length 00639 } 00640 // set ModemConfig1 00641 writeReg(LORARegModemConfig1, mc1); 00642 00643 mc2 = (SX1272_MC2_SF7 + ((sf-1)<<4)); 00644 if (getNocrc(LMIC.rps) == 0) { 00645 mc2 |= SX1276_MC2_RX_PAYLOAD_CRCON; 00646 } 00647 writeReg(LORARegModemConfig2, mc2); 00648 00649 mc3 = SX1276_MC3_AGCAUTO; 00650 if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) { 00651 mc3 |= SX1276_MC3_LOW_DATA_RATE_OPTIMIZE; 00652 } 00653 writeReg(LORARegModemConfig3, mc3); 00654 #elif CFG_sx1272_radio 00655 u1_t mc1 = (getBw(LMIC.rps)<<6); 00656 00657 switch( getCr(LMIC.rps) ) { 00658 case CR_4_5: mc1 |= SX1272_MC1_CR_4_5; break; 00659 case CR_4_6: mc1 |= SX1272_MC1_CR_4_6; break; 00660 case CR_4_7: mc1 |= SX1272_MC1_CR_4_7; break; 00661 case CR_4_8: mc1 |= SX1272_MC1_CR_4_8; break; 00662 } 00663 00664 if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) { 00665 mc1 |= SX1272_MC1_LOW_DATA_RATE_OPTIMIZE; 00666 } 00667 00668 if (getNocrc(LMIC.rps) == 0) { 00669 mc1 |= SX1272_MC1_RX_PAYLOAD_CRCON; 00670 } 00671 00672 if (getIh(LMIC.rps)) { 00673 mc1 |= SX1272_MC1_IMPLICIT_HEADER_MODE_ON; 00674 writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length 00675 } 00676 // set ModemConfig1 00677 writeReg(LORARegModemConfig1, mc1); 00678 00679 // set ModemConfig2 (sf, AgcAutoOn=1 SymbTimeoutHi=00) 00680 writeReg(LORARegModemConfig2, (SX1272_MC2_SF7 + ((sf-1)<<4)) | 0x04); 00681 #else 00682 #error Missing CFG_sx1272_radio/CFG_sx1276_radio 00683 #endif /* CFG_sx1272_radio */ 00684 } 00685 00686 static void configChannel () { 00687 // set frequency: FQ = (FRF * 32 Mhz) / (2 ^ 19) 00688 u8_t frf = ((u8_t)LMIC.freq << 19) / 32000000; 00689 writeReg(RegFrfMsb, (u1_t)(frf>>16)); 00690 writeReg(RegFrfMid, (u1_t)(frf>> 8)); 00691 writeReg(RegFrfLsb, (u1_t)(frf>> 0)); 00692 } 00693 00694 00695 00696 static void configPower () { 00697 #ifdef CFG_sx1276_radio 00698 // no boost used for now 00699 s1_t pw = (s1_t)LMIC.txpow; 00700 if(pw >= 17) { 00701 pw = 15; 00702 } else if(pw < 2) { 00703 pw = 2; 00704 } 00705 // check board type for BOOST pin 00706 writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf))); 00707 writeReg(RegPaDac, readReg(RegPaDac)|0x4); 00708 00709 #elif CFG_sx1272_radio 00710 // set PA config (2-17 dBm using PA_BOOST) 00711 s1_t pw = (s1_t)LMIC.txpow; 00712 if(pw > 17) { 00713 pw = 17; 00714 } else if(pw < 2) { 00715 pw = 2; 00716 } 00717 writeReg(RegPaConfig, (u1_t)(0x80|(pw-2))); 00718 #else 00719 #error Missing CFG_sx1272_radio/CFG_sx1276_radio 00720 #endif /* CFG_sx1272_radio */ 00721 } 00722 00723 static void txfsk () { 00724 // select FSK modem (from sleep mode) 00725 writeReg(RegOpMode, 0x10); // FSK, BT=0.5 00726 ASSERT(readReg(RegOpMode) == 0x10); 00727 // enter standby mode (required for FIFO loading)) 00728 opmode(OPMODE_STANDBY); 00729 #if defined(RADIO_DBG) 00730 txStateIo = 0; 00731 rxStateIo = 0; 00732 #endif 00733 // set bitrate 00734 writeReg(FSKRegBitrateMsb, 0x02); // 50kbps 00735 writeReg(FSKRegBitrateLsb, 0x80); 00736 // set frequency deviation 00737 writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz 00738 writeReg(FSKRegFdevLsb, 0x99); 00739 // frame and packet handler settings 00740 writeReg(FSKRegPreambleMsb, 0x00); 00741 writeReg(FSKRegPreambleLsb, 0x05); 00742 writeReg(FSKRegSyncConfig, 0x12); 00743 writeReg(FSKRegPacketConfig1, 0xD0); 00744 writeReg(FSKRegPacketConfig2, 0x40); 00745 writeReg(FSKRegSyncValue1, 0xC1); 00746 writeReg(FSKRegSyncValue2, 0x94); 00747 writeReg(FSKRegSyncValue3, 0xC1); 00748 // configure frequency 00749 configChannel(); 00750 // configure output power 00751 configPower(); 00752 00753 // set the IRQ mapping DIO0=PacketSent DIO1=NOP DIO2=NOP 00754 writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TXNOP); 00755 00756 // initialize the payload size and address pointers 00757 writeReg(FSKRegPayloadLength, LMIC.dataLen+1); // (insert length byte into payload)) 00758 00759 // download length byte and buffer to the radio FIFO 00760 writeReg(RegFifo, LMIC.dataLen); 00761 writeBuf(RegFifo, LMIC.frame, LMIC.dataLen); 00762 00763 // enable antenna switch for TX 00764 hal_pin_rxtx(1); 00765 00766 // now we actually start the transmission 00767 opmode(OPMODE_TX); 00768 #if defined(RADIO_DBG) 00769 txStateIo = 1; 00770 #endif 00771 } 00772 00773 static void txlora () { 00774 // select LoRa modem (from sleep mode) 00775 //writeReg(RegOpMode, OPMODE_LORA); 00776 opmodeLora(); 00777 ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0); 00778 00779 // enter standby mode (required for FIFO loading)) 00780 opmode(OPMODE_STANDBY); 00781 #if defined(RADIO_DBG) 00782 txStateIo = 0; 00783 rxStateIo = 0; 00784 #endif 00785 // configure LoRa modem (cfg1, cfg2) 00786 configLoraModem(); 00787 // configure frequency 00788 configChannel(); 00789 // configure output power 00790 writeReg(RegPaRamp, (readReg(RegPaRamp) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec 00791 configPower(); 00792 // set sync word 00793 writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE); 00794 00795 // set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP 00796 writeReg(RegDioMapping1, MAP_DIO0_LORA_TXDONE|MAP_DIO1_LORA_NOP|MAP_DIO2_LORA_NOP); 00797 // clear all radio IRQ flags 00798 writeReg(LORARegIrqFlags, 0xFF); 00799 // mask all IRQs but TxDone 00800 writeReg(LORARegIrqFlagsMask, ~IRQ_LORA_TXDONE_MASK); 00801 00802 // initialize the payload size and address pointers 00803 writeReg(LORARegFifoTxBaseAddr, 0x00); 00804 writeReg(LORARegFifoAddrPtr, 0x00); 00805 writeReg(LORARegPayloadLength, LMIC.dataLen); 00806 00807 // download buffer to the radio FIFO 00808 writeBuf(RegFifo, LMIC.frame, LMIC.dataLen); 00809 00810 // enable antenna switch for TX 00811 hal_pin_rxtx(1); 00812 00813 // now we actually start the transmission 00814 opmode(OPMODE_TX); 00815 } 00816 00817 // start transmitter (buf=LMIC.frame, len=LMIC.dataLen) 00818 static void starttx () { 00819 ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP ); 00820 if(getSf(LMIC.rps) == FSK) { // FSK modem 00821 txfsk(); 00822 } else { // LoRa modem 00823 txlora(); 00824 } 00825 // the radio will go back to STANDBY mode as soon as the TX is finished 00826 // the corresponding IRQ will inform us about completion. 00827 } 00828 00829 enum { RXMODE_SINGLE, RXMODE_SCAN, RXMODE_RSSI }; 00830 00831 static const u1_t rxlorairqmask[] = { 00832 [RXMODE_SINGLE] = IRQ_LORA_RXDONE_MASK|IRQ_LORA_RXTOUT_MASK, 00833 [RXMODE_SCAN] = IRQ_LORA_RXDONE_MASK, 00834 [RXMODE_RSSI] = 0x00, 00835 }; 00836 00837 // start LoRa receiver (time=LMIC.rxtime, timeout=LMIC.rxsyms, result=LMIC.frame[LMIC.dataLen]) 00838 static void rxlora (u1_t rxmode) { 00839 // select LoRa modem (from sleep mode) 00840 opmodeLora(); 00841 ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0); 00842 // enter standby mode (warm up)) 00843 opmode(OPMODE_STANDBY); 00844 #if defined(RADIO_DBG) 00845 txStateIo = 0; 00846 rxStateIo = 0; 00847 #endif 00848 // don't use MAC settings at startup 00849 if(rxmode == RXMODE_RSSI) { // use fixed settings for rssi scan 00850 writeReg(LORARegModemConfig1, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1); 00851 writeReg(LORARegModemConfig2, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2); 00852 } else { // single or continuous rx mode 00853 // configure LoRa modem (cfg1, cfg2) 00854 configLoraModem(); 00855 // configure frequency 00856 configChannel(); 00857 } 00858 // set LNA gain 00859 writeReg(RegLna, LNA_RX_GAIN); 00860 // set max payload size 00861 writeReg(LORARegPayloadMaxLength, 64); 00862 // use inverted I/Q signal (prevent mote-to-mote communication) 00863 writeReg(LORARegInvertIQ, readReg(LORARegInvertIQ)|(1<<6)); 00864 // set symbol timeout (for single rx) 00865 writeReg(LORARegSymbTimeoutLsb, LMIC.rxsyms); 00866 // set sync word 00867 writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE); 00868 00869 // configure DIO mapping DIO0=RxDone DIO1=RxTout DIO2=NOP 00870 writeReg(RegDioMapping1, MAP_DIO0_LORA_RXDONE|MAP_DIO1_LORA_RXTOUT|MAP_DIO2_LORA_NOP); 00871 // clear all radio IRQ flags 00872 writeReg(LORARegIrqFlags, 0xFF); 00873 // enable required radio IRQs 00874 writeReg(LORARegIrqFlagsMask, ~rxlorairqmask[rxmode]); 00875 00876 // enable antenna switch for RX 00877 hal_pin_rxtx(0); 00878 00879 // now instruct the radio to receive 00880 if (rxmode == RXMODE_SINGLE) { // single rx 00881 hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time 00882 opmode(OPMODE_RX_SINGLE); 00883 #if defined(RADIO_DBG) 00884 rxStateIo = 1; 00885 #endif 00886 } else { // continous rx (scan or rssi) 00887 opmode(OPMODE_RX); 00888 #if defined(RADIO_DBG) 00889 rxStateIo = 1; 00890 #endif 00891 } 00892 } 00893 00894 static void rxfsk (u1_t rxmode) { 00895 // only single rx (no continuous scanning, no noise sampling) 00896 ASSERT( rxmode == RXMODE_SINGLE ); 00897 // select FSK modem (from sleep mode) 00898 //writeReg(RegOpMode, 0x00); // (not LoRa) 00899 opmodeFSK(); 00900 ASSERT((readReg(RegOpMode) & OPMODE_LORA) == 0); 00901 // enter standby mode (warm up)) 00902 opmode(OPMODE_STANDBY); 00903 #if defined(RADIO_DBG) 00904 txStateIo = 0; 00905 rxStateIo = 0; 00906 #endif 00907 // configure frequency 00908 configChannel(); 00909 // set LNA gain 00910 //writeReg(RegLna, 0x20|0x03); // max gain, boost enable 00911 writeReg(RegLna, LNA_RX_GAIN); 00912 // configure receiver 00913 writeReg(FSKRegRxConfig, 0x1E); // AFC auto, AGC, trigger on preamble?!? 00914 // set receiver bandwidth 00915 writeReg(FSKRegRxBw, 0x0B); // 50kHz SSb 00916 // set AFC bandwidth 00917 writeReg(FSKRegAfcBw, 0x12); // 83.3kHz SSB 00918 // set preamble detection 00919 writeReg(FSKRegPreambleDetect, 0xAA); // enable, 2 bytes, 10 chip errors 00920 // set sync config 00921 writeReg(FSKRegSyncConfig, 0x12); // no auto restart, preamble 0xAA, enable, fill FIFO, 3 bytes sync 00922 // set packet config 00923 writeReg(FSKRegPacketConfig1, 0xD8); // var-length, whitening, crc, no auto-clear, no adr filter 00924 writeReg(FSKRegPacketConfig2, 0x40); // packet mode 00925 // set sync value 00926 writeReg(FSKRegSyncValue1, 0xC1); 00927 writeReg(FSKRegSyncValue2, 0x94); 00928 writeReg(FSKRegSyncValue3, 0xC1); 00929 // set preamble timeout 00930 writeReg(FSKRegRxTimeout2, 0xFF);//(LMIC.rxsyms+1)/2); 00931 // set bitrate 00932 writeReg(FSKRegBitrateMsb, 0x02); // 50kbps 00933 writeReg(FSKRegBitrateLsb, 0x80); 00934 // set frequency deviation 00935 writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz 00936 writeReg(FSKRegFdevLsb, 0x99); 00937 00938 // configure DIO mapping DIO0=PayloadReady DIO1=NOP DIO2=TimeOut 00939 writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TIMEOUT); 00940 00941 // enable antenna switch for RX 00942 hal_pin_rxtx(0); 00943 00944 // now instruct the radio to receive 00945 hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time 00946 opmode(OPMODE_RX); // no single rx mode available in FSK 00947 #if defined(RADIO_DBG) 00948 rxStateIo = 1; 00949 #endif 00950 } 00951 00952 static void startrx (u1_t rxmode) { 00953 ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP ); 00954 if(getSf(LMIC.rps) == FSK) { // FSK modem 00955 rxfsk(rxmode); 00956 } else { // LoRa modem 00957 rxlora(rxmode); 00958 } 00959 // the radio will go back to STANDBY mode as soon as the RX is finished 00960 // or timed out, and the corresponding IRQ will inform us about completion. 00961 } 00962 00963 // get random seed from wideband noise rssi 00964 void radio_init () { 00965 hal_disableIRQs(); 00966 00967 // manually reset radio 00968 #ifdef CFG_sx1276_radio 00969 hal_pin_rst(0); // drive RST pin low 00970 #else 00971 hal_pin_rst(1); // drive RST pin high 00972 #endif 00973 hal_waitUntil(os_getTime()+ms2osticks(1)); // wait >100us 00974 hal_pin_rst(2); // configure RST pin floating! 00975 hal_waitUntil(os_getTime()+ms2osticks(5)); // wait 5ms 00976 00977 opmode(OPMODE_SLEEP); 00978 #if defined(RADIO_DBG) 00979 txStateIo = 0; 00980 rxStateIo = 0; 00981 #endif 00982 // some sanity checks, e.g., read version number 00983 u1_t v = readReg(RegVersion); 00984 #ifdef CFG_sx1276_radio 00985 ASSERT(v == 0x12 ); 00986 #elif CFG_sx1272_radio 00987 ASSERT(v == 0x22); 00988 #else 00989 #error Missing CFG_sx1272_radio/CFG_sx1276_radio 00990 #endif 00991 // seed 15-byte randomness via noise rssi 00992 rxlora(RXMODE_RSSI); 00993 while( (readReg(RegOpMode) & OPMODE_MASK) != OPMODE_RX ); // continuous rx 00994 for(int i=1; i<16; i++) { 00995 for(int j=0; j<8; j++) { 00996 u1_t b; // wait for two non-identical subsequent least-significant bits 00997 while( (b = readReg(LORARegRssiWideband) & 0x01) == (readReg(LORARegRssiWideband) & 0x01) ); 00998 randbuf[i] = (randbuf[i] << 1) | b; 00999 } 01000 } 01001 randbuf[0] = 16; // set initial index 01002 01003 #ifdef CFG_sx1276mb1_board 01004 // chain calibration 01005 writeReg(RegPaConfig, 0); 01006 01007 // Launch Rx chain calibration for LF band 01008 writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START); 01009 while((readReg(FSKRegImageCal)&RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING){ ; } 01010 01011 // Sets a Frequency in HF band 01012 u4_t frf = 868000000; 01013 writeReg(RegFrfMsb, (u1_t)(frf>>16)); 01014 writeReg(RegFrfMid, (u1_t)(frf>> 8)); 01015 writeReg(RegFrfLsb, (u1_t)(frf>> 0)); 01016 01017 // Launch Rx chain calibration for HF band 01018 writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START); 01019 while((readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING) { ; } 01020 #endif /* CFG_sx1276mb1_board */ 01021 01022 opmode(OPMODE_SLEEP); 01023 #if defined(RADIO_DBG) 01024 txStateIo = 0; 01025 rxStateIo = 0; 01026 #endif 01027 hal_enableIRQs(); 01028 } 01029 01030 // return next random byte derived from seed buffer 01031 // (buf[0] holds index of next byte to be returned) 01032 u1_t radio_rand1 () { 01033 u1_t i = randbuf[0]; 01034 ASSERT( i != 0 ); 01035 if( i==16 ) { 01036 os_aes(AES_ENC, randbuf, 16); // encrypt seed with any key 01037 i = 0; 01038 } 01039 u1_t v = randbuf[i++]; 01040 randbuf[0] = i; 01041 return v; 01042 } 01043 01044 u1_t radio_rssi () { 01045 hal_disableIRQs(); 01046 u1_t r = readReg(LORARegRssiValue); 01047 hal_enableIRQs(); 01048 return r; 01049 } 01050 01051 static const u2_t LORA_RXDONE_FIXUP[] = { 01052 [FSK] = us2osticks(0), // ( 0 ticks) 01053 [SF7] = us2osticks(0), // ( 0 ticks) 01054 [SF8] = us2osticks(1648), // ( 54 ticks) 01055 [SF9] = us2osticks(3265), // ( 107 ticks) 01056 [SF10] = us2osticks(7049), // ( 231 ticks) 01057 [SF11] = us2osticks(13641), // ( 447 ticks) 01058 [SF12] = us2osticks(31189), // (1022 ticks) 01059 }; 01060 01061 // called by hal ext IRQ handler 01062 // (radio goes to stanby mode after tx/rx operations) 01063 void radio_irq_handler (u1_t dio) { 01064 ostime_t now = os_getTime(); 01065 if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem 01066 u1_t flags = readReg(LORARegIrqFlags); 01067 if( flags & IRQ_LORA_TXDONE_MASK ) { 01068 // save exact tx time 01069 LMIC.txend = now - us2osticks(43); // TXDONE FIXUP 01070 } else if( flags & IRQ_LORA_RXDONE_MASK ) { 01071 // save exact rx time 01072 if(getBw(LMIC.rps) == BW125) { 01073 now -= LORA_RXDONE_FIXUP[getSf(LMIC.rps)]; 01074 } 01075 LMIC.rxtime = now; 01076 // read the PDU and inform the MAC that we received something 01077 LMIC.dataLen = (readReg(LORARegModemConfig1) & SX1272_MC1_IMPLICIT_HEADER_MODE_ON) ? 01078 readReg(LORARegPayloadLength) : readReg(LORARegRxNbBytes); 01079 // set FIFO read address pointer 01080 writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr)); 01081 // now read the FIFO 01082 readBuf(RegFifo, LMIC.frame, LMIC.dataLen); 01083 // read rx quality parameters 01084 LMIC.snr = readReg(LORARegPktSnrValue); // SNR [dB] * 4 01085 LMIC.rssi = readReg(LORARegPktRssiValue) - 125 + 64; // RSSI [dBm] (-196...+63) 01086 } else if( flags & IRQ_LORA_RXTOUT_MASK ) { 01087 // indicate timeout 01088 LMIC.dataLen = 0; 01089 } 01090 // mask all radio IRQs 01091 writeReg(LORARegIrqFlagsMask, 0xFF); 01092 // clear radio IRQ flags 01093 writeReg(LORARegIrqFlags, 0xFF); 01094 } else { // FSK modem 01095 u1_t flags1 = readReg(FSKRegIrqFlags1); 01096 u1_t flags2 = readReg(FSKRegIrqFlags2); 01097 if( flags2 & IRQ_FSK2_PACKETSENT_MASK ) { 01098 // save exact tx time 01099 LMIC.txend = now; 01100 } else if( flags2 & IRQ_FSK2_PAYLOADREADY_MASK ) { 01101 // save exact rx time 01102 LMIC.rxtime = now; 01103 // read the PDU and inform the MAC that we received something 01104 LMIC.dataLen = readReg(FSKRegPayloadLength); 01105 // now read the FIFO 01106 readBuf(RegFifo, LMIC.frame, LMIC.dataLen); 01107 // read rx quality parameters 01108 LMIC.snr = 0; // determine snr 01109 LMIC.rssi = 0; // determine rssi 01110 } else if( flags1 & IRQ_FSK1_TIMEOUT_MASK ) { 01111 // indicate timeout 01112 LMIC.dataLen = 0; 01113 } else { 01114 while(1); 01115 } 01116 } 01117 // go from stanby to sleep 01118 opmode(OPMODE_SLEEP); 01119 #if defined(RADIO_DBG) 01120 txStateIo = 0; 01121 rxStateIo = 0; 01122 #endif 01123 // run os job (use preset func ptr) 01124 os_setCallback(&LMIC.osjob, LMIC.osjob.func); 01125 } 01126 01127 void os_radio (u1_t mode) { 01128 hal_disableIRQs(); 01129 switch (mode) { 01130 case RADIO_RST: 01131 // put radio to sleep 01132 opmode(OPMODE_SLEEP); 01133 #if defined(RADIO_DBG) 01134 txStateIo = 0; 01135 rxStateIo = 0; 01136 #endif 01137 break; 01138 01139 case RADIO_TX: 01140 // transmit frame now 01141 starttx(); // buf=LMIC.frame, len=LMIC.dataLen 01142 #if defined(RADIO_DBG) 01143 txStateIo = 1; 01144 #endif 01145 break; 01146 01147 case RADIO_RX: 01148 // receive frame now (exactly at rxtime) 01149 startrx(RXMODE_SINGLE); // buf=LMIC.frame, time=LMIC.rxtime, timeout=LMIC.rxsyms 01150 #if defined(RADIO_DBG) 01151 rxStateIo = 1; 01152 #endif 01153 break; 01154 01155 case RADIO_RXON: 01156 // start scanning for beacon now 01157 startrx(RXMODE_SCAN); // buf=LMIC.frame 01158 #if defined(RADIO_DBG) 01159 rxStateIo = 1; 01160 #endif 01161 break; 01162 } 01163 hal_enableIRQs(); 01164 } 01165 01166 #endif // USE_SMTC_RADIO_DRIVER
Generated on Wed Jul 13 2022 00:34:16 by 1.7.2