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
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 }
Generated on Wed Jul 13 2022 07:38:35 by 1.7.2