SX126X_PingPong_Template

Dependencies:   SX126xLib mbed

Files at this revision

API Documentation at this revision

Comitter:
mverdy
Date:
Tue Oct 16 15:12:01 2018 +0000
Parent:
0:ea5a948dfc97
Commit message:
Delete duplicate debug.h; Define state machines for ping-pong

Changed in this revision

SX126xLib.lib Show annotated file Show diff for this revision Revisions of this file
SX1276Lib.lib Show diff for this revision Revisions of this file
debug.h Show diff for this revision Revisions of this file
main_pingpong.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r ea5a948dfc97 -r ecd6c7ea3545 SX126xLib.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SX126xLib.lib	Tue Oct 16 15:12:01 2018 +0000
@@ -0,0 +1,1 @@
+http://os.mbed.com/teams/Semtech/code/SX126xLib/#1e2345700991
diff -r ea5a948dfc97 -r ecd6c7ea3545 SX1276Lib.lib
--- a/SX1276Lib.lib	Tue Oct 09 14:07:38 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://os.mbed.com/teams/Semtech/code/SX1276Lib/#d09a8ef807e2
diff -r ea5a948dfc97 -r ecd6c7ea3545 debug.h
--- a/debug.h	Tue Oct 09 14:07:38 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/* Copyright (c) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- 
-#ifndef DEBUG_H
-#define DEBUG_H
-
-/** @file debug.h */
-
-#ifndef NDEBUG
-
-#include <stdarg.h>
-#include <stdio.h>
-
-/** Output a debug message
- * 
- * @param format printf-style format string, followed by variables
- */
-static inline void debug(const char *format, ...) {
-    va_list args;
-    va_start(args, format);
-    vfprintf(stderr, format, args);
-    va_end(args);
-}
-
-/** Conditionally output a debug message
- * 
- * @param condition output only if condition is true
- * @param format printf-style format string, followed by variables
- */
-static inline void debug_if(bool condition, const char *format, ...) {
-    if(condition) {
-        va_list args;
-        va_start(args, format);
-        vfprintf(stderr, format, args);
-        va_end(args);
-    }
-}
-
-#else
-
-static inline void debug(const char *format, ...) {}
-static inline void debug(bool condition, const char *format, ...) {}
-
-#endif
-
-#endif
diff -r ea5a948dfc97 -r ecd6c7ea3545 main_pingpong.cpp
--- a/main_pingpong.cpp	Tue Oct 09 14:07:38 2018 +0000
+++ b/main_pingpong.cpp	Tue Oct 16 15:12:01 2018 +0000
@@ -12,7 +12,7 @@
  *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
  *               _____) ) ____| | | || |_| ____( (___| | | |
  *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
- *              (C)2013-2017 Semtech
+ *              (C)2013-2018 Semtech
  *
  * \endcode
  *
@@ -21,8 +21,11 @@
 #include "mbed.h"
 #include "sx126x-hal.h"
 #include "sx126x.h"
-#include "debug.h"
+//#include "debug.h"
  
+#define SEND_PING_BEAT_US 200000
+#define RX_TIMEOUT_US 200000
+
 /* Set this flag to '1' to display debug messages on the console */
 #define DEBUG_MESSAGE   1
  
@@ -35,33 +38,37 @@
  
 #if USE_MODEM_LORA == 1
  
-    #define LORA_BANDWIDTH                              2         // [0: 125 kHz,
+    #define LORA_BANDWIDTH                              LORA_BW_500         // [0: 125 kHz,
                                                                   //  1: 250 kHz,
                                                                   //  2: 500 kHz,
                                                                   //  3: Reserved]
-    #define LORA_SPREADING_FACTOR                       7         // [SF7..SF12]
-    #define LORA_CODINGRATE                             1         // [1: 4/5,
+    #define LORA_SPREADING_FACTOR                       LORA_SF7         // [SF7..SF12]
+    #define LORA_LOWDATARATEOPTIMIZE                    0
+    #define LORA_CODINGRATE                             LORA_CR_4_5         // [1: 4/5,
                                                                   //  2: 4/6,
                                                                   //  3: 4/7,
                                                                   //  4: 4/8]
     #define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
     #define LORA_SYMBOL_TIMEOUT                         5         // Symbols
-    #define LORA_FIX_LENGTH_PAYLOAD_ON                  false
+    #define LORA_HEADER_TYPE                            LORA_PACKET_VARIABLE_LENGTH
     #define LORA_FHSS_ENABLED                           false  
     #define LORA_NB_SYMB_HOP                            4     
-    #define LORA_IQ_INVERSION_ON                        false
-    #define LORA_CRC_ENABLED                            true
+    #define LORA_IQ                                     LORA_IQ_NORMAL
+    #define LORA_CRC_MODE                               LORA_CRC_OFF
  
 #elif USE_MODEM_FSK == 1
  
     #define FSK_FDEV                                    25000     // Hz
     #define FSK_DATARATE                                19200     // bps
-    #define FSK_BANDWIDTH                               50000     // Hz
-    #define FSK_AFC_BANDWIDTH                           83333     // Hz
+    #define FSK_BANDWIDTH                               RX_BW_93800     // Hz
+    #define FSK_MODULATION_SHAPPING                     MOD_SHAPING_G_BT_05
     #define FSK_PREAMBLE_LENGTH                         5         // Same for Tx and Rx
-    #define FSK_FIX_LENGTH_PAYLOAD_ON                   false
-    #define FSK_CRC_ENABLED                             true
- 
+    #define FSK_HEADER_TYPE                             RADIO_PACKET_VARIABLE_LENGTH
+    #define FSK_CRC_MODE                                RADIO_CRC_2_BYTES_CCIT
+    #define FSK_ADDR_FILTERING                          RADIO_ADDRESSCOMP_FILT_NODE;
+    #define FSK_WHITENING_MODE                          RADIO_DC_FREE_OFF
+    #define FSK_PREAMBLE_DETECTOR_MODE                  RADIO_PREAMBLE_DETECTOR_OFF
+    #define FSK_SYNCWORD_LENGTH                         8
 #else
     #error "Please define a modem in the compiler options."
 #endif
@@ -86,7 +93,7 @@
 /*!
  * @brief Function to be executed on Radio Rx Done event
  */
-void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
+void OnRxDone( void );
  
 /*!
  * @brief Function executed on Radio Tx Timeout event
@@ -101,304 +108,375 @@
 /*!
  * @brief Function executed on Radio Rx Error event
  */
-void OnRxError( void );
+void OnRxError( IrqErrorCode_t errCode );
  
 /*!
  * @brief Function executed on Radio Fhss Change Channel event
  */
 void OnFhssChangeChannel( uint8_t channelIndex );
- 
-/*!
- * @brief Function executed on CAD Done event
- */
-void OnCadDone( void );
+
+typedef struct{
+    RadioPacketTypes_t packetType;
+    int8_t txPower;
+    RadioRampTimes_t txRampTime;
+    ModulationParams_t modParams;
+    PacketParams_t packetParams;
+    uint32_t rfFrequency;
+    uint16_t irqTx;
+    uint16_t irqRx;
+    uint32_t txTimeout;
+    uint32_t rxTimeout;
+}RadioConfigurations_t;
+RadioConfigurations_t radioConfiguration;
  
 /*
  *  Global variables declarations
  */
 typedef enum
 {
-    LOWPOWER = 0,
-    IDLE,
- 
-    RX,
-    RX_TIMEOUT,
-    RX_ERROR,
- 
-    TX,
-    TX_TIMEOUT,
- 
-    CAD,
-    CAD_DONE
+    SEND_PACKET,
+    WAIT_SEND_DONE,
+    RECEIVE_PACKET,
+    WAIT_RECEIVE_DONE,
+    PACKET_RECEIVED,
 }AppStates_t;
- 
-volatile AppStates_t State = LOWPOWER;
+volatile AppStates_t State = SEND_PACKET;
+
+typedef struct{
+    bool rxDone;
+    bool rxError;
+    bool txDone;
+    bool rxTimeout;
+    bool txTimeout;
+}RadioFlags_t;
+RadioFlags_t radioFlags = {
+    .txDone = false,
+    .rxDone = false,
+    .rxError = false,
+    .rxTimeout = false,
+    .txTimeout = false,
+};
  
 /*!
  * Radio events function pointer
  */
-static RadioCallbacks_t RadioEvents;
- 
+static RadioCallbacks_t RadioEvents = {
+    .txDone = &OnTxDone,
+    .txTimeout = &OnTxTimeout,
+    .rxDone = &OnRxDone,
+    .rxPreambleDetect = NULL,
+    .rxHeaderDone = NULL,
+    .rxTimeout = &OnRxTimeout,
+    .rxError = &OnRxError,
+    .cadDone = NULL,
+};
+
 /*
  *  Global variables declarations
  */
 //Radio Radio( NULL );
+#define MESSAGE_SIZE 4
+typedef uint8_t Messages_t[MESSAGE_SIZE];
+const Messages_t PingMsg = {'P', 'I', 'N', 'G'};
+const Messages_t PongMsg = {'P', 'O', 'N', 'G'};
+const Messages_t *messageToReceive = &PongMsg;
+const Messages_t *messageToSend = &PingMsg;
  
-const uint8_t PingMsg[] = "PING";
-const uint8_t PongMsg[] = "PONG";
- 
-uint16_t BufferSize = BUFFER_SIZE;
+uint8_t BufferSize = BUFFER_SIZE;
 uint8_t Buffer[BUFFER_SIZE];
  
-int16_t RssiValue = 0.0;
-int8_t SnrValue = 0.0;
- 
+int8_t RssiValue = 0;
+int8_t SnrValue = 0;
+
+void GetRssiSnr(int8_t *rssi, int8_t *snr);
+SX126xHal Radio( D11, D12, D13, D7, D3, D5, NC, NC, A0, A1, A2, D8, &RadioEvents );
+
+void SetToMaster(void);
+void SetToSlave(void);
+void RunMasterStateMachine();
+void RunSlaveStateMachine();
+void SetConfiguration(RadioConfigurations_t *config);
+void ConfigureGeneralRadio(SX126xHal *radio, RadioConfigurations_t *config);
+void ConfigureRadioTx(SX126xHal *radio, RadioConfigurations_t *config);
+void ConfigureRadioRx(SX126xHal *radio, RadioConfigurations_t *config);
+void PrepareBuffer(SX126xHal *radio, const Messages_t *messageToSend);
+bool isMaster = true;
+bool masterCanSend = true;
+void MasterSendNextEvent(void){masterCanSend = true;}
+bool slaveCanListen = false;
+void SlaveListenNextEvent(void){slaveCanListen = true;}
+Ticker masterSendNextTicker;
+Ticker slaveListenNextTicker;
+
+Serial serial(USBTX, USBRX);
+
 int main( void ) 
 {
-    uint8_t i;
-    bool isMaster = true;
- 
-    debug( "\n\n\r     SX1272 Ping Pong Demo Application \n\n\r" );
- 
-    // Initialize Radio driver
-    RadioEvents.TxDone = OnTxDone;
-    RadioEvents.RxDone = OnRxDone;
-    RadioEvents.RxError = OnRxError;
-    RadioEvents.TxTimeout = OnTxTimeout;
-    RadioEvents.RxTimeout = OnRxTimeout;
-    Radio.Init( &RadioEvents );
- 
-    // verify the connection with the board
-    while( Radio.Read( REG_VERSION ) == 0x00  )
-    {
-        debug( "Radio could not be detected!\n\r", NULL );
-        wait( 1 );
+    Radio.Reset();
+    Radio.Init();
+    serial.baud(115200);
+    SetToMaster();
+    SetConfiguration(&radioConfiguration);
+    ConfigureGeneralRadio(&Radio, &radioConfiguration);
+    while(true){
+        if(isMaster){
+            RunMasterStateMachine();
+        }
+        else{
+            RunSlaveStateMachine();
+        }
     }
- 
-    debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1272MB2XAS ) ), "\n\r > Board Type: SX1272MB2xAS < \n\r" );
- 
-    Radio.SetChannel( RF_FREQUENCY ); 
- 
-#if USE_MODEM_LORA == 1
- 
-    debug_if( LORA_FHSS_ENABLED, "\n\n\r             > LORA FHSS Mode < \n\n\r" );
-    debug_if( !LORA_FHSS_ENABLED, "\n\n\r             > LORA Mode < \n\n\r" );
- 
-    Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
-                         LORA_SPREADING_FACTOR, LORA_CODINGRATE,
-                         LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
-                         LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
-                         LORA_IQ_INVERSION_ON, 2000 );
- 
-    Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
-                         LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
-                         LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
-                         LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
-                         LORA_IQ_INVERSION_ON, true );
- 
-#elif USE_MODEM_FSK == 1
- 
-    debug("\n\n\r              > FSK Mode < \n\n\r" );
-    Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
-                         FSK_DATARATE, 0,
-                         FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
-                         FSK_CRC_ENABLED, 0, 0, 0, 2000 );
- 
-    Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
-                         0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
-                         0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
-                         0, 0, false, true );
- 
-#else
- 
-#error "Please define a modem in the compiler options."
- 
-#endif
- 
-    debug_if( DEBUG_MESSAGE, "Starting Ping-Pong loop\r\n" );
- 
-    led = 0;
- 
-    Radio.Rx( RX_TIMEOUT_VALUE );
- 
-    while( 1 )
-    {
-        switch( State )
-        {
-        case RX:
-            if( isMaster == true )
-            {
-                if( BufferSize > 0 )
-                {
-                    if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 )
-                    {
-                        led = !led;
-                        debug( "...Pong\r\n" );
-                        // Send the next PING frame
-                        strcpy( ( char* )Buffer, ( char* )PingMsg );
-                        // We fill the buffer with numbers for the payload
-                        for( i = 4; i < BufferSize; i++ )
-                        {
-                            Buffer[i] = i - 4;
-                        }
-                        wait_ms( 10 );
-                        Radio.Send( Buffer, BufferSize );
-                    }
-                    else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
-                    { // A master already exists then become a slave
-                        debug( "...Ping\r\n" );
-                        led = !led;
-                        isMaster = false;
-                        // Send the next PONG frame
-                        strcpy( ( char* )Buffer, ( char* )PongMsg );
-                        // We fill the buffer with numbers for the payload
-                        for( i = 4; i < BufferSize; i++ )
-                        {
-                            Buffer[i] = i - 4;
-                        }
-                        wait_ms( 10 );
-                        Radio.Send( Buffer, BufferSize );
-                    }
-                    else // valid reception but neither a PING or a PONG message
-                    {    // Set device as master ans start again
-                        isMaster = true;
-                        Radio.Rx( RX_TIMEOUT_VALUE );
-                    }
-                }
+}
+
+void RunMasterStateMachine(){
+    switch(State){
+        case SEND_PACKET:{
+            if(masterCanSend == true){
+                masterCanSend = false;
+                masterSendNextTicker.attach_us(&MasterSendNextEvent, SEND_PING_BEAT_US);
+                PrepareBuffer(&Radio, messageToSend);
+                ConfigureRadioTx(&Radio, &radioConfiguration);
+                Radio.SetTx(radioConfiguration.txTimeout);
+                printf("Ping...\n");
+                State = WAIT_SEND_DONE;
+            }
+            break;
+        }
+        
+        case WAIT_SEND_DONE:{
+            if(radioFlags.txDone){
+                radioFlags.txDone = false;
+                State = RECEIVE_PACKET;
+            }
+            if(radioFlags.txTimeout){
+                radioFlags.txTimeout = false;
+                State = SEND_PACKET;
             }
-            else
-            {
-                if( BufferSize > 0 )
-                {
-                    if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
-                    {
-                        led = !led;
-                        debug( "...Ping\r\n" );
-                        // Send the reply to the PING string
-                        strcpy( ( char* )Buffer, ( char* )PongMsg );
-                        // We fill the buffer with numbers for the payload
-                        for( i = 4; i < BufferSize; i++ )
-                        {
-                            Buffer[i] = i - 4;
-                        }
-                        wait_ms( 10 );
-                        Radio.Send( Buffer, BufferSize );
-                    }
-                    else // valid reception but not a PING as expected
-                    {    // Set device as master and start again
-                        isMaster = true;
-                        Radio.Rx( RX_TIMEOUT_VALUE );
-                    }
-                }
-            }
-            State = LOWPOWER;
             break;
-        case TX:
-            led = !led;
-            if( isMaster == true )  
-            {
-                debug( "Ping...\r\n" );
-            }
-            else
-            {
-                debug( "Pong...\r\n" );
-            }
-            Radio.Rx( RX_TIMEOUT_VALUE );
-            State = LOWPOWER;
+        }
+        
+        case RECEIVE_PACKET:{
+            ConfigureRadioRx(&Radio, &radioConfiguration);
+            Radio.SetRx(radioConfiguration.rxTimeout);
+            State = WAIT_RECEIVE_DONE;
             break;
-        case RX_TIMEOUT:
-            if( isMaster == true )
-            {
-                // Send the next PING frame
-                strcpy( ( char* )Buffer, ( char* )PingMsg );
-                for( i = 4; i < BufferSize; i++ )
-                {
-                    Buffer[i] = i - 4;
-                }
-                wait_ms( 10 );
-                Radio.Send( Buffer, BufferSize );
+        }
+        
+        case WAIT_RECEIVE_DONE:{
+            if(radioFlags.rxDone == true){
+                radioFlags.rxDone = false;
+                State = PACKET_RECEIVED;
             }
-            else
-            {
-                Radio.Rx( RX_TIMEOUT_VALUE );
+            if(radioFlags.rxTimeout == true){
+                radioFlags.rxTimeout = false;
+                State = SEND_PACKET;
             }
-            State = LOWPOWER;
             break;
-        case RX_ERROR:
-            // We have received a Packet with a CRC error, send reply as if packet was correct
-            if( isMaster == true )
-            {
-                // Send the next PING frame
-                strcpy( ( char* )Buffer, ( char* )PingMsg );
-                for( i = 4; i < BufferSize; i++ )
-                {
-                    Buffer[i] = i - 4;
-                }
-                wait_ms( 10 );
-                Radio.Send( Buffer, BufferSize );
+        }
+        
+        case PACKET_RECEIVED:{
+            Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE );
+            RssiValue = Radio.GetRssiInst();
+            GetRssiSnr(&RssiValue, &SnrValue);
+            if( strncmp(( const char* )Buffer, (const char*)messageToReceive, MESSAGE_SIZE ) == 0 ){
+                printf("...Pong\n");
+                State = SEND_PACKET;
             }
-            else
-            {
-                // Send the next PONG frame
-                strcpy( ( char* )Buffer, ( char* )PongMsg );
-                for( i = 4; i < BufferSize; i++ )
-                {
-                    Buffer[i] = i - 4;
-                }
-                wait_ms( 10 );
-                Radio.Send( Buffer, BufferSize );
+            else if( strncmp(( const char* )Buffer, (const char*)messageToSend, MESSAGE_SIZE ) == 0 ){
+                // Another Master is in the air, swith to slave
+                SetToSlave();
             }
-            State = LOWPOWER;
-            break;
-        case TX_TIMEOUT:
-            Radio.Rx( RX_TIMEOUT_VALUE );
-            State = LOWPOWER;
-            break;
-        case LOWPOWER:
-            break;
-        default:
-            State = LOWPOWER;
+            else{
+                printf("WRONG PAYLOAD\n");
+                SetToMaster();
+            }
             break;
         }
     }
 }
+
+void RunSlaveStateMachine(){
+    switch(State){
+        case RECEIVE_PACKET:{
+            if(slaveCanListen == true){
+                slaveCanListen = false;
+                ConfigureRadioRx(&Radio, &radioConfiguration);
+                Radio.SetRx(radioConfiguration.rxTimeout);
+                slaveListenNextTicker.attach_us(&SlaveListenNextEvent, SEND_PING_BEAT_US - ( RX_TIMEOUT_US>>1 ));
+                State = WAIT_RECEIVE_DONE;
+            }
+            break;
+        }
+        
+        case WAIT_RECEIVE_DONE:{
+            if(radioFlags.rxDone == true){
+                radioFlags.rxDone = false;
+                State = PACKET_RECEIVED;
+            }
+            if(radioFlags.rxTimeout == true){
+                radioFlags.rxTimeout = false;
+                SetToMaster();
+            }
+            break;
+        }
+        
+        case PACKET_RECEIVED:{
+            Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE );
+            RssiValue = Radio.GetRssiInst();
+            GetRssiSnr(&RssiValue, &SnrValue);
+            if( strncmp(( const char* )Buffer, (const char*)messageToReceive, MESSAGE_SIZE ) == 0 ){
+                printf("...Ping\n");
+                State = SEND_PACKET;
+            }
+            else{
+                SetToMaster();
+            }
+            break;
+        }
+        
+        case SEND_PACKET:{
+            PrepareBuffer(&Radio, messageToSend);
+            ConfigureRadioTx(&Radio, &radioConfiguration);
+            printf("Pong...\n");
+            Radio.SetTx(radioConfiguration.txTimeout);
+            State = WAIT_SEND_DONE;
+            break;
+        }
+        
+        case WAIT_SEND_DONE:{
+            if(radioFlags.txDone){
+                radioFlags.txDone = false;
+                State = RECEIVE_PACKET;
+            }
+            if(radioFlags.txTimeout){
+                radioFlags.txTimeout = false;
+                SetToMaster();
+            }
+            break;
+        }
+    }
+}
+
+void SetToMaster(){
+    printf("-->Master\n");
+    isMaster = true;
+    masterCanSend = true;
+    State = SEND_PACKET;
+    messageToReceive = &PongMsg;
+    messageToSend = &PingMsg;
+}
+
+void SetToSlave(){
+    slaveCanListen = false;
+    slaveListenNextTicker.attach_us(&SlaveListenNextEvent, SEND_PING_BEAT_US - ( RX_TIMEOUT_US>>1 ));
+    printf("--> Slave\n");
+    isMaster = false;
+    State = RECEIVE_PACKET;
+    messageToReceive = &PingMsg;
+    messageToSend = &PongMsg;
+}
  
 void OnTxDone( void )
 {
-    Radio.Sleep( );
-    State = TX;
-    debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" );
+    radioFlags.txDone = true;
 }
  
-void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
+void OnRxDone( void )
 {
-    Radio.Sleep( );
-    BufferSize = size;
-    memcpy( Buffer, payload, BufferSize );
-    RssiValue = rssi;
-    SnrValue = snr;
-    State = RX;
-    debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
+    radioFlags.rxDone = true;
 }
  
 void OnTxTimeout( void )
 {
-    Radio.Sleep( );
-    State = TX_TIMEOUT;
+    radioFlags.txTimeout = true;
     debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
 }
  
 void OnRxTimeout( void )
 {
-    Radio.Sleep( );
-    Buffer[BufferSize] = 0;
-    State = RX_TIMEOUT;
+    radioFlags.rxTimeout = true;
     debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
 }
  
-void OnRxError( void )
+void OnRxError( IrqErrorCode_t errCode )
 {
-    Radio.Sleep( );
-    State = RX_ERROR;
+    radioFlags.rxError = true;
     debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
-}
\ No newline at end of file
+}
+
+void SetConfiguration(RadioConfigurations_t *config){
+    config->irqRx = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT;
+    config->irqTx = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
+    config->rfFrequency = RF_FREQUENCY;
+    config->txTimeout = 0;
+    config->rxTimeout = (uint32_t)(RX_TIMEOUT_US / 15.625);
+    config->txPower = TX_OUTPUT_POWER;
+    config->txRampTime = RADIO_RAMP_200_US;
+    #if USE_MODEM_LORA == 1
+        config->packetType = PACKET_TYPE_LORA;
+        config->modParams.PacketType = PACKET_TYPE_LORA;
+        config->modParams.Params.LoRa.Bandwidth = LORA_BANDWIDTH;
+        config->modParams.Params.LoRa.CodingRate = LORA_CODINGRATE;
+        config->modParams.Params.LoRa.LowDatarateOptimize = LORA_LOWDATARATEOPTIMIZE;
+        config->modParams.Params.LoRa.SpreadingFactor = LORA_SPREADING_FACTOR;
+        config->packetParams.PacketType = PACKET_TYPE_LORA;
+        config->packetParams.Params.LoRa.CrcMode = LORA_CRC_MODE;
+        config->packetParams.Params.LoRa.HeaderType = LORA_HEADER_TYPE;
+        config->packetParams.Params.LoRa.InvertIQ = LORA_IQ;
+        config->packetParams.Params.LoRa.PayloadLength = BUFFER_SIZE;
+        config->packetParams.Params.LoRa.PreambleLength = LORA_PREAMBLE_LENGTH;
+    #elif USE_MODEM_FSK == 1
+        config->packetType = PACKET_TYPE_GFSK;
+        config->modParams.PacketType = PACKET_TYPE_GFSK;
+        config->modParams.Params.Gfsk.Bandwidth = FSK_BANDWIDTH;
+        config->modParams.Params.Gfsk.BitRate = 1024000000 / FSK_DATARATE;
+        config->modParams.Params.Gfsk.Fdev = FSK_FDEV * 1.048576;
+        config->modParams.Params.Gfsk.ModulationShaping = FSK_MODULATION_SHAPPING;
+        config->packetParams.PacketType = PACKET_TYPE_GFSK;
+        config->packetParams.Params.Gfsk.AddrComp = FSK_ADDR_FILTERING;
+        config->packetParams.Params.Gfsk.CrcLength = FSK_CRC_MODE;
+        config->packetParams.Params.Gfsk.DcFree = FSK_WHITENING_MODE;
+        config->packetParams.Params.Gfsk.HeaderType = FSK_HEADER_TYPE;
+        config->packetParams.Params.Gfsk.PayloadLength = BUFFER_SIZE;
+        config->packetParams.Params.Gfsk.PreambleLength = FSK_PREAMBLE_LENGTH;
+        config->packetParams.Params.Gfsk.PreambleMinDetect = FSK_PREAMBLE_DETECTOR_MODE;
+        config->packetParams.Params.Gfsk.SyncWordLength = FSK_SYNCWORD_LENGTH;
+    #endif
+}
+
+void ConfigureGeneralRadio(SX126xHal *radio, RadioConfigurations_t *config){
+    radio->SetPacketType(config->packetType);
+    radio->SetPacketParams(&config->packetParams);
+    radio->SetModulationParams(&config->modParams);
+    radio->SetRfFrequency(config->rfFrequency);
+    radio->SetTxParams(config->txPower, config->txRampTime);
+    radio->SetInterruptMode();
+    if(config->packetType == PACKET_TYPE_GFSK){
+        uint8_t syncword[8] = {0xF0, 0x0F, 0x55, 0xAA, 0xF0, 0x0F, 0x55, 0xAA};
+        radio->SetSyncWord(syncword);
+    }
+}
+
+void ConfigureRadioTx(SX126xHal *radio, RadioConfigurations_t *config){
+    radio->SetDioIrqParams(config->irqTx, config->irqTx, IRQ_RADIO_NONE, IRQ_RADIO_NONE);
+}
+
+void ConfigureRadioRx(SX126xHal *radio, RadioConfigurations_t *config){
+    radio->SetDioIrqParams(config->irqRx, config->irqRx, IRQ_RADIO_NONE, IRQ_RADIO_NONE);
+}
+
+void PrepareBuffer(SX126xHal *radio, const Messages_t *messageToSend){
+    radio->SetPayload((uint8_t*)messageToSend, MESSAGE_SIZE);
+}
+
+void GetRssiSnr(int8_t *rssi, int8_t *snr)
+{
+    PacketStatus_t pkt_stat;
+    Radio.GetPacketStatus(&pkt_stat);    
+    #if USE_MODEM_LORA == 1
+        *rssi = pkt_stat.Params.LoRa.RssiPkt;
+        *snr = pkt_stat.Params.LoRa.SnrPkt;
+    #else
+        *rssi = pkt_stat.Params.Gfsk.RssiSync;
+    #endif
+}