nimita naik
/
SX1262PingPong
ping pong with modifiable parameters
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 #include "mbed.h" 00002 #include "radio.h" 00003 #include "sx126x-hal.h" 00004 00005 #define buffer_size 256 // incoming buffer size 00006 #define buffer_fill buffer_size+1 // number, when buffer is ready 00007 #define BUFFER_SIZE 16 // payload size 00008 #define PINGPONGSIZE 4 // size of token defining message type in the payload 00009 #define TX_TIMEOUT_VALUE 0xFFFF // ms 00010 #define RX_TIMEOUT_VALUE 0xFFFF // ms 00011 00012 typedef enum //states of the application 00013 { 00014 APP_LOWPOWER, 00015 APP_RX, 00016 APP_RX_TIMEOUT, 00017 APP_RX_ERROR, 00018 APP_TX, 00019 APP_TX_TIMEOUT, 00020 }AppStates_t; 00021 00022 const uint8_t PingMsg[] = "PING"; 00023 const uint8_t PongMsg[] = "PONG"; 00024 00025 long unsigned RF_FREQUENCY = 500000000; // Hz 00026 RadioLoRaSpreadingFactors_t spreading_factor = LORA_SF7; 00027 RadioLoRaBandwidths_t bandwidth = LORA_BW_500; 00028 RadioLoRaCodingRates_t coding_rate = LORA_CR_4_5; 00029 int TX_OUTPUT_POWER = 10; //The range of the output power is [-18..+13] dBm 00030 bool isMaster = true; 00031 00032 Serial s( USBTX, USBRX ); // serial object for AT commands 00033 char serial_buffer[buffer_size]; // buffer to save incoming data 00034 char serial_buffer2[buffer_size]; // second buffer to save incoming data 00035 int serial_buffer_where=0; // index array for buffer 00036 int serial_buffer2_where=0; // index array for second buffer 00037 bool serial_end_line = false; // searching for end line 00038 00039 00040 uint8_t BufferSize = BUFFER_SIZE; 00041 uint8_t Buffer[BUFFER_SIZE]; 00042 00043 uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT; 00044 uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT; 00045 00046 PacketParams_t PacketParams; 00047 PacketStatus_t PacketStatus; 00048 00049 ModulationParams_t modulationParams; 00050 00051 /*! 00052 * \brief The State of the application 00053 */ 00054 AppStates_t AppState = APP_LOWPOWER; 00055 void OnTxDone( void ); 00056 void OnRxDone( void ); 00057 void OnTxTimeout( void ); 00058 void OnRxTimeout( void ); 00059 void OnRxError( IrqErrorCode_t ); 00060 void parser(char*); 00061 void LoRa_init(); 00062 00063 00064 RadioCallbacks_t callbacks = { 00065 &OnTxDone, // txDone 00066 &OnRxDone, // rxDone 00067 NULL, // rxPreambleDetect 00068 NULL, // rxSyncWordDone 00069 NULL, // rxHeaderDone 00070 &OnTxTimeout, // txTimeout 00071 &OnRxTimeout, // rxTimeout 00072 &OnRxError, // rxError 00073 NULL, // cadDone 00074 }; 00075 00076 // mosi, miso, sclk, nss, busy, dio1, dio2, dio3, rst, callbacks... 00077 00078 SX126xHal Radio( D11, D12, D13, D7, D3, D5, NC, NC, A0, A1, A2, D8, &callbacks ); 00079 00080 DigitalOut ANT_SW( A3 ); 00081 DigitalOut TxLed( A4 ); 00082 DigitalOut RxLed( A5 ); 00083 00084 /*! 00085 * \brief Define IO for Unused Pin 00086 */ 00087 DigitalOut F_CS( D6 ); // MBED description of pin 00088 DigitalOut SD_CS( D8 ); // MBED description of pin 00089 00090 00091 void serialRx() 00092 { 00093 00094 while(s.readable()) { // read all data from serial 00095 char character=s.getc(); // get a char form serial 00096 if(((int)character==10 || (int)character==13) && serial_end_line) { // search for end line /r or /n 00097 serial_end_line=true; // end was find in the previous charascter, skip 00098 continue; 00099 } else { 00100 serial_end_line=false; // clear serial_end_line flag 00101 } 00102 if(serial_buffer_where!=buffer_fill && !(serial_buffer2_where != 0 && serial_buffer2_where!=buffer_fill)) { 00103 serial_buffer[serial_buffer_where++]=character; 00104 if(serial_buffer_where==buffer_size) { // check if incoming data are smaller than buffer size 00105 serial_buffer[buffer_size-1]='\0'; // posibility to lost data, if the incoming data are too big 00106 serial_buffer_where=buffer_fill; // set index array to indicate buffer fill 00107 continue; 00108 } 00109 if(character==13 || character==10) { // if end of line (\r \n) is indicated, prepare the buffer to serialGetBuffer 00110 serial_buffer[serial_buffer_where-1]='\0'; // set end of buffer with 0 00111 serial_buffer_where=buffer_fill; // set index array to indicate buffer fill 00112 serial_end_line=true; // end of line was find, set serial_end_line flag 00113 } 00114 } else if(serial_buffer2_where!=buffer_fill) { // same for second buffer 00115 serial_buffer2[serial_buffer2_where++]=character; 00116 if(serial_buffer2_where==buffer_size) { 00117 serial_buffer2[buffer_size-1]='\0'; 00118 serial_buffer2_where=buffer_fill; 00119 continue; 00120 } 00121 if(character==13 || character==10) { 00122 serial_buffer2[serial_buffer2_where-1]='\0'; 00123 serial_buffer2_where=buffer_fill; 00124 serial_end_line=true; 00125 } 00126 } 00127 } 00128 } 00129 00130 int serialGetBuffer(char * & data) 00131 { 00132 if(serial_buffer_where==buffer_fill && serial_buffer2_where==buffer_fill) { 00133 data=serial_buffer; 00134 //memcpy(data, serial_buffer, strlen(serial_buffer)+1); 00135 serial_buffer_where=0; 00136 return 2; 00137 } else if(serial_buffer2_where==buffer_fill) { 00138 data=serial_buffer2; 00139 //memcpy(data, serial_buffer2, strlen(serial_buffer2)+1); 00140 serial_buffer2_where=0; 00141 return 1; 00142 } else if(serial_buffer_where==buffer_fill) { 00143 data=serial_buffer; 00144 //memcpy(data, serial_buffer, strlen(serial_buffer)+1); 00145 serial_buffer_where=0; 00146 return 1; 00147 } else { 00148 data = NULL; 00149 return 0; 00150 } 00151 } 00152 00153 /*! 00154 * \brief Specify serial datarate for UART debug output 00155 */ 00156 void baud( int baudrate ) 00157 { 00158 s.baud(baudrate); 00159 s.attach(&serialRx,Serial::RxIrq); 00160 } 00161 00162 void LoRa_init() { 00163 modulationParams.PacketType = PACKET_TYPE_LORA; 00164 modulationParams.Params.LoRa.SpreadingFactor = spreading_factor; 00165 modulationParams.Params.LoRa.Bandwidth = bandwidth; 00166 modulationParams.Params.LoRa.CodingRate = coding_rate; 00167 00168 PacketParams.PacketType = PACKET_TYPE_LORA; 00169 PacketParams.Params.LoRa.PreambleLength = 0x08; 00170 PacketParams.Params.LoRa.HeaderType = LORA_PACKET_VARIABLE_LENGTH; 00171 PacketParams.Params.LoRa.PayloadLength = 15; 00172 PacketParams.Params.LoRa.CrcMode = LORA_CRC_ON; 00173 PacketParams.Params.LoRa.InvertIQ = LORA_IQ_INVERTED; 00174 00175 00176 00177 Radio.SetStandby( STDBY_RC ); 00178 Radio.SetPacketType( modulationParams.PacketType ); 00179 Radio.SetModulationParams( &modulationParams ); 00180 Radio.SetPacketParams( &PacketParams ); 00181 00182 Radio.SetRfFrequency( RF_FREQUENCY ); 00183 Radio.SetBufferBaseAddresses( 0x00, 0x00 ); 00184 Radio.SetTxParams( TX_OUTPUT_POWER, RADIO_RAMP_20_US ); 00185 00186 RxLed = 0; 00187 TxLed = 0; 00188 00189 Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00190 Radio.SetRx( RX_TIMEOUT_VALUE ); 00191 AppState = APP_LOWPOWER; 00192 isMaster = true; 00193 00194 Radio.ProcessIrqs( ); 00195 } 00196 00197 int main( ) 00198 { 00199 baud( 115200 ); 00200 00201 F_CS = 1; 00202 SD_CS = 1; 00203 RxLed = 1; 00204 TxLed = 1; 00205 ANT_SW = 1; 00206 00207 wait_ms( 500 ); // wait for on board DC/DC start-up time 00208 00209 Radio.Init( ); 00210 Radio.SetRegulatorMode( USE_DCDC ); // Can also be set in LDO mode but consume more power 00211 00212 memset( &Buffer, 0x00, BufferSize ); 00213 00214 printf( "\n\n\r SX1262 Whitespace Ping Pong Application \n\n\r"); 00215 00216 LoRa_init(); 00217 printf( "\nPing Pong running in LORA mode\n\r"); 00218 00219 00220 while( 1 ) 00221 { 00222 Radio.ProcessIrqs( ); 00223 char *data; 00224 serialGetBuffer(data); 00225 if(data) 00226 parser(data); 00227 switch( AppState ) 00228 { 00229 case APP_RX: 00230 AppState = APP_LOWPOWER; 00231 RxLed = !RxLed; 00232 Radio.GetPayload( Buffer, &BufferSize, BUFFER_SIZE ); 00233 printf("\n%s\n", Buffer); 00234 if( isMaster == true ) 00235 { 00236 if( BufferSize > 0 ) 00237 { 00238 if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, PINGPONGSIZE ) == 0 ) 00239 { 00240 printf( "...Pong\r\n" ); 00241 memcpy( Buffer, PingMsg, PINGPONGSIZE ); 00242 Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00243 Radio.SendPayload( Buffer, BufferSize, (TX_TIMEOUT_VALUE)); 00244 } 00245 else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, PINGPONGSIZE ) == 0 ) 00246 { 00247 // A master already exists then become a slave 00248 printf( "...Ping\r\n" ); 00249 isMaster = false; 00250 memcpy( Buffer, PongMsg, PINGPONGSIZE ); 00251 Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00252 Radio.SendPayload( Buffer, BufferSize, TX_TIMEOUT_VALUE ); 00253 } 00254 else // valid reception but neither a PING or a PONG message 00255 { // Set device as master ans start again 00256 isMaster = true; 00257 Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00258 Radio.SetRx(RX_TIMEOUT_VALUE ); 00259 } 00260 } 00261 } 00262 else 00263 { 00264 if( BufferSize > 0 ) 00265 { 00266 if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, PINGPONGSIZE ) == 0 ) 00267 { 00268 printf( "...Ping\r\n" ); 00269 memcpy( Buffer, PongMsg, 4 ); 00270 Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00271 Radio.SendPayload( Buffer, BufferSize, TX_TIMEOUT_VALUE ); 00272 } 00273 else // valid reception but not a PING as expected 00274 { 00275 isMaster = true; 00276 Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00277 Radio.SetRx(RX_TIMEOUT_VALUE); 00278 } 00279 } 00280 } 00281 break; 00282 00283 case APP_TX: 00284 AppState = APP_LOWPOWER; 00285 TxLed = !TxLed; 00286 if( isMaster == true ) 00287 { 00288 printf( "Ping...\r\n" ); 00289 } 00290 else 00291 { 00292 printf( "Pong...\r\n" ); 00293 } 00294 Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00295 Radio.SetRx(RX_TIMEOUT_VALUE ); 00296 break; 00297 00298 case APP_RX_TIMEOUT: 00299 AppState = APP_LOWPOWER; 00300 if( isMaster == true ) 00301 { 00302 // Send the next PING frame 00303 memcpy( Buffer, PingMsg, PINGPONGSIZE ); 00304 Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00305 Radio.SendPayload( Buffer, BufferSize, TX_TIMEOUT_VALUE ); 00306 } 00307 else 00308 { 00309 Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00310 Radio.SetRx( RX_TIMEOUT_VALUE ); 00311 } 00312 break; 00313 00314 case APP_RX_ERROR: 00315 AppState = APP_LOWPOWER; 00316 // We have received a Packet with a CRC error, send reply as if packet was correct 00317 if( isMaster == true ) 00318 { 00319 // Send the next PING frame 00320 memcpy( Buffer, PingMsg, PINGPONGSIZE ); 00321 Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00322 Radio.SendPayload( Buffer, BufferSize, TX_TIMEOUT_VALUE); 00323 } 00324 else 00325 { 00326 // Send the next PONG frame 00327 memcpy( Buffer, PongMsg, PINGPONGSIZE ); 00328 Radio.SetDioIrqParams( TxIrqMask, TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00329 Radio.SendPayload( Buffer, BufferSize, TX_TIMEOUT_VALUE ); 00330 } 00331 break; 00332 00333 case APP_TX_TIMEOUT: 00334 AppState = APP_LOWPOWER; 00335 Radio.SetDioIrqParams( RxIrqMask, RxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); 00336 Radio.SetRx( RX_TIMEOUT_VALUE ); 00337 break; 00338 00339 case APP_LOWPOWER: 00340 break; 00341 00342 default: 00343 // Set low power 00344 break; 00345 } 00346 } 00347 } 00348 00349 void OnTxDone( void ) { 00350 AppState = APP_TX; 00351 } 00352 00353 void OnRxDone( void ) { 00354 int RssiValue, SnrValue; 00355 AppState = APP_RX; 00356 PacketStatus_t packetStatus; 00357 Radio.GetPacketStatus(&packetStatus); 00358 RssiValue = packetStatus.Params.LoRa.RssiPkt; 00359 SnrValue = packetStatus.Params.LoRa.SnrPkt; 00360 printf("rssi: %d; snr: %d\n\r", RssiValue, SnrValue ); 00361 } 00362 00363 void OnTxTimeout( void ) { 00364 AppState = APP_TX_TIMEOUT; 00365 printf( "<>>>>>>>>TXE\r\n" ); 00366 } 00367 00368 void OnRxTimeout( void ) { 00369 AppState = APP_RX_TIMEOUT; 00370 } 00371 00372 void OnRxError( IrqErrorCode_t errorCode ) { 00373 AppState = APP_RX_ERROR; 00374 printf( "RXE<>>>>>>>>\r\n" ); 00375 } 00376 00377 void OnCadDone( bool channelActivityDetected ) { 00378 } 00379 00380 00381 void parser(char* serial_in) { 00382 printf("%s\n\r", serial_in); 00383 char command[10]; 00384 long val; 00385 if(sscanf(serial_in, "%10s %lu", command, &val) != 2){ 00386 printf("Invalid Input\n\r"); 00387 return; 00388 } 00389 if(strcmp(command, "FREQ") == 0) { 00390 if((125000000<=val) && (val<=960000000)) { 00391 RF_FREQUENCY = val; 00392 printf("Frequency set to: %lu\n\r", val); 00393 LoRa_init(); 00394 } 00395 } 00396 else if(strcmp(command, "TX") == 0) { 00397 if((-22<=val) && (val<=13)) { 00398 TX_OUTPUT_POWER = val; 00399 printf("TX output power set to: %lu\n\r", val); 00400 LoRa_init(); 00401 } 00402 } 00403 else if(strcmp(command, "S_F") == 0) { 00404 switch(val) { 00405 case 5: 00406 spreading_factor = LORA_SF5; 00407 break; 00408 case 6: 00409 spreading_factor = LORA_SF6; 00410 break; 00411 case 7: 00412 spreading_factor = LORA_SF7; 00413 break; 00414 case 8: 00415 spreading_factor = LORA_SF8; 00416 break; 00417 case 9: 00418 spreading_factor = LORA_SF9; 00419 break; 00420 case 10: 00421 spreading_factor = LORA_SF10; 00422 break; 00423 case 11: 00424 spreading_factor = LORA_SF11; 00425 break; 00426 case 12: 00427 spreading_factor = LORA_SF12; 00428 break; 00429 default: 00430 printf("enter spreading factor between 5 and 12\n\r"); 00431 return; 00432 } 00433 } 00434 else if(strcmp(command, "CR") == 0) { 00435 switch(val) { 00436 case 45: 00437 coding_rate = LORA_CR_4_5; 00438 break; 00439 case 46: 00440 coding_rate = LORA_CR_4_6; 00441 break; 00442 case 47: 00443 coding_rate = LORA_CR_4_7; 00444 break; 00445 case 48: 00446 coding_rate = LORA_CR_4_8; 00447 break; 00448 default: 00449 printf("enter valid coding rate\n\r"); 00450 return; 00451 } 00452 printf("Spreading factor changed to %lu\n\r", val); 00453 LoRa_init(); 00454 } 00455 else if(strcmp(command, "BW") == 0) { 00456 switch(val) { 00457 case 500: 00458 bandwidth = LORA_BW_500; 00459 break; 00460 case 250: 00461 bandwidth = LORA_BW_250; 00462 break; 00463 case 125: 00464 bandwidth = LORA_BW_125; 00465 break; 00466 case 62: 00467 bandwidth = LORA_BW_062; 00468 break; 00469 case 41: 00470 bandwidth = LORA_BW_041; 00471 break; 00472 case 31: 00473 bandwidth = LORA_BW_031; 00474 break; 00475 case 20: 00476 bandwidth = LORA_BW_020; 00477 break; 00478 case 15: 00479 bandwidth = LORA_BW_015; 00480 break; 00481 case 10: 00482 bandwidth = LORA_BW_010; 00483 break; 00484 case 7: 00485 bandwidth = LORA_BW_007; 00486 break; 00487 default: 00488 printf("Valid bandwidths: 500, 250, 125, 62, 41, 31, 20, "); 00489 printf("15, 10, 7\n\r"); 00490 return; 00491 } 00492 00493 00494 // TODO separate master slave 00495 // TODO make a separate lorawan compatible 00496 // TODO view current settings 00497 // TODO stop display 00498 // ncurses 00499 printf("LoRa bandwidth changed to %lu\n\r", val); 00500 LoRa_init(); 00501 } 00502 else 00503 printf("Invalid command\n\r"); 00504 00505 00506 }
Generated on Wed Jul 13 2022 01:42:10 by 1.7.2