first test

Dependents:   LoRaWAN-lmic-app_tjm

Fork of LMiC by Semtech

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 #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