Elmo Terminal provides functionality to test Lora radio and access SX1272 chip registers delivered with Elmo board. Also contains example ping-pong application.
Dependencies: SX1272lib mbed-src
Diff: RadioContex.cpp
- Revision:
- 2:8d8295a51f68
- Child:
- 4:2767f13b0a75
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RadioContex.cpp Thu Oct 01 09:40:30 2015 +0200 @@ -0,0 +1,257 @@ +#include "assert.h" + +#include "RadioContex.h" +#include "Settings.h" +#include "dbg.h" +#include <sstream> + + +/* Set this flag to '1' to display debug messages on the console */ + +#define DEBUG_MESSAGE 0 +#define RX_TIMEOUT_VALUE 3500000 // in us +#define BUFFER_SIZE 32 // Define the payload size here + + // 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 + + #if USE_MODEM_LORA == 1 + + #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 + + +RadioContex* RadioContex::thi = 0; + +const char* RadioContex::rx_error_msg = "rx_error"; +const char* RadioContex::rx_timeout_msg = "rx_timeout"; + + +RadioContex::RadioContex (Settings* settings) + : radio_ (0) +{ + assert(thi == 0); + thi = this; + BufferSize = BUFFER_SIZE; + State = LOWPOWER; + + sendCntr = 0; + + radio_ = new SX1272MB1xAS ( RadioContex::StaticOnTxDone, RadioContex::StaticOnTxTimeout, RadioContex::StaticOnRxDone, + RadioContex::StaticOnRxTimeout, RadioContex::StaticOnRxError, NULL, NULL, + RF_SPI_MOSI, RF_SPI_MISO, RF_SPI_SCK, RF_SPI_CS, + RF_RESET, RF_DIO0, RF_DIO1, RF_DIO2, RF_DIO3, RF_DIO4, RF_DIO5, + RF_RXTX_SW ); + + // verify the connection with the board + while( radio_->Read( REG_VERSION ) == 0x00 ) + { + debug( "Radio could not be detected!\n\r", NULL ); + wait( 1 ); + } + + radio_->SetChannel( settings->aget("freq") * 1000 ); + +#if USE_MODEM_LORA == 1 + + debug_if( LORA_FHSS_ENABLED, "> Radio start LORA FHSS Mode < \n\r"); + debug_if( !LORA_FHSS_ENABLED, "> Radio start LORA Mode < \n\r"); + + radio_->SetTxConfig( MODEM_LORA, settings->aget("power") , 0, settings->aget("bandwidth"), + settings->aget("dataRate"), settings->aget("codeRate"), + settings->aget("preambleLen"), LORA_FIX_LENGTH_PAYLOAD_ON, + LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, + LORA_IQ_INVERSION_ON, 2000000, settings->aget("paBoost")); + + radio_->SetRxConfig( MODEM_LORA, settings->aget("bandwidth"), + settings->aget("dataRate"), settings->aget("codeRate"), 0, settings->aget("preambleLen"), + settings->aget("symbTimeout"), 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 + +} + + +RadioContex::States_t RadioContex::getState() const +{ + return State; +} + + +bool RadioContex::setState(States_t newState) +{ + State = newState; + return true; +} + + +bool RadioContex::Send(std::string arg) +{ + stringstream ss; + ss <<" "<< sendCntr; + arg.append(ss.str()); + + const uint8_t* msg = (const unsigned char *)(arg.c_str()); + uint16_t msgSize = static_cast<uint16_t>(arg.size()); + + strcpy( ( char* )Buffer, ( char* )msg ); + // We fill the buffer with numbers for the payload + for(int i = msgSize; i < BufferSize; i++ ) + { + Buffer[i] = i - msgSize; + } + sendCntr++; + + wait_ms( 10 ); + radio_->Send( Buffer, BufferSize ); + debug("%s\r\n", arg.c_str()); + return true; +} + +bool RadioContex::initReceive() +{ + radio_->Rx( RX_TIMEOUT_VALUE ); + return true; +} + +bool RadioContex::pool_rx() +{ + switch( State ) + { + case RX: + Buffer[BUFFER_SIZE-1] = 0; + State = LOWPOWER; + radio_->Rx( RX_TIMEOUT_VALUE ); +// Buffer[0] = 0; + return true; + case RX_TIMEOUT: + case RX_ERROR: + case IDLE: + radio_->Rx( RX_TIMEOUT_VALUE ); + State = LOWPOWER; + /* no break */ + case LOWPOWER: + break; + default: + State = LOWPOWER; + } + return false; +} + + +Radio& RadioContex::radio() +{ + return *radio_; +} + +RadioContex::~RadioContex () +{ + radio_->Reset(); + delete radio_; + thi = 0; + debug( "> Radio stop <\n\r" ); + // TODO Auto-generated destructor stub +} + +void RadioContex::StaticOnTxDone() +{ + thi->OnTxDone(); +} + +void RadioContex::StaticOnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) +{ + thi->OnRxDone(payload, size, rssi, snr); +} + +void RadioContex::StaticOnTxTimeout( void ) +{ + thi->OnTxTimeout(); +} + +void RadioContex::StaticOnRxTimeout( void ) +{ + thi->OnRxTimeout(); +} + +void RadioContex::StaticOnRxError( void ) +{ + thi->OnRxError(); +} + +void RadioContex::OnTxDone( void ) +{ + radio_->Sleep( ); + State = TX; + debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" ); +} + +void RadioContex::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 RadioContex::OnTxTimeout( void ) +{ + radio_->Sleep( ); + State = TX_TIMEOUT; + debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" ); +} + +void RadioContex::OnRxTimeout( void ) +{ + radio_->Sleep( ); + Buffer[ BufferSize ] = 0; + State = RX_TIMEOUT; + debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" ); +} + +void RadioContex::OnRxError( void ) +{ + radio_->Sleep( ); + State = RX_ERROR; + debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" ); +} +