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.
Diff: main.cpp
- Revision:
- 0:90252f6ec3d0
diff -r 000000000000 -r 90252f6ec3d0 main.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Feb 22 00:04:36 2017 +0000
@@ -0,0 +1,575 @@
+#include "mbed.h"
+#include "main.h"
+#include "sx1276-hal.h"
+#include "debug.h"
+
+/* Set this flag to '1' to display debug messages on the console */
+#define DEBUG_MESSAGE 0
+
+/* 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
+
+//#define RF868 1
+
+#ifdef RF868
+
+ #define RF_FREQUENCY 868000000 // Hz
+ #define TX_OUTPUT_POWER 14 // 14 dBm
+
+#else
+
+ #define RF_FREQUENCY 433000000 // Hz
+ #define TX_OUTPUT_POWER 14 // 26 dBm
+
+#endif
+
+#if USE_MODEM_LORA == 1
+ #define LORA_BANDWIDTH 0
+ #define LORA_SPREADING_FACTOR 10
+ #define LORA_CODINGRATE 2
+
+ //#define LORA_BANDWIDTH 2 // [0: 125 kHz,
+ // 1: 250 kHz,
+ // 2: 500 kHz,
+ // 3: Reserved]
+ //#define LORA_SPREADING_FACTOR 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);
+//DigitalOut led2(LED2);
+//DigitalOut led3(LED3);
+//DigitalOut led4(LED4);
+DigitalOut debugled(D6);
+DigitalOut debugled2(D7);
+
+#endif
+
+DigitalIn role(USER_BUTTON); // PC_13 in Mini 103RC mini board
+Timer tx_tmr;
+
+#define UART_ENABLE
+
+#ifdef UART_ENABLE
+//Serial pc(USBTX, USBRX);
+Serial pc(SERIAL_TX, SERIAL_RX);
+#endif
+
+Ticker nwk_ticker;
+
+bool channelOccupied = false;
+
+#define NWK_SLEEP 0
+#define NWK_TX 1
+#define NWK_TX_NOK 2
+#define NWK_RX_OK 3
+#define NWK_RX_NOK 4
+
+//#define PINGPONG
+
+void nwk_toggle()
+{
+ debugled = !debugled;
+ debugled2 = !debugled2;
+}
+
+void nwk_setmode(uint8_t mode)
+{
+ switch(mode){
+ case NWK_TX:
+ case NWK_RX_OK:
+ nwk_ticker.attach(&nwk_toggle, 1);
+ break;
+ case NWK_TX_NOK:
+ case NWK_RX_NOK:
+ nwk_ticker.attach(&nwk_toggle, 0.1);
+ break;
+ case NWK_SLEEP:
+ default:
+ debugled = 0;
+ debugled2 = 0;
+ nwk_ticker.detach();
+ break;
+ }
+}
+
+/*
+ * Global variables declarations
+ */
+typedef enum
+{
+ ST_LOWPOWER = 0,
+ ST_IDLE,
+
+ ST_RX,
+ ST_RX_TIMEOUT,
+ ST_RX_ERROR,
+
+ ST_TX,
+ ST_TX_TIMEOUT,
+
+ ST_CAD,
+ ST_CAD_DONE
+}AppStates_t;
+
+volatile AppStates_t State = ST_LOWPOWER;
+
+/*!
+ * Radio events function pointer
+ */
+static RadioEvents_t RadioEvents;
+
+/*
+ * Global variables declarations
+ */
+SX1276MB1xAS Radio( NULL );
+
+const uint8_t PingMsg[] = "PING";
+const uint8_t PongMsg[] = "PONG";
+const uint8_t TestMsg[] = "LoRa Test";
+
+uint16_t BufferSize = BUFFER_SIZE;
+uint8_t Buffer[BUFFER_SIZE];
+
+//int16_t RssiValue = 0.0;
+//int8_t SnrValue = 0.0;
+
+int16_t RssiValue = 0;
+int8_t SnrValue = 0;
+
+#define REG_SIZE 0x70 // see below
+#define REG_IDX_SIZE 39
+
+static int my_strncmp(const char *, const char *, int);
+static void my_strcpy(char * , const char *);
+
+int my_strncmp(const char * s1, const char * s2, int size)
+{
+ int n = size;
+ for ( ; n > 0; s1++, s2++, --n)
+ if (*s1 != *s2)
+ return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
+ else if (*s1 == '\0')
+ return 0;
+ return 0;
+}
+
+void my_strcpy(char * s1, const char * s2)
+{
+ char *s = s1;
+ while ((*s++ = *s2++) != 0)
+ ;
+}
+
+void Sender ( void )
+{
+ int i;
+ my_strcpy( ( char* )Buffer, ( char* )PingMsg );
+ for( i = 4; i < BufferSize; i++ ){
+ Buffer[i] = i - 4;
+ }
+ Radio.Send( Buffer, BufferSize );
+}
+
+int main()
+{
+ uint8_t i;
+ uint8_t regval;
+ bool isMaster = true;
+ int begin, end;
+
+ uint32_t rand;
+ debugled = 1;
+ debugled2 = 1;
+
+ isMaster = role.read();
+
+ //debug( "\n\n\r SX1276 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 );
+
+ #ifdef UART_ENABLE
+ regval = Radio.Read(REG_VERSION);
+ pc.printf("%s", TestMsg);
+ pc.printf("IC Version: %02X\r\n", regval);
+ regval = Radio.Read(REG_OPMODE);
+ pc.printf("OPMODE: %02X\r\n", regval);
+ #endif
+
+ debugled = 0;
+ debugled2 = 0;
+
+ // 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( ) == SX1276MB1LAS ) ) , "\n\r > Board Type: SX1276MB1LAS < \n\r" );
+ //debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1MAS ) ) , "\n\r > Board Type: SX1276MB1MAS < \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" );
+
+ rand = Radio.Random();
+ rand = rand%1000;
+ wait_ms((uint16_t)rand);
+
+#ifdef PINGPONG
+ Radio.Rx( RX_TIMEOUT_VALUE );
+
+
+ while( 1 )
+ {
+ switch( State )
+ {
+ case ST_RX:
+ if( isMaster == true )
+ {
+ if( BufferSize > 0 )
+ {
+ #ifdef UART_ENABLE
+ pc.printf("Received message:\r\n");
+ pc.printf("%s",Buffer);
+ #endif
+ //if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 )
+ if( my_strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 )
+ {
+ nwk_setmode(NWK_NORMAL);
+ //debug( "...Pong\r\n" );
+ // Send the next PING frame
+ my_strcpy( ( char* )Buffer, ( char* )PingMsg );
+ //_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( my_strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
+ { // A master already exists then become a slave
+ debug( "...Ping\r\n" );
+ //nwk_setmode(NWK_NORMAL);
+ //led = !led;
+ isMaster = false;
+ // Send the next PONG frame
+ my_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 )
+ {
+ #ifdef UART_ENABLE
+ pc.printf("Received message:\r\n");
+ pc.printf("%s",Buffer);
+ #endif
+
+ if( my_strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
+ {
+ nwk_setmode(NWK_NORMAL);
+ //led = !led;
+ //debug( "...Ping\r\n" );
+ // Send the reply to the PING string
+ my_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 = ST_LOWPOWER;
+ break;
+ case ST_TX:
+ //nwk_setmode(NWK_NORMAL);
+ //led = !led;
+ if( isMaster == true )
+ {
+ //debug( "Ping...\r\n" );
+ }
+ else
+ {
+ //debug( "Pong...\r\n" );
+ }
+ Radio.Rx( RX_TIMEOUT_VALUE );
+ State = ST_LOWPOWER;
+ break;
+ case ST_RX_TIMEOUT:
+ //debugled = !debugled;
+ //debugled2 = !debugled2;
+ nwk_setmode(NWK_ERR);
+ if( isMaster == true )
+ {
+ // Send the next PING frame
+ my_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 = ST_LOWPOWER;
+ break;
+ case ST_RX_ERROR:
+ // We have received a Packet with a CRC error, send reply as if packet was correct
+ nwk_setmode(NWK_ERR);
+ if( isMaster == true )
+ {
+ // Send the next PING frame
+ my_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
+ my_strcpy( ( char* )Buffer, ( char* )PongMsg );
+ for( i = 4; i < BufferSize; i++ )
+ {
+ Buffer[i] = i - 4;
+ }
+ wait_ms( 10 );
+ Radio.Send( Buffer, BufferSize );
+ }
+ State = ST_LOWPOWER;
+ break;
+ case ST_TX_TIMEOUT:
+ nwk_setmode(NWK_ERR);
+ Radio.Rx( RX_TIMEOUT_VALUE );
+ State = ST_LOWPOWER;
+ break;
+ case ST_CAD:
+ break;
+ case ST_CAD_DONE:
+ if(channelOccupied){
+ State = ST_LOWPOWER;
+ }else{
+ // start to transmit here.
+ }
+ break;
+ case ST_LOWPOWER:
+ break;
+ default:
+ nwk_setmode(0xFF);
+ State = ST_LOWPOWER;
+ break;
+ }
+ }
+
+#else
+
+ if(isMaster == true){
+ tx_tmr.start();
+ begin = tx_tmr.read_ms();
+ }else{
+ Radio.Rx( RX_TIMEOUT_VALUE );
+ }
+
+ while(1){
+ switch(State){
+ case ST_RX:
+ //nwk_setmode(NWK_RX_OK);
+ Radio.Rx( RX_TIMEOUT_VALUE );
+ State = ST_LOWPOWER;
+#ifdef UART_ENABLE
+ //pc.printf("\r\nRX OK\tRSSI:%f SNR:%f \r\n",float(RssiValue),float(SnrValue));
+ pc.printf("\r\nRX OK\tRSSI:%d SNR:%d \r\n",RssiValue,SnrValue);
+ pc.printf("\r\nRSSI: %02X SNR: %01X\r\n", RssiValue, SnrValue);
+#endif
+ break;
+ case ST_TX:
+ nwk_setmode(NWK_TX);
+ State = ST_LOWPOWER;
+#ifdef UART_ENABLE
+ pc.printf("\r\nTX Done.\r\n");
+#endif
+ break;
+ case ST_RX_TIMEOUT:
+ case ST_RX_ERROR:
+ //nwk_setmode(NWK_RX_NOK);
+ Radio.Rx( RX_TIMEOUT_VALUE );
+ State = ST_LOWPOWER;
+#ifdef UART_ENABLE
+ pc.printf("\r\nRX TIMEOUT or ERROR.\r\n");
+#endif
+ break;
+ case ST_TX_TIMEOUT:
+ State = ST_LOWPOWER;
+ break;
+ case ST_LOWPOWER:
+ if (isMaster){
+ end = tx_tmr.read_ms();
+ if ((end-begin) >= 2000){
+ Sender();
+ tx_tmr.stop();
+ tx_tmr.start();
+ begin = tx_tmr.read_ms();
+ }
+ }
+ break;
+ default:
+ State = ST_LOWPOWER;
+ break;
+ }
+ }
+#endif
+
+}
+
+
+void OnTxDone( void )
+{
+ Radio.Sleep( );
+ State = ST_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 = ST_RX;
+ nwk_setmode(NWK_RX_OK);
+ //debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
+}
+
+void OnTxTimeout( void )
+{
+ Radio.Sleep( );
+ State = ST_TX_TIMEOUT;
+ //debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
+}
+
+void OnRxTimeout( void )
+{
+ Radio.Sleep( );
+ Buffer[ BufferSize ] = 0;
+ State = ST_RX_TIMEOUT;
+ nwk_setmode(NWK_RX_NOK);
+ //debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
+}
+
+void OnRxError( void )
+{
+ Radio.Sleep( );
+ State = ST_RX_ERROR;
+ //debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
+}
+
+// Added by allankliu
+void OnCadDone( bool channelActivityDetected )
+{
+ Radio.Sleep();
+ channelOccupied = channelActivityDetected;
+ State = ST_CAD_DONE;
+}