RadioShuttle Lib for the STM32 L4 Heltec Board
Dependents: Turtle_RadioShuttle
GenericPingPong.cpp
00001 00002 #include "mbed.h" 00003 #include "PinMap.h" 00004 #include "GenericPingPong.h" 00005 #if defined(DEVICE_LPTICKER) || defined(DEVICE_LOWPOWERTIMER) // LOWPOWERTIMER in older mbed versions 00006 #define MyTimeout LowPowerTimeout 00007 #else 00008 #define MyTimeout Timeout 00009 #endif 00010 #include "sx1276-mbed-hal.h" 00011 #include "main.h" 00012 00013 #ifdef FEATURE_LORA_PING_PONG 00014 00015 /* Set this flag to '1' to display debug messages on the console */ 00016 #define DEBUG_MESSAGE 1 00017 00018 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */ 00019 #define USE_MODEM_LORA 1 00020 #define USE_MODEM_FSK !USE_MODEM_LORA 00021 #define RF_FREQUENCY RF_FREQUENCY_868_1 // Hz 00022 #define TX_OUTPUT_POWER 14 // 14 dBm 00023 00024 #if USE_MODEM_LORA == 1 00025 00026 #define LORA_BANDWIDTH 125000 // see LoRa bandwidth map for details 00027 #define LORA_SPREADING_FACTOR LORA_SF7 00028 #define LORA_CODINGRATE LORA_ERROR_CODING_RATE_4_5 00029 00030 #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx 00031 #define LORA_SYMBOL_TIMEOUT 5 // Symbols 00032 #define LORA_FIX_LENGTH_PAYLOAD_ON false 00033 #define LORA_FHSS_ENABLED false 00034 #define LORA_NB_SYMB_HOP 4 00035 #define LORA_IQ_INVERSION_ON false 00036 #define LORA_CRC_ENABLED true 00037 00038 #elif USE_MODEM_FSK == 1 00039 00040 #define FSK_FDEV 25000 // Hz 00041 #define FSK_DATARATE 19200 // bps 00042 #define FSK_BANDWIDTH 50000 // Hz 00043 #define FSK_AFC_BANDWIDTH 83333 // Hz 00044 #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx 00045 #define FSK_FIX_LENGTH_PAYLOAD_ON false 00046 #define FSK_CRC_ENABLED true 00047 00048 #else 00049 #error "Please define a modem in the compiler options." 00050 #endif 00051 00052 00053 #define RX_TIMEOUT_VALUE 3500 // in ms 00054 00055 //#define BUFFER_SIZE 32 // Define the payload size here 00056 #define BUFFER_SIZE 64 // Define the payload size here 00057 00058 /* 00059 * Global variables declarations 00060 */ 00061 typedef enum 00062 { 00063 LOWPOWER = 0, 00064 IDLE, 00065 00066 RX, 00067 RX_TIMEOUT, 00068 RX_ERROR, 00069 00070 TX, 00071 TX_TIMEOUT, 00072 00073 CAD, 00074 CAD_DONE 00075 } AppStates_t; 00076 00077 volatile AppStates_t State = LOWPOWER; 00078 00079 /*! 00080 * Radio events function pointer 00081 */ 00082 static RadioEvents_t RadioEvents; 00083 00084 /* 00085 * Global variables declarations 00086 */ 00087 SX1276Generic *Radio; 00088 00089 00090 const uint8_t PingMsg[] = { 0xff, 0xff, 0x00, 0x00, 'P', 'I', 'N', 'G'};// "PING"; 00091 const uint8_t PongMsg[] = { 0xff, 0xff, 0x00, 0x00, 'P', 'O', 'N', 'G'};// "PONG"; 00092 00093 uint16_t BufferSize = BUFFER_SIZE; 00094 uint8_t *Buffer; 00095 00096 DigitalOut *led3; 00097 00098 00099 int SX1276PingPong() 00100 { 00101 #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) ) 00102 DigitalOut *led = new DigitalOut(LED2); 00103 #elif defined(TARGET_NUCLEO_L073RZ) || defined (TARGET_DISCO_L072CZ_LRWAN1) 00104 DigitalOut *led = new DigitalOut(LED4); // RX red 00105 led3 = new DigitalOut(LED3); // TX blue 00106 #else 00107 DigitalOut *led = new DigitalOut(LED1); 00108 led3 = led; 00109 #endif 00110 00111 Buffer = new uint8_t[BUFFER_SIZE]; 00112 *led3 = 1; 00113 00114 #ifdef TARGET_DISCO_L072CZ_LRWAN1 00115 Radio = new SX1276Generic(NULL, MURATA_SX1276, 00116 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00117 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5, 00118 LORA_ANT_RX, LORA_ANT_TX, LORA_ANT_BOOST, LORA_TCXO); 00119 #elif defined(HELTECL432_REV1) 00120 Radio = new SX1276Generic(NULL, HELTEC_L4_1276, 00121 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00122 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5, 00123 LORA_ANT_PWR); 00124 #else // RFM95 00125 Radio = new SX1276Generic(NULL, RFM95_SX1276, 00126 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00127 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5); 00128 00129 #endif 00130 00131 uint8_t i; 00132 bool isMaster = true; 00133 00134 dprintf("SX1276 Ping Pong Demo Application" ); 00135 dprintf("Freqency: %.1f", (double)RF_FREQUENCY/1000000.0); 00136 dprintf("TXPower: %d dBm", TX_OUTPUT_POWER); 00137 #if USE_MODEM_LORA == 1 00138 dprintf("Bandwidth: %d Hz", LORA_BANDWIDTH); 00139 dprintf("Spreading factor: SF%d", LORA_SPREADING_FACTOR); 00140 #elif USE_MODEM_FSK == 1 00141 dprintf("Bandwidth: %d kHz", FSK_BANDWIDTH); 00142 dprintf("Baudrate: %d", FSK_DATARATE); 00143 #endif 00144 // Initialize Radio driver 00145 RadioEvents.TxDone = OnTxDone; 00146 RadioEvents.RxDone = OnRxDone; 00147 RadioEvents.RxError = OnRxError; 00148 RadioEvents.TxTimeout = OnTxTimeout; 00149 RadioEvents.RxTimeout = OnRxTimeout; 00150 if (Radio->Init( &RadioEvents ) == false) { 00151 while(1) { 00152 dprintf("Radio could not be detected!"); 00153 wait( 1 ); 00154 } 00155 } 00156 00157 switch(Radio->DetectBoardType()) { 00158 case SX1276MB1LAS: 00159 if (DEBUG_MESSAGE) 00160 dprintf(" > Board Type: SX1276MB1LAS <"); 00161 break; 00162 case SX1276MB1MAS: 00163 if (DEBUG_MESSAGE) 00164 dprintf(" > Board Type: SX1276MB1LAS <"); 00165 break; 00166 case MURATA_SX1276: 00167 if (DEBUG_MESSAGE) 00168 dprintf(" > Board Type: MURATA_SX1276_STM32L0 <"); 00169 break; 00170 case RFM95_SX1276: 00171 if (DEBUG_MESSAGE) 00172 dprintf(" > HopeRF RFM95xx <"); 00173 break; 00174 default: 00175 dprintf(" > Board Type: unknown <"); 00176 } 00177 00178 Radio->SetChannel(RF_FREQUENCY ); 00179 00180 #if USE_MODEM_LORA == 1 00181 00182 if (LORA_FHSS_ENABLED) 00183 dprintf(" > LORA FHSS Mode <"); 00184 if (!LORA_FHSS_ENABLED) 00185 dprintf(" > LORA Mode <"); 00186 00187 Radio->SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, 00188 LORA_SPREADING_FACTOR, LORA_CODINGRATE, 00189 LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, 00190 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 00191 LORA_IQ_INVERSION_ON, 2000 ); 00192 00193 Radio->SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, 00194 LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, 00195 LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, 00196 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 00197 LORA_IQ_INVERSION_ON, true ); 00198 00199 #elif USE_MODEM_FSK == 1 00200 00201 dprintf(" > FSK Mode <"); 00202 Radio->SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, 00203 FSK_DATARATE, 0, 00204 FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, 00205 FSK_CRC_ENABLED, 0, 0, 0, 2000 ); 00206 00207 Radio->SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, 00208 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, 00209 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED, 00210 0, 0, false, true ); 00211 00212 #else 00213 00214 #error "Please define a modem in the compiler options." 00215 00216 #endif 00217 00218 if (DEBUG_MESSAGE) 00219 dprintf("Starting Ping-Pong loop"); 00220 00221 00222 Radio->Rx( RX_TIMEOUT_VALUE ); 00223 00224 while( 1 ) 00225 { 00226 #ifdef TARGET_STM32L4 00227 WatchDogUpdate(); 00228 #endif 00229 00230 switch( State ) 00231 { 00232 case RX: 00233 *led3 = 0; 00234 if( isMaster == true ) 00235 { 00236 if( BufferSize > 0 ) 00237 { 00238 if( memcmp(Buffer, PongMsg, sizeof(PongMsg)) == 0 ) 00239 { 00240 *led = !*led; 00241 dprintf( "...Pong" ); 00242 // Send the next PING frame 00243 memcpy(Buffer, PingMsg, sizeof(PingMsg)); 00244 // We fill the buffer with numbers for the payload 00245 for( i = sizeof(PingMsg); i < BufferSize; i++ ) 00246 { 00247 Buffer[i] = i - sizeof(PingMsg); 00248 } 00249 wait_ms( 10 ); 00250 Radio->Send( Buffer, BufferSize ); 00251 } 00252 else if( memcmp(Buffer, PingMsg, sizeof(PingMsg)) == 0 ) 00253 { // A master already exists then become a slave 00254 dprintf( "...Ping" ); 00255 *led = !*led; 00256 isMaster = false; 00257 // Send the next PONG frame 00258 memcpy(Buffer, PongMsg, sizeof(PongMsg)); 00259 // We fill the buffer with numbers for the payload 00260 for( i = sizeof(PongMsg); i < BufferSize; i++ ) 00261 { 00262 Buffer[i] = i - sizeof(PongMsg); 00263 } 00264 wait_ms( 10 ); 00265 Radio->Send( Buffer, BufferSize ); 00266 } 00267 else // valid reception but neither a PING or a PONG message 00268 { // Set device as master ans start again 00269 isMaster = true; 00270 Radio->Rx( RX_TIMEOUT_VALUE ); 00271 } 00272 } 00273 } 00274 else 00275 { 00276 if( BufferSize > 0 ) 00277 { 00278 if( memcmp(Buffer, PingMsg, sizeof(PingMsg)) == 0 ) 00279 { 00280 *led = !*led; 00281 dprintf( "...Ping" ); 00282 // Send the reply to the PING string 00283 memcpy(Buffer, PongMsg, sizeof(PongMsg)); 00284 // We fill the buffer with numbers for the payload 00285 for( i = sizeof(PongMsg); i < BufferSize; i++ ) 00286 { 00287 Buffer[i] = i - sizeof(PongMsg); 00288 } 00289 wait_ms( 10 ); 00290 Radio->Send( Buffer, BufferSize ); 00291 } 00292 else // valid reception but not a PING as expected 00293 { // Set device as master and start again 00294 isMaster = true; 00295 Radio->Rx( RX_TIMEOUT_VALUE ); 00296 } 00297 } 00298 } 00299 State = LOWPOWER; 00300 break; 00301 case TX: 00302 *led3 = 1; 00303 if( isMaster == true ) 00304 { 00305 dprintf("Ping..." ); 00306 } 00307 else 00308 { 00309 dprintf("Pong..." ); 00310 } 00311 Radio->Rx( RX_TIMEOUT_VALUE ); 00312 State = LOWPOWER; 00313 break; 00314 case RX_TIMEOUT: 00315 if( isMaster == true ) 00316 { 00317 // Send the next PING frame 00318 memcpy(Buffer, PingMsg, sizeof(PingMsg)); 00319 for( i = sizeof(PingMsg); i < BufferSize; i++ ) 00320 { 00321 Buffer[i] = i - sizeof(PingMsg); 00322 } 00323 wait_ms( 10 ); 00324 Radio->Send( Buffer, BufferSize ); 00325 } 00326 else 00327 { 00328 Radio->Rx( RX_TIMEOUT_VALUE ); 00329 } 00330 State = LOWPOWER; 00331 break; 00332 case RX_ERROR: 00333 // We have received a Packet with a CRC error, send reply as if packet was correct 00334 if( isMaster == true ) 00335 { 00336 // Send the next PING frame 00337 memcpy(Buffer, PingMsg, sizeof(PingMsg)); 00338 for( i = 4; i < BufferSize; i++ ) 00339 { 00340 Buffer[i] = i - 4; 00341 } 00342 wait_ms( 10 ); 00343 Radio->Send( Buffer, BufferSize ); 00344 } 00345 else 00346 { 00347 // Send the next PONG frame 00348 memcpy(Buffer, PongMsg, sizeof(PongMsg)); 00349 for( i = sizeof(PongMsg); i < BufferSize; i++ ) 00350 { 00351 Buffer[i] = i - sizeof(PongMsg); 00352 } 00353 wait_ms( 10 ); 00354 Radio->Send( Buffer, BufferSize ); 00355 } 00356 State = LOWPOWER; 00357 break; 00358 case TX_TIMEOUT: 00359 Radio->Rx( RX_TIMEOUT_VALUE ); 00360 State = LOWPOWER; 00361 break; 00362 case LOWPOWER: 00363 break; 00364 default: 00365 State = LOWPOWER; 00366 break; 00367 } 00368 } 00369 } 00370 00371 void OnTxDone(void *radio, void *userThisPtr, void *userData) 00372 { 00373 SX1276Generic *r = (SX1276Generic *)radio; 00374 r->Sleep( ); 00375 State = TX; 00376 if (DEBUG_MESSAGE) 00377 dprintf("> OnTxDone"); 00378 } 00379 00380 void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) 00381 { 00382 SX1276Generic *r = (SX1276Generic *)radio; 00383 r->Sleep( ); 00384 BufferSize = size; 00385 memcpy( Buffer, payload, BufferSize ); 00386 State = RX; 00387 if (DEBUG_MESSAGE) 00388 dprintf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d", rssi, snr); 00389 dump("Data:", payload, size); 00390 } 00391 00392 void OnTxTimeout(void *radio, void *userThisPtr, void *userData) 00393 { 00394 SX1276Generic *r = (SX1276Generic *)radio; 00395 *led3 = 0; 00396 r->Sleep( ); 00397 State = TX_TIMEOUT; 00398 if(DEBUG_MESSAGE) 00399 dprintf("> OnTxTimeout"); 00400 } 00401 00402 void OnRxTimeout(void *radio, void *userThisPtr, void *userData) 00403 { 00404 SX1276Generic *r = (SX1276Generic *)radio; 00405 *led3 = 0; 00406 r->Sleep( ); 00407 Buffer[BufferSize-1] = 0; 00408 State = RX_TIMEOUT; 00409 if (DEBUG_MESSAGE) 00410 dprintf("> OnRxTimeout"); 00411 } 00412 00413 void OnRxError(void *radio, void *userThisPtr, void *userData) 00414 { 00415 SX1276Generic *r = (SX1276Generic *)radio; 00416 r->Sleep( ); 00417 State = RX_ERROR; 00418 if (DEBUG_MESSAGE) 00419 dprintf("> OnRxError"); 00420 } 00421 #endif
Generated on Mon Jul 18 2022 05:09:52 by 1.7.2