LMIC lib Lora OTA device for Everynet

Fork of LMiC-10secs by Alcatel-Lucent IoT Development

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers radio.cpp Source File

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