QuakeGod
2024-11-25 9aed5d7e7b3c7bf09da712e9c272ece401a7acc9
提交 | 用户 | age
9aed5d 1 /*!
Q 2  * \file      radio.c
3  *
4  * \brief     Radio driver API definition
5  *
6  * \copyright Revised BSD License, see section \ref LICENSE.
7  *
8  * \code
9  *                ______                              _
10  *               / _____)             _              | |
11  *              ( (____  _____ ____ _| |_ _____  ____| |__
12  *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
13  *               _____) ) ____| | | || |_| ____( (___| | | |
14  *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
15  *              (C)2013-2017 Semtech
16  *
17  * \endcode
18  *
19  * \author    Miguel Luis ( Semtech )
20  *
21  * \author    Gregory Cristian ( Semtech )
22  */
23 #include <math.h>
24 #include <string.h>
25 #include <stdbool.h>
26 #include "stm32f0xx.h"
27 #include "delay.h"
28 #include "gpio.h"
29 #include "spi.h"
30 #include "radio.h"
31 #include "sx126x.h"
32 #include "sx126x-board.h"
33
34 /*!
35  * \brief Initializes the radio
36  *
37  * \param [IN] events Structure containing the driver callback functions
38  */
39 void RadioInit( RadioEvents_t *events );
40
41 /*!
42  * Return current radio status
43  *
44  * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING]
45  */
46 RadioState_t RadioGetStatus( void );
47
48 /*!
49  * \brief Configures the radio with the given modem
50  *
51  * \param [IN] modem Modem to be used [0: FSK, 1: LoRa]
52  */
53 void RadioSetModem( RadioModems_t modem );
54
55 /*!
56  * \brief Sets the channel frequency
57  *
58  * \param [IN] freq         Channel RF frequency
59  */
60 void RadioSetChannel( uint32_t freq );
61
62 /*!
63  * \brief Checks if the channel is free for the given time
64  *
65  * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
66  * \param [IN] freq       Channel RF frequency
67  * \param [IN] rssiThresh RSSI threshold
68  * \param [IN] maxCarrierSenseTime Max time while the RSSI is measured
69  *
70  * \retval isFree         [true: Channel is free, false: Channel is not free]
71  */
72 bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime );
73
74 /*!
75  * \brief Generates a 32 bits random value based on the RSSI readings
76  *
77  * \remark This function sets the radio in LoRa modem mode and disables
78  *         all interrupts.
79  *         After calling this function either Radio.SetRxConfig or
80  *         Radio.SetTxConfig functions must be called.
81  *
82  * \retval randomValue    32 bits random value
83  */
84 uint32_t RadioRandom( void );
85
86 /*!
87  * \brief Sets the reception parameters
88  *
89  * \param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa]
90  * \param [IN] bandwidth    Sets the bandwidth
91  *                          FSK : >= 2600 and <= 250000 Hz
92  *                          LoRa: [0: 125 kHz, 1: 250 kHz,
93  *                                 2: 500 kHz, 3: Reserved]
94  * \param [IN] datarate     Sets the Datarate
95  *                          FSK : 600..300000 bits/s
96  *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
97  *                                10: 1024, 11: 2048, 12: 4096  chips]
98  * \param [IN] coderate     Sets the coding rate (LoRa only)
99  *                          FSK : N/A ( set to 0 )
100  *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
101  * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only)
102  *                          FSK : >= 2600 and <= 250000 Hz
103  *                          LoRa: N/A ( set to 0 )
104  * \param [IN] preambleLen  Sets the Preamble length
105  *                          FSK : Number of bytes
106  *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
107  * \param [IN] symbTimeout  Sets the RxSingle timeout value
108  *                          FSK : timeout in number of bytes
109  *                          LoRa: timeout in symbols
110  * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
111  * \param [IN] payloadLen   Sets payload length when fixed length is used
112  * \param [IN] crcOn        Enables/Disables the CRC [0: OFF, 1: ON]
113  * \param [IN] FreqHopOn    Enables disables the intra-packet frequency hopping
114  *                          FSK : N/A ( set to 0 )
115  *                          LoRa: [0: OFF, 1: ON]
116  * \param [IN] HopPeriod    Number of symbols between each hop
117  *                          FSK : N/A ( set to 0 )
118  *                          LoRa: Number of symbols
119  * \param [IN] iqInverted   Inverts IQ signals (LoRa only)
120  *                          FSK : N/A ( set to 0 )
121  *                          LoRa: [0: not inverted, 1: inverted]
122  * \param [IN] rxContinuous Sets the reception in continuous mode
123  *                          [false: single mode, true: continuous mode]
124  */
125 void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth,
126                           uint32_t datarate, uint8_t coderate,
127                           uint32_t bandwidthAfc, uint16_t preambleLen,
128                           uint16_t symbTimeout, bool fixLen,
129                           uint8_t payloadLen,
130                           bool crcOn, bool FreqHopOn, uint8_t HopPeriod,
131                           bool iqInverted, bool rxContinuous );
132
133 /*!
134  * \brief Sets the transmission parameters
135  *
136  * \param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa]
137  * \param [IN] power        Sets the output power [dBm]
138  * \param [IN] fdev         Sets the frequency deviation (FSK only)
139  *                          FSK : [Hz]
140  *                          LoRa: 0
141  * \param [IN] bandwidth    Sets the bandwidth (LoRa only)
142  *                          FSK : 0
143  *                          LoRa: [0: 125 kHz, 1: 250 kHz,
144  *                                 2: 500 kHz, 3: Reserved]
145  * \param [IN] datarate     Sets the Datarate
146  *                          FSK : 600..300000 bits/s
147  *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
148  *                                10: 1024, 11: 2048, 12: 4096  chips]
149  * \param [IN] coderate     Sets the coding rate (LoRa only)
150  *                          FSK : N/A ( set to 0 )
151  *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
152  * \param [IN] preambleLen  Sets the preamble length
153  *                          FSK : Number of bytes
154  *                          LoRa: Length in symbols (the hardware adds 4 more symbols)
155  * \param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
156  * \param [IN] crcOn        Enables disables the CRC [0: OFF, 1: ON]
157  * \param [IN] FreqHopOn    Enables disables the intra-packet frequency hopping
158  *                          FSK : N/A ( set to 0 )
159  *                          LoRa: [0: OFF, 1: ON]
160  * \param [IN] HopPeriod    Number of symbols between each hop
161  *                          FSK : N/A ( set to 0 )
162  *                          LoRa: Number of symbols
163  * \param [IN] iqInverted   Inverts IQ signals (LoRa only)
164  *                          FSK : N/A ( set to 0 )
165  *                          LoRa: [0: not inverted, 1: inverted]
166  * \param [IN] timeout      Transmission timeout [ms]
167  */
168 void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
169                           uint32_t bandwidth, uint32_t datarate,
170                           uint8_t coderate, uint16_t preambleLen,
171                           bool fixLen, bool crcOn, bool FreqHopOn,
172                           uint8_t HopPeriod, bool iqInverted, uint32_t timeout );
173
174 /*!
175  * \brief Checks if the given RF frequency is supported by the hardware
176  *
177  * \param [IN] frequency RF frequency to be checked
178  * \retval isSupported [true: supported, false: unsupported]
179  */
180 bool RadioCheckRfFrequency( uint32_t frequency );
181
182 /*!
183  * \brief Computes the packet time on air in ms for the given payload
184  *
185  * \Remark Can only be called once SetRxConfig or SetTxConfig have been called
186  *
187  * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
188  * \param [IN] pktLen     Packet payload length
189  *
190  * \retval airTime        Computed airTime (ms) for the given packet payload length
191  */
192 uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen );
193
194 /*!
195  * \brief Computes the packet time on air in ms for the given payload
196  *
197  * \Remark Can only be called once SetRxConfig or SetTxConfig have been called
198  *
199  * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
200  * \param [IN] pktLen     Packet payload length
201  *
202  * \retval airTime        Computed airTime (us) for the given packet payload length
203  */
204 uint32_t RadioTimeOnAiruS( RadioModems_t modem, uint8_t pktLen );
205
206 /*!
207  * \brief Sends the buffer of size. Prepares the packet to be sent and sets
208  *        the radio in transmission
209  *
210  * \param [IN]: buffer     Buffer pointer
211  * \param [IN]: size       Buffer size
212  */
213 void RadioSend( uint8_t *buffer, uint8_t size );
214
215 /*!
216  * \brief Sets the radio in sleep mode
217  */
218 void RadioSleep( void );
219
220 /*!
221  * \brief Sets the radio in standby mode
222  */
223 void RadioStandby( void );
224
225 /*!
226  * \brief Sets the radio in reception mode for the given time
227  * \param [IN] timeout Reception timeout [ms]
228  *                     [0: continuous, others timeout]
229  */
230 void RadioRx( uint32_t timeout );
231
232 /*!
233  * \brief Start a Channel Activity Detection
234  */
235 void RadioStartCad( void );
236
237 /*!
238  * \brief Sets the radio in continuous wave transmission mode
239  *
240  * \param [IN]: freq       Channel RF frequency
241  * \param [IN]: power      Sets the output power [dBm]
242  * \param [IN]: time       Transmission mode timeout [s]
243  */
244 void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time );
245
246 /*!
247  * \brief Reads the current RSSI value
248  *
249  * \retval rssiValue Current RSSI value in [dBm]
250  */
251 int16_t RadioRssi( RadioModems_t modem );
252
253 /*!
254  * \brief Writes the radio register at the specified address
255  *
256  * \param [IN]: addr Register address
257  * \param [IN]: data New register value
258  */
259 void RadioWrite( uint16_t addr, uint8_t data );
260
261 /*!
262  * \brief Reads the radio register at the specified address
263  *
264  * \param [IN]: addr Register address
265  * \retval data Register value
266  */
267 uint8_t RadioRead( uint16_t addr );
268
269 /*!
270  * \brief Writes multiple radio registers starting at address
271  *
272  * \param [IN] addr   First Radio register address
273  * \param [IN] buffer Buffer containing the new register's values
274  * \param [IN] size   Number of registers to be written
275  */
276 void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
277
278 /*!
279  * \brief Reads multiple radio registers starting at address
280  *
281  * \param [IN] addr First Radio register address
282  * \param [OUT] buffer Buffer where to copy the registers data
283  * \param [IN] size Number of registers to be read
284  */
285 void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size );
286
287 /*!
288  * \brief Sets the maximum payload length.
289  *
290  * \param [IN] modem      Radio modem to be used [0: FSK, 1: LoRa]
291  * \param [IN] max        Maximum payload length in bytes
292  */
293 void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max );
294
295 /*!
296  * \brief Sets the network to public or private. Updates the sync byte.
297  *
298  * \remark Applies to LoRa modem only
299  *
300  * \param [IN] enable if true, it enables a public network
301  */
302 void RadioSetPublicNetwork( bool enable );
303
304 /*!
305  * \brief Gets the time required for the board plus radio to get out of sleep.[ms]
306  *
307  * \retval time Radio plus board wakeup time in ms.
308  */
309 uint32_t RadioGetWakeupTime( void );
310
311 /*!
312  * \brief Process radio irq
313  */
314 void RadioIrqProcess( void );
315
316 /*!
317  * \brief Sets the radio in reception mode with Max LNA gain for the given time
318  * \param [IN] timeout Reception timeout [ms]
319  *                     [0: continuous, others timeout]
320  */
321 void RadioRxBoosted( uint32_t timeout );
322
323 /*!
324  * \brief Sets the Rx duty cycle management parameters
325  *
326  * \param [in]  rxTime        Structure describing reception timeout value
327  * \param [in]  sleepTime     Structure describing sleep timeout value
328  */
329 void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime );
330
331 /*!
332  * Radio driver structure initialization
333  */
334 const struct Radio_s Radio =
335 {
336     RadioInit,
337     RadioGetStatus,
338     RadioSetModem,
339     RadioSetChannel,
340     RadioIsChannelFree,
341     RadioRandom,
342     RadioSetRxConfig,
343     RadioSetTxConfig,
344     RadioCheckRfFrequency,
345     RadioTimeOnAiruS,
346     RadioSend,
347     RadioSleep,
348     RadioStandby,
349     RadioRx,
350     RadioStartCad,
351     RadioSetTxContinuousWave,
352     RadioRssi,
353     RadioWrite,
354     RadioRead,
355     RadioWriteBuffer,
356     RadioReadBuffer,
357     RadioSetMaxPayloadLength,
358     RadioSetPublicNetwork,
359     RadioGetWakeupTime,
360     RadioIrqProcess,
361     // Available on SX126x only
362     RadioRxBoosted,
363     RadioSetRxDutyCycle
364 };
365
366 /*
367  * Local types definition
368  */
369
370
371  /*!
372  * FSK bandwidth definition
373  */
374 typedef struct
375 {
376     uint32_t bandwidth;
377     uint8_t  RegValue;
378 }FskBandwidth_t;
379
380 /*!
381  * Precomputed FSK bandwidth registers values
382  */
383 const FskBandwidth_t FskBandwidths[] =
384 {
385     { 4800  , 0x1F },
386     { 5800  , 0x17 },
387     { 7300  , 0x0F },
388     { 9700  , 0x1E },
389     { 11700 , 0x16 },
390     { 14600 , 0x0E },
391     { 19500 , 0x1D },
392     { 23400 , 0x15 },
393     { 29300 , 0x0D },
394     { 39000 , 0x1C },
395     { 46900 , 0x14 },
396     { 58600 , 0x0C },
397     { 78200 , 0x1B },
398     { 93800 , 0x13 },
399     { 117300, 0x0B },
400     { 156200, 0x1A },
401     { 187200, 0x12 },
402     { 234300, 0x0A },
403     { 312000, 0x19 },
404     { 373600, 0x11 },
405     { 467000, 0x09 },
406     { 500000, 0x00 }, // Invalid Bandwidth
407 };
408
409 const RadioLoRaBandwidths_t Bandwidths[] = { LORA_BW_125, LORA_BW_250, LORA_BW_500 };
410 /*
411 //                                          SF12    SF11    SF10    SF9    SF8    SF7    SF6    SF5
412 const double RadioLoRaSymbTime[3][8] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024,    0.512,    0.256},  // 125 KHz
413                                          { 16.384, 8.192,  4.096, 2.048, 1.024, 0.512,    0.256,    0.128},  // 250 KHz
414                                          { 8.192,  4.096,  2.048, 1.024, 0.512, 0.256,    0.128,    0.064}}; // 500 KHz
415
416 // */                        
417 /*
418 static uint16_t RadioLoRaSymbTimeUs[3][8] = {{ 32768, 16384,  8192, 4096, 2048, 1024,    512,    256},  // 125 KHz
419                                          {   16384,  8192,  4096, 2048, 1024, 512,    256,    128},  // 250 KHz
420                                          {    8192,  4096,  2048, 1024,  512, 256,    128,    64}}; // 500 KHz
421
422 */
423 uint8_t MaxPayloadLength = 0xFF;
424
425 uint32_t TxTimeout = 0;
426 uint32_t RxTimeout = 0;
427
428 bool RxContinuous = false;
429
430
431 PacketStatus_t RadioPktStatus;
432 uint8_t RadioRxPayload[256];
433
434 bool IrqFired = false;
435
436 /*
437  * SX126x DIO IRQ callback functions prototype
438  */
439
440 /*!
441  * \brief DIO 0 IRQ callback
442  */
443 void RadioOnDioIrq( void );
444
445 /*!
446  * \brief Tx timeout timer callback
447  */
448 void RadioOnTxTimeoutIrq( void );
449
450 /*!
451  * \brief Rx timeout timer callback
452  */
453 void RadioOnRxTimeoutIrq( void );
454
455 /*
456  * Private global variables
457  */
458
459
460 /*!
461  * Holds the current network type for the radio
462  */
463 typedef struct
464 {
465     bool Previous;
466     bool Current;
467 }RadioPublicNetwork_t;
468
469 static RadioPublicNetwork_t RadioPublicNetwork = { false };
470
471 /*!
472  * Radio callbacks variable
473  */
474 static RadioEvents_t* RadioEvents;
475
476 /*
477  * Public global variables
478  */
479
480 /*!
481  * Radio hardware and global parameters
482  */
483 SX126x_t SX126x;
484
485 /*!
486  * Tx and Rx timers
487  */
488 //TimerEvent_t TxTimeoutTimer;
489 //TimerEvent_t RxTimeoutTimer;
490
491 /*!
492  * Returns the known FSK bandwidth registers value
493  *
494  * \param [IN] bandwidth Bandwidth value in Hz
495  * \retval regValue Bandwidth register value.
496  */
497 static uint8_t RadioGetFskBandwidthRegValue( uint32_t bandwidth )
498 {
499     uint8_t i;
500
501     if( bandwidth == 0 )
502     {
503         return( 0x1F );
504     }
505
506     for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ )
507     {
508         if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) )
509         {
510             return FskBandwidths[i+1].RegValue;
511         }
512     }
513     // ERROR: Value not found
514     while( 1 );
515 }
516
517 void RadioInit( RadioEvents_t *events )
518 {
519     RadioEvents = events;
520     
521     SX126xInit( RadioOnDioIrq );
522     SX126xSetStandby( STDBY_XOSC );        //STDBY_RC
523     SX126xSetRegulatorMode( USE_DCDC );
524     
525     SX126xSetBufferBaseAddress( 0x00, 0x00 );
526     SX126xSetTxParams( 0, RADIO_RAMP_200_US );
527     SX126xSetDioIrqParams( IRQ_RADIO_ALL, IRQ_RADIO_ALL, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
528     
529     //Initialize driver timeout timers
530     //TimerInit( &TxTimeoutTimer, RadioOnTxTimeoutIrq );
531     //TimerInit( &RxTimeoutTimer, RadioOnRxTimeoutIrq );
532     
533     IrqFired = false;
534 }
535
536 RadioState_t RadioGetStatus( void )
537 {
538     switch( SX126xGetOperatingMode( ) )
539     {
540         case MODE_TX:
541             return RF_TX_RUNNING;
542         case MODE_RX:
543             return RF_RX_RUNNING;
544         case MODE_CAD:
545             return RF_CAD;
546         default:
547             return RF_IDLE;
548     }
549 }
550
551 void RadioSetModem( RadioModems_t modem )
552 {
553     switch( modem )
554     {
555     default:
556     case MODEM_FSK:
557         SX126xSetPacketType( PACKET_TYPE_GFSK );
558         // When switching to GFSK mode the LoRa SyncWord register value is reset
559         // Thus, we also reset the RadioPublicNetwork variable
560         RadioPublicNetwork.Current = false;
561         break;
562     case MODEM_LORA:
563         SX126xSetPacketType( PACKET_TYPE_LORA );
564         // Public/Private network register is reset when switching modems
565         if( RadioPublicNetwork.Current != RadioPublicNetwork.Previous )
566         {
567             RadioPublicNetwork.Current = RadioPublicNetwork.Previous;
568             RadioSetPublicNetwork( RadioPublicNetwork.Current );
569         }
570         break;
571     }
572 }
573
574 void RadioSetChannel( uint32_t freq )
575 {
576     SX126xSetRfFrequency( freq );
577 }
578
579 bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime )
580 {
581     bool status = true;
582     int16_t rssi = 0;
583     uint32_t carrierSenseTime = 0;
584
585     RadioSetModem( modem );
586
587     RadioSetChannel( freq );
588
589     RadioRx( 0 );
590
591     HAL_Delay_nMS( 1 );
592
593     //carrierSenseTime = TimerGetCurrentTime( );
594
595     
596      //Perform carrier sense for maxCarrierSenseTime
597 //    while( TimerGetElapsedTime( carrierSenseTime ) < maxCarrierSenseTime )
598 //    {
599         rssi = RadioRssi( modem );
600 //
601         if( rssi > rssiThresh )
602         {
603             status = false;
604 //            break;
605         }
606 //    }
607 //    RadioSleep( );
608     return status;
609 }
610
611 uint32_t RadioRandom( void )
612 {
613     uint8_t i;
614     uint32_t rnd = 0;
615
616     /*
617      * Radio setup for random number generation
618      */
619     // Set LoRa modem ON
620     RadioSetModem( MODEM_LORA );
621
622     // Set radio in continuous reception
623     SX126xSetRx( 0 );
624
625     for( i = 0; i < 32; i++ )
626     {
627         HAL_Delay_nMS( 1 );
628         // Unfiltered RSSI value reading. Only takes the LSB value
629         rnd |= ( ( uint32_t )SX126xGetRssiInst( ) & 0x01 ) << i;
630     }
631
632     RadioSleep( );
633
634     return rnd;
635 }
636
637 void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth,
638                          uint32_t datarate, uint8_t coderate,
639                          uint32_t bandwidthAfc, uint16_t preambleLen,
640                          uint16_t symbTimeout, bool fixLen,
641                          uint8_t payloadLen,
642                          bool crcOn, bool freqHopOn, uint8_t hopPeriod,
643                          bool iqInverted, bool rxContinuous )
644 {
645
646     RxContinuous = rxContinuous;
647
648     if( fixLen == true )
649     {
650         MaxPayloadLength = payloadLen;
651     }
652     else
653     {
654         MaxPayloadLength = 0xFF;
655     }
656
657     switch( modem )
658     {
659         case MODEM_FSK:
660             SX126xSetStopRxTimerOnPreambleDetect( false );
661             SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK;
662
663             SX126x.ModulationParams.Params.Gfsk.BitRate = datarate;
664             SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1;
665             SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth );
666
667             SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK;
668             SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit
669             SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS;
670             SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3; // convert byte into bit
671             SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF;
672             SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH;
673             SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength;
674             if( crcOn == true )
675             {
676                 SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT;
677             }
678             else
679             {
680                 SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF;
681             }
682             SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREE_OFF;
683
684             RadioStandby( );
685             RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA );
686             SX126xSetModulationParams( &SX126x.ModulationParams );
687             SX126xSetPacketParams( &SX126x.PacketParams );
688             SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } );
689             SX126xSetWhiteningSeed( 0x01FF );
690
691             RxTimeout = ( uint32_t )( symbTimeout * 1000 * 8 / datarate );            //( symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1000 );
692             break;
693
694         case MODEM_LORA:
695             SX126xSetStopRxTimerOnPreambleDetect( false );
696             SX126xSetLoRaSymbNumTimeout( symbTimeout );
697             SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA;
698             SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t )datarate;
699             SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth];
700             SX126x.ModulationParams.Params.LoRa.CodingRate = ( RadioLoRaCodingRates_t )coderate;
701
702             if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
703             ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
704             {
705                 SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01;
706             }
707             else
708             {
709                 SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00;
710             }
711
712             SX126x.PacketParams.PacketType = PACKET_TYPE_LORA;
713
714             if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) ||
715                 ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) )
716             {
717                 if( preambleLen < 8 )
718                 {
719                     SX126x.PacketParams.Params.LoRa.PreambleLength = 8;
720                 }
721                 else
722                 {
723                     SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen;
724                 }
725             }
726             else
727             {
728                 SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen;
729             }
730
731             SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen;
732
733             SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength;
734             SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn;
735             SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted;
736
737             RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA );
738             SX126xSetModulationParams( &SX126x.ModulationParams );
739             SX126xSetPacketParams( &SX126x.PacketParams );
740
741             // Timeout Max, Timeout handled directly in SetRx function
742              RxTimeout = 0xFFFF;
743
744             break;
745     }
746 }
747
748 void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
749                         uint32_t bandwidth, uint32_t datarate,
750                         uint8_t coderate, uint16_t preambleLen,
751                         bool fixLen, bool crcOn, bool freqHopOn,
752                         uint8_t hopPeriod, bool iqInverted, uint32_t timeout )
753 {
754
755     switch( modem )
756     {
757         case MODEM_FSK:
758             SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK;
759             SX126x.ModulationParams.Params.Gfsk.BitRate = datarate;
760
761             SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1;
762             SX126x.ModulationParams.Params.Gfsk.Bandwidth = ( bandwidth );
763             SX126x.ModulationParams.Params.Gfsk.Fdev = fdev;
764
765             SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK;
766             SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit
767             SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS;
768             SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3 ; // convert byte into bit
769             SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF;
770             SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH;
771
772             if( crcOn == true )
773             {
774                 SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT;
775             }
776             else
777             {
778                 SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF;
779             }
780             SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREEWHITENING;
781
782             RadioStandby( );
783             RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA );
784             SX126xSetModulationParams( &SX126x.ModulationParams );
785             SX126xSetPacketParams( &SX126x.PacketParams );
786             SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } );
787             SX126xSetWhiteningSeed( 0x01FF );
788             break;
789
790         case MODEM_LORA:
791             SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA;
792             SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) datarate;
793             SX126x.ModulationParams.Params.LoRa.Bandwidth =  Bandwidths[bandwidth];
794             SX126x.ModulationParams.Params.LoRa.CodingRate= ( RadioLoRaCodingRates_t )coderate;
795
796             if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
797             ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
798             {
799                 SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01;
800             }
801             else
802             {
803                 SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00;
804             }
805
806             SX126x.PacketParams.PacketType = PACKET_TYPE_LORA;
807
808             if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) ||
809                 ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) )
810             {
811                 if( preambleLen < 12 )
812                 {
813                     SX126x.PacketParams.Params.LoRa.PreambleLength = 12;
814                 }
815                 else
816                 {
817                     SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen;
818                 }
819             }
820             else
821             {
822                 SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen;
823             }
824
825             SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen;
826             SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength;
827             SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn;
828             SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted;
829
830             RadioStandby( );
831             RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA );
832             SX126xSetModulationParams( &SX126x.ModulationParams );
833             SX126xSetPacketParams( &SX126x.PacketParams );
834             break;
835     }
836     SX126xSetRfTxPower( power );
837     TxTimeout = timeout;
838 }
839
840 bool RadioCheckRfFrequency( uint32_t frequency )
841 {
842     return true;
843 }
844
845 /*
846
847 uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen )
848 {
849     uint32_t airTime = 0;
850
851     switch( modem )
852     {
853     case MODEM_FSK:
854         {
855            airTime = rint( ( 8 * ( SX126x.PacketParams.Params.Gfsk.PreambleLength +
856                                      ( SX126x.PacketParams.Params.Gfsk.SyncWordLength >> 3 ) +
857                                      ( ( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_FIXED_LENGTH ) ? 0.0 : 1.0 ) +
858                                      pktLen +
859                                      ( ( SX126x.PacketParams.Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES ) ? 2.0 : 0 ) ) /
860                                      SX126x.ModulationParams.Params.Gfsk.BitRate ) * 1e3 );
861         }
862         break;
863     case MODEM_LORA:
864         {
865             double ts = RadioLoRaSymbTime[SX126x.ModulationParams.Params.LoRa.Bandwidth - 4][12 - SX126x.ModulationParams.Params.LoRa.SpreadingFactor];
866                     
867             // time of preamble
868             double tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 4.25 ) * ts;
869                     
870             // Symbol length of payload and time
871                     
872             double tmp = ceil( ( 8 * pktLen - 4 * SX126x.ModulationParams.Params.LoRa.SpreadingFactor +
873                                  28 + 16 * SX126x.PacketParams.Params.LoRa.CrcMode -
874                                  ( ( SX126x.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_FIXED_LENGTH ) ? 20 : 0 ) ) /
875                                  ( double )( 4 * ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor -
876                                  ( ( SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) *
877                                  ( ( SX126x.ModulationParams.Params.LoRa.CodingRate % 4 ) + 4 );
878
879                                                                  
880             double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 );
881             double tPayload = nPayload * ts;
882
883             // Time on air
884                         double tOnAir = tPreamble + tPayload;
885             // return milli seconds
886             airTime = floor( tOnAir + 0.999 );
887         }
888         break;
889     }
890     return airTime;
891 }
892 // */
893
894 uint32_t RadioTimeOnAiruS( RadioModems_t modem, uint8_t pktLen )
895 {
896     uint32_t airTime = 0;
897
898     switch( modem )
899     {
900     case MODEM_FSK:
901         {
902            airTime =  (1000 *  8 * ( SX126x.PacketParams.Params.Gfsk.PreambleLength +
903                                      ( SX126x.PacketParams.Params.Gfsk.SyncWordLength >> 3 ) +
904                                      ( ( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_FIXED_LENGTH ) ? 0 : 1 ) +
905                                      pktLen +
906                                      ( ( SX126x.PacketParams.Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES ) ? 2 : 0 ) ) /
907                                      SX126x.ModulationParams.Params.Gfsk.BitRate ) ;
908         }
909         break;
910     case MODEM_LORA:
911         {
912                         uint32_t ts = (1 << (7 + SX126x.ModulationParams.Params.LoRa.SpreadingFactor - SX126x.ModulationParams.Params.LoRa.Bandwidth));///1000.0;
913                     
914             // time of preamble
915             uint32_t tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 4 ) * ts + (ts>>2);
916                         if (SX126x.ModulationParams.Params.LoRa.SpreadingFactor == 5 || SX126x.ModulationParams.Params.LoRa.SpreadingFactor == 6)
917                         {
918                             tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 6 ) * ts + (ts>>2);
919                         }
920             // Symbol length of payload and time
921                         uint32_t tmp32 = ( ( 8 * pktLen - 4 * SX126x.ModulationParams.Params.LoRa.SpreadingFactor +
922                                  28 + 16 * SX126x.PacketParams.Params.LoRa.CrcMode -
923                                  ( ( SX126x.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_FIXED_LENGTH ) ? 20 : 0 ) ) /
924                                  ( 4 * ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor -
925                                  ( ( SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 )  ) )  +1 ) *
926                     
927                                  ( ( SX126x.ModulationParams.Params.LoRa.CodingRate % 4 ) + 4 );
928                                                                  
929                      uint32_t nPayload = 8 + ( ( tmp32 > 0 ) ? tmp32 : 0 );
930                      uint32_t tPayload = nPayload * ts;
931             // Time on air
932                          uint32_t tOnAir = tPreamble + tPayload;
933             // return micro seconds
934                         airTime = tOnAir; //tPreamble;// tOnAir;
935         }
936         break;
937     }
938     return airTime;
939 }
940
941 void RadioSend( uint8_t *buffer, uint8_t size )
942 {
943     SX126xSetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT,
944                            IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT,
945                            IRQ_RADIO_NONE,
946                            IRQ_RADIO_NONE );
947
948     if( SX126xGetPacketType( ) == PACKET_TYPE_LORA )
949     {
950         SX126x.PacketParams.Params.LoRa.PayloadLength = size;
951     }
952     else
953     {
954         SX126x.PacketParams.Params.Gfsk.PayloadLength = size;
955     }
956     SX126xSetPacketParams( &SX126x.PacketParams );
957
958     SX126xSendPayload( buffer, size, 0 );
959 //    TimerSetValue( &TxTimeoutTimer, TxTimeout );
960 //    TimerStart( &TxTimeoutTimer );
961 }
962
963 void RadioSleep( void )
964 {
965     SleepParams_t params = { 0 };
966
967     params.Fields.WarmStart = 1;
968     SX126xSetSleep( params );
969
970     HAL_Delay_nMS( 2 );
971 }
972
973 void RadioStandby( void )
974 {
975   //  SX126xSetStandby( STDBY_XOSC ); //STDBY_RC
976       SX126xSetFs();
977 }
978
979 void RadioRx( uint32_t timeout )
980 {
981     SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,
982                            IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,
983                            IRQ_RADIO_NONE,
984                            IRQ_RADIO_NONE );
985     
986
987     if( RxContinuous == true )
988     {
989         SX126xSetRx( 0xFFFFFF ); // Rx Continuous
990     }
991     else
992     {
993         SX126xSetRx( timeout << 6 );
994     }
995 }
996
997 void RadioRxBoosted( uint32_t timeout )
998 {
999     SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,
1000                            IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,
1001                            IRQ_RADIO_NONE,
1002                            IRQ_RADIO_NONE );
1003
1004
1005     if( RxContinuous == true )
1006     {
1007         SX126xSetRxBoosted( 0xFFFFFF ); // Rx Continuous
1008     }
1009     else
1010     {
1011         SX126xSetRxBoosted( timeout << 6 );
1012     }
1013 }
1014
1015 void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime )
1016 {
1017     SX126xSetRxDutyCycle( rxTime, sleepTime );
1018 }
1019
1020 void RadioStartCad( void )
1021 {
1022     SX126xSetCad( );
1023 }
1024
1025 void RadioTx( uint32_t timeout )
1026 {
1027     SX126xSetTx( timeout << 6 );
1028 }
1029
1030 void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )
1031 {
1032     SX126xSetRfFrequency( freq );
1033     SX126xSetRfTxPower( power );
1034     SX126xSetTxContinuousWave( );
1035
1036 //    TimerSetValue( &RxTimeoutTimer, time  * 1e3 );
1037 //    TimerStart( &RxTimeoutTimer );
1038 }
1039
1040 int16_t RadioRssi( RadioModems_t modem )
1041 {
1042     return SX126xGetRssiInst( );
1043 }
1044
1045 void RadioWrite( uint16_t addr, uint8_t data )
1046 {
1047     SX126xWriteRegister( addr, data );
1048 }
1049
1050 uint8_t RadioRead( uint16_t addr )
1051 {
1052     return SX126xReadRegister( addr );
1053 }
1054
1055 void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
1056 {
1057     SX126xWriteRegisters( addr, buffer, size );
1058 }
1059
1060 void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size )
1061 {
1062     SX126xReadRegisters( addr, buffer, size );
1063 }
1064
1065 void RadioWriteFifo( uint8_t *buffer, uint8_t size )
1066 {
1067     SX126xWriteBuffer( 0, buffer, size );
1068 }
1069
1070 void RadioReadFifo( uint8_t *buffer, uint8_t size )
1071 {
1072     SX126xReadBuffer( 0, buffer, size );
1073 }
1074
1075 void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max )
1076 {
1077     if( modem == MODEM_LORA )
1078     {
1079         SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength = max;
1080         SX126xSetPacketParams( &SX126x.PacketParams );
1081     }
1082     else
1083     {
1084         if( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_VARIABLE_LENGTH )
1085         {
1086             SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength = max;
1087             SX126xSetPacketParams( &SX126x.PacketParams );
1088         }
1089     }
1090 }
1091
1092 void RadioSetPublicNetwork( bool enable )
1093 {
1094     RadioPublicNetwork.Current = RadioPublicNetwork.Previous = enable;
1095
1096     RadioSetModem( MODEM_LORA );
1097     if( enable == true )
1098     {
1099         // Change LoRa modem SyncWord
1100         SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PUBLIC_SYNCWORD >> 8 ) & 0xFF );
1101         SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF );
1102     }
1103     else
1104     {
1105         // Change LoRa modem SyncWord
1106         SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PRIVATE_SYNCWORD >> 8 ) & 0xFF );
1107         SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF );
1108     }
1109 }
1110
1111 uint32_t RadioGetWakeupTime( void )
1112 {
1113     return( RADIO_TCXO_SETUP_TIME + RADIO_WAKEUP_TIME );
1114 }
1115
1116 void RadioOnTxTimeoutIrq( void )
1117 {
1118     if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) )
1119     {
1120         RadioEvents->TxTimeout( );
1121     }
1122 }
1123
1124 void RadioOnRxTimeoutIrq( void )
1125 {
1126     if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )
1127     {
1128         RadioEvents->RxTimeout( );
1129     }
1130 }
1131
1132 void RadioOnDioIrq( void )
1133 {
1134     IrqFired = true;
1135 }
1136
1137 void RadioIrqProcess( void )
1138 {
1139    // if( IrqFired == true )
1140     if(GetRadioDio1Pin())
1141     {
1142         IrqFired = false;
1143
1144         uint16_t irqRegs = SX126xGetIrqStatus( );
1145         SX126xClearIrqStatus( irqRegs);            //IRQ_RADIO_ALL );
1146         
1147         if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )
1148         {
1149  
1150             if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) )
1151             {
1152                 RadioEvents->TxDone( );
1153             }
1154         }
1155         
1156                 if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )
1157         {
1158             if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) )
1159             {
1160                 RadioEvents->RxError( );
1161             }
1162         }
1163                 
1164         if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )
1165         {
1166             uint8_t size;
1167
1168             SX126xGetPayload( RadioRxPayload, &size , 120 );
1169             SX126xGetPacketStatus( &RadioPktStatus );
1170             if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )
1171             {
1172                             if (RadioPktStatus.packetType == PACKET_TYPE_LORA){
1173                 RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.LoRa.RssiPkt, RadioPktStatus.Params.LoRa.SnrPkt );
1174                             }else    if (RadioPktStatus.packetType == PACKET_TYPE_GFSK) {
1175                 RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.Gfsk.RssiAvg,  RadioPktStatus.Params.Gfsk.RssiSync);
1176                                 }
1177             }
1178         }
1179
1180         if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE )
1181         {
1182             if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) )
1183             {
1184                 RadioEvents->CadDone( ( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED ) );
1185             }
1186         }
1187
1188         if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )
1189         {
1190             if( SX126xGetOperatingMode( ) == MODE_TX )
1191             {
1192                 if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) )
1193                 {
1194                     RadioEvents->TxTimeout( );
1195                 }
1196             }
1197             else if( SX126xGetOperatingMode( ) == MODE_RX )
1198             {
1199  
1200                 if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )
1201                 {
1202                     RadioEvents->RxTimeout( );
1203                 }
1204             }
1205         }
1206
1207         if( ( irqRegs & IRQ_PREAMBLE_DETECTED ) == IRQ_PREAMBLE_DETECTED )
1208         {
1209             //__NOP( );
1210         }
1211
1212         if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID )
1213         {
1214             //__NOP( );
1215         }
1216
1217         if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID )
1218         {
1219             //__NOP( );
1220         }
1221
1222         if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR )
1223         {
1224 /*                    
1225             if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )
1226             {
1227                 RadioEvents->RxTimeout( );
1228             }
1229 */ 
1230                     if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) )
1231             {
1232                 RadioEvents->RxError( );
1233             }                        
1234         }
1235     }
1236 }