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