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