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