I-O DATA DEV2 / Mbed 2 deprecated Nucleo_Private_LoRa

Dependencies:   mbed Private_lora_SX1276

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }