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