This code holds the complete demo set for the sx1280: PingPong, PER and Ranging Outdoor demo application. >>>>> This code MUST run on the mbed library release 127 or everything will be painfully slow.

Dependencies:   mbed SX1280Lib DmTftLibrary

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DemoApplication.cpp Source File

DemoApplication.cpp

00001 /*
00002   ______                              _
00003  / _____)             _              | |
00004 ( (____  _____ ____ _| |_ _____  ____| |__
00005  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00006  _____) ) ____| | | || |_| ____( (___| | | |
00007 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00008     (C)2016 Semtech
00009 
00010 Description: PingPong, PER and Ranging demo implementation.
00011 
00012 Maintainer: Gregory Cristian & Gilbert Menth
00013 */
00014 
00015 #include "mbed.h"
00016 #include <math.h>
00017 #include "radio.h"
00018 #include "sx1280-hal.h"
00019 #include "Eeprom.h"
00020 #include "DemoApplication.h"
00021 #include "FreqLUT.h"
00022 #include "RangingCorrection.h"
00023 
00024 #define max(a,b) \
00025    ({ __typeof__ (a) _a = (a); \
00026        __typeof__ (b) _b = (b); \
00027      _a > _b ? _a : _b; })
00028    
00029 double t0 =       -0.016432807883697;                         // X0
00030 double t1 =       0.323147003165358;                          // X1
00031 double t2 =       0.014922061351196;                          // X1^2
00032 double t3 =       0.000137832006285;                          // X1^3
00033 double t4 =       0.536873856625399;                          // X2
00034 double t5 =       0.040890089178579;                          // X2^2
00035 double t6 =       -0.001074801048732;                         // X2^3
00036 double t7 =       0.000009240142234;                          // X2^4
00037 
00038 
00039 double p[8] = { 0,
00040                 -4.1e-9,
00041                 1.03e-7,
00042                 1.971e-5,
00043                 -0.00107,
00044                 0.018757,
00045                 0.869171,
00046                 3.072450 };
00047 
00048 /*!
00049  * \brief Defines the local payload buffer size
00050  */
00051 #define BUFFER_SIZE                     255
00052 
00053 /*!
00054  * \brief Defines the size of the token defining message type in the payload
00055  *        cf. above.
00056  */
00057 #define PINGPONG_SIZE                   4
00058 #define PER_SIZE                        3
00059 
00060 /*!
00061  * \brief Define time used in PingPong demo to synch with cycle
00062  * RX_TX_INTER_PACKET_DELAY is the free time between each cycle (time reserve)
00063  */
00064 #define RX_TX_INTER_PACKET_DELAY        150  // ms
00065 #define RX_TX_TRANSITION_WAIT           15   // ms
00066 
00067 /*!
00068  * \brief Size of ticks (used for Tx and Rx timeout)
00069  */
00070 #define RX_TIMEOUT_TICK_SIZE            RADIO_TICK_SIZE_1000_US
00071 
00072 #define RNG_TIMER_MS                    384 // ms
00073 #define RNG_COM_TIMEOUT                 100 // ms
00074 
00075 /*!
00076  * \brief Ranging raw factors
00077  *                                  SF5     SF6     SF7     SF8     SF9     SF10
00078  */
00079 const uint16_t RNG_CALIB_0400[] = { 10299,  10271,  10244,  10242,  10230,  10246  };
00080 const uint16_t RNG_CALIB_0800[] = { 11486,  11474,  11453,  11426,  11417,  11401  };
00081 const uint16_t RNG_CALIB_1600[] = { 13308,  13493,  13528,  13515,  13430,  13376  };
00082 const double   RNG_FGRAD_0400[] = { -0.148, -0.214, -0.419, -0.853, -1.686, -3.423 };
00083 const double   RNG_FGRAD_0800[] = { -0.041, -0.811, -0.218, -0.429, -0.853, -1.737 };
00084 const double   RNG_FGRAD_1600[] = { 0.103,  -0.041, -0.101, -0.211, -0.424, -0.87  };
00085 
00086 /*!
00087  * \brief Define the possible message type for the Ping-Pong and PER apps
00088  */
00089 const uint8_t PingMsg[] = "PING";
00090 const uint8_t PongMsg[] = "PONG";
00091 const uint8_t PerMsg[]  = "PER";
00092 
00093 /*!
00094  * \brief Buffer and its size
00095  */
00096 uint8_t BufferSize = BUFFER_SIZE;
00097 uint8_t Buffer[BUFFER_SIZE];
00098 
00099 static uint8_t CurrentChannel;
00100 static uint16_t MeasuredChannels;
00101 int RngResultIndex;
00102 double RawRngResults[DEMO_RNG_CHANNELS_COUNT_MAX];
00103 double RssiRng[DEMO_RNG_CHANNELS_COUNT_MAX];
00104 
00105 
00106 /*!
00107  * \brief Function to be executed on Radio Tx Done event
00108  */
00109 void OnTxDone( void );
00110 
00111 /*!
00112  * \brief Function to be executed on Radio Rx Done event
00113  */
00114 void OnRxDone( void );
00115 
00116 /*!
00117  * \brief Function executed on Radio Tx Timeout event
00118  */
00119 void OnTxTimeout( void );
00120 
00121 /*!
00122  * \brief Function executed on Radio Rx Timeout event
00123  */
00124 void OnRxTimeout( void );
00125 
00126 /*!
00127  * \brief Function executed on Radio Rx Error event
00128  */
00129 void OnRxError( IrqErrorCode_t );
00130 
00131 /*!
00132  * \brief Function executed on Radio Rx Error event
00133  */
00134 void OnRangingDone( IrqRangingCode_t );
00135 
00136 /*!
00137  * \brief All the callbacks are stored in a structure
00138  */
00139 RadioCallbacks_t Callbacks =
00140 {
00141     &OnTxDone,        // txDone
00142     &OnRxDone,        // rxDone
00143     NULL,             // syncWordDone
00144     NULL,             // headerDone
00145     &OnTxTimeout,     // txTimeout
00146     &OnRxTimeout,     // rxTimeout
00147     &OnRxError,       // rxError
00148     &OnRangingDone,   // rangingDone
00149     NULL,             // cadDone
00150 };
00151 
00152 /*!
00153  * \brief Define IO and callbacks for radio
00154  * mosi, miso, sclk, nss, busy, dio1, dio2, dio3, rst, callbacks
00155  */
00156 SX1280Hal Radio( D11, D12, D13, D7, D3, D5, NC, NC, A0, &Callbacks );
00157 
00158 /*!
00159  * \brief Control the Antenna Diversity switch
00160  */
00161 DigitalOut ANT_SW( A3 );
00162 
00163 /*!
00164  * \brief Tx LED toggling on transmition success
00165  */
00166 DigitalOut TX_LED( A4 );
00167 
00168 /*!
00169  * \brief Rx LED toggling on reception success
00170  */
00171 DigitalOut RX_LED( A5 );
00172 
00173 /*!
00174  * \brief Mask of IRQs
00175  */
00176 uint16_t IrqMask = 0x0000;
00177 
00178 /*!
00179  * \brief Locals parameters and status for radio API
00180  * NEED TO BE OPTIMIZED, COPY OF STUCTURE ALREADY EXISTING
00181  */
00182 PacketParams_t PacketParams;
00183 PacketStatus_t PacketStatus;
00184 ModulationParams_t ModulationParams;
00185 
00186 /*!
00187  * \brief Flag to indicate if the demo is already running
00188  */
00189 static bool DemoRunning = false;
00190 
00191 /*!
00192  * \brief Flag holding the current internal state of the demo application
00193  */
00194 static uint8_t DemoInternalState = APP_IDLE;
00195 
00196 /*!
00197  * \brief Ticker for master to synch Tx frames. Flags for PER and PingPong demo
00198  * for Synch TX in cycle.
00199  */
00200 Ticker SendNextPacket;
00201 static bool SendNext = false;
00202 
00203 /*!
00204  * \brief Ticker for slave to synch Tx frames. Flags for PER and PingPong demo
00205  * for Synch RX in cycle.
00206  */
00207 Ticker ReceiveNextPacket;
00208 static bool ReceiveNext = false;
00209 
00210 /*!
00211  * \brief Hold last Rx packet number to compute PER in PER and PingPong demo
00212  */
00213 static uint32_t PacketRxSequence = 0;
00214 static uint32_t PacketRxSequencePrev = 0;
00215 
00216 
00217 void SetAntennaSwitch( void );
00218 void LedBlink( void );
00219 void InitializeDemoParameters( uint8_t modulation );
00220 uint16_t GetTimeOnAir( uint8_t modulation );
00221 void SendNextPacketEvent( void );
00222 void ReceiveNextPacketEvent( void );
00223 uint8_t CheckDistance( void );
00224 
00225 // **************************     RF Test Demo    ******************************
00226 // *                                                                           *
00227 // *                                                                           *
00228 // *                                                                           *
00229 // *****************************************************************************
00230 
00231 uint8_t RunDemoSleepMode( void )
00232 {
00233     SleepParams_t SleepParam;
00234 
00235     if( Eeprom.EepromData.DemoSettings.HoldDemo == true )
00236     {
00237         return 0;
00238     }
00239     if( DemoRunning == false )
00240     {
00241         DemoRunning = true;
00242         InitializeDemoParameters( PACKET_TYPE_LORA );
00243         TX_LED = 0;
00244         RX_LED = 0;
00245         SleepParam.WakeUpRTC = 0;                    //!< Get out of sleep mode if wakeup signal received from RTC
00246         SleepParam.InstructionRamRetention = 0;      //!< InstructionRam is conserved during sleep
00247         SleepParam.DataBufferRetention = 0;          //!< Data buffer is conserved during sleep
00248         SleepParam.DataRamRetention = 0;             //!< Data ram is conserved during sleep
00249         Radio.SetSleep( SleepParam );
00250     }
00251     else
00252     {
00253         LedBlink( );
00254     }
00255     return 0;
00256 }
00257 
00258 uint8_t RunDemoStandbyRcMode( void )
00259 {
00260     if( Eeprom.EepromData.DemoSettings.HoldDemo == true )
00261     {
00262         return 0;
00263     }
00264     if( DemoRunning == false )
00265     {
00266         DemoRunning = true;
00267         InitializeDemoParameters( PACKET_TYPE_LORA );
00268         TX_LED = 0;
00269         RX_LED = 0;
00270         Radio.SetRegulatorMode( ( RadioRegulatorModes_t )Eeprom.EepromData.DemoSettings.RadioPowerMode );
00271         Radio.SetStandby( STDBY_RC );
00272         DemoRunning = true;
00273     }
00274     else
00275     {
00276         LedBlink( );
00277     }
00278     return 0;
00279 }
00280 
00281 uint8_t RunDemoStandbyXoscMode( void )
00282 {
00283     if( Eeprom.EepromData.DemoSettings.HoldDemo == true )
00284     {
00285         return 0;
00286     }
00287     if( DemoRunning == false )
00288     {
00289         DemoRunning = true;
00290         InitializeDemoParameters( PACKET_TYPE_LORA );
00291         TX_LED = 0;
00292         RX_LED = 0;
00293         Radio.SetRegulatorMode( ( RadioRegulatorModes_t )Eeprom.EepromData.DemoSettings.RadioPowerMode );
00294         Radio.SetStandby( STDBY_XOSC );
00295         DemoRunning = true;
00296     }
00297     else
00298     {
00299         LedBlink( );
00300     }
00301     return 0;
00302 }
00303 
00304 uint8_t RunDemoTxCw( void )
00305 {
00306     if( Eeprom.EepromData.DemoSettings.HoldDemo == true )
00307     {
00308         return 0;
00309     }
00310     if( DemoRunning == false )
00311     {
00312         DemoRunning = true;
00313         InitializeDemoParameters( PACKET_TYPE_LORA );
00314         TX_LED = 0;
00315         RX_LED = 0;
00316         SetAntennaSwitch( );
00317         Radio.SetStandby( STDBY_RC );
00318         Radio.SetRegulatorMode( ( RadioRegulatorModes_t )Eeprom.EepromData.DemoSettings.RadioPowerMode );
00319         Radio.SetRfFrequency( Eeprom.EepromData.DemoSettings.Frequency );
00320         Radio.SetTxParams( Eeprom.EepromData.DemoSettings.TxPower, RADIO_RAMP_20_US );
00321         Radio.SetTxContinuousWave( );
00322         DemoRunning = true;
00323     }
00324     else
00325     {
00326         LedBlink( );
00327     }
00328     return 0;
00329 }
00330 
00331 uint8_t RunDemoTxContinuousModulation( void )
00332 {
00333     uint8_t localPayloadSize = 250;
00334     uint8_t i = 0;
00335 
00336     if( Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_RANGING )
00337     {
00338         Eeprom.EepromData.DemoSettings.ModulationType = PACKET_TYPE_LORA;
00339     }
00340     if( Eeprom.EepromData.DemoSettings.HoldDemo == true )
00341     {
00342         return 0;
00343     }
00344 
00345     if( Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_FLRC )
00346     {
00347         localPayloadSize = 120; // Encoded in 4/8 so 240 bytes in total
00348     }
00349 
00350     Radio.ProcessIrqs( );
00351 
00352     if( DemoRunning == false )
00353     {
00354         DemoRunning = true;
00355         InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType );
00356         TX_LED = 0;
00357         RX_LED = 0;
00358         IrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
00359         Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00360         for( i = 0; i < localPayloadSize; i++ )
00361         {
00362             Buffer[i] = ( uint8_t )rand( );
00363         }
00364 //        Radio.SetAutoFS( true ); // no need to relock the PLL between packets
00365         Radio.SendPayload( Buffer, localPayloadSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, 10000 } );
00366         DemoInternalState = APP_IDLE;
00367     }
00368     else
00369     {
00370         switch( DemoInternalState )
00371         {
00372             case APP_RX:
00373                 break;
00374 
00375             case APP_TX:
00376                 DemoInternalState = APP_IDLE;
00377                 LedBlink( );
00378                 // Send the next frame
00379                 IrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
00380                 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00381                 for( i = 0; i < localPayloadSize; i++ )
00382                 {
00383                     Buffer[i] = ( uint8_t )rand( );
00384                 }
00385 //                Radio.SetAutoFS( true ); // no need to relock the PLL between packets
00386                 Radio.SendPayload( Buffer, localPayloadSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, 0xFFFF } );
00387                 break;
00388 
00389             case APP_RX_TIMEOUT:
00390                 DemoInternalState = APP_IDLE;
00391                 break;
00392 
00393             case APP_RX_ERROR:
00394                 DemoInternalState = APP_IDLE;
00395                 break;
00396 
00397             case APP_TX_TIMEOUT:
00398                 DemoInternalState = APP_IDLE; 
00399                 break;
00400 
00401             case APP_IDLE:
00402                 break;
00403 
00404             default:
00405                 break;
00406         }
00407     }
00408     return 0;
00409 }
00410 
00411 // *************************       PER Demo       ******************************
00412 // *                                                                           *
00413 // *                                                                           *
00414 // *                                                                           *
00415 // *****************************************************************************
00416 uint8_t RunDemoApplicationPer( void )
00417 {
00418     uint8_t i = 0;
00419     uint8_t refreshDisplay = 0;
00420     static uint8_t CurrentChannel;
00421 
00422     if( Eeprom.EepromData.DemoSettings.HoldDemo == true )
00423     {
00424         return 0;
00425     }
00426 
00427     if( DemoRunning == false )
00428     {
00429         DemoRunning = true;
00430         CurrentChannel = 0;
00431 
00432 #ifdef PRINT_DEBUG
00433         printf( "Start RunDemoApplicationPer\n\r" );
00434 #endif
00435 
00436         TX_LED = 0;
00437         RX_LED = 0;
00438         SetAntennaSwitch( );
00439         Eeprom.EepromData.DemoSettings.CntPacketTx    = 0;
00440         Eeprom.EepromData.DemoSettings.CntPacketRxOK  = 0;
00441         Eeprom.EepromData.DemoSettings.CntPacketRxKO  = 0;
00442         Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0;
00443 
00444         InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType );
00445 
00446         UpdateRadioFrequency( Channels[CurrentChannel] );
00447         Radio.SetRfFrequency( Channels[CurrentChannel] );
00448 
00449         Eeprom.EepromData.DemoSettings.TimeOnAir = GetTimeOnAir( Eeprom.EepromData.DemoSettings.ModulationType );
00450 
00451         if( Eeprom.EepromData.DemoSettings.Entity == MASTER )
00452         {
00453             SendNextPacket.attach_us( &SendNextPacketEvent, ( ( uint32_t )( Eeprom.EepromData.DemoSettings.TimeOnAir + RX_TX_INTER_PACKET_DELAY ) ) * 1000 );
00454             DemoInternalState = APP_TX;
00455         }
00456         else
00457         {
00458             IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT;
00459             Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00460             // Rx Single without timeout for the start
00461             Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, 0x0000 } );
00462             DemoInternalState = APP_IDLE;
00463         }
00464     }
00465 
00466     Radio.ProcessIrqs( );
00467 
00468     if( Eeprom.EepromData.DemoSettings.MaxNumPacket > 0 ) // != Infinite
00469     {
00470         if( ( Eeprom.EepromData.DemoSettings.CntPacketRxOK + \
00471               Eeprom.EepromData.DemoSettings.CntPacketRxKO + \
00472               Eeprom.EepromData.DemoSettings.RxTimeOutCount) >= \
00473             Eeprom.EepromData.DemoSettings.MaxNumPacket )
00474         {
00475             RX_LED = 0;
00476             TX_LED = 0;
00477             DemoInternalState = APP_IDLE;
00478             Radio.SetStandby( STDBY_RC );
00479             SendNextPacket.detach( );
00480             ReceiveNextPacket.detach( );
00481             Eeprom.EepromData.DemoSettings.HoldDemo = true;
00482             refreshDisplay = 1;
00483         }
00484     }
00485 
00486     switch( DemoInternalState )
00487     {
00488         case PER_TX_START:
00489             Eeprom.EepromData.DemoSettings.CntPacketTx++;
00490             DemoInternalState = APP_IDLE;
00491 
00492             Buffer[0] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 24 ) & 0xFF;
00493             Buffer[1] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 16 ) & 0xFF;
00494             Buffer[2] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 8 )  & 0xFF;
00495             Buffer[3] = Eeprom.EepromData.DemoSettings.CntPacketTx & 0xFF;
00496             Buffer[4] = PerMsg[0];
00497             Buffer[5] = PerMsg[1];
00498             Buffer[6] = PerMsg[2];
00499             for( i = 7; i < Eeprom.EepromData.DemoSettings.PayloadLength; i++ )
00500             {
00501                 Buffer[i] = i;
00502             }
00503             TX_LED = !TX_LED;
00504             IrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
00505 
00506             UpdateRadioFrequency( Channels[CurrentChannel] );
00507             Radio.SetRfFrequency( Channels[CurrentChannel] );
00508 
00509             Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00510             Radio.SendPayload( Buffer, Eeprom.EepromData.DemoSettings.PayloadLength, 
00511                                ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, Eeprom.EepromData.DemoSettings.TimeOnAir << 1 } );
00512             if( CurrentChannel < ( CHANNELS - 1 ) )
00513             {
00514                 CurrentChannel++;
00515             }
00516             else
00517             {
00518                 CurrentChannel = 0;
00519             }
00520             break;
00521 
00522         case PER_RX_START:
00523             UpdateRadioFrequency( Channels[CurrentChannel] );
00524             Radio.SetRfFrequency( Channels[CurrentChannel] );
00525             IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT;
00526             Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00527             Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, 0xFFFF } );
00528             DemoInternalState = APP_IDLE;
00529             break;
00530 
00531         case APP_TX:
00532             if( SendNext == true )
00533             {
00534                 SendNext = false;
00535                 if( ( Eeprom.EepromData.DemoSettings.MaxNumPacket == 0 ) || 
00536                     ( Eeprom.EepromData.DemoSettings.CntPacketTx < Eeprom.EepromData.DemoSettings.MaxNumPacket ) )
00537                 {
00538                     DemoInternalState = PER_TX_START;  // send next
00539                     refreshDisplay = 1;
00540                 }
00541                 else    // MaxNumPacket sent -> end of demo
00542                 {
00543                     RX_LED = 0;
00544                     TX_LED = 0;
00545                     DemoInternalState = APP_IDLE;
00546                     Radio.SetStandby( STDBY_RC );
00547                     SendNextPacket.detach( );
00548                     Eeprom.EepromData.DemoSettings.HoldDemo = true;
00549                     refreshDisplay = 1;
00550                 }
00551             }
00552             break;
00553 
00554         case APP_RX:
00555             RX_LED = !RX_LED;
00556             Radio.SetStandby( STDBY_RC );
00557             ReceiveNext = false;
00558             ReceiveNextPacket.detach( );
00559             ReceiveNextPacket.attach_us( &ReceiveNextPacketEvent, ( ( uint32_t )( Eeprom.EepromData.DemoSettings.TimeOnAir + RX_TX_INTER_PACKET_DELAY + RX_TX_TRANSITION_WAIT ) ) * 1000 );
00560             if( CurrentChannel < ( CHANNELS - 1 ) )
00561             {
00562                 CurrentChannel++;
00563             }
00564             else
00565             {
00566                 CurrentChannel = 0;
00567             }
00568             Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE );
00569             Radio.GetPacketStatus( &PacketStatus );
00570             if( Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_LORA )
00571             {
00572                 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.LoRa.RssiPkt;
00573                 Eeprom.EepromData.DemoSettings.SnrValue = PacketStatus.LoRa.SnrPkt;
00574             }
00575             else if( Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_FLRC )
00576             {
00577                 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Flrc.RssiSync;
00578                 Eeprom.EepromData.DemoSettings.SnrValue = 0;
00579             }
00580             else if( Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_GFSK  )
00581             {
00582                 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Gfsk.RssiSync;
00583                 Eeprom.EepromData.DemoSettings.SnrValue = 0;
00584             }
00585             DemoInternalState = PER_RX_START;
00586             if( ( BufferSize >= PER_SIZE ) && ( strncmp( ( const char* )( Buffer + 4 ), ( const char* )PerMsg, PER_SIZE ) == 0 ) )
00587             {
00588                 ComputePerPayload( Buffer, BufferSize );
00589                 refreshDisplay = 1;
00590             }
00591             else
00592             {
00593                 Eeprom.EepromData.DemoSettings.RxTimeOutCount++;
00594             }
00595             break;
00596 
00597         case APP_RX_ERROR:
00598             printf("crc\n\r");
00599             Radio.SetStandby( STDBY_RC );
00600             DemoInternalState = APP_IDLE;
00601             break;
00602 
00603         case APP_RX_TIMEOUT:
00604             printf("tmt\n\r");
00605             Radio.SetStandby( STDBY_RC );
00606             if( CurrentChannel < ( CHANNELS - 1 ) )
00607             {
00608                 CurrentChannel++;
00609             }
00610             else
00611             {
00612                 CurrentChannel = 0;
00613             }
00614             Eeprom.EepromData.DemoSettings.RxTimeOutCount++;
00615             DemoInternalState = PER_RX_START;
00616             refreshDisplay = 1;
00617             break;
00618 
00619         case APP_TX_TIMEOUT:
00620 #ifdef PRINT_DEBUG
00621             printf( "Failure: timeout in Tx is shorter than the packet time on air\n\r" );
00622 #endif
00623             DemoInternalState = APP_IDLE;
00624             Eeprom.EepromData.DemoSettings.HoldDemo = true;
00625             refreshDisplay = 1;
00626             break;
00627 
00628         case APP_IDLE: // do nothing
00629             if( ReceiveNext == true )
00630             {
00631                 ReceiveNext = false;
00632                 DemoInternalState = APP_RX_TIMEOUT;
00633             }
00634             break;
00635 
00636         default:
00637             break;
00638     }
00639     return refreshDisplay;
00640 }
00641 
00642 void ComputePerPayload( uint8_t *buffer, uint8_t bufferSize )
00643 {
00644     uint32_t i = 0;
00645 
00646     Eeprom.EepromData.DemoSettings.CntPacketRxOK++;
00647     PacketRxSequence = ( ( uint32_t )buffer[0] << 24 ) | \
00648                        ( ( uint32_t )buffer[1] << 16 ) | \
00649                        ( ( uint32_t )buffer[2] << 8 )  | \
00650                                      buffer[3];
00651 
00652     if( ( PacketRxSequence <= PacketRxSequencePrev ) || \
00653         ( PacketRxSequencePrev == 0xFFFFFFFF ) )
00654     {
00655         // Sequence went back => resynchronization
00656         // Don't count missed packets this time
00657         i = 0;
00658     }
00659     else
00660     {
00661         // Determine number of missed packets
00662         i = PacketRxSequence - PacketRxSequencePrev - 1;
00663     }
00664     // Be ready for the next
00665     PacketRxSequencePrev = PacketRxSequence;
00666     // increment 'missed' counter for the RX session
00667     Eeprom.EepromData.DemoSettings.CntPacketRxKO += i;
00668     Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0;
00669 }
00670 
00671 // ************************     Ping Pong Demo     *****************************
00672 // *                                                                           *
00673 // *                                                                           *
00674 // *                                                                           *
00675 // *****************************************************************************
00676 uint8_t RunDemoApplicationPingPong( void )
00677 {
00678     uint8_t i = 0;
00679     uint8_t refreshDisplay = 0;
00680 
00681     if( Eeprom.EepromData.DemoSettings.HoldDemo == true )
00682     {
00683         return 0;   // quit without refresh display
00684     }
00685 
00686     if( DemoRunning == false )
00687     {
00688         DemoRunning = true;
00689         TX_LED = 0;
00690         RX_LED = 0;
00691         SetAntennaSwitch( );
00692         ReceiveNext = false;
00693         SendNext = false;
00694         Eeprom.EepromData.DemoSettings.CntPacketTx        = 0;
00695         Eeprom.EepromData.DemoSettings.CntPacketRxOK      = 0;
00696         Eeprom.EepromData.DemoSettings.CntPacketRxOKSlave = 0;
00697         Eeprom.EepromData.DemoSettings.CntPacketRxKO      = 0;
00698         Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave = 0;
00699         Eeprom.EepromData.DemoSettings.RxTimeOutCount     = 0;
00700 
00701         InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType );
00702 
00703         Eeprom.EepromData.DemoSettings.TimeOnAir = GetTimeOnAir( Eeprom.EepromData.DemoSettings.ModulationType );
00704 
00705 #ifdef PRINT_DEBUG
00706         printf( "Start RunDemoApplicationPingPong.\n\r" );
00707 #endif
00708 
00709         if( Eeprom.EepromData.DemoSettings.Entity == MASTER )
00710         {
00711             DemoInternalState = SEND_PING_MSG;
00712             SendNextPacket.attach_us( &SendNextPacketEvent, ( ( uint32_t )( ( Eeprom.EepromData.DemoSettings.TimeOnAir * 2 ) + RX_TX_INTER_PACKET_DELAY * 2 ) * 1000 ) );
00713         }
00714         else
00715         {
00716             IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT;
00717             Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00718             // Rx Single without timeout for the start
00719             RX_LED = !RX_LED;
00720             Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, 0x0000 } );
00721             DemoInternalState = APP_IDLE;
00722         }
00723     }
00724 
00725     Radio.ProcessIrqs( );
00726 
00727     if( Eeprom.EepromData.DemoSettings.Entity == MASTER )
00728     {
00729         switch( DemoInternalState )
00730         {
00731             case SEND_PING_MSG:
00732                 if( ( Eeprom.EepromData.DemoSettings.MaxNumPacket != 0 ) \
00733                     && ( Eeprom.EepromData.DemoSettings.CntPacketTx >= Eeprom.EepromData.DemoSettings.MaxNumPacket ) )
00734                 {
00735                     SendNextPacket.detach( );
00736                     ReceiveNextPacket.detach( );
00737                     ReceiveNext = false;
00738                     SendNext = false;
00739                     RX_LED = 0;
00740                     TX_LED = 0;
00741                     DemoInternalState = APP_IDLE;
00742                     
00743                     Eeprom.EepromData.DemoSettings.HoldDemo = true;
00744                     refreshDisplay = 1;
00745                 }
00746                 else
00747                 {
00748                     if( SendNext == true )
00749                     {
00750                         SendNext = false;
00751 
00752                         DemoInternalState = APP_IDLE;
00753                         Eeprom.EepromData.DemoSettings.CntPacketTx++;
00754                         // Send the next PING frame
00755                         Buffer[0] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 24 ) & 0xFF;
00756                         Buffer[1] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 16 ) & 0xFF;
00757                         Buffer[2] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 8 )  & 0xFF;
00758                         Buffer[3] = ( Eeprom.EepromData.DemoSettings.CntPacketTx & 0xFF );
00759                         Buffer[4] = PingMsg[0];
00760                         Buffer[5] = PingMsg[1];
00761                         Buffer[6] = PingMsg[2];
00762                         Buffer[7] = PingMsg[3];
00763                         for( i = 8; i < Eeprom.EepromData.DemoSettings.PayloadLength; i++ )
00764                         {
00765                             Buffer[i] = i;
00766                         }
00767                         TX_LED = !TX_LED;
00768                         IrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
00769                         Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00770                         Radio.SendPayload( Buffer, Eeprom.EepromData.DemoSettings.PayloadLength, \
00771                                                    ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, \
00772                                                    Eeprom.EepromData.DemoSettings.TimeOnAir + RX_TX_TRANSITION_WAIT } );
00773                     }
00774                 }
00775                 break;
00776 
00777             case APP_TX:
00778                 DemoInternalState = SEND_PING_MSG;
00779                 TX_LED = !TX_LED;
00780                 RX_LED = !RX_LED;
00781                 IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT;
00782                 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00783                 Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, Eeprom.EepromData.DemoSettings.TimeOnAir + RX_TX_TRANSITION_WAIT } );
00784                 break;
00785 
00786             case APP_RX:
00787                 RX_LED = !RX_LED;
00788                 Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE );
00789                 Radio.GetPacketStatus( &PacketStatus );
00790                 if( Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_LORA )
00791                 {
00792                     Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.LoRa.RssiPkt;
00793                     Eeprom.EepromData.DemoSettings.SnrValue = PacketStatus.LoRa.SnrPkt;
00794                 }
00795                 else if( Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_FLRC )
00796                 {
00797                     Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Flrc.RssiSync;
00798                     Eeprom.EepromData.DemoSettings.SnrValue = 0;
00799                 }
00800                 else if( Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_GFSK )
00801                 {
00802                     Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Gfsk.RssiSync;
00803                     Eeprom.EepromData.DemoSettings.SnrValue = 0;
00804                 }
00805                 if( ( BufferSize >= PINGPONG_SIZE ) && ( strncmp( ( const char* )( Buffer + 8 ), ( const char* )PongMsg, PINGPONG_SIZE ) == 0 ) )
00806                 {
00807                     ComputePingPongPayload( Buffer, BufferSize );
00808                 }
00809                 else
00810                 {
00811                     Eeprom.EepromData.DemoSettings.CntPacketRxKO++;
00812                 }
00813                 DemoInternalState = SEND_PING_MSG;
00814                 refreshDisplay = 1;
00815                 break;
00816 
00817             case APP_RX_TIMEOUT:
00818             case APP_RX_ERROR:
00819                 Radio.SetStandby( STDBY_RC );
00820                 RX_LED = !RX_LED;
00821                 Eeprom.EepromData.DemoSettings.CntPacketRxKO++;
00822                 DemoInternalState = SEND_PING_MSG;
00823                 refreshDisplay = 1;
00824                 break;
00825 
00826             case APP_TX_TIMEOUT:
00827 #ifdef PRINT_DEBUG
00828                 printf( "Failure: timeout in Tx is shorter than the packet time on air\n\r" );
00829 #endif
00830                 DemoInternalState = APP_IDLE;
00831                 Eeprom.EepromData.DemoSettings.HoldDemo = true;
00832                 refreshDisplay = 1;
00833                 break;
00834 
00835             case APP_IDLE: // do nothing
00836                 break;
00837 
00838             default:
00839                 break;
00840         }
00841     }
00842     else // SLAVE
00843     {
00844         switch( DemoInternalState )
00845         {
00846             case SEND_PONG_MSG:
00847                 wait_ms( 2 );
00848 
00849                 DemoInternalState = APP_IDLE;
00850                 // Send the next PING frame
00851                 Buffer[0]  = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 24 ) & 0xFF;
00852                 Buffer[1]  = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 16 ) & 0xFF;
00853                 Buffer[2]  = ( Eeprom.EepromData.DemoSettings.CntPacketTx >>  8 ) & 0xFF;
00854                 Buffer[3]  = ( Eeprom.EepromData.DemoSettings.CntPacketTx & 0xFF );
00855                 Buffer[4]  = ( ( Eeprom.EepromData.DemoSettings.CntPacketRxKO + \
00856                                  Eeprom.EepromData.DemoSettings.RxTimeOutCount ) >> 24 ) & 0xFF;
00857                 Buffer[5]  = ( ( Eeprom.EepromData.DemoSettings.CntPacketRxKO + \
00858                                  Eeprom.EepromData.DemoSettings.RxTimeOutCount ) >> 16 ) & 0xFF;
00859                 Buffer[6]  = ( ( Eeprom.EepromData.DemoSettings.CntPacketRxKO + \
00860                                  Eeprom.EepromData.DemoSettings.RxTimeOutCount ) >> 8 ) & 0xFF;
00861                 Buffer[7]  = ( ( Eeprom.EepromData.DemoSettings.CntPacketRxKO + \
00862                                  Eeprom.EepromData.DemoSettings.RxTimeOutCount ) & 0xFF );
00863                 Buffer[8]  = PongMsg[0];
00864                 Buffer[9]  = PongMsg[1];
00865                 Buffer[10] = PongMsg[2];
00866                 Buffer[11] = PongMsg[3];
00867                 for( i = 12; i < Eeprom.EepromData.DemoSettings.PayloadLength; i++ )
00868                 {
00869                     Buffer[i] = i;
00870                 }
00871                 TX_LED = !TX_LED;
00872                 IrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
00873                 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00874                 Radio.SendPayload( Buffer, Eeprom.EepromData.DemoSettings.PayloadLength, \
00875                                    ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, \
00876                                    Eeprom.EepromData.DemoSettings.TimeOnAir + RX_TX_TRANSITION_WAIT } );
00877                 break;
00878 
00879             case APP_TX:
00880                 if( ( Eeprom.EepromData.DemoSettings.MaxNumPacket != 0 ) \
00881                     && ( ( Eeprom.EepromData.DemoSettings.CntPacketRxOK + Eeprom.EepromData.DemoSettings.CntPacketRxKO + \
00882                            Eeprom.EepromData.DemoSettings.RxTimeOutCount ) >= Eeprom.EepromData.DemoSettings.MaxNumPacket ) )
00883                 {
00884                     SendNextPacket.detach( ); 
00885                     SendNext = false;
00886                     RX_LED = 0;
00887                     TX_LED = 0;
00888                     DemoInternalState = APP_IDLE;
00889                     Radio.SetStandby( STDBY_RC );
00890                     Eeprom.EepromData.DemoSettings.HoldDemo = true;
00891                     refreshDisplay = 1;
00892                 }
00893                 else
00894                 {
00895                     DemoInternalState = APP_IDLE;
00896                     TX_LED = !TX_LED;
00897                     RX_LED = !RX_LED;
00898                     IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT;
00899                     Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00900                     Radio.SetRx( ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, 0xFFFF } );
00901                     refreshDisplay = 1;
00902                 }
00903                 break;
00904 
00905             case APP_RX:
00906                 DemoInternalState = APP_IDLE;
00907                 RX_LED = !RX_LED;
00908 
00909                 Radio.SetStandby( STDBY_RC );
00910                 ReceiveNext = false;
00911                 ReceiveNextPacket.detach( );
00912                 ReceiveNextPacket.attach_us( &ReceiveNextPacketEvent, ( ( uint32_t )( ( Eeprom.EepromData.DemoSettings.TimeOnAir << 1 ) + RX_TX_INTER_PACKET_DELAY * 2 + RX_TX_TRANSITION_WAIT ) ) * 1000 );
00913 
00914                 Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE );
00915                 Radio.GetPacketStatus( &PacketStatus );
00916                 if( Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_LORA )
00917                 {
00918                     Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.LoRa.RssiPkt;
00919                     Eeprom.EepromData.DemoSettings.SnrValue = PacketStatus.LoRa.SnrPkt;
00920                 }
00921                 else if( Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_FLRC )
00922                 {
00923                     Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Flrc.RssiSync;
00924                     Eeprom.EepromData.DemoSettings.SnrValue = 0;
00925                 }
00926                 else if( Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_GFSK  )
00927                 {
00928                     Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Gfsk.RssiSync;
00929                     Eeprom.EepromData.DemoSettings.SnrValue = 0;
00930                 }
00931                 ComputePingPongPayload( Buffer, BufferSize );
00932                 DemoInternalState = SEND_PONG_MSG;
00933                 break;
00934 
00935             case APP_RX_TIMEOUT:
00936                 printf("tmt\n\r");
00937                 Radio.SetStandby( STDBY_RC );
00938                 Eeprom.EepromData.DemoSettings.RxTimeOutCount++;
00939                 DemoInternalState = SEND_PONG_MSG;
00940                 refreshDisplay = 1;
00941                 break;
00942 
00943             case APP_RX_ERROR:
00944                 printf("crc\n\r");
00945                 Radio.SetStandby( STDBY_RC );
00946                 DemoInternalState = APP_IDLE;
00947                 break;
00948 
00949             case APP_TX_TIMEOUT:
00950 #ifdef PRINT_DEBUG
00951                 printf( "Failure: timeout in Tx is shorter than the packet time on air\n\r" );
00952 #endif
00953                 DemoInternalState = APP_IDLE;
00954                 Eeprom.EepromData.DemoSettings.HoldDemo = true;
00955                 refreshDisplay = 1;
00956                 break;
00957 
00958             case APP_IDLE: // do nothing
00959                 if( ReceiveNext == true )
00960                 {
00961                     ReceiveNext = false;
00962                     DemoInternalState = APP_RX_TIMEOUT;
00963                 }
00964                 break;
00965 
00966             default:
00967                 break;
00968         }
00969     }
00970     return refreshDisplay;
00971 }
00972 
00973 void ComputePingPongPayload( uint8_t *buffer, uint8_t bufferSize )
00974 {
00975     uint32_t i = 0;
00976 
00977     PacketRxSequence = ( ( uint32_t )buffer[0] << 24 ) | \
00978                        ( ( uint32_t )buffer[1] << 16 ) | \
00979                        ( ( uint32_t )buffer[2] << 8 )  | \
00980                                      buffer[3];
00981 
00982     if( Eeprom.EepromData.DemoSettings.Entity == MASTER )
00983     {
00984         Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave = 
00985                        ( ( uint32_t )buffer[4] << 24 ) | \
00986                        ( ( uint32_t )buffer[5] << 16 ) | \
00987                        ( ( uint32_t )buffer[6] << 8 )  | \
00988                                      buffer[7];
00989         if( PacketRxSequence > Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave )
00990         {
00991             Eeprom.EepromData.DemoSettings.CntPacketRxOKSlave = PacketRxSequence - \
00992                 Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave;
00993         }
00994         else
00995         {
00996             Eeprom.EepromData.DemoSettings.CntPacketRxOKSlave = 0;
00997         }
00998 
00999         if( PacketRxSequence == Eeprom.EepromData.DemoSettings.CntPacketTx )
01000         {
01001             Eeprom.EepromData.DemoSettings.CntPacketRxOK += 1;
01002         }
01003         else
01004         {
01005             Eeprom.EepromData.DemoSettings.CntPacketRxKO += 1;
01006         }
01007     }
01008     else
01009     {
01010         Eeprom.EepromData.DemoSettings.CntPacketRxOK += 1;
01011         if( ( PacketRxSequence <= PacketRxSequencePrev ) || \
01012             ( PacketRxSequencePrev == 0 ) )
01013         {
01014             // Sequence went back => resynchronization
01015             // Don't count missed packets this time
01016             i = 0;
01017         }
01018         else
01019         {
01020             // Determine number of missed packets
01021             i = PacketRxSequence - PacketRxSequencePrev - 1;
01022         }
01023         // Be ready for the next
01024         PacketRxSequencePrev = PacketRxSequence;
01025         Eeprom.EepromData.DemoSettings.CntPacketTx = PacketRxSequence;
01026         // increment 'missed' counter for the RX session
01027         Eeprom.EepromData.DemoSettings.CntPacketRxKO += i;
01028         Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0;
01029     }
01030 }
01031 
01032 // ************************      Ranging Demo      *****************************
01033 // *                                                                           *
01034 // *                                                                           *
01035 // *                                                                           *
01036 // *****************************************************************************
01037 uint8_t RunDemoApplicationRanging( void )
01038 {
01039     uint8_t refreshDisplay = 0;
01040 
01041     if( Eeprom.EepromData.DemoSettings.HoldDemo == true )
01042     {
01043         return 0;   // quit without refresh display
01044     }
01045 
01046     if( DemoRunning == false )
01047     {
01048         DemoRunning = true;
01049         TX_LED = 0;
01050         RX_LED = 0;
01051         ANT_SW = 1;
01052 
01053 #ifdef PRINT_DEBUG
01054         printf( "Start RunDemoApplicationRanging\r\n" );
01055 #endif
01056 
01057         Eeprom.EepromData.DemoSettings.CntPacketTx = 0;
01058         Eeprom.EepromData.DemoSettings.RngFei      = 0.0;
01059         Eeprom.EepromData.DemoSettings.RngStatus   = RNG_INIT;
01060         InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType );
01061 
01062         if( Eeprom.EepromData.DemoSettings.Entity == MASTER )
01063         {
01064             Eeprom.EepromData.DemoSettings.TimeOnAir = RX_TX_INTER_PACKET_DELAY;
01065             Radio.SetDioIrqParams( IRQ_RX_DONE | IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_RANGING_MASTER_RESULT_VALID | IRQ_RANGING_MASTER_TIMEOUT,
01066                                    IRQ_RX_DONE | IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT | IRQ_RANGING_MASTER_RESULT_VALID | IRQ_RANGING_MASTER_TIMEOUT,
01067                                    IRQ_RADIO_NONE, IRQ_RADIO_NONE );
01068             Eeprom.EepromData.DemoSettings.RngDistance = 0.0;
01069             DemoInternalState = APP_RANGING_CONFIG;
01070         }
01071         else
01072         {
01073             Radio.SetDioIrqParams( IRQ_RADIO_ALL, IRQ_RADIO_ALL, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
01074             DemoInternalState = APP_RANGING_CONFIG;
01075         }
01076     }
01077 
01078     Radio.ProcessIrqs( );
01079 
01080     if( Eeprom.EepromData.DemoSettings.Entity == MASTER )
01081     {
01082         switch( DemoInternalState )
01083         {
01084             case APP_RANGING_CONFIG:
01085                 if( Eeprom.EepromData.DemoSettings.HoldDemo == false )
01086                 {
01087                     Eeprom.EepromData.DemoSettings.RngStatus = RNG_INIT;
01088                     Eeprom.EepromData.DemoSettings.CntPacketTx++;
01089                     ModulationParams.PacketType = PACKET_TYPE_LORA;
01090                     PacketParams.PacketType     = PACKET_TYPE_LORA;
01091                     memcpy( &( ModulationParams.Params.LoRa.SpreadingFactor ), Eeprom.Buffer + MOD_RNG_SPREADF_EEPROM_ADDR,      1 );
01092                     memcpy( &( ModulationParams.Params.LoRa.Bandwidth ),       Eeprom.Buffer + MOD_RNG_BW_EEPROM_ADDR,           1 );
01093                     memcpy( &( ModulationParams.Params.LoRa.CodingRate ),      Eeprom.Buffer + MOD_RNG_CODERATE_EEPROM_ADDR,     1 );
01094                     memcpy( &( PacketParams.Params.LoRa.PreambleLength ),      Eeprom.Buffer + PAK_RNG_PREAMBLE_LEN_EEPROM_ADDR, 1 );
01095                     memcpy( &( PacketParams.Params.LoRa.HeaderType ),          Eeprom.Buffer + PAK_RNG_HEADERTYPE_EEPROM_ADDR,   1 );
01096                     PacketParams.Params.LoRa.PayloadLength = 7;
01097                     memcpy( &( PacketParams.Params.LoRa.Crc ),                 Eeprom.Buffer + PAK_RNG_CRC_MODE_EEPROM_ADDR,     1 );
01098                     memcpy( &( PacketParams.Params.LoRa.InvertIQ ),            Eeprom.Buffer + PAK_RNG_IQ_INV_EEPROM_ADDR,       1 );
01099                     Radio.SetPacketType( ModulationParams.PacketType );
01100                     Radio.SetModulationParams( &ModulationParams );
01101                     Radio.SetPacketParams( &PacketParams );
01102                     Radio.SetRfFrequency( Eeprom.EepromData.DemoSettings.Frequency );
01103                     Eeprom.EepromData.DemoSettings.CntPacketRxOK = 0;
01104                     Eeprom.EepromData.DemoSettings.CntPacketRxOKSlave = 0;
01105                     MeasuredChannels  = 0;
01106                     CurrentChannel    = 0;
01107                     Buffer[0] = ( Eeprom.EepromData.DemoSettings.RngAddress >> 24 ) & 0xFF;
01108                     Buffer[1] = ( Eeprom.EepromData.DemoSettings.RngAddress >> 16 ) & 0xFF;
01109                     Buffer[2] = ( Eeprom.EepromData.DemoSettings.RngAddress >>  8 ) & 0xFF;
01110                     Buffer[3] = ( Eeprom.EepromData.DemoSettings.RngAddress & 0xFF );
01111                     Buffer[4] = CurrentChannel;    // set the first channel to use
01112                     Buffer[5] = Eeprom.EepromData.DemoSettings.RngAntenna;      // set the antenna strategy
01113                     Buffer[6] = Eeprom.EepromData.DemoSettings.RngRequestCount; // set the number of hops
01114                     TX_LED = 1;
01115                     Radio.SendPayload( Buffer, PacketParams.Params.LoRa.PayloadLength, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, RNG_COM_TIMEOUT } );
01116                     DemoInternalState = APP_IDLE;
01117                 }
01118                 break;
01119 
01120             case APP_RNG:
01121                 if( SendNext == true )
01122                 {
01123                     SendNext = false;
01124                     MeasuredChannels++;
01125                     if( MeasuredChannels <= Eeprom.EepromData.DemoSettings.RngRequestCount )
01126                     {
01127                         Radio.SetRfFrequency( Channels[CurrentChannel] );
01128                         TX_LED = 1;
01129                         switch( Eeprom.EepromData.DemoSettings.RngAntenna )
01130                         {
01131                             case DEMO_RNG_ANT_1:
01132                                 //ANT_SW = 1; // ANT1
01133                                 Eeprom.EepromData.DemoSettings.AntennaSwitch = 0;
01134                                 CurrentChannel++;
01135                                 if( CurrentChannel >= CHANNELS )
01136                                 {
01137                                     CurrentChannel -= CHANNELS;
01138                                 }
01139                                 break;
01140 
01141                             case DEMO_RNG_ANT_0:
01142                                 //ANT_SW = 0; // ANT0
01143                                 Eeprom.EepromData.DemoSettings.AntennaSwitch = 1;
01144                                 CurrentChannel++;
01145                                 if( CurrentChannel >= CHANNELS )
01146                                 {
01147                                     CurrentChannel -= CHANNELS;
01148                                 }
01149                                 break;
01150 
01151                             case DEMO_RNG_ANT_BOTH:
01152                                 if( ANT_SW == 1 )
01153                                 {
01154                                     //ANT_SW = 0;
01155                                     Eeprom.EepromData.DemoSettings.AntennaSwitch = 1;
01156                                 }
01157                                 else
01158                                 {
01159                                     //ANT_SW = 1;
01160                                     Eeprom.EepromData.DemoSettings.AntennaSwitch = 0;
01161                                     CurrentChannel++;
01162                                     if( CurrentChannel >= CHANNELS )
01163                                     {
01164                                         CurrentChannel -= CHANNELS;
01165                                     }
01166                                 }
01167                                 break;
01168                         }
01169                         SetAntennaSwitch( );
01170                         DemoInternalState = APP_IDLE;
01171                         Radio.SetTx( ( TickTime_t ){ RADIO_TICK_SIZE_1000_US, 0xFFFF } );
01172                     }
01173                     else
01174                     {
01175                         Eeprom.EepromData.DemoSettings.CntPacketRxOKSlave = CheckDistance( );
01176                         refreshDisplay = 1;
01177                         SendNextPacket.detach( );
01178                         Eeprom.EepromData.DemoSettings.HoldDemo = true;
01179                         SendNext = false;
01180                         DemoInternalState = APP_RANGING_CONFIG;
01181                         Eeprom.EepromData.DemoSettings.RngStatus = RNG_INIT;
01182                     }
01183                 }
01184                 break;
01185 
01186             case APP_RANGING_DONE:
01187                 TX_LED = 0;
01188                 RawRngResults[RngResultIndex] = Radio.GetRangingResult( RANGING_RESULT_RAW );
01189                 RawRngResults[RngResultIndex] += Sx1280RangingCorrection::GetRangingCorrectionPerSfBwGain(
01190                     ModulationParams.Params.LoRa.SpreadingFactor,
01191                     ModulationParams.Params.LoRa.Bandwidth,
01192                     Radio.GetRangingPowerDeltaThresholdIndicator( )
01193                 );
01194                 RngResultIndex++;
01195 
01196                 Eeprom.EepromData.DemoSettings.CntPacketRxOK++;
01197                 DemoInternalState = APP_RNG;
01198                 break;
01199 
01200             case APP_RANGING_TIMEOUT:
01201                 TX_LED = 0;
01202                 DemoInternalState = APP_RNG;
01203                 break;
01204 
01205             case APP_RX:
01206                 RX_LED = 0;
01207                 if( Eeprom.EepromData.DemoSettings.RngStatus == RNG_INIT )
01208                 {
01209                     Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE );
01210                     if( BufferSize > 0 )
01211                     {
01212                         Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0;
01213                         Eeprom.EepromData.DemoSettings.RngStatus = RNG_PROCESS;
01214                         Eeprom.EepromData.DemoSettings.RngFei = ( double )( ( ( int32_t )Buffer[4] << 24 ) | \
01215                                                                             ( ( int32_t )Buffer[5] << 16 ) | \
01216                                                                             ( ( int32_t )Buffer[6] <<  8 ) | \
01217                                                                                          Buffer[7] );
01218                         Eeprom.EepromData.DemoSettings.RssiValue = Buffer[8]; // for ranging post-traitment (since V3 only)
01219                         ModulationParams.PacketType = PACKET_TYPE_RANGING;
01220                         PacketParams.PacketType     = PACKET_TYPE_RANGING;
01221 
01222                         memcpy( &( ModulationParams.Params.LoRa.SpreadingFactor ), Eeprom.Buffer + MOD_RNG_SPREADF_EEPROM_ADDR,      1 );
01223                         memcpy( &( ModulationParams.Params.LoRa.Bandwidth ),       Eeprom.Buffer + MOD_RNG_BW_EEPROM_ADDR,           1 );
01224                         memcpy( &( ModulationParams.Params.LoRa.CodingRate ),      Eeprom.Buffer + MOD_RNG_CODERATE_EEPROM_ADDR,     1 );
01225                         memcpy( &( PacketParams.Params.LoRa.PreambleLength ),      Eeprom.Buffer + PAK_RNG_PREAMBLE_LEN_EEPROM_ADDR, 1 );
01226                         memcpy( &( PacketParams.Params.LoRa.HeaderType ),          Eeprom.Buffer + PAK_RNG_HEADERTYPE_EEPROM_ADDR,   1 );
01227                         PacketParams.Params.LoRa.PayloadLength = 10;
01228                         memcpy( &( PacketParams.Params.LoRa.Crc ),                 Eeprom.Buffer + PAK_RNG_CRC_MODE_EEPROM_ADDR,     1 );
01229                         memcpy( &( PacketParams.Params.LoRa.InvertIQ ),            Eeprom.Buffer + PAK_RNG_IQ_INV_EEPROM_ADDR,       1 );
01230 
01231                         Radio.SetPacketType( ModulationParams.PacketType );
01232                         Radio.SetModulationParams( &ModulationParams );
01233                         Radio.SetPacketParams( &PacketParams );
01234                         Radio.SetRangingRequestAddress( Eeprom.EepromData.DemoSettings.RngAddress );
01235                         Radio.SetRangingCalibration( Eeprom.EepromData.DemoSettings.RngCalib );
01236                         Radio.SetTxParams( Eeprom.EepromData.DemoSettings.TxPower, RADIO_RAMP_20_US );
01237 
01238                         MeasuredChannels = 0;
01239                         RngResultIndex   = 0;
01240                         SendNextPacket.attach_us( &SendNextPacketEvent, Eeprom.EepromData.DemoSettings.RngReqDelay * 1000 );
01241                         DemoInternalState = APP_RNG;
01242                     }
01243                     else
01244                     {
01245                         DemoInternalState = APP_RANGING_CONFIG;
01246                     }
01247                 }
01248                 else
01249                 {
01250                     DemoInternalState = APP_RANGING_CONFIG;
01251                 }
01252                 break;
01253 
01254             case APP_TX:
01255                 TX_LED = 0;
01256                 if( Eeprom.EepromData.DemoSettings.RngStatus == RNG_INIT )
01257                 {
01258                     RX_LED = 1;
01259                     Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RNG_COM_TIMEOUT } );
01260                     DemoInternalState = APP_IDLE;
01261                 }
01262                 else
01263                 {
01264                     DemoInternalState = APP_RANGING_CONFIG;
01265                 }
01266                 break;
01267 
01268             case APP_RX_TIMEOUT:
01269                 RX_LED = 0;
01270                 Eeprom.EepromData.DemoSettings.RngStatus = RNG_TIMEOUT;
01271                 DemoInternalState = APP_RANGING_CONFIG;
01272                 Eeprom.EepromData.DemoSettings.HoldDemo = true;
01273                 refreshDisplay = 1; // display error on token color (RNG_TIMEOUT)
01274                 break;
01275 
01276             case APP_RX_ERROR:
01277                 RX_LED = 0;
01278                 DemoInternalState = APP_RANGING_CONFIG;
01279                 Eeprom.EepromData.DemoSettings.HoldDemo = true;
01280                 refreshDisplay = 1; // display error on token color (RNG_TIMEOUT)
01281                 break;
01282 
01283             case APP_TX_TIMEOUT:
01284                 TX_LED = 0;
01285                 DemoInternalState = APP_RANGING_CONFIG;
01286                 Eeprom.EepromData.DemoSettings.HoldDemo = true;
01287                 refreshDisplay = 1; // display error on token color (RNG_TIMEOUT)
01288                 break;
01289 
01290             case APP_IDLE: // do nothing
01291                 break;
01292 
01293             default:
01294                 DemoInternalState = APP_RANGING_CONFIG;
01295                 Eeprom.EepromData.DemoSettings.HoldDemo = true;
01296                 break;
01297         }
01298     }
01299     else    // Slave
01300     {
01301         switch( DemoInternalState )
01302         {
01303             case APP_RANGING_CONFIG:
01304                 Eeprom.EepromData.DemoSettings.RngStatus = RNG_INIT;
01305                 ModulationParams.PacketType = PACKET_TYPE_LORA;
01306                 PacketParams.PacketType     = PACKET_TYPE_LORA;
01307                 memcpy( &( ModulationParams.Params.LoRa.SpreadingFactor ), Eeprom.Buffer + MOD_RNG_SPREADF_EEPROM_ADDR,      1 );
01308                 memcpy( &( ModulationParams.Params.LoRa.Bandwidth ),       Eeprom.Buffer + MOD_RNG_BW_EEPROM_ADDR,           1 );
01309                 memcpy( &( ModulationParams.Params.LoRa.CodingRate ),      Eeprom.Buffer + MOD_RNG_CODERATE_EEPROM_ADDR,     1 );
01310                 memcpy( &( PacketParams.Params.LoRa.PreambleLength ),      Eeprom.Buffer + PAK_RNG_PREAMBLE_LEN_EEPROM_ADDR, 1 );
01311                 memcpy( &( PacketParams.Params.LoRa.HeaderType ),          Eeprom.Buffer + PAK_RNG_HEADERTYPE_EEPROM_ADDR,   1 );
01312                 PacketParams.Params.LoRa.PayloadLength = 9;
01313                 memcpy( &( PacketParams.Params.LoRa.Crc ),                 Eeprom.Buffer + PAK_RNG_CRC_MODE_EEPROM_ADDR,     1 );
01314                 memcpy( &( PacketParams.Params.LoRa.InvertIQ ),            Eeprom.Buffer + PAK_RNG_IQ_INV_EEPROM_ADDR,       1 );
01315                 Radio.SetPacketType( ModulationParams.PacketType );
01316                 Radio.SetModulationParams( &ModulationParams );
01317                 Radio.SetPacketParams( &PacketParams );
01318                 Radio.SetRfFrequency( Eeprom.EepromData.DemoSettings.Frequency );
01319                 RX_LED = 1;
01320                 // use listen mode here instead of rx continuous
01321                 Radio.SetRx( ( TickTime_t ) { RADIO_TICK_SIZE_1000_US, 0xFFFF } );
01322                 DemoInternalState = APP_IDLE;
01323                 break;
01324 
01325             case APP_RNG:
01326                 if( SendNext == true )
01327                 {
01328                     SendNext = false;
01329                     MeasuredChannels++;
01330                     if( MeasuredChannels <= Eeprom.EepromData.DemoSettings.RngRequestCount )
01331                     {
01332                         Radio.SetRfFrequency( Channels[CurrentChannel] );
01333                         RX_LED = 1;
01334                         switch( Eeprom.EepromData.DemoSettings.RngAntenna )
01335                         {
01336                             case DEMO_RNG_ANT_1:
01337                                 //ANT_SW = 1; // ANT1
01338                                 Eeprom.EepromData.DemoSettings.AntennaSwitch = 0;
01339                                 CurrentChannel++;
01340                                 if( CurrentChannel >= CHANNELS )
01341                                 {
01342                                     CurrentChannel -= CHANNELS;
01343                                 }
01344                                 break;
01345 
01346                             case DEMO_RNG_ANT_0:
01347                                 //ANT_SW = 0; // ANT0
01348                                 Eeprom.EepromData.DemoSettings.AntennaSwitch = 1;
01349                                 CurrentChannel++;
01350                                 if( CurrentChannel >= CHANNELS )
01351                                 {
01352                                     CurrentChannel -= CHANNELS;
01353                                 }
01354                                 break;
01355 
01356                             case DEMO_RNG_ANT_BOTH:
01357                                 if( ANT_SW == 1 )
01358                                 {
01359                                     //ANT_SW = 0;
01360                                     Eeprom.EepromData.DemoSettings.AntennaSwitch = 1;
01361                                 }
01362                                 else
01363                                 {
01364                                     //ANT_SW = 1;
01365                                     Eeprom.EepromData.DemoSettings.AntennaSwitch = 0;
01366                                     CurrentChannel++;
01367                                     if( CurrentChannel >= CHANNELS )
01368                                     {
01369                                         CurrentChannel -= CHANNELS;
01370                                     }
01371                                 }
01372                                 break;
01373                         }
01374                         SetAntennaSwitch( );
01375                         DemoInternalState = APP_IDLE;
01376                         Radio.SetRx( ( TickTime_t ){ RADIO_TICK_SIZE_1000_US, Eeprom.EepromData.DemoSettings.RngReqDelay } );
01377                     }
01378                     else
01379                     {
01380                         Radio.SetStandby( STDBY_RC );
01381                         refreshDisplay = 1;
01382                         SendNextPacket.detach( );
01383                         Eeprom.EepromData.DemoSettings.RngStatus = RNG_VALID;
01384                         DemoInternalState = APP_RANGING_CONFIG;
01385                     }
01386                 }
01387                 break;
01388 
01389             case APP_RANGING_DONE:
01390                 RX_LED = 0;
01391                 Eeprom.EepromData.DemoSettings.CntPacketRxOK++;
01392                 DemoInternalState = APP_RNG;
01393                 break;
01394 
01395             case APP_RANGING_TIMEOUT:
01396                 RX_LED = 0;
01397                 DemoInternalState = APP_RNG;
01398                 break;
01399 
01400             case APP_RX:
01401                 RX_LED = 0;
01402                 if( Eeprom.EepromData.DemoSettings.RngStatus == RNG_INIT )
01403                 {
01404                     Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE );
01405                     Radio.GetPacketStatus( &PacketStatus );
01406                     if( ( BufferSize > 0 ) && \
01407                         ( Buffer[0] == ( ( Eeprom.EepromData.DemoSettings.RngAddress >> 24 ) & 0xFF ) ) && \
01408                         ( Buffer[1] == ( ( Eeprom.EepromData.DemoSettings.RngAddress >> 16 ) & 0xFF ) ) && \
01409                         ( Buffer[2] == ( ( Eeprom.EepromData.DemoSettings.RngAddress >>  8 ) & 0xFF ) ) && \
01410                         ( Buffer[3] == (   Eeprom.EepromData.DemoSettings.RngAddress         & 0xFF ) ) )
01411                     {
01412                         Eeprom.EepromData.DemoSettings.RngFei    = Radio.GetFrequencyError( );
01413                         Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.LoRa.RssiPkt;
01414                         Eeprom.EepromData.DemoSettings.CntPacketTx++;
01415                         CurrentChannel                                 = Buffer[4];
01416                         Eeprom.EepromData.DemoSettings.RngAntenna      = Buffer[5];
01417                         Eeprom.EepromData.DemoSettings.RngRequestCount = Buffer[6];
01418                         wait_us( 10 );
01419                         Buffer[4] = ( ( ( int32_t )Eeprom.EepromData.DemoSettings.RngFei ) >> 24 ) & 0xFF ;
01420                         Buffer[5] = ( ( ( int32_t )Eeprom.EepromData.DemoSettings.RngFei ) >> 16 ) & 0xFF ;
01421                         Buffer[6] = ( ( ( int32_t )Eeprom.EepromData.DemoSettings.RngFei ) >>  8 ) & 0xFF ;
01422                         Buffer[7] = ( ( ( int32_t )Eeprom.EepromData.DemoSettings.RngFei ) & 0xFF );
01423                         Buffer[8] = Eeprom.EepromData.DemoSettings.RssiValue;
01424                         TX_LED = 1;
01425                         Radio.SendPayload( Buffer, 9, ( TickTime_t ){ RADIO_TICK_SIZE_1000_US, RNG_COM_TIMEOUT } );
01426                         DemoInternalState = APP_IDLE;
01427                     }
01428                     else
01429                     {
01430                         DemoInternalState = APP_RANGING_CONFIG;
01431                     }
01432                 }
01433                 else
01434                 {
01435                     DemoInternalState = APP_RANGING_CONFIG;
01436                 }
01437                 break;
01438 
01439             case APP_TX:
01440                 TX_LED = 0;
01441                 if( Eeprom.EepromData.DemoSettings.RngStatus == RNG_INIT )
01442                 {
01443                     Eeprom.EepromData.DemoSettings.RngStatus = RNG_PROCESS;
01444 
01445                     ModulationParams.PacketType = PACKET_TYPE_RANGING;
01446                     PacketParams.PacketType     = PACKET_TYPE_RANGING;
01447 
01448                     memcpy( &( ModulationParams.Params.LoRa.SpreadingFactor ), Eeprom.Buffer + MOD_RNG_SPREADF_EEPROM_ADDR,      1 );
01449                     memcpy( &( ModulationParams.Params.LoRa.Bandwidth ),       Eeprom.Buffer + MOD_RNG_BW_EEPROM_ADDR,           1 );
01450                     memcpy( &( ModulationParams.Params.LoRa.CodingRate ),      Eeprom.Buffer + MOD_RNG_CODERATE_EEPROM_ADDR,     1 );
01451                     memcpy( &( PacketParams.Params.LoRa.PreambleLength ),      Eeprom.Buffer + PAK_RNG_PREAMBLE_LEN_EEPROM_ADDR, 1 );
01452                     memcpy( &( PacketParams.Params.LoRa.HeaderType ),          Eeprom.Buffer + PAK_RNG_HEADERTYPE_EEPROM_ADDR,   1 );
01453                     PacketParams.Params.LoRa.PayloadLength = 10;
01454                     memcpy( &( PacketParams.Params.LoRa.Crc ),                 Eeprom.Buffer + PAK_RNG_CRC_MODE_EEPROM_ADDR,     1 );
01455                     memcpy( &( PacketParams.Params.LoRa.InvertIQ ),            Eeprom.Buffer + PAK_RNG_IQ_INV_EEPROM_ADDR,       1 );
01456 
01457                     Radio.SetPacketType( ModulationParams.PacketType );
01458 
01459                     Radio.SetModulationParams( &ModulationParams );
01460                     Radio.SetPacketParams( &PacketParams );
01461                     Radio.SetDeviceRangingAddress( Eeprom.EepromData.DemoSettings.RngAddress );
01462                     Radio.SetRangingCalibration( Eeprom.EepromData.DemoSettings.RngCalib );
01463                     Radio.SetTxParams( Eeprom.EepromData.DemoSettings.TxPower, RADIO_RAMP_20_US );
01464                     Eeprom.EepromData.DemoSettings.CntPacketRxOK = 0;
01465                     MeasuredChannels = 0;
01466                     Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave = 0;
01467                     SendNextPacket.attach_us( &SendNextPacketEvent, Eeprom.EepromData.DemoSettings.RngReqDelay * 1000 );
01468                     DemoInternalState = APP_RNG;
01469                 }
01470                 else
01471                 {
01472                     DemoInternalState = APP_RANGING_CONFIG;
01473                 }
01474                 break;
01475 
01476             case APP_RX_TIMEOUT:
01477                 RX_LED = 0;
01478                 DemoInternalState = APP_RANGING_CONFIG;
01479                 break;
01480 
01481             case APP_RX_ERROR:
01482                 RX_LED = 0;
01483                 DemoInternalState = APP_RANGING_CONFIG;
01484                 break;
01485 
01486             case APP_TX_TIMEOUT:
01487                 TX_LED = 0;
01488                 DemoInternalState = APP_RANGING_CONFIG;
01489                 break;
01490 
01491             case APP_IDLE: // do nothing
01492                 if( Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave > DEMO_RNG_CHANNELS_COUNT_MAX )
01493                 {
01494                     Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave = 0;
01495                     refreshDisplay = 1;
01496                     RX_LED = 0;
01497                     DemoInternalState = APP_RANGING_CONFIG;
01498                     SendNextPacket.detach( );
01499                 }
01500                 break;
01501 
01502             default:
01503                 DemoInternalState = APP_RANGING_CONFIG;
01504                 SendNextPacket.detach( );
01505                 break;
01506         }
01507     }
01508     return refreshDisplay;
01509 }
01510 
01511 // ************************        Utils            ****************************
01512 // *                                                                           *
01513 // *                                                                           *
01514 // *                                                                           *
01515 // *****************************************************************************
01516 
01517 void InitDemoApplication( void )
01518 {
01519     RX_LED = 1;
01520     TX_LED = 1;
01521 
01522     SetAntennaSwitch( );
01523 
01524     wait_ms( 500 ); // wait for on board DC/DC start-up time
01525 
01526     Radio.Init( );
01527 
01528     // Can also be set in LDO mode but consume more power
01529     Radio.SetRegulatorMode( ( RadioRegulatorModes_t )Eeprom.EepromData.DemoSettings.RadioPowerMode );
01530     Radio.SetStandby( STDBY_RC );
01531 
01532     memset( &Buffer, 0x00, BufferSize );
01533 
01534     RX_LED = 0;
01535     TX_LED = 0;
01536 
01537     PacketRxSequence = 0;
01538     PacketRxSequencePrev = 0;
01539     Eeprom.EepromData.DemoSettings.CntPacketTx    = 0;
01540     Eeprom.EepromData.DemoSettings.CntPacketRxOK  = 0;
01541     Eeprom.EepromData.DemoSettings.CntPacketRxKO  = 0;
01542     Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0;
01543 }
01544 
01545 void StopDemoApplication( void )
01546 {
01547     if( DemoRunning == true )
01548     {
01549         __disable_irq( );    // Disable Interrupts
01550 
01551 #ifdef PRINT_DEBUG
01552         printf( "StopDemoApplication\n\r" );
01553 #endif
01554 
01555         if( Radio.GetOpMode( ) == MODE_SLEEP )
01556         {
01557             Radio.Wakeup( );
01558             InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType );
01559         }
01560         RX_LED = 0;
01561         TX_LED = 0;
01562         DemoRunning = false;
01563         SendNext = false;
01564         ReceiveNext = false;
01565         PacketRxSequence = 0;
01566         PacketRxSequencePrev = 0;
01567         Eeprom.EepromData.DemoSettings.CntPacketTx    = 0;
01568         Eeprom.EepromData.DemoSettings.CntPacketRxOK  = 0;
01569         Eeprom.EepromData.DemoSettings.CntPacketRxKO  = 0;
01570         Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0;
01571 
01572         Radio.SetAutoFs( false );
01573         DemoInternalState = APP_IDLE;
01574         Radio.SetStandby( STDBY_RC );
01575         Radio.ClearIrqStatus( IRQ_RADIO_ALL );
01576         SendNextPacket.detach( );
01577         ReceiveNextPacket.detach( );
01578         
01579         __enable_irq( );     // Enable Interrupts
01580     }
01581 }
01582 
01583 /*
01584  * Function still being implemented >>> To be completed 
01585  * WARNING: Computation is in float and his really slow
01586  * LongInterLeaving vs LegacyInterLeaving has no influence on TimeOnAir.
01587  */
01588 uint16_t GetTimeOnAir( uint8_t modulation )
01589 {
01590     uint16_t result = 2000;
01591     double tPayload = 0.0;
01592     
01593     if( modulation == PACKET_TYPE_LORA )
01594     {
01595         uint16_t bw = 0.0;
01596         double nPayload = 0.0;
01597         double ts = 0.0;
01598 
01599         uint8_t SF = Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor >> 4;
01600         uint8_t crc = ( Eeprom.EepromData.PacketParams.Params.LoRa.Crc == LORA_CRC_ON ) ? 16 : 0; // 16 bit if present else 0
01601         uint8_t header = ( Eeprom.EepromData.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_VARIABLE_LENGTH ) ? 20 : 0; // 20 if present else 0
01602         uint16_t payload = 8 * Eeprom.EepromData.PacketParams.Params.LoRa.PayloadLength;
01603         uint8_t CR = Eeprom.EepromData.ModulationParams.Params.LoRa.CodingRate;
01604 
01605         switch( Eeprom.EepromData.ModulationParams.Params.LoRa.Bandwidth )
01606         {
01607             case LORA_BW_0200:
01608                 bw = 203;
01609                 break;
01610 
01611             case LORA_BW_0400:
01612                 bw = 406;
01613                 break;
01614 
01615             case LORA_BW_0800:
01616                 bw = 812;
01617                 break;
01618 
01619             case LORA_BW_1600:
01620                 bw = 1625;
01621                 break;
01622 
01623             default:
01624                 break;
01625         }
01626 
01627         if( SF < 7 )
01628         {
01629             nPayload = max( ( ( double )( payload + crc -(4 * SF) + header ) ), 0.0 );
01630             nPayload = nPayload / ( double )( 4 * SF );
01631             nPayload = ceil( nPayload );
01632             nPayload = nPayload * ( CR + 4 );
01633             nPayload = nPayload + Eeprom.EepromData.PacketParams.Params.LoRa.PreambleLength + 6.25 + 8;
01634         }
01635         else if( SF > 10 )
01636         {
01637             nPayload = max( ( ( double )( payload + crc -(4 * SF) + 8 + header ) ), 0.0 );
01638             nPayload = nPayload / ( double )( 4 * ( SF - 2 ) );
01639             nPayload = ceil( nPayload );
01640             nPayload = nPayload * ( CR + 4 );
01641             nPayload = nPayload + Eeprom.EepromData.PacketParams.Params.LoRa.PreambleLength + 4.25 + 8;
01642         }
01643         else
01644         {
01645             nPayload = max( ( ( double )( payload + crc -(4 * SF) + 8 + header ) ), 0.0 );
01646             nPayload = nPayload / ( double )( 4 * SF );
01647             nPayload = ceil( nPayload );
01648             nPayload = nPayload * ( CR + 4 );
01649             nPayload = nPayload + Eeprom.EepromData.PacketParams.Params.LoRa.PreambleLength + 4.25 + 8;
01650         }
01651         ts = ( double )( 1 << SF ) / ( double )( bw );
01652         tPayload = nPayload * ts;
01653 #ifdef PRINT_DEBUG
01654         printf( "ToA LoRa: %f \n\r", tPayload );
01655 #endif
01656         result = ceil( tPayload );   
01657     }
01658     else if( modulation == PACKET_TYPE_FLRC )
01659     {
01660         uint16_t BitCount = 0;
01661         uint16_t BitCountCoded = 0;
01662 
01663         BitCount = 4 + ( Eeprom.EepromData.PacketParams.Params.Flrc.PreambleLength >> 4 ) * 4;              // AGC preamble 
01664         BitCount = BitCount + 32;                                                                           // Sync Word
01665         BitCount = BitCount + 21;                                                                           // Preamble
01666         BitCount = BitCount + ( ( Eeprom.EepromData.PacketParams.Params.Flrc.HeaderType == RADIO_PACKET_VARIABLE_LENGTH ) ? 16 : 0 );
01667 
01668         switch( Eeprom.EepromData.ModulationParams.Params.Flrc.CodingRate )
01669         {
01670             case FLRC_CR_3_4:
01671                 BitCountCoded =  6 + ( Eeprom.EepromData.PacketParams.Params.Flrc.CrcLength >> 4 ) * 8;
01672                 BitCountCoded = BitCountCoded + Eeprom.EepromData.PacketParams.Params.Flrc.PayloadLength * 8;
01673                 BitCountCoded = ( uint16_t )( ( ( double )BitCountCoded * 4.0 ) / 3.0 );
01674                 break;
01675 
01676             case FLRC_CR_1_0:
01677                 BitCountCoded =  ( Eeprom.EepromData.PacketParams.Params.Flrc.CrcLength >> 4 ) * 8;
01678                 BitCountCoded = BitCountCoded + Eeprom.EepromData.PacketParams.Params.Flrc.PayloadLength * 8;
01679                 break;
01680 
01681             default:
01682             case FLRC_CR_1_2:
01683                 BitCountCoded =  6 + ( Eeprom.EepromData.PacketParams.Params.Flrc.CrcLength >> 4 ) * 8;
01684                 BitCountCoded = BitCountCoded + Eeprom.EepromData.PacketParams.Params.Flrc.PayloadLength * 8;
01685                 BitCountCoded = BitCountCoded << 1;
01686                 break;
01687         }
01688         BitCount = BitCount + BitCountCoded;
01689 
01690         switch( Eeprom.EepromData.ModulationParams.Params.Flrc.BitrateBandwidth )
01691         {
01692             case FLRC_BR_1_300_BW_1_2:
01693                 tPayload = ( double )BitCount / 1300.0;
01694                 break;
01695 
01696             case FLRC_BR_1_040_BW_1_2:
01697                 tPayload = ( double )BitCount / 1040.0;
01698                 break;
01699 
01700             case FLRC_BR_0_650_BW_0_6:
01701                 tPayload = ( double )BitCount / 650.0;
01702                 break;
01703 
01704             case FLRC_BR_0_520_BW_0_6:
01705                 tPayload = ( double )BitCount / 520.0;
01706                 break;
01707 
01708             case FLRC_BR_0_325_BW_0_3:
01709                 tPayload = ( double )BitCount / 325.0;
01710                 break;
01711 
01712             case FLRC_BR_0_260_BW_0_3:
01713                 tPayload = ( double )BitCount / 260.0;
01714                 break;
01715             
01716             default:
01717                 break;
01718         }
01719 
01720         printf( "ToA FLRC: %f \n\r", tPayload );
01721 
01722         result = ceil( tPayload );
01723     }
01724     else if( modulation == PACKET_TYPE_GFSK )
01725     {
01726         uint16_t BitCount = 0;
01727         
01728         BitCount = 4 + ( Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleLength >> 4 ) * 4;              // preamble
01729         BitCount = BitCount + 8 + ( Eeprom.EepromData.PacketParams.Params.Gfsk.SyncWordLength >> 1 ) * 8;   // sync word
01730         BitCount = BitCount + ( ( Eeprom.EepromData.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_VARIABLE_LENGTH ) ? 8 : 0 );
01731         BitCount = BitCount + Eeprom.EepromData.PacketParams.Params.Gfsk.PayloadLength * 8;
01732         BitCount = BitCount + ( Eeprom.EepromData.PacketParams.Params.Gfsk.CrcLength >> 4 ) * 8;
01733         
01734         switch( Eeprom.EepromData.ModulationParams.Params.Gfsk.BitrateBandwidth )
01735         {
01736             case GFSK_BLE_BR_2_000_BW_2_4:
01737                 tPayload = ( double )BitCount / 2000.0 ;
01738                 break;
01739 
01740             case GFSK_BLE_BR_1_600_BW_2_4:
01741                 tPayload = ( double )BitCount / 1600.0 ;
01742                 break;
01743 
01744             case GFSK_BLE_BR_1_000_BW_2_4:
01745             case GFSK_BLE_BR_1_000_BW_1_2:
01746                 tPayload = ( double )BitCount / 1000.0;
01747                 break;
01748 
01749             case GFSK_BLE_BR_0_800_BW_2_4:
01750             case GFSK_BLE_BR_0_800_BW_1_2:
01751                 tPayload = ( double )BitCount / 800.0;
01752                 break;
01753 
01754             case GFSK_BLE_BR_0_500_BW_1_2:
01755             case GFSK_BLE_BR_0_500_BW_0_6:
01756                 tPayload = ( double )BitCount / 500.0;
01757                 break;
01758 
01759             case GFSK_BLE_BR_0_400_BW_1_2:
01760             case GFSK_BLE_BR_0_400_BW_0_6:
01761                 tPayload = ( double )BitCount / 400.0;
01762                 break;
01763 
01764             case GFSK_BLE_BR_0_250_BW_0_6:
01765             case GFSK_BLE_BR_0_250_BW_0_3:
01766                 tPayload = ( double )BitCount / 250.0;
01767                 break;
01768 
01769             case GFSK_BLE_BR_0_125_BW_0_3:
01770                 tPayload = ( double )BitCount / 125.0;
01771                 break;
01772 
01773             default:
01774                 break;
01775         }
01776 #ifdef PRINT_DEBUG
01777         printf( "ToA GFSK: %f \n\r", tPayload );
01778 #endif
01779         result = ceil( tPayload );
01780     }
01781     
01782     return result;
01783 }
01784 
01785 void InitializeDemoParameters( uint8_t modulation )
01786 {
01787     Radio.SetStandby( STDBY_RC );
01788 
01789     Radio.SetRegulatorMode( ( RadioRegulatorModes_t )Eeprom.EepromData.DemoSettings.RadioPowerMode );
01790 
01791 #ifdef PRINT_DEBUG
01792     printf("> InitializeDemoParameters\n\r");
01793 #endif
01794     if( modulation == PACKET_TYPE_LORA )
01795     {
01796 #ifdef PRINT_DEBUG
01797         printf("set param LORA for demo\n\r");
01798 #endif
01799         ModulationParams.PacketType = PACKET_TYPE_LORA;
01800         PacketParams.PacketType     = PACKET_TYPE_LORA;
01801 
01802         ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t )  Eeprom.EepromData.DemoSettings.ModulationParam1;
01803         ModulationParams.Params.LoRa.Bandwidth       = ( RadioLoRaBandwidths_t )        Eeprom.EepromData.DemoSettings.ModulationParam2;
01804         ModulationParams.Params.LoRa.CodingRate      = ( RadioLoRaCodingRates_t )       Eeprom.EepromData.DemoSettings.ModulationParam3;
01805         PacketParams.Params.LoRa.PreambleLength      =                                  Eeprom.EepromData.DemoSettings.PacketParam1;
01806         PacketParams.Params.LoRa.HeaderType          = ( RadioLoRaPacketLengthsModes_t )Eeprom.EepromData.DemoSettings.PacketParam2;
01807         PacketParams.Params.LoRa.PayloadLength       =                                  Eeprom.EepromData.DemoSettings.PacketParam3;
01808         PacketParams.Params.LoRa.Crc                 = ( RadioLoRaCrcModes_t )          Eeprom.EepromData.DemoSettings.PacketParam4;
01809         PacketParams.Params.LoRa.InvertIQ            = ( RadioLoRaIQModes_t )           Eeprom.EepromData.DemoSettings.PacketParam5;
01810 
01811         Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.LoRa.PayloadLength;
01812 
01813         Radio.SetLNAGainSetting(LNA_LOW_POWER_MODE);
01814     }
01815     else if( modulation == PACKET_TYPE_FLRC )
01816     {
01817 #ifdef PRINT_DEBUG
01818         printf("set param FLRC for demo\n\r");
01819 #endif
01820         ModulationParams.PacketType = PACKET_TYPE_FLRC;
01821         PacketParams.PacketType     = PACKET_TYPE_FLRC;
01822 
01823         ModulationParams.Params.Flrc.BitrateBandwidth  = ( RadioFlrcBitrates_t )       Eeprom.EepromData.DemoSettings.ModulationParam1;
01824         ModulationParams.Params.Flrc.CodingRate        = ( RadioFlrcCodingRates_t )    Eeprom.EepromData.DemoSettings.ModulationParam2;
01825         ModulationParams.Params.Flrc.ModulationShaping = ( RadioModShapings_t )        Eeprom.EepromData.DemoSettings.ModulationParam3;
01826         PacketParams.Params.Flrc.PreambleLength        = ( RadioPreambleLengths_t )    Eeprom.EepromData.DemoSettings.PacketParam1;
01827         PacketParams.Params.Flrc.SyncWordLength        = ( RadioFlrcSyncWordLengths_t )Eeprom.EepromData.DemoSettings.PacketParam2;
01828         PacketParams.Params.Flrc.SyncWordMatch         = ( RadioSyncWordRxMatchs_t )   Eeprom.EepromData.DemoSettings.PacketParam3;
01829         PacketParams.Params.Flrc.HeaderType            = ( RadioPacketLengthModes_t )  Eeprom.EepromData.DemoSettings.PacketParam4;
01830         PacketParams.Params.Flrc.PayloadLength         =                               Eeprom.EepromData.DemoSettings.PacketParam5;
01831         PacketParams.Params.Flrc.CrcLength             = ( RadioCrcTypes_t )           Eeprom.EepromData.DemoSettings.PacketParam6;
01832         PacketParams.Params.Flrc.Whitening             = ( RadioWhiteningModes_t )     Eeprom.EepromData.DemoSettings.PacketParam7;
01833 
01834         Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.Flrc.PayloadLength;
01835 
01836         Radio.SetLNAGainSetting(LNA_HIGH_SENSITIVITY_MODE);
01837     }
01838     else if( modulation == PACKET_TYPE_GFSK )
01839     {
01840 #ifdef PRINT_DEBUG
01841         printf("set param GFSK for demo\n\r");
01842 #endif
01843         ModulationParams.PacketType = PACKET_TYPE_GFSK;
01844         PacketParams.PacketType     = PACKET_TYPE_GFSK;
01845 
01846         ModulationParams.Params.Gfsk.BitrateBandwidth  = ( RadioGfskBleBitrates_t )  Eeprom.EepromData.DemoSettings.ModulationParam1;
01847         ModulationParams.Params.Gfsk.ModulationIndex   = ( RadioGfskBleModIndexes_t )Eeprom.EepromData.DemoSettings.ModulationParam2;
01848         ModulationParams.Params.Gfsk.ModulationShaping = ( RadioModShapings_t )      Eeprom.EepromData.DemoSettings.ModulationParam3;
01849         PacketParams.Params.Gfsk.PreambleLength        = ( RadioPreambleLengths_t )  Eeprom.EepromData.DemoSettings.PacketParam1;
01850         PacketParams.Params.Gfsk.SyncWordLength        = ( RadioSyncWordLengths_t )  Eeprom.EepromData.DemoSettings.PacketParam2;
01851         PacketParams.Params.Gfsk.SyncWordMatch         = ( RadioSyncWordRxMatchs_t ) Eeprom.EepromData.DemoSettings.PacketParam3;
01852         PacketParams.Params.Gfsk.HeaderType            = ( RadioPacketLengthModes_t )Eeprom.EepromData.DemoSettings.PacketParam4;
01853         PacketParams.Params.Gfsk.PayloadLength         =                             Eeprom.EepromData.DemoSettings.PacketParam5;
01854         PacketParams.Params.Gfsk.CrcLength             = ( RadioCrcTypes_t )         Eeprom.EepromData.DemoSettings.PacketParam6;
01855         PacketParams.Params.Gfsk.Whitening             = ( RadioWhiteningModes_t )   Eeprom.EepromData.DemoSettings.PacketParam7;
01856 
01857         Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.Gfsk.PayloadLength;
01858 
01859         Radio.SetLNAGainSetting(LNA_HIGH_SENSITIVITY_MODE);
01860     }
01861     if( modulation == PACKET_TYPE_RANGING )
01862     {
01863         Radio.SetBufferBaseAddresses( 0x00, 0x00 );
01864         Radio.SetTxParams( Eeprom.EepromData.DemoSettings.TxPower, RADIO_RAMP_20_US );
01865         memcpy( &( ModulationParams.Params.LoRa.SpreadingFactor ), Eeprom.Buffer + MOD_RNG_SPREADF_EEPROM_ADDR, 1 );
01866         memcpy( &( ModulationParams.Params.LoRa.Bandwidth ),       Eeprom.Buffer + MOD_RNG_BW_EEPROM_ADDR,      1 );
01867         switch( ModulationParams.Params.LoRa.Bandwidth )
01868         {
01869             case LORA_BW_0400:
01870                 Eeprom.EepromData.DemoSettings.RngCalib     = RNG_CALIB_0400[ ( ModulationParams.Params.LoRa.SpreadingFactor >> 4 ) - 5 ];
01871                 Eeprom.EepromData.DemoSettings.RngFeiFactor = ( double )RNG_FGRAD_0400[ ( ModulationParams.Params.LoRa.SpreadingFactor >> 4 ) - 5 ];
01872                 Eeprom.EepromData.DemoSettings.RngReqDelay  = RNG_TIMER_MS >> ( 0 + 10 - ( ModulationParams.Params.LoRa.SpreadingFactor >> 4 ) );
01873                 break;
01874 
01875             case LORA_BW_0800:
01876                 Eeprom.EepromData.DemoSettings.RngCalib     = RNG_CALIB_0800[ ( ModulationParams.Params.LoRa.SpreadingFactor >> 4 ) - 5 ];
01877                 Eeprom.EepromData.DemoSettings.RngFeiFactor = ( double )RNG_FGRAD_0800[ ( ModulationParams.Params.LoRa.SpreadingFactor >> 4 ) - 5 ];
01878                 Eeprom.EepromData.DemoSettings.RngReqDelay  = RNG_TIMER_MS >> ( 1 + 10 - ( ModulationParams.Params.LoRa.SpreadingFactor >> 4 ) );
01879                 break;
01880 
01881             case LORA_BW_1600:
01882                 Eeprom.EepromData.DemoSettings.RngCalib     = RNG_CALIB_1600[ ( ModulationParams.Params.LoRa.SpreadingFactor >> 4 ) - 5 ];
01883                 Eeprom.EepromData.DemoSettings.RngFeiFactor = ( double )RNG_FGRAD_1600[ ( ModulationParams.Params.LoRa.SpreadingFactor >> 4 ) - 5 ];
01884                 Eeprom.EepromData.DemoSettings.RngReqDelay  = RNG_TIMER_MS >> ( 2 + 10 - ( ModulationParams.Params.LoRa.SpreadingFactor >> 4 ) );
01885                 break;
01886         }
01887 
01888         Radio.SetPollingMode( );
01889         Radio.SetLNAGainSetting(LNA_LOW_POWER_MODE);
01890     }
01891     else
01892     {
01893         Radio.SetStandby( STDBY_RC );
01894         Radio.SetPacketType( ModulationParams.PacketType );
01895         Radio.SetRfFrequency( Eeprom.EepromData.DemoSettings.Frequency );
01896         Radio.SetBufferBaseAddresses( 0x00, 0x00 );
01897         Radio.SetModulationParams( &ModulationParams );
01898         Radio.SetPacketParams( &PacketParams );
01899         // only used in GFSK, FLRC (4 bytes max) and BLE mode
01900         Radio.SetSyncWord( 1, ( uint8_t[] ){ 0xDD, 0xA0, 0x96, 0x69, 0xDD } );
01901         // only used in GFSK, FLRC
01902         uint8_t crcSeedLocal[2] = {0x45, 0x67};
01903         Radio.SetCrcSeed( crcSeedLocal );
01904         Radio.SetCrcPolynomial( 0x0123 );
01905         Radio.SetTxParams( Eeprom.EepromData.DemoSettings.TxPower, RADIO_RAMP_20_US );
01906         Radio.SetPollingMode( );
01907     }
01908 }
01909 
01910 /*!
01911  * \brief Callback of ticker PerSendNextPacket
01912  */
01913 void SendNextPacketEvent( void )
01914 {
01915     SendNext = true;
01916     if( Eeprom.EepromData.DemoSettings.RngStatus == RNG_PROCESS )
01917     {
01918         Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave++;
01919     }
01920 }
01921 
01922 /*!
01923  * \brief Callback of ticker ReceiveNextPacket
01924  */
01925 void ReceiveNextPacketEvent( void )
01926 {
01927     ReceiveNext = true;
01928 }
01929 
01930 uint8_t CheckDistance( void )
01931 {
01932     double displayRange = 0.0;
01933 
01934     uint16_t j = 0;
01935     uint16_t i;
01936 
01937 #ifdef PRINT_DEBUG
01938     printf( "#id: %d", Eeprom.EepromData.DemoSettings.CntPacketTx );
01939 #endif
01940     if( RngResultIndex > 0 )
01941     {
01942         for( i = 0; i < RngResultIndex; ++i )
01943         {
01944             RawRngResults[i] = RawRngResults[i] - ( Eeprom.EepromData.DemoSettings.RngFeiFactor * Eeprom.EepromData.DemoSettings.RngFei / 1000 );
01945         }
01946 
01947         for (int i = RngResultIndex - 1; i > 0; --i) 
01948         {
01949             for (int j = 0; j < i; ++j) 
01950             {
01951                 if (RawRngResults[j] > RawRngResults[j+1]) 
01952                 {
01953                     int temp = RawRngResults[j];
01954                     RawRngResults[j] = RawRngResults[j+1];
01955                     RawRngResults[j+1] = temp;
01956                 }
01957             }
01958         }
01959         double median;
01960         if ((RngResultIndex % 2) == 0) 
01961         {
01962             median = (RawRngResults[RngResultIndex/2] + RawRngResults[(RngResultIndex/2) - 1])/2.0;
01963         }
01964         else
01965         {
01966             median = RawRngResults[RngResultIndex/2];
01967         }
01968 
01969         if( median < 100 )
01970         {
01971             printf("median: %f \n\r", median );
01972             // Apply the short range correction and RSSI short range improvement below 50 m
01973             displayRange = Sx1280RangingCorrection::ComputeRangingCorrectionPolynome(
01974                 ModulationParams.Params.LoRa.SpreadingFactor,
01975                 ModulationParams.Params.LoRa.Bandwidth,
01976                 median
01977             );
01978             printf("Corrected range: %f \n\r", displayRange );
01979             //displayRange = t0 + t1 * rssi + t2 * pow(rssi,2) + t3 * pow(rssi, 3) + t4 * median + t5 * pow(median,2) + t6 * pow(median, 3) + t7 * pow(median, 4) ;
01980             //printf("displayRange %f \n\r", displayRange );
01981 //            double correctedRange = 0;
01982 //            uint8_t k = 0;
01983 //            uint8_t order = 6;
01984 //            for( k = 1; k <= (order+1); k++ )                    // loop though each polynomial term and sum
01985 //            {
01986 //                correctedRange = correctedRange + p[k] * pow( median, ( order + 1 - k ) );
01987 //                printf("correctedRange[%d] %f \n\r", k, correctedRange );
01988 //            }
01989 //            printf("Final correctedRange %f \n\r", correctedRange );
01990 //            displayRange = correctedRange - 2;
01991         }
01992         else
01993         {
01994             displayRange = median;
01995         }
01996 
01997         if( j < DEMO_RNG_CHANNELS_COUNT_MIN )
01998         {
01999             Eeprom.EepromData.DemoSettings.RngStatus = RNG_PER_ERROR;
02000         }
02001         else
02002         {
02003             Eeprom.EepromData.DemoSettings.RngStatus = RNG_VALID;
02004         }
02005 
02006         if( displayRange < 0 )
02007         {
02008             Eeprom.EepromData.DemoSettings.RngDistance = 0.0;
02009         }
02010         else
02011         {
02012             switch( Eeprom.EepromData.DemoSettings.RngUnit )
02013             {
02014                 case DEMO_RNG_UNIT_SEL_M:
02015                     Eeprom.EepromData.DemoSettings.RngDistance = displayRange;
02016                     break;
02017 
02018                 case DEMO_RNG_UNIT_SEL_YD:
02019                     Eeprom.EepromData.DemoSettings.RngDistance = displayRange * DEMO_RNG_UNIT_CONV_YD;
02020                     break;
02021 
02022                 case DEMO_RNG_UNIT_SEL_MI:
02023                     Eeprom.EepromData.DemoSettings.RngDistance = displayRange * DEMO_RNG_UNIT_CONV_MI;
02024                     break;
02025             }
02026         }
02027     }
02028     printf( ", Rssi: %d, Zn: %3d, Zmoy: %5.1f, FEI: %d\r\n", Eeprom.EepromData.DemoSettings.RssiValue, j, displayRange, ( int32_t )Eeprom.EepromData.DemoSettings.RngFei );
02029 
02030     return j;
02031 }
02032 
02033 void LedBlink( void )
02034 {
02035     if( ( TX_LED == 0 ) && ( RX_LED == 0 ) )
02036     {
02037         TX_LED = 1;
02038     }
02039     else if( ( TX_LED == 1 ) && ( RX_LED == 0 ) )
02040     {
02041         RX_LED = 1;
02042     }
02043     else if( ( TX_LED == 1 ) && ( RX_LED == 1 ) )
02044     {
02045         TX_LED = 0;
02046     }
02047     else
02048     {
02049         RX_LED = 0;
02050     }
02051 }
02052 
02053 void SetAntennaSwitch( void )
02054 {
02055     if( Eeprom.EepromData.DemoSettings.AntennaSwitch == 0 )
02056     {
02057         ANT_SW = 1; // ANT1
02058     }
02059     else
02060     {
02061         ANT_SW = 0; // ANT0
02062     }
02063 }
02064 
02065 // ************************     Radio Callbacks     ****************************
02066 // *                                                                           *
02067 // * These functions are called through function pointer by the Radio low      *
02068 // * level drivers                                                             *
02069 // *                                                                           *
02070 // *****************************************************************************
02071 void OnTxDone( void )
02072 {
02073     DemoInternalState = APP_TX;
02074 }
02075 
02076 void OnRxDone( void )
02077 {
02078     DemoInternalState = APP_RX;
02079 }
02080 
02081 void OnTxTimeout( void )
02082 {
02083     DemoInternalState = APP_TX_TIMEOUT;
02084 }
02085 
02086 void OnRxTimeout( void )
02087 {
02088     DemoInternalState = APP_RX_TIMEOUT;
02089 }
02090 
02091 void OnRxError( IrqErrorCode_t errorCode )
02092 {
02093     DemoInternalState = APP_RX_ERROR;
02094 }
02095 
02096 void OnRangingDone( IrqRangingCode_t val )
02097 {
02098     if( val == IRQ_RANGING_MASTER_VALID_CODE || val == IRQ_RANGING_SLAVE_VALID_CODE )
02099     {
02100         DemoInternalState = APP_RANGING_DONE;
02101     }
02102     else if( val == IRQ_RANGING_MASTER_ERROR_CODE || val == IRQ_RANGING_SLAVE_ERROR_CODE )
02103     {
02104         DemoInternalState = APP_RANGING_TIMEOUT;
02105     }
02106     else
02107     {
02108         DemoInternalState = APP_RANGING_TIMEOUT;
02109     }
02110 }
02111 
02112 void OnCadDone( bool channelActivityDetected )
02113 {
02114 }