Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 #include "mbed.h" 00002 #include "main.h" 00003 #include "sx1276-hal.h" 00004 #include "debug.h" 00005 00006 /* Set this flag to '1' to display debug messages on the console */ 00007 #define DEBUG_MESSAGE 0 00008 00009 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */ 00010 #define USE_MODEM_LORA 1 00011 #define USE_MODEM_FSK !USE_MODEM_LORA 00012 00013 //#define RF868 1 00014 00015 #ifdef RF868 00016 00017 #define RF_FREQUENCY 868000000 // Hz 00018 #define TX_OUTPUT_POWER 14 // 14 dBm 00019 00020 #else 00021 00022 #define RF_FREQUENCY 433000000 // Hz 00023 #define TX_OUTPUT_POWER 14 // 26 dBm 00024 00025 #endif 00026 00027 #if USE_MODEM_LORA == 1 00028 #define LORA_BANDWIDTH 0 00029 #define LORA_SPREADING_FACTOR 10 00030 #define LORA_CODINGRATE 2 00031 00032 //#define LORA_BANDWIDTH 2 // [0: 125 kHz, 00033 // 1: 250 kHz, 00034 // 2: 500 kHz, 00035 // 3: Reserved] 00036 //#define LORA_SPREADING_FACTOR 7 // [SF7..SF12] 00037 //#define LORA_CODINGRATE 1 // [1: 4/5, 00038 // 2: 4/6, 00039 // 3: 4/7, 00040 // 4: 4/8] 00041 #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx 00042 #define LORA_SYMBOL_TIMEOUT 5 // Symbols 00043 #define LORA_FIX_LENGTH_PAYLOAD_ON false 00044 #define LORA_FHSS_ENABLED false 00045 #define LORA_NB_SYMB_HOP 4 00046 #define LORA_IQ_INVERSION_ON false 00047 #define LORA_CRC_ENABLED true 00048 00049 #elif USE_MODEM_FSK == 1 00050 00051 #define FSK_FDEV 25000 // Hz 00052 #define FSK_DATARATE 19200 // bps 00053 #define FSK_BANDWIDTH 50000 // Hz 00054 #define FSK_AFC_BANDWIDTH 83333 // Hz 00055 #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx 00056 #define FSK_FIX_LENGTH_PAYLOAD_ON false 00057 #define FSK_CRC_ENABLED true 00058 00059 #else 00060 #error "Please define a modem in the compiler options." 00061 #endif 00062 00063 #define RX_TIMEOUT_VALUE 3500000 // in us 00064 #define BUFFER_SIZE 32 // Define the payload size here 00065 00066 #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) ) 00067 DigitalOut led(LED2); 00068 #else 00069 //DigitalOut led(LED1); 00070 //DigitalOut led2(LED2); 00071 //DigitalOut led3(LED3); 00072 //DigitalOut led4(LED4); 00073 DigitalOut debugled(D6); 00074 DigitalOut debugled2(D7); 00075 00076 #endif 00077 00078 DigitalIn role(USER_BUTTON); // PC_13 in Mini 103RC mini board 00079 Timer tx_tmr; 00080 00081 #define UART_ENABLE 00082 00083 #ifdef UART_ENABLE 00084 //Serial pc(USBTX, USBRX); 00085 Serial pc(SERIAL_TX, SERIAL_RX); 00086 #endif 00087 00088 Ticker nwk_ticker; 00089 00090 bool channelOccupied = false; 00091 00092 #define NWK_SLEEP 0 00093 #define NWK_TX 1 00094 #define NWK_TX_NOK 2 00095 #define NWK_RX_OK 3 00096 #define NWK_RX_NOK 4 00097 00098 //#define PINGPONG 00099 00100 void nwk_toggle() 00101 { 00102 debugled = !debugled; 00103 debugled2 = !debugled2; 00104 } 00105 00106 void nwk_setmode(uint8_t mode) 00107 { 00108 switch(mode){ 00109 case NWK_TX: 00110 case NWK_RX_OK: 00111 nwk_ticker.attach(&nwk_toggle, 1); 00112 break; 00113 case NWK_TX_NOK: 00114 case NWK_RX_NOK: 00115 nwk_ticker.attach(&nwk_toggle, 0.1); 00116 break; 00117 case NWK_SLEEP: 00118 default: 00119 debugled = 0; 00120 debugled2 = 0; 00121 nwk_ticker.detach(); 00122 break; 00123 } 00124 } 00125 00126 /* 00127 * Global variables declarations 00128 */ 00129 typedef enum 00130 { 00131 ST_LOWPOWER = 0, 00132 ST_IDLE, 00133 00134 ST_RX, 00135 ST_RX_TIMEOUT, 00136 ST_RX_ERROR, 00137 00138 ST_TX, 00139 ST_TX_TIMEOUT, 00140 00141 ST_CAD, 00142 ST_CAD_DONE 00143 }AppStates_t; 00144 00145 volatile AppStates_t State = ST_LOWPOWER; 00146 00147 /*! 00148 * Radio events function pointer 00149 */ 00150 static RadioEvents_t RadioEvents; 00151 00152 /* 00153 * Global variables declarations 00154 */ 00155 SX1276MB1xAS Radio( NULL ); 00156 00157 const uint8_t PingMsg[] = "PING"; 00158 const uint8_t PongMsg[] = "PONG"; 00159 const uint8_t TestMsg[] = "LoRa Test"; 00160 00161 uint16_t BufferSize = BUFFER_SIZE; 00162 uint8_t Buffer[BUFFER_SIZE]; 00163 00164 //int16_t RssiValue = 0.0; 00165 //int8_t SnrValue = 0.0; 00166 00167 int16_t RssiValue = 0; 00168 int8_t SnrValue = 0; 00169 00170 #define REG_SIZE 0x70 // see below 00171 #define REG_IDX_SIZE 39 00172 00173 static int my_strncmp(const char *, const char *, int); 00174 static void my_strcpy(char * , const char *); 00175 00176 int my_strncmp(const char * s1, const char * s2, int size) 00177 { 00178 int n = size; 00179 for ( ; n > 0; s1++, s2++, --n) 00180 if (*s1 != *s2) 00181 return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1); 00182 else if (*s1 == '\0') 00183 return 0; 00184 return 0; 00185 } 00186 00187 void my_strcpy(char * s1, const char * s2) 00188 { 00189 char *s = s1; 00190 while ((*s++ = *s2++) != 0) 00191 ; 00192 } 00193 00194 void Sender ( void ) 00195 { 00196 int i; 00197 my_strcpy( ( char* )Buffer, ( char* )PingMsg ); 00198 for( i = 4; i < BufferSize; i++ ){ 00199 Buffer[i] = i - 4; 00200 } 00201 Radio.Send( Buffer, BufferSize ); 00202 } 00203 00204 int main() 00205 { 00206 uint8_t i; 00207 uint8_t regval; 00208 bool isMaster = true; 00209 int begin, end; 00210 00211 uint32_t rand; 00212 debugled = 1; 00213 debugled2 = 1; 00214 00215 isMaster = role.read(); 00216 00217 //debug( "\n\n\r SX1276 Ping Pong Demo Application \n\n\r" ); 00218 00219 // Initialize Radio driver 00220 RadioEvents.TxDone = OnTxDone; 00221 RadioEvents.RxDone = OnRxDone; 00222 RadioEvents.RxError = OnRxError; 00223 RadioEvents.TxTimeout = OnTxTimeout; 00224 RadioEvents.RxTimeout = OnRxTimeout; 00225 Radio.Init( &RadioEvents ); 00226 00227 #ifdef UART_ENABLE 00228 regval = Radio.Read(REG_VERSION); 00229 pc.printf("%s", TestMsg); 00230 pc.printf("IC Version: %02X\r\n", regval); 00231 regval = Radio.Read(REG_OPMODE); 00232 pc.printf("OPMODE: %02X\r\n", regval); 00233 #endif 00234 00235 debugled = 0; 00236 debugled2 = 0; 00237 00238 // verify the connection with the board 00239 while( Radio.Read( REG_VERSION ) == 0x00 ) 00240 { 00241 //debug( "Radio could not be detected!\n\r", NULL ); 00242 wait( 1 ); 00243 } 00244 00245 //debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1LAS ) ) , "\n\r > Board Type: SX1276MB1LAS < \n\r" ); 00246 //debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1MAS ) ) , "\n\r > Board Type: SX1276MB1MAS < \n\r" ); 00247 00248 Radio.SetChannel( RF_FREQUENCY ); 00249 00250 #if USE_MODEM_LORA == 1 00251 00252 //debug_if( LORA_FHSS_ENABLED, "\n\n\r > LORA FHSS Mode < \n\n\r"); 00253 //debug_if( !LORA_FHSS_ENABLED, "\n\n\r > LORA Mode < \n\n\r"); 00254 00255 Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, 00256 LORA_SPREADING_FACTOR, LORA_CODINGRATE, 00257 LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, 00258 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 00259 LORA_IQ_INVERSION_ON, 2000000 ); 00260 00261 Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, 00262 LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, 00263 LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, 00264 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 00265 LORA_IQ_INVERSION_ON, true ); 00266 00267 #elif USE_MODEM_FSK == 1 00268 00269 //debug("\n\n\r > FSK Mode < \n\n\r"); 00270 Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, 00271 FSK_DATARATE, 0, 00272 FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, 00273 FSK_CRC_ENABLED, 0, 0, 0, 2000000 ); 00274 00275 Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, 00276 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, 00277 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED, 00278 0, 0, false, true ); 00279 00280 #else 00281 00282 #error "Please define a modem in the compiler options." 00283 00284 #endif 00285 00286 //debug_if( DEBUG_MESSAGE, "Starting Ping-Pong loop\r\n" ); 00287 00288 rand = Radio.Random(); 00289 rand = rand%1000; 00290 wait_ms((uint16_t)rand); 00291 00292 #ifdef PINGPONG 00293 Radio.Rx( RX_TIMEOUT_VALUE ); 00294 00295 00296 while( 1 ) 00297 { 00298 switch( State ) 00299 { 00300 case ST_RX: 00301 if( isMaster == true ) 00302 { 00303 if( BufferSize > 0 ) 00304 { 00305 #ifdef UART_ENABLE 00306 pc.printf("Received message:\r\n"); 00307 pc.printf("%s",Buffer); 00308 #endif 00309 //if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) 00310 if( my_strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) 00311 { 00312 nwk_setmode(NWK_NORMAL); 00313 //debug( "...Pong\r\n" ); 00314 // Send the next PING frame 00315 my_strcpy( ( char* )Buffer, ( char* )PingMsg ); 00316 //_strcpy( ( char* )Buffer, ( char* )PingMsg ); 00317 // We fill the buffer with numbers for the payload 00318 for( i = 4; i < BufferSize; i++ ) 00319 { 00320 Buffer[i] = i - 4; 00321 } 00322 wait_ms( 10 ); 00323 Radio.Send( Buffer, BufferSize ); 00324 } 00325 else if( my_strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) 00326 { // A master already exists then become a slave 00327 debug( "...Ping\r\n" ); 00328 //nwk_setmode(NWK_NORMAL); 00329 //led = !led; 00330 isMaster = false; 00331 // Send the next PONG frame 00332 my_strcpy( ( char* )Buffer, ( char* )PongMsg ); 00333 // We fill the buffer with numbers for the payload 00334 for( i = 4; i < BufferSize; i++ ) 00335 { 00336 Buffer[i] = i - 4; 00337 } 00338 wait_ms( 10 ); 00339 Radio.Send( Buffer, BufferSize ); 00340 } 00341 else // valid reception but neither a PING or a PONG message 00342 { // Set device as master ans start again 00343 isMaster = true; 00344 Radio.Rx( RX_TIMEOUT_VALUE ); 00345 } 00346 } 00347 } 00348 else 00349 { 00350 if( BufferSize > 0 ) 00351 { 00352 #ifdef UART_ENABLE 00353 pc.printf("Received message:\r\n"); 00354 pc.printf("%s",Buffer); 00355 #endif 00356 00357 if( my_strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) 00358 { 00359 nwk_setmode(NWK_NORMAL); 00360 //led = !led; 00361 //debug( "...Ping\r\n" ); 00362 // Send the reply to the PING string 00363 my_strcpy( ( char* )Buffer, ( char* )PongMsg ); 00364 // We fill the buffer with numbers for the payload 00365 for( i = 4; i < BufferSize; i++ ) 00366 { 00367 Buffer[i] = i - 4; 00368 } 00369 wait_ms( 10 ); 00370 Radio.Send( Buffer, BufferSize ); 00371 } 00372 else // valid reception but not a PING as expected 00373 { // Set device as master and start again 00374 isMaster = true; 00375 Radio.Rx( RX_TIMEOUT_VALUE ); 00376 } 00377 } 00378 } 00379 State = ST_LOWPOWER; 00380 break; 00381 case ST_TX: 00382 //nwk_setmode(NWK_NORMAL); 00383 //led = !led; 00384 if( isMaster == true ) 00385 { 00386 //debug( "Ping...\r\n" ); 00387 } 00388 else 00389 { 00390 //debug( "Pong...\r\n" ); 00391 } 00392 Radio.Rx( RX_TIMEOUT_VALUE ); 00393 State = ST_LOWPOWER; 00394 break; 00395 case ST_RX_TIMEOUT: 00396 //debugled = !debugled; 00397 //debugled2 = !debugled2; 00398 nwk_setmode(NWK_ERR); 00399 if( isMaster == true ) 00400 { 00401 // Send the next PING frame 00402 my_strcpy( ( char* )Buffer, ( char* )PingMsg ); 00403 for( i = 4; i < BufferSize; i++ ) 00404 { 00405 Buffer[i] = i - 4; 00406 } 00407 wait_ms( 10 ); 00408 Radio.Send( Buffer, BufferSize ); 00409 } 00410 else 00411 { 00412 Radio.Rx( RX_TIMEOUT_VALUE ); 00413 } 00414 State = ST_LOWPOWER; 00415 break; 00416 case ST_RX_ERROR: 00417 // We have received a Packet with a CRC error, send reply as if packet was correct 00418 nwk_setmode(NWK_ERR); 00419 if( isMaster == true ) 00420 { 00421 // Send the next PING frame 00422 my_strcpy( ( char* )Buffer, ( char* )PingMsg ); 00423 for( i = 4; i < BufferSize; i++ ) 00424 { 00425 Buffer[i] = i - 4; 00426 } 00427 wait_ms( 10 ); 00428 Radio.Send( Buffer, BufferSize ); 00429 } 00430 else 00431 { 00432 // Send the next PONG frame 00433 my_strcpy( ( char* )Buffer, ( char* )PongMsg ); 00434 for( i = 4; i < BufferSize; i++ ) 00435 { 00436 Buffer[i] = i - 4; 00437 } 00438 wait_ms( 10 ); 00439 Radio.Send( Buffer, BufferSize ); 00440 } 00441 State = ST_LOWPOWER; 00442 break; 00443 case ST_TX_TIMEOUT: 00444 nwk_setmode(NWK_ERR); 00445 Radio.Rx( RX_TIMEOUT_VALUE ); 00446 State = ST_LOWPOWER; 00447 break; 00448 case ST_CAD: 00449 break; 00450 case ST_CAD_DONE: 00451 if(channelOccupied){ 00452 State = ST_LOWPOWER; 00453 }else{ 00454 // start to transmit here. 00455 } 00456 break; 00457 case ST_LOWPOWER: 00458 break; 00459 default: 00460 nwk_setmode(0xFF); 00461 State = ST_LOWPOWER; 00462 break; 00463 } 00464 } 00465 00466 #else 00467 00468 if(isMaster == true){ 00469 tx_tmr.start(); 00470 begin = tx_tmr.read_ms(); 00471 }else{ 00472 Radio.Rx( RX_TIMEOUT_VALUE ); 00473 } 00474 00475 while(1){ 00476 switch(State){ 00477 case ST_RX: 00478 //nwk_setmode(NWK_RX_OK); 00479 Radio.Rx( RX_TIMEOUT_VALUE ); 00480 State = ST_LOWPOWER; 00481 #ifdef UART_ENABLE 00482 //pc.printf("\r\nRX OK\tRSSI:%f SNR:%f \r\n",float(RssiValue),float(SnrValue)); 00483 pc.printf("\r\nRX OK\tRSSI:%d SNR:%d \r\n",RssiValue,SnrValue); 00484 pc.printf("\r\nRSSI: %02X SNR: %01X\r\n", RssiValue, SnrValue); 00485 #endif 00486 break; 00487 case ST_TX: 00488 nwk_setmode(NWK_TX); 00489 State = ST_LOWPOWER; 00490 #ifdef UART_ENABLE 00491 pc.printf("\r\nTX Done.\r\n"); 00492 #endif 00493 break; 00494 case ST_RX_TIMEOUT: 00495 case ST_RX_ERROR: 00496 //nwk_setmode(NWK_RX_NOK); 00497 Radio.Rx( RX_TIMEOUT_VALUE ); 00498 State = ST_LOWPOWER; 00499 #ifdef UART_ENABLE 00500 pc.printf("\r\nRX TIMEOUT or ERROR.\r\n"); 00501 #endif 00502 break; 00503 case ST_TX_TIMEOUT: 00504 State = ST_LOWPOWER; 00505 break; 00506 case ST_LOWPOWER: 00507 if (isMaster){ 00508 end = tx_tmr.read_ms(); 00509 if ((end-begin) >= 2000){ 00510 Sender(); 00511 tx_tmr.stop(); 00512 tx_tmr.start(); 00513 begin = tx_tmr.read_ms(); 00514 } 00515 } 00516 break; 00517 default: 00518 State = ST_LOWPOWER; 00519 break; 00520 } 00521 } 00522 #endif 00523 00524 } 00525 00526 00527 void OnTxDone( void ) 00528 { 00529 Radio.Sleep( ); 00530 State = ST_TX; 00531 //debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" ); 00532 } 00533 00534 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) 00535 { 00536 Radio.Sleep( ); 00537 BufferSize = size; 00538 memcpy( Buffer, payload, BufferSize ); 00539 RssiValue = rssi; 00540 SnrValue = snr; 00541 State = ST_RX; 00542 nwk_setmode(NWK_RX_OK); 00543 //debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" ); 00544 } 00545 00546 void OnTxTimeout( void ) 00547 { 00548 Radio.Sleep( ); 00549 State = ST_TX_TIMEOUT; 00550 //debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" ); 00551 } 00552 00553 void OnRxTimeout( void ) 00554 { 00555 Radio.Sleep( ); 00556 Buffer[ BufferSize ] = 0; 00557 State = ST_RX_TIMEOUT; 00558 nwk_setmode(NWK_RX_NOK); 00559 //debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" ); 00560 } 00561 00562 void OnRxError( void ) 00563 { 00564 Radio.Sleep( ); 00565 State = ST_RX_ERROR; 00566 //debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" ); 00567 } 00568 00569 // Added by allankliu 00570 void OnCadDone( bool channelActivityDetected ) 00571 { 00572 Radio.Sleep(); 00573 channelOccupied = channelActivityDetected; 00574 State = ST_CAD_DONE; 00575 }
Generated on Thu Jul 21 2022 02:23:05 by
1.7.2