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: SX1276GenericLib USBDevice
Fork of NonPingPong_PICO_LoRa_LP1 by
SX1276GenericPingPong/GenericPingPong2.cpp
- Committer:
- walterluu
- Date:
- 2020-10-16
- Revision:
- 8:5ff74d7381dc
- Parent:
- 7:6264bc5b6421
File content as of revision 8:5ff74d7381dc:
/*
* This file contains a copy of the master content sx1276PingPong
* with adaption for the SX1276Generic environment
* (c) 2017 Helmut Tschemernjak
* 30826 Garbsen (Hannover) Germany
*/
#include "mbed.h"
#include "PinMap.h"
#include "GenericPingPong2.h"
#include "sx1276-mbed-hal.h"
#include "main.h"
#include "global_buffers.h" //adding this for development
#include "sx1276.h"
#include "USBSerial.h"
#ifdef FEATURE_LORA // in main.cpp
/* 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
#define RF_FREQUENCY RF_FREQUENCY_915_0 // Hz
#define TX_OUTPUT_POWER 1 // 14 dBm
#if USE_MODEM_LORA == 1
#define LORA_BANDWIDTH 125000 // LoRa default, details in SX1276::BandwidthMap
#define LORA_SPREADING_FACTOR LORA_SF7
#define LORA_CODINGRATE LORA_ERROR_CODING_RATE_4_5
//#define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx, default
#define LORA_PREAMBLE_LENGTH 5
//#define LORA_SYMBOL_TIMEOUT 5 // Symbols
#define LORA_SYMBOL_TIMEOUT 4 // 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
#if MASTER == 1
#define RX_TIMEOUT_VALUE 3500 // in ms, default
#elif SLAVE == 1
#define RX_TIMEOUT_VALUE 333 // in ms
#endif
//#define BUFFER_SIZE 32 // Define the payload size here
//#define BUFFER_SIZE 64 // Define the payload size here
/*
* 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
*/
SX1276Generic *Radio;
//const uint8_t PingMsg[] = { 0xff, 0xff, 0x00, 0x00, 'P', 'I', 'N', 'G'};// "PING";
//const uint8_t PongMsg[] = { 0xff, 0xff, 0x00, 0x00, 'P', 'O', 'N', 'G'};// "PONG";
//uint16_t BufferSize = BUFFER_SIZE;
//uint8_t *Buffer;
// Aliases for the buffers that are made in the main()
uint8_t *BufferTx;
uint8_t *BufferRx;
USBSerial *ad;
DigitalOut *led3;
/*
This function is in Devin's main function
*/
int SX1276PingPongSetup(uint8_t *BufferTxFromMain, uint8_t *BufferRxFromMain, USBSerial *_ad)
{
ad = _ad;
ad->printf("TEST\r\n" );
#if( defined ( TARGET_KL25Z ) || defined ( TARGET_Lad11U6X ) )
DigitalOut *led = new DigitalOut(LED2);
#elif defined(TARGET_NUCLEO_L073RZ) || defined(TARGET_DISCO_L072CZ_LRWAN1)
DigitalOut *led = new DigitalOut(LED4); // RX red
led3 = new DigitalOut(LED3); // TX blue
#else
DigitalOut *led = new DigitalOut(LED1);
// led = 0;
led3 = led;
#endif
BufferTx = BufferTxFromMain;
BufferRx = BufferRxFromMain;
*led3 = 0; // change to 0
#ifdef B_L072Z_LRWAN1_LORA
Radio = new SX1276Generic(NULL, MURATA_SX1276,
LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET,
LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5,
LORA_ANT_RX, LORA_ANT_TX, LORA_ANT_BOOST, LORA_TCXO);
#else // RFM95
Radio = new SX1276Generic(NULL, RFM95_SX1276,
LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET,
LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5);
#endif
// dprintf("SX1276 Ping Pong Demo Application" );
ad->printf("SX1276 Ping Pong Demo Application\r\n");
// dprintf("Freqency: %.1f", (double)RF_FREQUENCY/1000000.0);
ad->printf("Freqency: %.1f\r\n", (double)RF_FREQUENCY/1000000.0);
// dprintf("TXPower: %d dBm", TX_OUTPUT_POWER);
ad->printf("TXPower: %d dBm\r\n", TX_OUTPUT_POWER);
#if USE_MODEM_LORA == 1
// dprintf("Bandwidth: %d Hz", LORA_BANDWIDTH);
ad->printf("Bandwidth: %d Hz\r\n", LORA_BANDWIDTH);
// dprintf("Spreading factor: SF%d", LORA_SPREADING_FACTOR);
ad->printf("Spreading factor: SF%d\r\n", LORA_SPREADING_FACTOR);
#elif USE_MODEM_FSK == 1
// dprintf("Bandwidth: %d kHz", FSK_BANDWIDTH);
ad->printf("Bandwidth: %d kHz\r\n", FSK_BANDWIDTH);
// dprintf("Baudrate: %d", FSK_DATARATE);
ad->printf("Baudrate: %d\r\n", FSK_DATARATE);
#endif
// Initialize Radio driver
RadioEvents.TxDone = OnTxDone;
RadioEvents.RxDone = OnRxDone;
RadioEvents.RxError = OnRxError;
RadioEvents.TxTimeout = OnTxTimeout;
RadioEvents.RxTimeout = OnRxTimeout;
if (Radio->Init( &RadioEvents ) == false) {
while(1) {
// dprintf("Radio could not be detected!");
ad->printf("Radio could not be detected!\r\n");
wait( 1 );
}
}
switch(Radio->DetectBoardType()) {
case SX1276MB1LAS:
if (DEBUG_MESSAGE)
ad->printf(" > Board Type: SX1276MB1LAS <\r\n");
break;
case SX1276MB1MAS:
if (DEBUG_MESSAGE)
ad->printf(" > Board Type: SX1276MB1LAS <\r\n");
case MURATA_SX1276:
if (DEBUG_MESSAGE)
ad->printf(" > Board Type: MURATA_SX1276_STM32L0 <\r\n");
break;
case RFM95_SX1276:
if (DEBUG_MESSAGE)
ad->printf(" > HopeRF RFM95xx <\r\n");
break;
default:
ad->printf(" > Board Type: unknown <\r\n");
}
Radio->SetChannel(RF_FREQUENCY );
#if USE_MODEM_LORA == 1
if (LORA_FHSS_ENABLED)
ad->printf(" > LORA FHSS Mode <\r\n");
if (!LORA_FHSS_ENABLED)
ad->printf(" > LORA Mode <\r\n");
// Without this line, the default max payload length is only 64 bytes
Radio->SetMaxPayloadLength(MODEM_LORA, 255);
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, 2000 );
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
ad->printf(" > FSK Mode <\n");
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, 2000 );
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
if (DEBUG_MESSAGE)
ad->printf("Starting Ping-Pong loop\r\n");
#if MASTER == 1
Radio->Rx( RX_TIMEOUT_VALUE ); // initate Rx State for Master
#endif
return 0; //added by Walter due to "Control reaches end of non-void function"
}
bool SX1276MasterCheckForNewData(void)
{
bool new_data_available = false;
switch( State )
{
case RX:
if( BufferSizeRx > 0 )
{
new_data_available = true;
wait_ms( 10 ); //do we need this?
if (DEBUG_MESSAGE)
ad->printf( "State=RX\r\n" );
}
Radio->Rx( RX_TIMEOUT_VALUE );
State = LOWPOWER;
break;
case RX_TIMEOUT:
wait_ms( 10 );
if (DEBUG_MESSAGE)
ad->printf( "State=RX_TIMEOUT\r\n" );
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
wait_ms( 10 );
if (DEBUG_MESSAGE)
ad->printf( "State=RX_ERROR\r\n" );
Radio->Rx( RX_TIMEOUT_VALUE );
State = LOWPOWER;
break;
case TX_TIMEOUT:
if (DEBUG_MESSAGE)
ad->printf( "State=TX_TIMEOUT\r\n" );
State = LOWPOWER;
break;
case LOWPOWER:
sleep();
break;
default:
sleep(); // TODO, should this be removed?
break;
}
return new_data_available;
}
void SX1276SlaveSendData(void)
{
//wait_ms( 10 );
Radio->Send( BufferTx, BufferSizeTx );
sleep();
}
/****************************************************************************************************************************************
*
****************************************************************************************************************************************/
//int SX1276PingPong(void)
//{
//#if MASTER == 1 // Master Device: Bluetooth Gateway
// bool isMaster = true;
//#elif SLAVE == 1 // Slave Device: Robot
// bool isMaster = false;
//#endif
//
// switch( State )
// {
// case RX:
//// *led3 = 0; // uncommented
// if( isMaster == true ) // Master Device received payload from Slave
// {
// if( BufferSizeRx > 0 )
// {
// /* This checks if the ID of the received transaction is matching that of
// * the slave device's ID. This is defined in the GenericPingPong.h
// */
// if( memcmp(&BufferRx[rx_idx_signature], PongMsg, sizeof(PongMsg)) == 0 )
// {
//// *led = !*led;
//// *led = 0; // changed to 0
// if (DEBUG_MESSAGE)
// ad->printf( "...Pong\r\n" );
// wait_ms( 10 );
// Radio->Send( BufferTx, BufferSizeTx );
// } // memcmp != 0
// else // valid reception but not a PONG message
// { // Set device as master and start again
// isMaster = true; // new update
// Radio->Rx( RX_TIMEOUT_VALUE );
// } // end of if memcmp
// } // end of if BufferSizeRx > 0
// } // end of isMaster == true
// else // Slave Device received payload from Master
// {
// if( BufferSizeRx > 0 )
// {
// if( memcmp(BufferRx, PingMsg, sizeof(PingMsg)) == 0 )
// {
//// *led = !*led;
//// *led = 0 //changed to 0
// if (DEBUG_MESSAGE)
// ad->printf( "...Ping\r\n" );
// wait_ms( 10 );
// Radio->Send( BufferTx, BufferSizeTx );
// }
// else // valid reception but not a PING as expected
// { // Set device as slave and start again
// isMaster = false; // new update
// Radio->Rx( RX_TIMEOUT_VALUE );
// }
// } // end of if BufferSizeRx > 0
// } // end of if (isMaster == True), end of checking devices
//
// State = LOWPOWER; // back to LOWPOWER State
//
// break;
// case TX:
//// *led3 = 0; // change to 0
// if( isMaster == true ) // Master Device
// {
// if (DEBUG_MESSAGE)
// ad->printf("Ping...\r\n" );
// }
// else // Slave Device
// {
// if (DEBUG_MESSAGE)
// ad->printf("Pong...\r\n" );
// }
// Radio->Rx( RX_TIMEOUT_VALUE );
// State = LOWPOWER; // back to LOWPOWER State
// break;
// case RX_TIMEOUT:
// if( isMaster == true ) // Master Device
// {
// wait_ms( 10 );
// Radio->Send( BufferTx, BufferSizeTx );
// }
// else // Slave Device
// {
// Radio->Rx( RX_TIMEOUT_VALUE );
// }
// State = LOWPOWER; // back to LOWPOWER State
// break;
// case RX_ERROR:
// // We have received a Packet with a CRC error, send reply as if packet was correct
// if( isMaster == true ) // Master Device
// {
// // Send the next PING frame
//// memcpy(BufferTx, PingMsg, sizeof(PingMsg));
///*
// for( i = 4; i < BufferSizeTx; i++ )
// {
// BufferTx[i] = i - 4;
// }
//*/
//// fillPayloadWithGlobalBufs(BufferTx);
// wait_ms( 10 );
// Radio->Send( BufferTx, BufferSizeTx );
// }
// else // Slave Device
// {
// // Send the next PONG frame
//// memcpy(BufferTx, PongMsg, sizeof(PongMsg));
///*
// for( i = sizeof(PongMsg); i < BufferSizeTx; i++ )
// {
// BufferTx[i] = i - sizeof(PongMsg);
// }
//*/
// wait_ms( 10 );
// Radio->Send( BufferTx, BufferSizeTx );
// }
// State = LOWPOWER; // Back to Low Power State
// break;
// case TX_TIMEOUT:
// Radio->Rx( RX_TIMEOUT_VALUE );
// State = LOWPOWER;
// break;
// case LOWPOWER:
// sleep();
// break;
// default:
// State = LOWPOWER;
// break;
// }
//}
int TimeOnAirSend(void) {
return Radio->TimeOnAir( MODEM_LORA, sizeof(BufferSizeTx));
}
int SX1276SensorSend(void) {
switch( State )
{
case RX:
// if( BufferSizeRx > 0 )
// {
// Radio->Send( BufferTx, BufferSizeTx );
// Radio->Rx( RX_TIMEOUT_VALUE );
// } // end of if BufferSizeRx > 0
Radio->Send( BufferTx, BufferSizeTx );
Radio->Rx( RX_TIMEOUT_VALUE );
State = LOWPOWER; // back to LOWPOWER State
break;
} // end of switch statement
}
int SX1276GateWayReceive(int TimeOut) {
switch( State )
{
case RX:
// if( BufferSizeRx > 0 )
// {
//// Radio->Send( BufferTx, BufferSizeTx );
// Radio->Rx( RX_TIMEOUT_VALUE );
// } // end of if BufferSizeRx > 0
// Radio->Rx( RX_TIMEOUT_VALUE );
Radio->Rx( TimeOut );
State = LOWPOWER; // back to LOWPOWER State
break;
} // end of switch statement
}
//void OnTxDone(void *radio, void *userThisPtr, void *userData)
//{
// Radio->Sleep( );
// State = TX;
// if (DEBUG_MESSAGE)
// dprintf("> OnTxDone");
//}
// moved to main
void OnTxDone(void *radio, void *userThisPtr, void *userData)
{
Radio->Sleep( );
State = TX;
if (DEBUG_MESSAGE)
//dprintf("> OnTxDone");
ad->printf("> OnTxDone");
}
//void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
//{
// Radio->Sleep( );
// BufferSize = size;
// memcpy( Buffer, payload, BufferSize );
// State = RX;
// if (DEBUG_MESSAGE)
// dprintf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d", rssi, snr);
// dump("Data:", payload, size);
//}
// moved to main
void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
{
Radio->Sleep( );
if(BufferSizeRx != size)
memcpy( BufferRx, payload, size );
else
memcpy( BufferRx, payload, BufferSizeRx );
State = RX;
// Reset the RxTimeoutCount
RxTimeoutCount = 0;
if (DEBUG_MESSAGE) {
ad->printf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d\n", rssi, snr);
dump("Data:", payload, size);
}
}
//void OnTxTimeout(void *radio, void *userThisPtr, void *userData)
//{
// *led3 = 0;
// Radio->Sleep( );
// State = TX_TIMEOUT;
// if(DEBUG_MESSAGE)
// dprintf("> OnTxTimeout");
//}
// moved to main
void OnTxTimeout(void *radio, void *userThisPtr, void *userData)
{
// *led3 = 0;
Radio->Sleep( );
State = TX_TIMEOUT;
if(DEBUG_MESSAGE)
ad->printf("> OnTxTimeout");
}
//void OnRxTimeout(void *radio, void *userThisPtr, void *userData)
//{
// *led3 = 0;
// Radio->Sleep( );
// Buffer[BufferSize-1] = 0;
// State = RX_TIMEOUT;
// if (DEBUG_MESSAGE)
// dprintf("> OnRxTimeout");
//}
// moved to main
void OnRxTimeout(void *radio, void *userThisPtr, void *userData)
{
Radio->Sleep( );
BufferRx[BufferSizeRx-1] = 0;
State = RX_TIMEOUT;
if (DEBUG_MESSAGE)
ad->printf("> OnRxTimeout\n");
// Increment how many times a transmission times out\
RxTimeoutCount = RxTimeoutCount + 1;
}
//void OnRxError(void *radio, void *userThisPtr, void *userData)
//{
// Radio->Sleep( );
// State = RX_ERROR;
// if (DEBUG_MESSAGE)
// dprintf("> OnRxError");
//}
// moved to main
void OnRxError(void *radio, void *userThisPtr, void *userData)
{
Radio->Sleep( );
State = RX_ERROR;
if (DEBUG_MESSAGE)
ad->printf("> OnRxError\n");
// Increment how many times a transmission times out\
RxTimeoutCount = RxTimeoutCount + 1;
}
int numOfRxTimeouts()
{
return RxTimeoutCount;
}
#endif
