Demo for Semtech Lora SX1272MB2xAS 868MHz an NUCLEO-F401RE (STM Cortex M4)
Fork of SX1272PingPong by
main.cpp
- Committer:
- emcu
- Date:
- 2016-04-03
- Revision:
- 15:3365ba2777d2
- Parent:
- 14:62abee5e269d
File content as of revision 15:3365ba2777d2:
/* Demo for Semtech Lora SX1272MB2xAS 868MHz an NUCLEO-F401RE (STM Cortex M4) by www.emcu.it Date: Mar.2016 Ver.: 1.0.1 Project name: LORA-SX1272MB2xAS-PP Note: The original project is here: https://developer.mbed.org/components/SX1272MB2xAS/ is: SX1272 Ping Pong Demo Application How to use: We tested this SW on NUCLEO-F401RE Program two kits (NUCLEO-F401RE + SX1272MB2xAS) with this SW. Connect the KITs to the PC and open a terminal emulation (for example TeraTerm). The TeraTerm configurations are shown below. 9600 bauds, 8-bit data, no parity On the TeraTerm you see the link informations. 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. If the GREEN led flash slowly means that is not present the link between the two KITs. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "mbed.h" #include "main.h" #include "sx1272-hal.h" #include "debug.h" /* Set this flag to '1' to display debug messages on the console */ #define DEBUG_MESSAGE 1 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */ #define USE_MODEM_LORA 1 #define USE_MODEM_FSK !USE_MODEM_LORA /* NOTE LORA_BANDWIDTH=2 & LORA_SPREADING_FACTOR=7 == MaxSpeed 41Kbit LORA_BANDWIDTH=1 & LORA_SPREADING_FACTOR=12 == MediumSpeed */ #define RF_FREQUENCY 868000000 // Hz #define TX_OUTPUT_POWER 14 // 14 dBm #if USE_MODEM_LORA == 1 #define LORA_BANDWIDTH 0 //2 // [0: 125 kHz, // 1: 250 kHz, // 2: 500 kHz, // 3: Reserved] #define LORA_SPREADING_FACTOR 11 //7 // [SF7..SF12] #define LORA_CODINGRATE 1 // [1: 4/5, // 2: 4/6, // 3: 4/7, // 4: 4/8] #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx #define LORA_SYMBOL_TIMEOUT 5 // Symbols #define LORA_FIX_LENGTH_PAYLOAD_ON false #define LORA_FHSS_ENABLED false #define LORA_NB_SYMB_HOP 4 #define LORA_IQ_INVERSION_ON false #define LORA_CRC_ENABLED true #elif USE_MODEM_FSK == 1 #define FSK_FDEV 25000 // Hz #define FSK_DATARATE 19200 // bps #define FSK_BANDWIDTH 50000 // Hz #define FSK_AFC_BANDWIDTH 83333 // Hz #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx #define FSK_FIX_LENGTH_PAYLOAD_ON false #define FSK_CRC_ENABLED true #else #error "Please define a modem in the compiler options." #endif #define RX_TIMEOUT_VALUE 3500000 // in us #define BUFFER_SIZE 32 // Define the payload size here #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) ) DigitalOut led(LED2); #else DigitalOut led(LED1); #endif //------------------------------------ // Hyperterminal configuration // 9600 bauds, 8-bit data, no parity //------------------------------------ Serial pc(SERIAL_TX, SERIAL_RX); /* * Global variables declarations */ typedef enum { LOWPOWER = 0, IDLE, RX, RX_TIMEOUT, RX_ERROR, TX, TX_TIMEOUT, CAD, CAD_DONE }AppStates_t; volatile AppStates_t State = LOWPOWER; /*! * Radio events function pointer */ static RadioEvents_t RadioEvents; /* * Global variables declarations */ SX1272MB2xAS Radio( NULL ); const uint8_t PingMsg[] = "em_PING"; const uint8_t PongMsg[] = "em_PONG"; uint16_t BufferSize = BUFFER_SIZE; uint8_t Buffer[BUFFER_SIZE]; int16_t RssiValue = 0.0; int8_t SnrValue = 0.0; int main() { uint8_t i; bool isMaster = true; pc.printf("\n\n\rModified by: http://www.wmcu.it \n\n\r" ); pc.printf("\n\r RF_FREQUENCY: %d Hz", RF_FREQUENCY); pc.printf("\n\r TX_OUTPUT_POWER: %d dBm", TX_OUTPUT_POWER); pc.printf("\n\r LORA_BANDWIDTH: %d -> 0==125KHz, 1==250KHz, 2==500KHz, 3==Reserved", LORA_BANDWIDTH); pc.printf("\n\r LORA_SPREADING_FACTOR: %d (SF7..SF12)", LORA_SPREADING_FACTOR); pc.printf("\n\r LORA_CODINGRATE: %d", LORA_CODINGRATE); pc.printf(" -> 1==4/5; 2==4/6; 3==4/7; 4==4/8\n\r"); pc.printf("\n\rSee this link: https://developer.mbed.org/components/SX1272MB2xAS/ \n\rfor original example.\n\r "); debug( "\n\n\r SX1272 Ping Pong Demo Application \n\n\r" ); // Initialize Radio driver RadioEvents.TxDone = OnTxDone; RadioEvents.RxDone = OnRxDone; RadioEvents.RxError = OnRxError; RadioEvents.TxTimeout = OnTxTimeout; RadioEvents.RxTimeout = OnRxTimeout; Radio.Init( &RadioEvents ); // verify the connection with the board while( Radio.Read( REG_VERSION ) == 0x00 ) { debug( "Radio could not be detected!\n\r", NULL ); wait( 1 ); } debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1272MB2XAS ) ) , "\n\r > Board Type: SX1272MB2xAS < \n\r" ); Radio.SetChannel( RF_FREQUENCY ); #if USE_MODEM_LORA == 1 debug_if( LORA_FHSS_ENABLED, "\n\n\r > LORA FHSS Mode < \n\n\r"); debug_if( !LORA_FHSS_ENABLED, "\n\n\r > LORA Mode < \n\n\r"); Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, LORA_IQ_INVERSION_ON, 2000000 ); Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, LORA_IQ_INVERSION_ON, true ); #elif USE_MODEM_FSK == 1 debug("\n\n\r > FSK Mode < \n\n\r"); Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, FSK_DATARATE, 0, FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, FSK_CRC_ENABLED, 0, 0, 0, 2000000 ); Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED, 0, 0, false, true ); #else #error "Please define a modem in the compiler options." #endif debug_if( DEBUG_MESSAGE, "Starting Ping-Pong loop\r\n" ); led = 0; Radio.Rx( RX_TIMEOUT_VALUE ); while( 1 ) { switch( State ) { case RX: if( isMaster == true ) { if( BufferSize > 0 ) { if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 ) { led = !led; debug( "...em_Pong\r\n" ); // Send the next PING frame strcpy( ( char* )Buffer, ( char* )PingMsg ); // We fill the buffer with numbers for the payload for( i = 4; i < BufferSize; i++ ) { Buffer[i] = i - 4; } wait_ms( 10 ); Radio.Send( Buffer, BufferSize ); } else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) { // A master already exists then become a slave debug( "...em_Ping\r\n" ); led = !led; isMaster = false; // Send the next PONG frame strcpy( ( char* )Buffer, ( char* )PongMsg ); // We fill the buffer with numbers for the payload for( i = 4; i < BufferSize; i++ ) { Buffer[i] = i - 4; } wait_ms( 10 ); Radio.Send( Buffer, BufferSize ); } else // valid reception but neither a PING or a PONG message { // Set device as master ans start again isMaster = true; Radio.Rx( RX_TIMEOUT_VALUE ); } } } else { if( BufferSize > 0 ) { if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 ) { led = !led; debug( "...em_Ping\r\n" ); // Send the reply to the PING string strcpy( ( char* )Buffer, ( char* )PongMsg ); // We fill the buffer with numbers for the payload for( i = 4; i < BufferSize; i++ ) { Buffer[i] = i - 4; } wait_ms( 10 ); Radio.Send( Buffer, BufferSize ); } else // valid reception but not a PING as expected { // Set device as master and start again isMaster = true; Radio.Rx( RX_TIMEOUT_VALUE ); } } } State = LOWPOWER; break; case TX: led = !led; if( isMaster == true ) { debug( "em_Ping...\r\n" ); } else { debug( "Pong...\r\n" ); } Radio.Rx( RX_TIMEOUT_VALUE ); State = LOWPOWER; break; case RX_TIMEOUT: if( isMaster == true ) { // Send the next PING frame strcpy( ( char* )Buffer, ( char* )PingMsg ); for( i = 4; i < BufferSize; i++ ) { Buffer[i] = i - 4; } wait_ms( 10 ); Radio.Send( Buffer, BufferSize ); } else { Radio.Rx( RX_TIMEOUT_VALUE ); } State = LOWPOWER; break; case RX_ERROR: // We have received a Packet with a CRC error, send reply as if packet was correct if( isMaster == true ) { // Send the next PING frame strcpy( ( char* )Buffer, ( char* )PingMsg ); for( i = 4; i < BufferSize; i++ ) { Buffer[i] = i - 4; } wait_ms( 10 ); Radio.Send( Buffer, BufferSize ); } else { // Send the next PONG frame strcpy( ( char* )Buffer, ( char* )PongMsg ); for( i = 4; i < BufferSize; i++ ) { Buffer[i] = i - 4; } wait_ms( 10 ); Radio.Send( Buffer, BufferSize ); } State = LOWPOWER; break; case TX_TIMEOUT: Radio.Rx( RX_TIMEOUT_VALUE ); State = LOWPOWER; break; case LOWPOWER: break; default: State = LOWPOWER; break; } } } void OnTxDone( void ) { Radio.Sleep( ); State = TX; debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" ); } void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) { Radio.Sleep( ); BufferSize = size; memcpy( Buffer, payload, BufferSize ); RssiValue = rssi; SnrValue = snr; State = RX; debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" ); } void OnTxTimeout( void ) { Radio.Sleep( ); State = TX_TIMEOUT; debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" ); } void OnRxTimeout( void ) { Radio.Sleep( ); Buffer[ BufferSize ] = 0; State = RX_TIMEOUT; debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" ); } void OnRxError( void ) { Radio.Sleep( ); State = RX_ERROR; debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" ); }