Demo for Semtech Lora SX1272MB2xAS 868MHz an NUCLEO-F401RE (STM Cortex M4)

Dependencies:   SX1272Lib mbed

Fork of SX1272PingPong by Semtech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002     
00003     Demo for Semtech Lora SX1272MB2xAS 868MHz an NUCLEO-F401RE (STM Cortex M4)
00004     
00005     by www.emcu.it
00006     
00007     Date: Mar.2016
00008     Ver.: 1.0.1
00009     Project name: LORA-SX1272MB2xAS-PP
00010     
00011     Note: 
00012         The original project is here: https://developer.mbed.org/components/SX1272MB2xAS/
00013         is: SX1272 Ping Pong Demo Application
00014     
00015     How to use:
00016         We tested this SW on NUCLEO-F401RE
00017         Program two kits (NUCLEO-F401RE + SX1272MB2xAS) with this SW.
00018         Connect the KITs to the PC and open a terminal emulation (for example TeraTerm).
00019         The TeraTerm configurations are shown below.
00020             9600 bauds, 8-bit data, no parity
00021         On the TeraTerm you see the link informations.
00022         On the NUCLEO-F401RE, if all is OK, you must see the GREEN led that flashing . This means that the two KITs are working properly.
00023         If the GREEN led flash slowly means that is not present the link between the two KITs.
00024 
00025 
00026  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00027  and associated documentation files (the "Software"), to deal in the Software without
00028  restriction, including without limitation the rights to use, copy, modify, merge, publish,
00029  distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
00030  Software is furnished to do so, subject to the following conditions:
00031 
00032  The above copyright notice and this permission notice shall be included in all copies or
00033  substantial portions of the Software.
00034 
00035  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00036  BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00037  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00038  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00039  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00040 
00041 
00042 */
00043 
00044 #include "mbed.h"
00045 #include "main.h"
00046 #include "sx1272-hal.h"
00047 #include "debug.h"
00048 
00049 /* Set this flag to '1' to display debug messages on the console */
00050 #define DEBUG_MESSAGE   1
00051 
00052 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */
00053 #define USE_MODEM_LORA  1
00054 #define USE_MODEM_FSK   !USE_MODEM_LORA
00055 
00056 /* NOTE
00057          LORA_BANDWIDTH=2 & LORA_SPREADING_FACTOR=7  == MaxSpeed 41Kbit
00058          LORA_BANDWIDTH=1 & LORA_SPREADING_FACTOR=12 == MediumSpeed
00059 */
00060 
00061 #define RF_FREQUENCY                                    868000000 // Hz
00062 #define TX_OUTPUT_POWER                                 14        // 14 dBm
00063 
00064 #if USE_MODEM_LORA == 1
00065 
00066     #define LORA_BANDWIDTH                              0  //2         // [0: 125 kHz,
00067                                                                   //  1: 250 kHz,
00068                                                                   //  2: 500 kHz,
00069                                                                   //  3: Reserved]
00070     #define LORA_SPREADING_FACTOR                       11  //7         // [SF7..SF12]
00071     #define LORA_CODINGRATE                             1         // [1: 4/5,
00072                                                                   //  2: 4/6,
00073                                                                   //  3: 4/7,
00074                                                                   //  4: 4/8]
00075     #define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
00076     #define LORA_SYMBOL_TIMEOUT                         5         // Symbols
00077     #define LORA_FIX_LENGTH_PAYLOAD_ON                  false
00078     #define LORA_FHSS_ENABLED                           false  
00079     #define LORA_NB_SYMB_HOP                            4     
00080     #define LORA_IQ_INVERSION_ON                        false
00081     #define LORA_CRC_ENABLED                            true
00082     
00083 #elif USE_MODEM_FSK == 1
00084 
00085     #define FSK_FDEV                                    25000     // Hz
00086     #define FSK_DATARATE                                19200     // bps
00087     #define FSK_BANDWIDTH                               50000     // Hz
00088     #define FSK_AFC_BANDWIDTH                           83333     // Hz
00089     #define FSK_PREAMBLE_LENGTH                         5         // Same for Tx and Rx
00090     #define FSK_FIX_LENGTH_PAYLOAD_ON                   false
00091     #define FSK_CRC_ENABLED                             true
00092     
00093 #else
00094     #error "Please define a modem in the compiler options."
00095 #endif
00096 
00097 #define RX_TIMEOUT_VALUE                                3500000   // in us
00098 #define BUFFER_SIZE                                     32        // Define the payload size here
00099 
00100 #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) )
00101 DigitalOut led(LED2);
00102 #else
00103 DigitalOut led(LED1);
00104 #endif
00105 
00106 //------------------------------------
00107 // Hyperterminal configuration
00108 // 9600 bauds, 8-bit data, no parity
00109 //------------------------------------
00110 
00111 Serial pc(SERIAL_TX, SERIAL_RX);
00112 
00113 /*
00114  *  Global variables declarations
00115  */
00116 typedef enum
00117 {
00118     LOWPOWER = 0,
00119     IDLE,
00120     
00121     RX,
00122     RX_TIMEOUT,
00123     RX_ERROR,
00124     
00125     TX,
00126     TX_TIMEOUT,
00127     
00128     CAD,
00129     CAD_DONE
00130 }AppStates_t;
00131 
00132 volatile AppStates_t State = LOWPOWER;
00133 
00134 /*!
00135  * Radio events function pointer
00136  */
00137 static RadioEvents_t RadioEvents;
00138 
00139 /*
00140  *  Global variables declarations
00141  */
00142 SX1272MB2xAS Radio( NULL );
00143 
00144 const uint8_t PingMsg[] = "em_PING";
00145 const uint8_t PongMsg[] = "em_PONG";
00146 
00147 uint16_t BufferSize = BUFFER_SIZE;
00148 uint8_t Buffer[BUFFER_SIZE];
00149 
00150 int16_t RssiValue = 0.0;
00151 int8_t SnrValue = 0.0;
00152 
00153 int main() 
00154 {
00155     uint8_t i;
00156     bool isMaster = true;
00157     
00158     pc.printf("\n\n\rModified by: http://www.wmcu.it \n\n\r" );
00159     
00160     pc.printf("\n\r RF_FREQUENCY: %d Hz", RF_FREQUENCY);
00161     pc.printf("\n\r TX_OUTPUT_POWER: %d dBm", TX_OUTPUT_POWER);
00162     pc.printf("\n\r LORA_BANDWIDTH: %d -> 0==125KHz, 1==250KHz, 2==500KHz, 3==Reserved", LORA_BANDWIDTH);
00163     pc.printf("\n\r LORA_SPREADING_FACTOR: %d (SF7..SF12)", LORA_SPREADING_FACTOR);
00164     pc.printf("\n\r LORA_CODINGRATE: %d", LORA_CODINGRATE);
00165     pc.printf(" -> 1==4/5; 2==4/6; 3==4/7; 4==4/8\n\r");
00166     
00167                                                                   
00168     pc.printf("\n\rSee this link: https://developer.mbed.org/components/SX1272MB2xAS/ \n\rfor original example.\n\r ");
00169     debug( "\n\n\r     SX1272 Ping Pong Demo Application \n\n\r" );
00170 
00171     // Initialize Radio driver
00172     RadioEvents.TxDone = OnTxDone;
00173     RadioEvents.RxDone = OnRxDone;
00174     RadioEvents.RxError = OnRxError;
00175     RadioEvents.TxTimeout = OnTxTimeout;
00176     RadioEvents.RxTimeout = OnRxTimeout;
00177     Radio.Init( &RadioEvents );
00178     
00179     // verify the connection with the board
00180     while( Radio.Read( REG_VERSION ) == 0x00  )
00181     {
00182         debug( "Radio could not be detected!\n\r", NULL );
00183         wait( 1 );
00184     }
00185             
00186     debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1272MB2XAS ) ) , "\n\r > Board Type: SX1272MB2xAS < \n\r" );
00187   
00188     Radio.SetChannel( RF_FREQUENCY ); 
00189 
00190 #if USE_MODEM_LORA == 1
00191     
00192     debug_if( LORA_FHSS_ENABLED, "\n\n\r             > LORA FHSS Mode < \n\n\r");
00193     debug_if( !LORA_FHSS_ENABLED, "\n\n\r             > LORA Mode < \n\n\r");
00194 
00195     Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
00196                          LORA_SPREADING_FACTOR, LORA_CODINGRATE,
00197                          LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
00198                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
00199                          LORA_IQ_INVERSION_ON, 2000000 );
00200     
00201     Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
00202                          LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
00203                          LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
00204                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
00205                          LORA_IQ_INVERSION_ON, true );
00206                          
00207 #elif USE_MODEM_FSK == 1
00208 
00209     debug("\n\n\r              > FSK Mode < \n\n\r");
00210     Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
00211                          FSK_DATARATE, 0,
00212                          FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
00213                          FSK_CRC_ENABLED, 0, 0, 0, 2000000 );
00214     
00215     Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
00216                          0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
00217                          0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
00218                          0, 0, false, true );
00219                          
00220 #else
00221 
00222 #error "Please define a modem in the compiler options."
00223 
00224 #endif
00225      
00226     debug_if( DEBUG_MESSAGE, "Starting Ping-Pong loop\r\n" ); 
00227         
00228     led = 0;
00229         
00230     Radio.Rx( RX_TIMEOUT_VALUE );
00231     
00232     while( 1 )
00233     {
00234         switch( State )
00235         {
00236         case RX:
00237             if( isMaster == true )
00238             {
00239                 if( BufferSize > 0 )
00240                 {
00241                     if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 )
00242                     {
00243                         led = !led;
00244                         debug( "...em_Pong\r\n" );
00245                         // Send the next PING frame            
00246                         strcpy( ( char* )Buffer, ( char* )PingMsg );
00247                         // We fill the buffer with numbers for the payload 
00248                         for( i = 4; i < BufferSize; i++ )
00249                         {
00250                             Buffer[i] = i - 4;
00251                         }
00252                         wait_ms( 10 ); 
00253                         Radio.Send( Buffer, BufferSize );
00254                     }
00255                     else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
00256                     { // A master already exists then become a slave
00257                         debug( "...em_Ping\r\n" );
00258                         led = !led;
00259                         isMaster = false;
00260                         // Send the next PONG frame            
00261                         strcpy( ( char* )Buffer, ( char* )PongMsg );
00262                         // We fill the buffer with numbers for the payload 
00263                         for( i = 4; i < BufferSize; i++ )
00264                         {
00265                             Buffer[i] = i - 4;
00266                         }
00267                         wait_ms( 10 ); 
00268                         Radio.Send( Buffer, BufferSize );
00269                     }
00270                     else // valid reception but neither a PING or a PONG message
00271                     {    // Set device as master ans start again
00272                         isMaster = true;
00273                         Radio.Rx( RX_TIMEOUT_VALUE );
00274                     }    
00275                 }
00276             }
00277             else
00278             {
00279                 if( BufferSize > 0 )
00280                 {
00281                     if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
00282                     {
00283                         led = !led;
00284                         debug( "...em_Ping\r\n" );
00285                         // Send the reply to the PING string
00286                         strcpy( ( char* )Buffer, ( char* )PongMsg );
00287                         // We fill the buffer with numbers for the payload 
00288                         for( i = 4; i < BufferSize; i++ )
00289                         {
00290                             Buffer[i] = i - 4;
00291                         }
00292                         wait_ms( 10 );  
00293                         Radio.Send( Buffer, BufferSize );
00294                     }
00295                     else // valid reception but not a PING as expected
00296                     {    // Set device as master and start again
00297                         isMaster = true;
00298                         Radio.Rx( RX_TIMEOUT_VALUE );
00299                     }    
00300                 }
00301             }
00302             State = LOWPOWER;
00303             break;
00304         case TX:    
00305             led = !led; 
00306             if( isMaster == true )  
00307             {
00308                 debug( "em_Ping...\r\n" );
00309             }
00310             else
00311             {
00312                 debug( "Pong...\r\n" );
00313             }
00314             Radio.Rx( RX_TIMEOUT_VALUE );
00315             State = LOWPOWER;
00316             break;
00317         case RX_TIMEOUT:
00318             if( isMaster == true )
00319             {
00320                 // Send the next PING frame
00321                 strcpy( ( char* )Buffer, ( char* )PingMsg );
00322                 for( i = 4; i < BufferSize; i++ )
00323                 {
00324                     Buffer[i] = i - 4;
00325                 }
00326                 wait_ms( 10 ); 
00327                 Radio.Send( Buffer, BufferSize );
00328             }
00329             else
00330             {
00331                 Radio.Rx( RX_TIMEOUT_VALUE );  
00332             }             
00333             State = LOWPOWER;
00334             break;
00335         case RX_ERROR:
00336             // We have received a Packet with a CRC error, send reply as if packet was correct
00337             if( isMaster == true )
00338             {
00339                 // Send the next PING frame
00340                 strcpy( ( char* )Buffer, ( char* )PingMsg );
00341                 for( i = 4; i < BufferSize; i++ )
00342                 {
00343                     Buffer[i] = i - 4;
00344                 }
00345                 wait_ms( 10 );  
00346                 Radio.Send( Buffer, BufferSize );
00347             }
00348             else
00349             {
00350                 // Send the next PONG frame
00351                 strcpy( ( char* )Buffer, ( char* )PongMsg );
00352                 for( i = 4; i < BufferSize; i++ )
00353                 {
00354                     Buffer[i] = i - 4;
00355                 }
00356                 wait_ms( 10 );  
00357                 Radio.Send( Buffer, BufferSize );
00358             }
00359             State = LOWPOWER;
00360             break;
00361         case TX_TIMEOUT:
00362             Radio.Rx( RX_TIMEOUT_VALUE );
00363             State = LOWPOWER;
00364             break;
00365         case LOWPOWER:
00366             break;
00367         default:
00368             State = LOWPOWER;
00369             break;
00370         }    
00371     }
00372 }
00373 
00374 void OnTxDone( void )
00375 {
00376     Radio.Sleep( );
00377     State = TX;
00378     debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" );
00379 }
00380 
00381 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
00382 {
00383     Radio.Sleep( );
00384     BufferSize = size;
00385     memcpy( Buffer, payload, BufferSize );
00386     RssiValue = rssi;
00387     SnrValue = snr;
00388     State = RX;
00389     debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
00390 }
00391 
00392 void OnTxTimeout( void )
00393 {
00394     Radio.Sleep( );
00395     State = TX_TIMEOUT;
00396     debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
00397 }
00398 
00399 void OnRxTimeout( void )
00400 {
00401     Radio.Sleep( );
00402     Buffer[ BufferSize ] = 0;
00403     State = RX_TIMEOUT;
00404     debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
00405 }
00406 
00407 void OnRxError( void )
00408 {
00409     Radio.Sleep( );
00410     State = RX_ERROR;
00411     debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
00412 }
00413