Source code for the SX126xDVK1xAS Dev Kit. This example code has only been tested on the Nucleo L476RG
Dependencies: mbed DmTftLibrary SX126xLib
DemoApplication.cpp
00001 /* 00002 ______ _ 00003 / _____) _ | | 00004 ( (____ _____ ____ _| |_ _____ ____| |__ 00005 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00006 _____) ) ____| | | || |_| ____( (___| | | | 00007 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00008 (C)2016 Semtech 00009 00010 Description: PingPong, PER demo implementation. 00011 00012 Maintainer: Gregory Cristian & Gilbert Menth 00013 */ 00014 00015 #include "mbed.h" 00016 #include "radio.h" 00017 #include "sx126x-hal.h" 00018 #include "Eeprom.h" 00019 #include "DemoApplication.h" 00020 00021 /*! 00022 * \brief Defines the local payload buffer size 00023 */ 00024 #define BUFFER_SIZE 255 00025 00026 /*! 00027 * \brief Defines the size of the token defining message type in the payload 00028 * cf. above. 00029 */ 00030 #define PINGPONG_SIZE 4 00031 #define PER_SIZE 3 00032 00033 /*! 00034 * \brief Define time used in PingPong demo to synch with cycle 00035 * RX_TIMEOUT_MARGIN is the free time between each cycle (time reserve) 00036 */ 00037 #define RX_TIMEOUT_MARGIN 150 // ms 00038 #define RX_TX_TRANSITION_WAIT 5 // ms 00039 00040 00041 /*! 00042 * \brief Define the possible message type for the Ping-Pong and PER apps 00043 */ 00044 const uint8_t PingMsg[] = "PING"; 00045 const uint8_t PongMsg[] = "PONG"; 00046 const uint8_t PerMsg[] = "PER"; 00047 00048 /*! 00049 * \brief Buffer and its size 00050 */ 00051 uint8_t BufferSize = BUFFER_SIZE; 00052 uint8_t Buffer[BUFFER_SIZE]; 00053 00054 /*! 00055 * \brief Function to be executed on Radio Tx Done event 00056 */ 00057 void OnTxDone( void ); 00058 00059 /*! 00060 * \brief Function to be executed on Radio Rx Done event 00061 */ 00062 void OnRxDone( void ); 00063 00064 /*! 00065 * \brief Function executed on Radio Tx Timeout event 00066 */ 00067 void OnTxTimeout( void ); 00068 00069 /*! 00070 * \brief Function executed on Radio Rx Timeout event 00071 */ 00072 void OnRxTimeout( void ); 00073 00074 /*! 00075 * \brief Function executed on Radio Rx Error event 00076 */ 00077 void OnRxError( IrqErrorCode_t ); 00078 00079 /*! 00080 * \brief Function executed on Radio CAD Done event 00081 */ 00082 void OnCadDone( bool channelActivityDetected ); 00083 00084 /*! 00085 * \brief All the callbacks are stored in a structure 00086 */ 00087 RadioCallbacks_t RadioEvents = 00088 { 00089 &OnTxDone, // txDone 00090 &OnRxDone, // rxDone 00091 NULL, // rxPreambleDetect 00092 NULL, // rxSyncWordDone 00093 NULL, // rxHeaderDone 00094 &OnTxTimeout, // txTimeout 00095 &OnRxTimeout, // rxTimeout 00096 &OnRxError, // rxError 00097 &OnCadDone, // cadDone 00098 }; 00099 00100 // SPI 00101 // mosi, miso, sclk, nss, dio0, dio1, dio2, dio3, rst, freqSel, deviceSel, antSwPower, callbacks... 00102 SX126xHal Radio( D11, D12, D13, D7, D3, D5, NC, NC, A0, A1, A2, D8, &RadioEvents ); 00103 00104 /*! 00105 * \brief Tx LED toggling on transmition success 00106 */ 00107 DigitalOut TX_LED( A4 ); 00108 00109 /*! 00110 * \brief Rx LED toggling on reception success 00111 */ 00112 DigitalOut RX_LED( A5 ); 00113 00114 /*! 00115 * \brief Mask of IRQs 00116 */ 00117 uint16_t IrqMask = 0x0000; 00118 00119 /*! 00120 * \brief Locals parameters and status for radio API 00121 * NEED TO BE OPTIMIZED, COPY OF STUCTURE ALREADY EXISTING 00122 */ 00123 PacketParams_t PacketParams; 00124 PacketStatus_t PacketStatus; 00125 ModulationParams_t ModulationParams; 00126 00127 /*! 00128 * \brief Flag to indicate if the demo is already running 00129 */ 00130 static bool DemoRunning = false; 00131 00132 /*! 00133 * \brief Frequency Error (only LSB) 00134 */ 00135 static double FreErrorLsb = 0.0; 00136 00137 /*! 00138 * \brief Flag holding the current internal state of the demo application 00139 */ 00140 static uint8_t DemoInternalState = APP_IDLE; 00141 00142 /*! 00143 * \brief Ticker for master to synch Tx frames. Flags for PER and PingPong demo 00144 * for Synch TX in cycle. 00145 */ 00146 Ticker SendNextPacket; 00147 static bool SendNext = false; 00148 00149 /*! 00150 * \brief Hold last Rx packet number to compute PER in PER and PingPong demo 00151 */ 00152 static uint32_t PacketRxSequence = 0; 00153 static uint32_t PacketRxSequencePrev = 0; 00154 00155 void LedBlink( void ); 00156 void InitializeDemoParameters( uint8_t modulation ); 00157 uint16_t GetTimeOnAir( uint8_t modulation ); 00158 void SendNextPacketEvent( void ); 00159 00160 // ************************** RF Test Demo ****************************** 00161 // * * 00162 // * * 00163 // * * 00164 // ***************************************************************************** 00165 uint8_t RunDemoTestRssi( void ) 00166 { 00167 uint8_t refreshDisplay = 0; 00168 static uint16_t i; 00169 00170 if( Eeprom.EepromData.DemoSettings.HoldDemo == true ) 00171 { 00172 return 0; 00173 } 00174 00175 if( DemoRunning == false ) 00176 { 00177 DemoRunning = true; 00178 00179 printf( "Start RunDemoTestRssi\n\r" ); 00180 00181 TX_LED = 0; 00182 RX_LED = 0; 00183 00184 Eeprom.EepromData.DemoSettings.CntPacketTx = 0; 00185 Eeprom.EepromData.DemoSettings.CntPacketRxOK = 0; 00186 Eeprom.EepromData.DemoSettings.CntPacketRxKO = 0; 00187 00188 InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType ); 00189 00190 IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 00191 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00192 // Rx Continuous 00193 if( Eeprom.EepromData.DemoSettings.BoostedRx == false ) 00194 { 00195 Radio.SetRx( 0xFFFFFF ); 00196 } 00197 else 00198 { 00199 Radio.SetRxBoosted( 0xFFFFFF ); 00200 } 00201 DemoInternalState = APP_IDLE; 00202 i = 0; 00203 } 00204 00205 Radio.ProcessIrqs( ); 00206 00207 if( i < 5000 ) 00208 { 00209 i++; 00210 } 00211 else 00212 { 00213 i = 0; 00214 Eeprom.EepromData.DemoSettings.RssiValue = Radio.GetRssiInst( ); 00215 refreshDisplay = 1; 00216 } 00217 00218 return refreshDisplay; 00219 } 00220 00221 uint8_t RunDemoSleepMode( void ) 00222 { 00223 SleepParams_t SleepParam; 00224 00225 if( Eeprom.EepromData.DemoSettings.HoldDemo == true ) 00226 { 00227 return 0; 00228 } 00229 00230 if( DemoRunning == false ) 00231 { 00232 DemoRunning = true; 00233 InitializeDemoParameters( PACKET_TYPE_LORA ); 00234 TX_LED = 0; 00235 RX_LED = 0; 00236 00237 SleepParam.Fields.WakeUpRTC = 0; //!< Get out of sleep mode if wakeup signal received from RTC 00238 SleepParam.Fields.Reset = 0; //!< 00239 SleepParam.Fields.WarmStart = 1; //!< 00240 Radio.SetSleep( SleepParam ); 00241 } 00242 else 00243 { 00244 LedBlink( ); 00245 } 00246 return 0; 00247 } 00248 00249 uint8_t RunDemoStandbyRcMode( void ) 00250 { 00251 if( Eeprom.EepromData.DemoSettings.HoldDemo == true ) 00252 { 00253 return 0; 00254 } 00255 00256 if( DemoRunning == false ) 00257 { 00258 DemoRunning = true; 00259 InitializeDemoParameters( PACKET_TYPE_LORA ); 00260 TX_LED = 0; 00261 RX_LED = 0; 00262 Radio.SetRegulatorMode( ( RadioRegulatorMode_t )Eeprom.EepromData.DemoSettings.RadioPowerMode ); 00263 Radio.SetStandby( STDBY_RC ); 00264 DemoRunning = true; 00265 } 00266 else 00267 { 00268 LedBlink( ); 00269 } 00270 return 0; 00271 } 00272 00273 uint8_t RunDemoStandbyXoscMode( void ) 00274 { 00275 if( Eeprom.EepromData.DemoSettings.HoldDemo == true ) 00276 { 00277 return 0; 00278 } 00279 if( DemoRunning == false ) 00280 { 00281 DemoRunning = true; 00282 InitializeDemoParameters( PACKET_TYPE_LORA ); 00283 TX_LED = 0; 00284 RX_LED = 0; 00285 Radio.SetRegulatorMode( ( RadioRegulatorMode_t )Eeprom.EepromData.DemoSettings.RadioPowerMode ); 00286 Radio.SetStandby( STDBY_XOSC ); 00287 DemoRunning = true; 00288 } 00289 else 00290 { 00291 LedBlink( ); 00292 } 00293 return 0; 00294 } 00295 00296 uint8_t RunDemoTxCw( void ) 00297 { 00298 if( Eeprom.EepromData.DemoSettings.HoldDemo == true ) 00299 { 00300 return 0; 00301 } 00302 00303 if( DemoRunning == false ) 00304 { 00305 DemoRunning = true; 00306 InitializeDemoParameters( PACKET_TYPE_LORA ); 00307 TX_LED = 0; 00308 RX_LED = 0; 00309 Radio.SetStandby( STDBY_RC ); 00310 Radio.SetRegulatorMode( ( RadioRegulatorMode_t )Eeprom.EepromData.DemoSettings.RadioPowerMode ); 00311 Radio.SetRfFrequency( Eeprom.EepromData.DemoSettings.Frequency ); 00312 Radio.SetTxParams( Eeprom.EepromData.DemoSettings.TxPower, RADIO_RAMP_200_US ); 00313 Radio.SetTxContinuousWave( ); 00314 DemoRunning = true; 00315 } 00316 else 00317 { 00318 LedBlink( ); 00319 } 00320 return 0; 00321 } 00322 00323 uint8_t RunDemoTxContinuousModulation( void ) 00324 { 00325 uint8_t localPayloadSize = 250; 00326 uint8_t i = 0; 00327 00328 if( Eeprom.EepromData.DemoSettings.HoldDemo == true ) 00329 { 00330 return 0; 00331 } 00332 00333 Radio.ProcessIrqs( ); 00334 00335 if( DemoRunning == false ) 00336 { 00337 DemoRunning = true; 00338 InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType ); 00339 Radio.SetTxParams( Eeprom.EepromData.DemoSettings.TxPower, RADIO_RAMP_3400_US ); 00340 TX_LED = 0; 00341 RX_LED = 0; 00342 IrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT; 00343 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00344 for( i = 0; i < localPayloadSize; i++ ) 00345 { 00346 Buffer[i] = ( uint8_t )rand( ); 00347 } 00348 Radio.SendPayload( Buffer, localPayloadSize, 0xFFFFFF ); 00349 DemoInternalState = APP_IDLE; 00350 } 00351 else 00352 { 00353 switch( DemoInternalState ) 00354 { 00355 case APP_RX: 00356 break; 00357 00358 case APP_TX: 00359 DemoInternalState = APP_IDLE; 00360 LedBlink( ); 00361 // Send the next frame 00362 IrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT; 00363 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00364 00365 Radio.SendPayload( Buffer, localPayloadSize, 0xFFFFFF ); 00366 // we prepare next payload during transmission 00367 for( i = 0; i < localPayloadSize; i++ ) 00368 { 00369 Buffer[i] = ( uint8_t )rand( ); 00370 } 00371 break; 00372 00373 case APP_RX_TIMEOUT: 00374 DemoInternalState = APP_IDLE; 00375 break; 00376 00377 case APP_RX_ERROR: 00378 DemoInternalState = APP_IDLE; 00379 break; 00380 00381 case APP_TX_TIMEOUT: 00382 DemoInternalState = APP_IDLE; 00383 break; 00384 00385 case APP_IDLE: 00386 break; 00387 00388 default: 00389 break; 00390 } 00391 } 00392 00393 return 0; 00394 } 00395 00396 uint8_t RunDemoRxContinuous( void ) 00397 { 00398 uint8_t refreshDisplay = 0; 00399 00400 if( Eeprom.EepromData.DemoSettings.HoldDemo == true ) 00401 { 00402 return 0; 00403 } 00404 00405 if( DemoRunning == false ) 00406 { 00407 DemoRunning = true; 00408 00409 printf( "Start RunDemoRxContinuous\n\r" ); 00410 00411 TX_LED = 0; 00412 RX_LED = 0; 00413 00414 Eeprom.EepromData.DemoSettings.CntPacketTx = 0; 00415 Eeprom.EepromData.DemoSettings.CntPacketRxOK = 0; 00416 Eeprom.EepromData.DemoSettings.CntPacketRxKO = 0; 00417 00418 InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType ); 00419 00420 // set preamble to max size to avoid filtering of the receiver on preamble lenght 00421 if( Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_LORA ) 00422 { 00423 PacketParams.Params.LoRa.PreambleLength = 0xFFFF; 00424 PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )Eeprom.EepromData.DemoSettings.PacketParam2; 00425 PacketParams.Params.LoRa.PayloadLength = Eeprom.EepromData.DemoSettings.PacketParam3; 00426 PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t ) Eeprom.EepromData.DemoSettings.PacketParam4; 00427 PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t ) Eeprom.EepromData.DemoSettings.PacketParam5; 00428 Radio.SetPacketParams( &PacketParams ); 00429 } 00430 00431 IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 00432 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00433 // Rx Continuous 00434 if( Eeprom.EepromData.DemoSettings.BoostedRx == false ) 00435 { 00436 Radio.SetRx( 0xFFFFFF ); 00437 } 00438 else 00439 { 00440 Radio.SetRxBoosted( 0xFFFFFF ); 00441 } 00442 DemoInternalState = APP_IDLE; 00443 00444 } 00445 00446 if( Eeprom.EepromData.DemoSettings.MaxNumPacket > 0 ) // != Infinite 00447 { 00448 if( ( Eeprom.EepromData.DemoSettings.CntPacketRxOK + \ 00449 Eeprom.EepromData.DemoSettings.CntPacketRxKO ) >= \ 00450 Eeprom.EepromData.DemoSettings.MaxNumPacket ) 00451 { 00452 RX_LED = 0; 00453 TX_LED = 0; 00454 DemoInternalState = APP_IDLE; 00455 Radio.SetStandby( STDBY_RC ); 00456 SendNextPacket.detach( ); 00457 Eeprom.EepromData.DemoSettings.HoldDemo = true; 00458 refreshDisplay = 1; 00459 } 00460 } 00461 00462 Radio.ProcessIrqs( ); 00463 00464 switch( DemoInternalState ) 00465 { 00466 case APP_TX: 00467 break; 00468 00469 case APP_RX: 00470 RX_LED = !RX_LED; 00471 Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE ); 00472 Radio.GetPacketStatus( &PacketStatus ); 00473 if( Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_LORA ) 00474 { 00475 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Params.LoRa.RssiPkt; 00476 Eeprom.EepromData.DemoSettings.SnrValue = PacketStatus.Params.LoRa.SnrPkt; 00477 if( ( PacketStatus.Params.LoRa.FreqError & 0x00080000 ) == 0x00080000 ) 00478 { 00479 PacketStatus.Params.LoRa.FreqError = 0xFFFFF - PacketStatus.Params.LoRa.FreqError; 00480 } 00481 Eeprom.EepromData.DemoSettings.FreqErrorEst = ( double )PacketStatus.Params.LoRa.FreqError * FreErrorLsb; 00482 } 00483 else // Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_GFSK 00484 { 00485 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Params.Gfsk.RssiAvg; 00486 Eeprom.EepromData.DemoSettings.SnrValue = 0; 00487 } 00488 00489 DemoInternalState = APP_IDLE; 00490 Eeprom.EepromData.DemoSettings.CntPacketRxOK ++; 00491 refreshDisplay = 1; 00492 break; 00493 00494 case APP_RX_ERROR: 00495 case APP_RX_TIMEOUT: 00496 Eeprom.EepromData.DemoSettings.CntPacketRxKO ++; 00497 DemoInternalState = APP_IDLE; 00498 refreshDisplay = 1; 00499 break; 00500 00501 case APP_TX_TIMEOUT: 00502 break; 00503 00504 case APP_IDLE: 00505 break; 00506 00507 default: 00508 break; 00509 } 00510 return refreshDisplay; 00511 } 00512 00513 // ************************* PER Demo ****************************** 00514 // * * 00515 // * * 00516 // * * 00517 // ***************************************************************************** 00518 uint8_t RunDemoApplicationPer( void ) 00519 { 00520 uint8_t i = 0; 00521 uint8_t refreshDisplay = 0; 00522 00523 if( Eeprom.EepromData.DemoSettings.HoldDemo == true ) 00524 { 00525 return 0; 00526 } 00527 00528 if( DemoRunning == false ) 00529 { 00530 DemoRunning = true; 00531 00532 printf( "Start RunDemoApplicationPer\n\r" ); 00533 00534 TX_LED = 0; 00535 RX_LED = 0; 00536 00537 Eeprom.EepromData.DemoSettings.CntPacketTx = 0; 00538 Eeprom.EepromData.DemoSettings.CntPacketRxOK = 0; 00539 Eeprom.EepromData.DemoSettings.CntPacketRxKO = 0; 00540 Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0; 00541 00542 InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType ); 00543 00544 Eeprom.EepromData.DemoSettings.InterPacketDelay = GetTimeOnAir( Eeprom.EepromData.DemoSettings.ModulationType ) + RX_TX_TRANSITION_WAIT; 00545 00546 if( Eeprom.EepromData.DemoSettings.Entity == MASTER ) 00547 { 00548 SendNextPacket.attach_us( &SendNextPacketEvent, ( uint32_t )( ( Eeprom.EepromData.DemoSettings.InterPacketDelay + RX_TIMEOUT_MARGIN ) * 1000 ) ); 00549 DemoInternalState = APP_TX; 00550 } 00551 else 00552 { 00553 IrqMask = /*0xFFFF; */IRQ_HEADER_VALID | IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 00554 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00555 // Rx Single without timeout for the start 00556 if( Eeprom.EepromData.DemoSettings.BoostedRx == false ) 00557 { 00558 Radio.SetRx( 0x0000 ); 00559 } 00560 else 00561 { 00562 Radio.SetRxBoosted( 0x0000 ); 00563 } 00564 DemoInternalState = APP_IDLE; 00565 } 00566 } 00567 00568 Radio.ProcessIrqs( ); 00569 00570 if( Eeprom.EepromData.DemoSettings.MaxNumPacket > 0 ) // != Infinite 00571 { 00572 if( ( Eeprom.EepromData.DemoSettings.CntPacketRxOK + \ 00573 Eeprom.EepromData.DemoSettings.CntPacketRxKO + \ 00574 Eeprom.EepromData.DemoSettings.RxTimeOutCount) >= \ 00575 Eeprom.EepromData.DemoSettings.MaxNumPacket ) 00576 { 00577 RX_LED = 0; 00578 TX_LED = 0; 00579 DemoInternalState = APP_IDLE; 00580 Radio.SetStandby( STDBY_RC ); 00581 SendNextPacket.detach( ); 00582 Eeprom.EepromData.DemoSettings.HoldDemo = true; 00583 refreshDisplay = 1; 00584 } 00585 } 00586 00587 switch( DemoInternalState ) 00588 { 00589 case PER_TX_START: 00590 Eeprom.EepromData.DemoSettings.CntPacketTx++; 00591 DemoInternalState = APP_IDLE; 00592 00593 Buffer[0] = 0x00; 00594 Buffer[1] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 24 ) & 0xFF; 00595 Buffer[2] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 16 ) & 0xFF; 00596 Buffer[3] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 8 ) & 0xFF; 00597 Buffer[4] = Eeprom.EepromData.DemoSettings.CntPacketTx & 0xFF; 00598 Buffer[5] = PerMsg[0]; 00599 Buffer[6] = PerMsg[1]; 00600 Buffer[7] = PerMsg[2]; 00601 for( i = 8; i < Eeprom.EepromData.DemoSettings.PayloadLength; i++ ) 00602 { 00603 Buffer[i] = i; 00604 } 00605 TX_LED = !TX_LED; 00606 IrqMask = 0xFFFF; //IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT; 00607 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00608 Radio.SendPayload( Buffer, Eeprom.EepromData.DemoSettings.PayloadLength, ( Eeprom.EepromData.DemoSettings.InterPacketDelay ) << 6 ); 00609 break; 00610 00611 case PER_RX_START: 00612 IrqMask = /*0xFFFF;*/ IRQ_HEADER_VALID | IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 00613 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00614 if( Eeprom.EepromData.DemoSettings.BoostedRx == false ) 00615 { 00616 Radio.SetRx( ( Eeprom.EepromData.DemoSettings.InterPacketDelay + RX_TIMEOUT_MARGIN ) << 6 ); 00617 } 00618 else 00619 { 00620 Radio.SetRxBoosted( ( Eeprom.EepromData.DemoSettings.InterPacketDelay + RX_TIMEOUT_MARGIN ) << 6 ); 00621 } 00622 DemoInternalState = APP_IDLE; 00623 break; 00624 00625 case APP_TX: 00626 if( SendNext == true ) 00627 { 00628 SendNext = false; 00629 if( Eeprom.EepromData.DemoSettings.MaxNumPacket == 0 ) 00630 { 00631 DemoInternalState = PER_TX_START; // Infinite -> send next 00632 refreshDisplay = 1; 00633 } 00634 else if( Eeprom.EepromData.DemoSettings.CntPacketTx < \ 00635 Eeprom.EepromData.DemoSettings.MaxNumPacket ) 00636 { 00637 DemoInternalState = PER_TX_START; // MaxNumPacket not sent 00638 refreshDisplay = 1; 00639 } 00640 else // MaxNumPacket sent -> end of demo 00641 { 00642 RX_LED = 0; 00643 TX_LED = 0; 00644 DemoInternalState = APP_IDLE; 00645 Radio.SetStandby( STDBY_RC ); 00646 SendNextPacket.detach( ); 00647 Eeprom.EepromData.DemoSettings.HoldDemo = true; 00648 refreshDisplay = 1; 00649 } 00650 } 00651 break; 00652 00653 case APP_RX: 00654 RX_LED = !RX_LED; 00655 Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE ); 00656 Radio.GetPacketStatus( &PacketStatus ); 00657 if( Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_LORA ) 00658 { 00659 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Params.LoRa.RssiPkt; 00660 Eeprom.EepromData.DemoSettings.SnrValue = PacketStatus.Params.LoRa.SnrPkt; 00661 if( ( PacketStatus.Params.LoRa.FreqError & 0x00080000 ) == 0x00080000 ) 00662 { 00663 PacketStatus.Params.LoRa.FreqError = 0xFFFFF - PacketStatus.Params.LoRa.FreqError; 00664 } 00665 Eeprom.EepromData.DemoSettings.FreqErrorEst = ( double )PacketStatus.Params.LoRa.FreqError * FreErrorLsb; 00666 } 00667 else // Eeprom.EepromData.DemoSettings.ModulationType == PACKET_TYPE_GFSK 00668 { 00669 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Params.Gfsk.RssiAvg; 00670 Eeprom.EepromData.DemoSettings.SnrValue = 0; 00671 if( ( PacketStatus.Params.Gfsk.FreqError & 0x00000800 ) == 0x00000800 ) 00672 { 00673 PacketStatus.Params.Gfsk.FreqError = 0x00000FFF - PacketStatus.Params.Gfsk.FreqError; 00674 } 00675 PacketStatus.Params.LoRa.FreqError = PacketStatus.Params.LoRa.FreqError / 2048; 00676 Eeprom.EepromData.DemoSettings.FreqErrorEst = ( ( double )PacketStatus.Params.Gfsk.FreqError / 2048.0 ); 00677 } 00678 00679 DemoInternalState = PER_RX_START; 00680 if( ( BufferSize >= PER_SIZE ) && ( strncmp( ( const char* )( Buffer + 5 ), ( const char* )PerMsg, PER_SIZE ) == 0 ) ) 00681 { 00682 ComputePerPayload( Buffer, BufferSize ); 00683 refreshDisplay = 1; 00684 } 00685 else 00686 { 00687 Eeprom.EepromData.DemoSettings.RxTimeOutCount++; 00688 } 00689 break; 00690 00691 case APP_RX_ERROR: 00692 case APP_RX_TIMEOUT: 00693 Eeprom.EepromData.DemoSettings.RxTimeOutCount++; 00694 DemoInternalState = PER_RX_START; 00695 refreshDisplay = 1; 00696 break; 00697 00698 case APP_TX_TIMEOUT: 00699 printf( "Failure: timeout in Tx is shorter than the packet time on air\n\r" ); 00700 DemoInternalState = APP_IDLE; 00701 Eeprom.EepromData.DemoSettings.HoldDemo = true; 00702 refreshDisplay = 1; 00703 break; 00704 00705 case APP_IDLE: // do nothing 00706 /* 00707 val = Radio.GetSysErrors( ); 00708 if( val.Value != 0x0000 ) 00709 { 00710 printf(" Dev Error = 0x%04x \n\r", val.Value ); 00711 } 00712 */ 00713 break; 00714 00715 default: 00716 break; 00717 } 00718 return refreshDisplay; 00719 } 00720 00721 void ComputePerPayload( uint8_t *buffer, uint8_t bufferSize ) 00722 { 00723 uint32_t i = 0; 00724 00725 Eeprom.EepromData.DemoSettings.CntPacketRxOK++; 00726 PacketRxSequence = ( ( uint32_t )buffer[1] << 24 ) | \ 00727 ( ( uint32_t )buffer[2] << 16 ) | \ 00728 ( ( uint32_t )buffer[3] << 8 ) | \ 00729 buffer[4]; 00730 00731 if( ( PacketRxSequence <= PacketRxSequencePrev ) || \ 00732 ( PacketRxSequencePrev == 0xFFFFFFFF ) ) 00733 { 00734 // Sequence went back => resynchronization 00735 // Don't count missed packets this time 00736 i = 0; 00737 } 00738 else 00739 { 00740 // Determine number of missed packets 00741 i = PacketRxSequence - PacketRxSequencePrev - 1; 00742 } 00743 // Be ready for the next 00744 PacketRxSequencePrev = PacketRxSequence; 00745 // increment 'missed' counter for the RX session 00746 Eeprom.EepromData.DemoSettings.CntPacketRxKO += i; 00747 Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0; 00748 } 00749 00750 // ************************ Ping Pong Demo ***************************** 00751 // * * 00752 // * * 00753 // * * 00754 // ***************************************************************************** 00755 uint8_t RunDemoApplicationPingPong( void ) 00756 { 00757 uint8_t i = 0; 00758 uint8_t refreshDisplay = 0; 00759 00760 if( Eeprom.EepromData.DemoSettings.HoldDemo == true ) 00761 { 00762 return 0; // quit without refresh display 00763 } 00764 00765 if( DemoRunning == false ) 00766 { 00767 DemoRunning = true; 00768 TX_LED = 0; 00769 RX_LED = 0; 00770 Eeprom.EepromData.DemoSettings.CntPacketTx = 0; 00771 Eeprom.EepromData.DemoSettings.CntPacketRxOK = 0; 00772 Eeprom.EepromData.DemoSettings.CntPacketRxOKSlave = 0; 00773 Eeprom.EepromData.DemoSettings.CntPacketRxKO = 0; 00774 Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave = 0; 00775 Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0; 00776 00777 InitializeDemoParameters( Eeprom.EepromData.DemoSettings.ModulationType ); 00778 00779 Eeprom.EepromData.DemoSettings.InterPacketDelay = GetTimeOnAir( Eeprom.EepromData.DemoSettings.ModulationType ) + RX_TX_TRANSITION_WAIT; 00780 00781 printf( "Start RunDemoApplicationPingPong.\n\r" ); 00782 00783 if( Eeprom.EepromData.DemoSettings.Entity == MASTER ) 00784 { 00785 DemoInternalState = SEND_PING_MSG; 00786 uint32_t temp = ( Eeprom.EepromData.DemoSettings.InterPacketDelay << 1 ) + RX_TIMEOUT_MARGIN; 00787 float val = ( float )temp / 1000.0; 00788 SendNextPacket.attach( &SendNextPacketEvent, val ); 00789 } 00790 else 00791 { 00792 IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 00793 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00794 // Rx Single without timeout for the start 00795 RX_LED = !RX_LED; 00796 00797 if( Eeprom.EepromData.DemoSettings.BoostedRx == false ) 00798 { 00799 Radio.SetRx( 0x0000 ); 00800 } 00801 else 00802 { 00803 Radio.SetRxBoosted( 0x0000 ); 00804 } 00805 DemoInternalState = APP_IDLE; 00806 } 00807 } 00808 00809 Radio.ProcessIrqs( ); 00810 00811 if( Eeprom.EepromData.DemoSettings.Entity == MASTER ) 00812 { 00813 switch( DemoInternalState ) 00814 { 00815 case SEND_PING_MSG: 00816 if( ( Eeprom.EepromData.DemoSettings.MaxNumPacket != 0 ) \ 00817 && ( Eeprom.EepromData.DemoSettings.CntPacketTx >= Eeprom.EepromData.DemoSettings.MaxNumPacket ) ) 00818 { 00819 SendNextPacket.detach( ); 00820 SendNext = false; 00821 RX_LED = 0; 00822 TX_LED = 0; 00823 DemoInternalState = APP_IDLE; 00824 Radio.SetStandby( STDBY_RC ); 00825 Eeprom.EepromData.DemoSettings.HoldDemo = true; 00826 refreshDisplay = 1; 00827 } 00828 else 00829 { 00830 if( SendNext == true ) 00831 { 00832 SendNext = false; 00833 Radio.SetStandby( STDBY_RC ); 00834 DemoInternalState = APP_IDLE; 00835 Eeprom.EepromData.DemoSettings.CntPacketTx++; 00836 // Send the next PING frame 00837 Buffer[0] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 24 ) & 0xFF; 00838 Buffer[1] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 16 ) & 0xFF; 00839 Buffer[2] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 8 ) & 0xFF; 00840 Buffer[3] = ( Eeprom.EepromData.DemoSettings.CntPacketTx & 0xFF ); 00841 Buffer[4] = PingMsg[0]; 00842 Buffer[5] = PingMsg[1]; 00843 Buffer[6] = PingMsg[2]; 00844 Buffer[7] = PingMsg[3]; 00845 for( i = 8; i < Eeprom.EepromData.DemoSettings.PayloadLength; i++ ) 00846 { 00847 Buffer[i] = i; 00848 } 00849 TX_LED = !TX_LED; 00850 IrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT; 00851 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00852 Radio.SendPayload( Buffer, Eeprom.EepromData.DemoSettings.PayloadLength, \ 00853 Eeprom.EepromData.DemoSettings.InterPacketDelay << 6 ); 00854 } 00855 } 00856 break; 00857 00858 case APP_TX: 00859 DemoInternalState = APP_IDLE; 00860 TX_LED = !TX_LED; 00861 RX_LED = !RX_LED; 00862 IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 00863 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00864 00865 if( Eeprom.EepromData.DemoSettings.BoostedRx == false ) 00866 { 00867 Radio.SetRx( ( ( Eeprom.EepromData.DemoSettings.InterPacketDelay << 1 ) + RX_TIMEOUT_MARGIN ) << 6 ); 00868 } 00869 else 00870 { 00871 Radio.SetRxBoosted( ( ( Eeprom.EepromData.DemoSettings.InterPacketDelay << 1 ) + RX_TIMEOUT_MARGIN ) << 6 ); 00872 } 00873 break; 00874 00875 case APP_RX: 00876 RX_LED = !RX_LED; 00877 Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE ); 00878 Radio.GetPacketStatus( &PacketStatus ); 00879 if( Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_LORA ) 00880 { 00881 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Params.LoRa.RssiPkt; 00882 Eeprom.EepromData.DemoSettings.SnrValue = PacketStatus.Params.LoRa.SnrPkt; 00883 } 00884 else // Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_GFSK 00885 { 00886 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Params.Gfsk.RssiAvg; 00887 Eeprom.EepromData.DemoSettings.SnrValue = 0; 00888 } 00889 00890 if( ( BufferSize >= PINGPONG_SIZE ) && ( strncmp( ( const char* )( Buffer + 8 ), ( const char* )PongMsg, PINGPONG_SIZE ) == 0 ) ) 00891 { 00892 ComputePingPongPayload( Buffer, BufferSize ); 00893 } 00894 else 00895 { 00896 Eeprom.EepromData.DemoSettings.CntPacketRxKO++; 00897 } 00898 DemoInternalState = SEND_PING_MSG; 00899 refreshDisplay = 1; 00900 break; 00901 00902 case APP_RX_TIMEOUT: 00903 case APP_RX_ERROR: 00904 RX_LED = !RX_LED; 00905 Eeprom.EepromData.DemoSettings.CntPacketRxKO++; 00906 DemoInternalState = SEND_PING_MSG; 00907 refreshDisplay = 1; 00908 break; 00909 00910 case APP_TX_TIMEOUT: 00911 printf( "Failure: timeout in Tx is shorter than the packet time on air\n\r" ); 00912 DemoInternalState = APP_IDLE; 00913 Eeprom.EepromData.DemoSettings.HoldDemo = true; 00914 refreshDisplay = 1; 00915 break; 00916 00917 case APP_IDLE: // do nothing 00918 break; 00919 00920 default: 00921 break; 00922 } 00923 } 00924 else // SLAVE 00925 { 00926 switch( DemoInternalState ) 00927 { 00928 case SEND_PONG_MSG: 00929 wait_ms( RX_TX_TRANSITION_WAIT ); 00930 00931 DemoInternalState = APP_IDLE; 00932 // Send the next PING frame 00933 Buffer[0] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 24 ) & 0xFF; 00934 Buffer[1] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 16 ) & 0xFF; 00935 Buffer[2] = ( Eeprom.EepromData.DemoSettings.CntPacketTx >> 8 ) & 0xFF; 00936 Buffer[3] = ( Eeprom.EepromData.DemoSettings.CntPacketTx & 0xFF ); 00937 Buffer[4] = ( ( Eeprom.EepromData.DemoSettings.CntPacketRxKO + \ 00938 Eeprom.EepromData.DemoSettings.RxTimeOutCount ) >> 24 ) & 0xFF; 00939 Buffer[5] = ( ( Eeprom.EepromData.DemoSettings.CntPacketRxKO + \ 00940 Eeprom.EepromData.DemoSettings.RxTimeOutCount ) >> 16 ) & 0xFF; 00941 Buffer[6] = ( ( Eeprom.EepromData.DemoSettings.CntPacketRxKO + \ 00942 Eeprom.EepromData.DemoSettings.RxTimeOutCount ) >> 8 ) & 0xFF; 00943 Buffer[7] = ( ( Eeprom.EepromData.DemoSettings.CntPacketRxKO + \ 00944 Eeprom.EepromData.DemoSettings.RxTimeOutCount ) & 0xFF ); 00945 Buffer[8] = PongMsg[0]; 00946 Buffer[9] = PongMsg[1]; 00947 Buffer[10] = PongMsg[2]; 00948 Buffer[11] = PongMsg[3]; 00949 for( i = 12; i < Eeprom.EepromData.DemoSettings.PayloadLength; i++ ) 00950 { 00951 Buffer[i] = i; 00952 } 00953 TX_LED = !TX_LED; 00954 IrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT; 00955 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00956 Radio.SendPayload( Buffer, Eeprom.EepromData.DemoSettings.PayloadLength, \ 00957 ( Eeprom.EepromData.DemoSettings.InterPacketDelay ) << 6 ); 00958 break; 00959 00960 case APP_TX: 00961 if( ( Eeprom.EepromData.DemoSettings.MaxNumPacket != 0 ) \ 00962 && ( ( Eeprom.EepromData.DemoSettings.CntPacketRxOK + Eeprom.EepromData.DemoSettings.CntPacketRxKO + \ 00963 Eeprom.EepromData.DemoSettings.RxTimeOutCount ) >= Eeprom.EepromData.DemoSettings.MaxNumPacket ) ) 00964 { 00965 SendNextPacket.detach( ); 00966 SendNext = false; 00967 RX_LED = 0; 00968 TX_LED = 0; 00969 DemoInternalState = APP_IDLE; 00970 Radio.SetStandby( STDBY_RC ); 00971 Eeprom.EepromData.DemoSettings.HoldDemo = true; 00972 refreshDisplay = 1; 00973 } 00974 else 00975 { 00976 DemoInternalState = APP_IDLE; 00977 TX_LED = !TX_LED; 00978 RX_LED = !RX_LED; 00979 IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 00980 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00981 if( Eeprom.EepromData.DemoSettings.BoostedRx == false ) 00982 { 00983 Radio.SetRx( ( ( Eeprom.EepromData.DemoSettings.InterPacketDelay << 1 ) + RX_TIMEOUT_MARGIN ) << 6 ); 00984 } 00985 else 00986 { 00987 Radio.SetRxBoosted( ( ( Eeprom.EepromData.DemoSettings.InterPacketDelay << 1 ) + RX_TIMEOUT_MARGIN ) << 6 ); 00988 } 00989 refreshDisplay = 1; 00990 } 00991 break; 00992 00993 case APP_RX: 00994 DemoInternalState = APP_IDLE; 00995 RX_LED = !RX_LED; 00996 Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE ); 00997 Radio.GetPacketStatus( &PacketStatus ); 00998 if( Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_LORA ) 00999 { 01000 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Params.LoRa.RssiPkt; 01001 Eeprom.EepromData.DemoSettings.SnrValue = PacketStatus.Params.LoRa.SnrPkt; 01002 } 01003 else // Eeprom.EepromData.ModulationParams.PacketType == PACKET_TYPE_GFSK 01004 { 01005 Eeprom.EepromData.DemoSettings.RssiValue = PacketStatus.Params.Gfsk.RssiAvg; 01006 Eeprom.EepromData.DemoSettings.SnrValue = 0; 01007 } 01008 01009 if( ( BufferSize >= PINGPONG_SIZE ) && ( strncmp( ( const char* )( Buffer + 4 ), ( const char* )PingMsg, PINGPONG_SIZE ) == 0 ) ) 01010 { 01011 ComputePingPongPayload( Buffer, BufferSize ); 01012 DemoInternalState = SEND_PONG_MSG; 01013 } 01014 else 01015 { 01016 Eeprom.EepromData.DemoSettings.CntPacketRxKO++; 01017 RX_LED = !RX_LED; 01018 IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 01019 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 01020 if( Eeprom.EepromData.DemoSettings.BoostedRx == false ) 01021 { 01022 Radio.SetRx( ( Eeprom.EepromData.DemoSettings.InterPacketDelay ) << 6 ); 01023 } 01024 else 01025 { 01026 Radio.SetRxBoosted( ( Eeprom.EepromData.DemoSettings.InterPacketDelay ) << 6 ); 01027 } 01028 refreshDisplay = 1; 01029 } 01030 break; 01031 01032 case APP_RX_TIMEOUT: 01033 case APP_RX_ERROR: 01034 DemoInternalState = APP_IDLE; 01035 Eeprom.EepromData.DemoSettings.RxTimeOutCount++; 01036 IrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 01037 Radio.SetDioIrqParams( IrqMask, IrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 01038 if( Eeprom.EepromData.DemoSettings.BoostedRx == false ) 01039 { 01040 Radio.SetRx( ( ( Eeprom.EepromData.DemoSettings.InterPacketDelay << 1 ) + RX_TIMEOUT_MARGIN ) << 6 ); 01041 } 01042 else 01043 { 01044 Radio.SetRxBoosted( ( ( Eeprom.EepromData.DemoSettings.InterPacketDelay << 1 ) + RX_TIMEOUT_MARGIN ) << 6 ); 01045 } 01046 refreshDisplay = 1; 01047 break; 01048 01049 case APP_TX_TIMEOUT: 01050 printf( "Failure: timeout in Tx is shorter than the packet time on air\n\r" ); 01051 DemoInternalState = APP_IDLE; 01052 Eeprom.EepromData.DemoSettings.HoldDemo = true; 01053 refreshDisplay = 1; 01054 break; 01055 01056 case APP_IDLE: // do nothing 01057 break; 01058 01059 default: 01060 break; 01061 } 01062 } 01063 return refreshDisplay; 01064 } 01065 01066 void ComputePingPongPayload( uint8_t *buffer, uint8_t bufferSize ) 01067 { 01068 uint32_t i = 0; 01069 01070 PacketRxSequence = ( ( uint32_t )buffer[0] << 24 ) | \ 01071 ( ( uint32_t )buffer[1] << 16 ) | \ 01072 ( ( uint32_t )buffer[2] << 8 ) | \ 01073 buffer[3]; 01074 01075 if( Eeprom.EepromData.DemoSettings.Entity == MASTER ) 01076 { 01077 Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave = 01078 ( ( uint32_t )buffer[4] << 24 ) | \ 01079 ( ( uint32_t )buffer[5] << 16 ) | \ 01080 ( ( uint32_t )buffer[6] << 8 ) | \ 01081 buffer[7]; 01082 if( PacketRxSequence > Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave ) 01083 { 01084 Eeprom.EepromData.DemoSettings.CntPacketRxOKSlave = PacketRxSequence - \ 01085 Eeprom.EepromData.DemoSettings.CntPacketRxKOSlave; 01086 } 01087 else 01088 { 01089 Eeprom.EepromData.DemoSettings.CntPacketRxOKSlave = 0; 01090 } 01091 01092 if( PacketRxSequence == Eeprom.EepromData.DemoSettings.CntPacketTx ) 01093 { 01094 Eeprom.EepromData.DemoSettings.CntPacketRxOK += 1; 01095 } 01096 else 01097 { 01098 Eeprom.EepromData.DemoSettings.CntPacketRxKO += 1; 01099 } 01100 } 01101 else 01102 { 01103 Eeprom.EepromData.DemoSettings.CntPacketRxOK += 1; 01104 if( ( PacketRxSequence <= PacketRxSequencePrev ) || \ 01105 ( PacketRxSequencePrev == 0 ) ) 01106 { 01107 // Sequence went back => resynchronization 01108 // Don't count missed packets this time 01109 i = 0; 01110 } 01111 else 01112 { 01113 // Determine number of missed packets 01114 i = PacketRxSequence - PacketRxSequencePrev - 1; 01115 } 01116 // Be ready for the next 01117 PacketRxSequencePrev = PacketRxSequence; 01118 Eeprom.EepromData.DemoSettings.CntPacketTx = PacketRxSequence; 01119 // increment 'missed' counter for the RX session 01120 Eeprom.EepromData.DemoSettings.CntPacketRxKO += i; 01121 Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0; 01122 } 01123 } 01124 01125 // ************************ Utils **************************** 01126 // * * 01127 // * * 01128 // * * 01129 // ***************************************************************************** 01130 01131 uint8_t GetConnectedDevice( void ) 01132 { 01133 return( Radio.GetDeviceType( ) ); 01134 } 01135 01136 uint8_t GetMatchingFrequency( void ) 01137 { 01138 return( Radio.GetFreqSelect( ) ); 01139 } 01140 01141 void InitDemoApplication( void ) 01142 { 01143 RX_LED = 1; 01144 TX_LED = 1; 01145 01146 Radio.Init( ); 01147 01148 // Can also be set in LDO mode but consume more power 01149 Radio.SetRegulatorMode( ( RadioRegulatorMode_t )Eeprom.EepromData.DemoSettings.RadioPowerMode ); 01150 Radio.SetStandby( STDBY_RC ); 01151 01152 memset( &Buffer, 0x00, BufferSize ); 01153 01154 RX_LED = 0; 01155 TX_LED = 0; 01156 01157 PacketRxSequence = 0; 01158 PacketRxSequencePrev = 0; 01159 Eeprom.EepromData.DemoSettings.CntPacketTx = 0; 01160 Eeprom.EepromData.DemoSettings.CntPacketRxOK = 0; 01161 Eeprom.EepromData.DemoSettings.CntPacketRxKO = 0; 01162 Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0; 01163 } 01164 01165 void StopDemoApplication( void ) 01166 { 01167 if( DemoRunning == true ) 01168 { 01169 Radio.CheckDeviceReady( ); 01170 01171 RX_LED = 0; 01172 TX_LED = 0; 01173 DemoRunning = false; 01174 SendNext = false; 01175 PacketRxSequence = 0; 01176 PacketRxSequencePrev = 0; 01177 Eeprom.EepromData.DemoSettings.CntPacketTx = 0; 01178 Eeprom.EepromData.DemoSettings.CntPacketRxOK = 0; 01179 Eeprom.EepromData.DemoSettings.CntPacketRxKO = 0; 01180 Eeprom.EepromData.DemoSettings.RxTimeOutCount = 0; 01181 01182 DemoInternalState = APP_IDLE; 01183 Radio.SetStandby( STDBY_RC ); 01184 Radio.ClearIrqStatus( IRQ_RADIO_ALL ); 01185 SendNextPacket.detach( ); 01186 } 01187 } 01188 01189 /* 01190 * Function still being implemented >>> To be completed 01191 * WARNING: Computation is in float and his really slow 01192 * LongInterLeaving vs LegacyInterLeaving has no influence on TimeOnAir. 01193 */ 01194 uint16_t GetTimeOnAir( uint8_t modulation ) 01195 { 01196 uint16_t result = 2000; 01197 uint8_t LowDatarateOptimize = 0; 01198 01199 if( modulation == PACKET_TYPE_LORA ) 01200 { 01201 volatile double loraBw = 0.0; 01202 volatile double FreqErrorUnits = 0.0; 01203 01204 switch( Eeprom.EepromData.ModulationParams.Params.LoRa.Bandwidth ) 01205 { 01206 case LORA_BW_500: 01207 loraBw = 500e3; 01208 break; 01209 01210 case LORA_BW_250: 01211 loraBw = 250e3; 01212 break; 01213 01214 case LORA_BW_125: 01215 loraBw = 125e3; 01216 break; 01217 01218 case LORA_BW_062: 01219 loraBw = 62e3; 01220 break; 01221 01222 case LORA_BW_041: 01223 loraBw = 41e3; 01224 break; 01225 01226 case LORA_BW_031: 01227 loraBw = 31e3; 01228 break; 01229 01230 case LORA_BW_020: 01231 loraBw = 20e3; 01232 break; 01233 01234 case LORA_BW_015: 01235 loraBw = 15e3; 01236 break; 01237 01238 case LORA_BW_010: 01239 loraBw = 10e3; 01240 break; 01241 01242 case LORA_BW_007: 01243 loraBw = 7e3; 01244 break; 01245 01246 default: 01247 loraBw = 7e3; 01248 break; 01249 } 01250 01251 /* Used to compute the freq Error */ 01252 FreqErrorUnits = FREQ_ERR; 01253 FreErrorLsb = FreqErrorUnits * ( ( double )loraBw / 1000 ) / 500; 01254 01255 float ts = 1 << Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor; // time for one symbol in ms 01256 ts = (float)ts / (float)loraBw; 01257 ts = ts * 1000; // from seconds to miliseconds 01258 01259 float tPreamble = ( Eeprom.EepromData.PacketParams.Params.LoRa.PreambleLength + 4.25 + ( ( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor > 6 ) ? 2 : 0 )) * ts; // time of preamble 01260 01261 switch( Eeprom.EepromData.ModulationParams.Params.LoRa.Bandwidth ) 01262 { 01263 case LORA_BW_500: 01264 break; 01265 01266 case LORA_BW_250: 01267 if( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF12 ) 01268 { 01269 LowDatarateOptimize = 1; 01270 } 01271 break; 01272 01273 case LORA_BW_125: 01274 if( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor >= LORA_SF11 ) 01275 { 01276 LowDatarateOptimize = 1; 01277 } 01278 break; 01279 01280 case LORA_BW_062: 01281 if( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor >= LORA_SF10 ) 01282 { 01283 LowDatarateOptimize = 1; 01284 } 01285 break; 01286 01287 case LORA_BW_041: 01288 case LORA_BW_031: 01289 if( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor >= LORA_SF9 ) 01290 { 01291 LowDatarateOptimize = 1; 01292 } 01293 break; 01294 01295 case LORA_BW_020: 01296 case LORA_BW_015: 01297 if( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor >= LORA_SF8 ) 01298 { 01299 LowDatarateOptimize = 1; 01300 } 01301 break; 01302 01303 case LORA_BW_010: 01304 case LORA_BW_007: 01305 if( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor >= LORA_SF7 ) 01306 { 01307 LowDatarateOptimize = 1; 01308 } 01309 break; 01310 } 01311 01312 float nData = ceil( ( float )( ( 8 * Eeprom.EepromData.PacketParams.Params.LoRa.PayloadLength + \ 01313 16 * ( ( Eeprom.EepromData.PacketParams.Params.LoRa.CrcMode == LORA_CRC_OFF ) ? 0 : 1 ) + \ 01314 ( ( Eeprom.EepromData.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_VARIABLE_LENGTH ) ? 20 : 0 ) - \ 01315 ( 4 * Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor ) + 8 - \ 01316 ( 8 *( ( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor > 6 ) ? 1 : 0 ) ) ) / 4 ) ); 01317 01318 nData = ceil( ( float )nData / ( ( float )( Eeprom.EepromData.ModulationParams.Params.LoRa.SpreadingFactor - \ 01319 ( LowDatarateOptimize * 2 ) ) ) * ( ( Eeprom.EepromData.ModulationParams.Params.LoRa.CodingRate % 4 ) + 4 ) ); 01320 01321 float tPayload = nData * ts; 01322 01323 float tHeader = 8 * ts; 01324 // Time on air [ms] 01325 float ToA = ceil( tPreamble + tPayload + tHeader ); 01326 01327 result = ( uint16_t )ToA + ( ( uint16_t )ToA >> 1 ); // Set some margin 01328 } 01329 else if( modulation == PACKET_TYPE_GFSK ) 01330 { 01331 uint16_t packetBitCount = Eeprom.EepromData.PacketParams.Params.Gfsk.PreambleLength; 01332 01333 packetBitCount += ( Eeprom.EepromData.PacketParams.Params.Gfsk.SyncWordLength + 1 ); 01334 packetBitCount += Eeprom.EepromData.PacketParams.Params.Gfsk.PayloadLength + 3; 01335 packetBitCount *= 8; 01336 // 1500 = 1000 * 1.5 : 1000 for translate s in ms and 1.5 is some margin 01337 result = ( uint16_t )( ceil( 1500 * ( float )packetBitCount / Eeprom.EepromData.ModulationParams.Params.Gfsk.BitRate ) ); 01338 } 01339 return result; 01340 } 01341 01342 void InitializeDemoParameters( uint8_t modulation ) 01343 { 01344 Radio.SetStandby( STDBY_RC ); 01345 01346 Radio.SetRegulatorMode( ( RadioRegulatorMode_t )Eeprom.EepromData.DemoSettings.RadioPowerMode ); 01347 01348 printf("> InitializeDemoParameters\n\r"); 01349 if( modulation == PACKET_TYPE_LORA ) 01350 { 01351 printf("set param LORA for demo\n\r"); 01352 ModulationParams.PacketType = PACKET_TYPE_LORA; 01353 PacketParams.PacketType = PACKET_TYPE_LORA; 01354 01355 ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) Eeprom.EepromData.DemoSettings.ModulationParam1; 01356 ModulationParams.Params.LoRa.Bandwidth = ( RadioLoRaBandwidths_t ) Eeprom.EepromData.DemoSettings.ModulationParam2; 01357 ModulationParams.Params.LoRa.CodingRate = ( RadioLoRaCodingRates_t ) Eeprom.EepromData.DemoSettings.ModulationParam3; 01358 01359 PacketParams.Params.LoRa.PreambleLength = Eeprom.EepromData.DemoSettings.PacketParam1; 01360 PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )Eeprom.EepromData.DemoSettings.PacketParam2; 01361 PacketParams.Params.LoRa.PayloadLength = Eeprom.EepromData.DemoSettings.PacketParam3; 01362 PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t ) Eeprom.EepromData.DemoSettings.PacketParam4; 01363 PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t ) Eeprom.EepromData.DemoSettings.PacketParam5; 01364 01365 Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.LoRa.PayloadLength; 01366 01367 if( ( ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) || ( ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) ) 01368 { 01369 if( PacketParams.Params.LoRa.PreambleLength < 12 ) 01370 { 01371 PacketParams.Params.LoRa.PreambleLength = 12; 01372 } 01373 } 01374 } 01375 else// if( modulation == PACKET_TYPE_GFSK ) 01376 { 01377 printf("set param GFSK for demo\n\r"); 01378 ModulationParams.PacketType = PACKET_TYPE_GFSK; 01379 PacketParams.PacketType = PACKET_TYPE_GFSK; 01380 01381 ModulationParams.Params.Gfsk.BitRate = Eeprom.EepromData.DemoSettings.ModulationParam1; 01382 ModulationParams.Params.Gfsk.Fdev = Eeprom.EepromData.DemoSettings.ModulationParam2; 01383 ModulationParams.Params.Gfsk.ModulationShaping = ( RadioModShapings_t ) Eeprom.EepromData.DemoSettings.ModulationParam3; 01384 ModulationParams.Params.Gfsk.Bandwidth = ( RadioRxBandwidth_t ) Eeprom.EepromData.DemoSettings.ModulationParam4; 01385 PacketParams.Params.Gfsk.PreambleLength = Eeprom.EepromData.DemoSettings.PacketParam1; 01386 PacketParams.Params.Gfsk.PreambleMinDetect = ( RadioPreambleDetection_t )Eeprom.EepromData.DemoSettings.PacketParam2; 01387 PacketParams.Params.Gfsk.SyncWordLength = Eeprom.EepromData.DemoSettings.PacketParam3; 01388 PacketParams.Params.Gfsk.AddrComp = ( RadioAddressComp_t ) Eeprom.EepromData.DemoSettings.PacketParam4; 01389 PacketParams.Params.Gfsk.HeaderType = ( RadioPacketLengthModes_t )Eeprom.EepromData.DemoSettings.PacketParam5; 01390 PacketParams.Params.Gfsk.PayloadLength = Eeprom.EepromData.DemoSettings.PacketParam6; 01391 01392 PacketParams.Params.Gfsk.CrcLength = ( RadioCrcTypes_t ) Eeprom.EepromData.DemoSettings.PacketParam7; 01393 PacketParams.Params.Gfsk.DcFree = ( RadioDcFree_t ) Eeprom.EepromData.DemoSettings.PacketParam8; 01394 01395 Eeprom.EepromData.DemoSettings.PayloadLength = PacketParams.Params.Gfsk.PayloadLength; 01396 } 01397 01398 Radio.SetStandby( STDBY_RC ); 01399 Radio.ClearIrqStatus( IRQ_RADIO_ALL ); 01400 Radio.SetPacketType( ModulationParams.PacketType ); 01401 Radio.SetModulationParams( &ModulationParams ); 01402 Radio.SetPacketParams( &PacketParams ); 01403 01404 Radio.SetRfFrequency( Eeprom.EepromData.DemoSettings.Frequency ); 01405 Radio.SetBufferBaseAddresses( 0x00, 0x00 ); 01406 01407 01408 Radio.SetTxParams( Eeprom.EepromData.DemoSettings.TxPower, RADIO_RAMP_200_US ); 01409 01410 // only used in GFSK 01411 Radio.SetSyncWord( ( uint8_t[] ){ 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 } ); 01412 Radio.SetWhiteningSeed( 0x01FF ); 01413 01414 RX_LED = 0; 01415 TX_LED = 0; 01416 } 01417 01418 /*! 01419 * \brief Callback of ticker PerSendNextPacket 01420 */ 01421 void SendNextPacketEvent( void ) 01422 { 01423 SendNext = true; 01424 } 01425 01426 void LedBlink( void ) 01427 { 01428 if( ( TX_LED == 0 ) && ( RX_LED == 0 ) ) 01429 { 01430 TX_LED = 1; 01431 } 01432 else if( ( TX_LED == 1 ) && ( RX_LED == 0 ) ) 01433 { 01434 RX_LED = 1; 01435 } 01436 else if( ( TX_LED == 1 ) && ( RX_LED == 1 ) ) 01437 { 01438 TX_LED = 0; 01439 } 01440 else 01441 { 01442 RX_LED = 0; 01443 } 01444 } 01445 01446 // ************************ Radio Callbacks **************************** 01447 // * * 01448 // * These functions are called through function pointer by the Radio low * 01449 // * level drivers * 01450 // * * 01451 // ***************************************************************************** 01452 void OnTxDone( void ) 01453 { 01454 DemoInternalState = APP_TX; 01455 } 01456 01457 void OnRxDone( void ) 01458 { 01459 DemoInternalState = APP_RX; 01460 } 01461 01462 void OnTxTimeout( void ) 01463 { 01464 DemoInternalState = APP_TX_TIMEOUT; 01465 } 01466 01467 void OnRxTimeout( void ) 01468 { 01469 DemoInternalState = APP_RX_TIMEOUT; 01470 } 01471 01472 void OnRxError( IrqErrorCode_t errorCode ) 01473 { 01474 DemoInternalState = APP_RX_ERROR; 01475 01476 if( errorCode == IRQ_HEADER_ERROR_CODE ) 01477 { 01478 #ifdef ADV_DEBUG 01479 printf( ">> IRQ_HEADER_ERROR_CODE\n\r" ); 01480 #endif 01481 } 01482 else if( errorCode == IRQ_SYNCWORD_ERROR_CODE ) 01483 { 01484 #ifdef ADV_DEBUG 01485 printf( ">> IRQ_SYNCWORD_ERROR_CODE\n\r" ); 01486 #endif 01487 } 01488 else if( errorCode == IRQ_CRC_ERROR_CODE ) 01489 { 01490 #ifdef ADV_DEBUG 01491 printf( ">> IRQ_CRC_ERROR_CODE\n\r" ); 01492 #endif 01493 } 01494 else 01495 { 01496 #ifdef ADV_DEBUG 01497 printf( "unknown error\n\r" ); 01498 #endif 01499 } 01500 Radio.GetPacketStatus( &PacketStatus ); 01501 } 01502 01503 void OnCadDone( bool channelActivityDetected ) 01504 { 01505 if( channelActivityDetected == true ) 01506 { 01507 DemoInternalState = CAD_DONE_CHANNEL_DETECTED; 01508 } 01509 else 01510 { 01511 DemoInternalState = CAD_DONE; 01512 } 01513 }
Generated on Tue Jul 12 2022 15:49:22 by 1.7.2