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

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" );
+}
+