Simple Ping-Pong demo application between two SX1280 demo boards. Application demonstrating simple Tx/Rx between two boards. By default, each board starts as a "master" and will transmit a "Ping" message, and then wait for an answer. The first board receiving a "Ping" message will become a slave and answer the "master" with a "Pong". The Ping-Pong is then started

Dependencies:   SX1280Lib mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002   ______                              _
00003  / _____)             _              | |
00004 ( (____  _____ ____ _| |_ _____  ____| |__
00005  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00006  _____) ) ____| | | || |_| ____( (___| | | |
00007 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00008     (C)2017 Semtech
00009 
00010 Description: Main program
00011 
00012 Maintainer: Gregory Cristian & Gilbert Menth
00013 */
00014 
00015 #include "mbed.h"
00016 #include "radio.h"
00017 #include "sx1280-hal.h"
00018 
00019 
00020 /*!
00021  * \brief Used to display firmware version on RS232
00022  */
00023 #define FIRMWARE_VERSION ( ( char* )"Firmware Version: 170314A" )
00024 
00025 /*!
00026  * Use the Ping Ping in uncommented Mode
00027  */
00028 //#define MODE_BLE
00029 #define MODE_LORA
00030 //#define MODE_GENERIC
00031 //#define MODE_FLRC
00032 
00033 
00034 /*!
00035  * \brief Defines the nominal frequency
00036  */
00037 #define RF_FREQUENCY                                2400000000UL // Hz
00038 
00039 /*!
00040  * \brief Defines the output power in dBm
00041  *
00042  * \remark The range of the output power is [-18..+13] dBm
00043  */
00044 #define TX_OUTPUT_POWER                             13
00045 
00046 /*!
00047  * \brief Defines the states of the application
00048  */
00049 typedef enum
00050 {
00051     APP_LOWPOWER,
00052     APP_RX,
00053     APP_RX_TIMEOUT,
00054     APP_RX_ERROR,
00055     APP_TX,
00056     APP_TX_TIMEOUT,
00057 }AppStates_t;
00058 
00059 /*!
00060  * \brief Defines the buffer size, i.e. the payload size
00061  */
00062 #define BUFFER_SIZE                                 16
00063 
00064 /*!
00065  * \brief Define the possible message type for this application
00066  */
00067 const uint8_t PingMsg[] = "PING";
00068 const uint8_t PongMsg[] = "PONG";
00069 
00070 /*!
00071  * \brief Defines the size of the token defining message type in the payload
00072  */
00073 #define PINGPONGSIZE                    4
00074 
00075 /*!
00076  * \brief The size of the buffer
00077  */
00078 uint8_t BufferSize = BUFFER_SIZE;
00079 
00080 /*!
00081  * \brief The buffer
00082  */
00083 uint8_t Buffer[BUFFER_SIZE];
00084 
00085 /*!
00086  * \brief The State of the application
00087  */
00088 AppStates_t AppState = APP_LOWPOWER;
00089 
00090 int8_t RssiValue = 0;
00091 int8_t SnrValue = 0;
00092 
00093 /*!
00094  * \brief Function to be executed on Radio Tx Done event
00095  */
00096 void OnTxDone( void );
00097 
00098 /*!
00099  * \brief Function to be executed on Radio Rx Done event
00100  */
00101 void OnRxDone( void );
00102 
00103 /*!
00104  * \brief Function executed on Radio Tx Timeout event
00105  */
00106 void OnTxTimeout( void );
00107 
00108 /*!
00109  * \brief Function executed on Radio Rx Timeout event
00110  */
00111 void OnRxTimeout( void );
00112 
00113 /*!
00114  * \brief Function executed on Radio Rx Error event
00115  */
00116 void OnRxError( IrqErrorCode_t );
00117 
00118 /*!
00119  * \brief All the callbacks are stored in a structure
00120  */
00121 RadioCallbacks_t callbacks =
00122 {
00123     &OnTxDone,        // txDone
00124     &OnRxDone,        // rxDone
00125     NULL,             // syncWordDone
00126     NULL,             // headerDone
00127     &OnTxTimeout,     // txTimeout
00128     &OnRxTimeout,     // rxTimeout
00129     &OnRxError,       // rxError
00130     NULL,             // rangingDone
00131     NULL,             // cadDone
00132 };
00133 
00134 // mosi, miso, sclk, nss, busy, dio1, dio2, dio3, rst, callbacks...
00135 SX1280Hal Radio( D11, D12, D13, D7, D3, D5, NC, NC, A0, &callbacks );
00136 
00137 DigitalOut ANT_SW( A3 );
00138 DigitalOut TxLed( A4 );
00139 DigitalOut RxLed( A5 );
00140 
00141 /*!
00142  * \brief Define IO for Unused Pin
00143  */
00144 DigitalOut F_CS( D6 );      // MBED description of pin
00145 DigitalOut SD_CS( D8 );     // MBED description of pin
00146 
00147 /*!
00148  * \brief Number of tick size steps for tx timeout
00149  */
00150 #define TX_TIMEOUT_VALUE                            100 // ms
00151 
00152 /*!
00153  * \brief Number of tick size steps for rx timeout
00154  */
00155 #define RX_TIMEOUT_VALUE                            100 // ms
00156 
00157 /*!
00158  * \brief Size of ticks (used for Tx and Rx timeout)
00159  */
00160 #define RX_TIMEOUT_TICK_SIZE                        RADIO_TICK_SIZE_1000_US
00161 
00162 /*!
00163  * \brief Mask of IRQs to listen to in rx mode
00164  */
00165 uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT;
00166 
00167 /*!
00168  * \brief Mask of IRQs to listen to in tx mode
00169  */
00170 uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;
00171 
00172 /*!
00173  * \brief Locals parameters and status for radio API
00174  * NEED TO BE OPTIMIZED, COPY OF STUCTURE ALREADY EXISTING
00175  */
00176 PacketParams_t PacketParams;
00177 PacketStatus_t PacketStatus;
00178 
00179 /*!
00180  * \brief Specify serial datarate for UART debug output
00181  */
00182 void baud( int baudrate )
00183 {
00184     Serial s( USBTX, USBRX );
00185 
00186     s.baud( baudrate );
00187 }
00188 
00189 int main( )
00190 {
00191     bool isMaster = true;
00192     ModulationParams_t modulationParams;
00193 
00194     baud( 115200 );
00195 
00196     F_CS   = 1;
00197     SD_CS  = 1;
00198     RxLed  = 1;
00199     TxLed  = 1;
00200     ANT_SW = 1;
00201 
00202     wait_ms( 500 ); // wait for on board DC/DC start-up time
00203 
00204     Radio.Init( );
00205     Radio.SetRegulatorMode( USE_DCDC ); // Can also be set in LDO mode but consume more power
00206 
00207     memset( &Buffer, 0x00, BufferSize );
00208 
00209     printf( "\n\n\r     SX1280 Ping Pong Demo Application (%s)\n\n\r", FIRMWARE_VERSION );
00210 
00211 #if defined( MODE_BLE )
00212 
00213     printf( "\nPing Pong running in BLE mode\n\r");
00214     modulationParams.PacketType                   = PACKET_TYPE_BLE;
00215     modulationParams.Params.Ble.BitrateBandwidth  = GEN_BLE_BR_0_125_BW_0_3;
00216     modulationParams.Params.Ble.ModulationIndex   = GEN_BLE_MOD_IND_1_00;
00217     modulationParams.Params.Ble.ModulationShaping = RADIO_MOD_SHAPING_BT_1_0;
00218 
00219     packetParams.PacketType                 = PACKET_TYPE_BLE;
00220     packetParams.Params.Ble.BlePacketType   = BLE_EYELONG_1_0;
00221     packetParams.Params.Ble.ConnectionState = BLE_MASTER_SLAVE;
00222     packetParams.Params.Ble.CrcField        = BLE_CRC_3B;
00223     packetParams.Params.Ble.Whitening       = RADIO_WHITENING_OFF;
00224 
00225 #elif defined( MODE_GENERIC )
00226 
00227     printf( "\nPing Pong running in GENERIC mode\n\r");
00228     modulationParams.PacketType                       = PACKET_TYPE_GENERIC;
00229     modulationParams.Params.Generic.BitrateBandwidth  = GEN_BLE_BR_0_125_BW_0_3;
00230     modulationParams.Params.Generic.ModulationIndex   = GEN_BLE_MOD_IND_1_00;
00231     modulationParams.Params.Generic.ModulationShaping = RADIO_MOD_SHAPING_BT_1_0;
00232 
00233     packetParams.PacketType                    = PACKET_TYPE_GENERIC;
00234     packetParams.Params.Generic.PreambleLength = PREAMBLE_LENGTH_32_BITS;
00235     packetParams.Params.Generic.SyncWordLength = GEN_SYNCWORD_LENGTH_5_BYTE;
00236     packetParams.Params.Generic.SyncWordMatch  = RADIO_RX_MATCH_SYNCWORD_1;
00237     packetParams.Params.Generic.HeaderType     = RADIO_PACKET_VARIABLE_LENGTH;
00238     packetParams.Params.Generic.PayloadLength  = 15;
00239     packetParams.Params.Generic.CrcLength      = RADIO_CRC_3_BYTES;
00240     packetParams.Params.Generic.Whitening      = RADIO_WHITENING_ON;
00241 
00242 #elif defined( MODE_LORA )
00243 
00244     printf( "\nPing Pong running in LORA mode\n\r");
00245     modulationParams.PacketType                  = PACKET_TYPE_LORA;
00246     modulationParams.Params.LoRa.SpreadingFactor = LORA_SF7;
00247     modulationParams.Params.LoRa.Bandwidth       = LORA_BW_0400;
00248     modulationParams.Params.LoRa.CodingRate      = LORA_CR_4_5;
00249 
00250     PacketParams.PacketType                 = PACKET_TYPE_LORA;
00251     PacketParams.Params.LoRa.PreambleLength = 0x08;
00252     PacketParams.Params.LoRa.HeaderType     = LORA_PACKET_VARIABLE_LENGTH;
00253     PacketParams.Params.LoRa.PayloadLength  = 15;
00254     PacketParams.Params.LoRa.CrcMode        = LORA_CRC_ON;
00255     PacketParams.Params.LoRa.InvertIQ       = LORA_IQ_INVERTED;
00256 
00257 #elif defined( MODE_FLRC )
00258 
00259     printf( "\nPing Pong running in FLRC mode\n\r");
00260     modulationParams.PacketType                    = PACKET_TYPE_FLRC;
00261     modulationParams.Params.Flrc.BitrateBandwidth  = FLRC_BR_0_260_BW_0_3;
00262     modulationParams.Params.Flrc.CodingRate        = FLRC_CR_1_2;
00263     modulationParams.Params.Flrc.ModulationShaping = RADIO_MOD_SHAPING_BT_1_0;
00264 
00265     packetParams.PacketType                 = PACKET_TYPE_FLRC;
00266     packetParams.Params.Flrc.PreambleLength = PREAMBLE_LENGTH_32_BITS;
00267     packetParams.Params.Flrc.SyncWordLength = FLRC_SYNCWORD_LENGTH_4_BYTE;
00268     packetParams.Params.Flrc.SyncWordMatch  = RADIO_RX_MATCH_SYNCWORD_1;
00269     packetParams.Params.Flrc.HeaderType     = RADIO_PACKET_VARIABLE_LENGTH;
00270     packetParams.Params.Flrc.PayloadLength  = 15;
00271     packetParams.Params.Flrc.CrcLength      = RADIO_CRC_3_BYTES;
00272     packetParams.Params.Flrc.Whitening      = RADIO_WHITENING_OFF;
00273 
00274 #else
00275 #error "Please select the mode of operation for the Ping Ping demo"
00276 #endif
00277 
00278     Radio.SetStandby( STDBY_RC );
00279     Radio.SetPacketType( modulationParams.PacketType );
00280     Radio.SetModulationParams( &modulationParams );
00281     Radio.SetPacketParams( &PacketParams );
00282 
00283     Radio.SetRfFrequency( RF_FREQUENCY );
00284     Radio.SetBufferBaseAddresses( 0x00, 0x00 );
00285     Radio.SetTxParams( TX_OUTPUT_POWER, RADIO_RAMP_20_US );
00286 
00287     // only used in GENERIC and BLE mode
00288     Radio.SetSyncWord( 1, ( uint8_t[] ){ 0xDD, 0xA0, 0x96, 0x69, 0xDD } );
00289 
00290     RxLed = 0;
00291     TxLed = 0;
00292 
00293     Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00294     Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
00295     AppState = APP_LOWPOWER;
00296 
00297     while( 1 )
00298     {
00299         switch( AppState )
00300         {
00301             case APP_RX:
00302                 AppState = APP_LOWPOWER;
00303                 RxLed = !RxLed;
00304                 Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE );
00305                 if( isMaster == true )
00306                 {
00307                     if( BufferSize > 0 )
00308                     {
00309                         if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, PINGPONGSIZE ) == 0 )
00310                         {
00311                             printf( "...Pong\r\n" );
00312                             memcpy( Buffer, PingMsg, PINGPONGSIZE );
00313                             Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00314                             Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
00315                         }
00316                         else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, PINGPONGSIZE ) == 0 )
00317                         {
00318                             // A master already exists then become a slave
00319                             printf( "...Ping\r\n" );
00320                             isMaster = false;
00321                             memcpy( Buffer, PongMsg, PINGPONGSIZE );
00322                             Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00323                             Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
00324                         }
00325                         else // valid reception but neither a PING or a PONG message
00326                         {    // Set device as master ans start again
00327                             isMaster = true;
00328                             Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00329                             Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
00330                         }
00331                     }
00332                 }
00333                 else
00334                 {
00335                     if( BufferSize > 0 )
00336                     {
00337                         if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, PINGPONGSIZE ) == 0 )
00338                         {
00339                             printf( "...Ping\r\n" );
00340                             memcpy( Buffer, PongMsg, 4 );
00341                             Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00342                             Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
00343                         }
00344                         else // valid reception but not a PING as expected
00345                         {
00346                             isMaster = true;
00347                             Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00348                             Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
00349                         }
00350                     }
00351                 }
00352                 break;
00353 
00354             case APP_TX:
00355                 AppState = APP_LOWPOWER;
00356                 TxLed = !TxLed;
00357                 if( isMaster == true )
00358                 {
00359                     printf( "Ping...\r\n" );
00360                 }
00361                 else
00362                 {
00363                     printf( "Pong...\r\n" );
00364                 }
00365                 Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00366                 Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
00367                 break;
00368 
00369             case APP_RX_TIMEOUT:
00370                 AppState = APP_LOWPOWER;
00371                 if( isMaster == true )
00372                 {
00373                     // Send the next PING frame
00374                     memcpy( Buffer, PingMsg, PINGPONGSIZE );
00375                     Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00376                     Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
00377                 }
00378                 else
00379                 {
00380                     Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00381                     Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
00382                 }
00383                 break;
00384 
00385             case APP_RX_ERROR:
00386                 AppState = APP_LOWPOWER;
00387                 // We have received a Packet with a CRC error, send reply as if packet was correct
00388                 if( isMaster == true )
00389                 {
00390                     // Send the next PING frame
00391                     memcpy( Buffer, PingMsg, PINGPONGSIZE );
00392                     Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00393                     Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
00394                 }
00395                 else
00396                 {
00397                     // Send the next PONG frame
00398                     memcpy( Buffer, PongMsg, PINGPONGSIZE );
00399                     Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00400                     Radio.SendPayload( Buffer, BufferSize, ( TickTime_t ){ RX_TIMEOUT_TICK_SIZE, TX_TIMEOUT_VALUE } );
00401                 }
00402                 break;
00403 
00404             case APP_TX_TIMEOUT:
00405                 AppState = APP_LOWPOWER;
00406                 Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE );
00407                 Radio.SetRx( ( TickTime_t ) { RX_TIMEOUT_TICK_SIZE, RX_TIMEOUT_VALUE } );
00408                 break;
00409 
00410             case APP_LOWPOWER:
00411                 break;
00412 
00413             default:
00414                 // Set low power
00415                 break;
00416         }
00417     }
00418 }
00419 
00420 void OnTxDone( void )
00421 {
00422     AppState = APP_TX;
00423 }
00424 
00425 void OnRxDone( void )
00426 {
00427     AppState = APP_RX;/*
00428     Radio.GetPacketStatus(&packetStatus);
00429 #if ( defined( MODE_BLE ) || defined( MODE_GENERIC ) )
00430     RssiValue = packetStatus.Ble.RssiSync;
00431     printf("rssi: %d\n\r", RssiValue);
00432 #elif defined( MODE_LORA )
00433     RssiValue = packetStatus.Lr24.RssiPkt;
00434     SnrValue = packetStatus.Lr24.SnrPkt;
00435     printf("rssi: %d; snr: %d\n\r", RssiValue, SnrValue );
00436 #endif*/
00437 }
00438 
00439 void OnTxTimeout( void )
00440 {
00441     AppState = APP_TX_TIMEOUT;
00442     printf( "<>>>>>>>>TXE\r\n" );
00443 }
00444 
00445 void OnRxTimeout( void )
00446 {
00447     AppState = APP_RX_TIMEOUT;
00448 }
00449 
00450 void OnRxError( IrqErrorCode_t errorCode )
00451 {
00452     AppState = APP_RX_ERROR;
00453     printf( "RXE<>>>>>>>>\r\n" );
00454 }
00455 
00456 void OnRangingDone( IrqRangingCode_t val )
00457 {
00458 }
00459 
00460 void OnCadDone( bool channelActivityDetected )
00461 {
00462 }