Elmo Terminal provides functionality to test Lora radio and access SX1272 chip registers delivered with Elmo board. This firmware allows the user to control the LoRa radio parameters (eg. frequency, bandwidth, spreading factor etc.) by entering console commands via serial terminal. Application also contains "Ping-Pong" and data transmission functionalities.

Dependencies:   SX1272lib mbed

Fork of Elmo-Terminal by Michal Leksinski

Committer:
WGorniak
Date:
Thu Oct 01 13:13:08 2015 +0000
Revision:
6:453b018a9ba0
Parent:
4:2767f13b0a75
Child:
10:e4cbc7292f40
removed sstream from radiocontext

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WGorniak 2:8d8295a51f68 1 #include "assert.h"
WGorniak 2:8d8295a51f68 2
WGorniak 2:8d8295a51f68 3 #include "RadioContex.h"
WGorniak 2:8d8295a51f68 4 #include "Settings.h"
WGorniak 2:8d8295a51f68 5 #include "dbg.h"
WGorniak 2:8d8295a51f68 6
WGorniak 2:8d8295a51f68 7
WGorniak 2:8d8295a51f68 8 /* Set this flag to '1' to display debug messages on the console */
WGorniak 2:8d8295a51f68 9
WGorniak 2:8d8295a51f68 10 #define DEBUG_MESSAGE 0
WGorniak 2:8d8295a51f68 11 #define RX_TIMEOUT_VALUE 3500000 // in us
WGorniak 2:8d8295a51f68 12 #define BUFFER_SIZE 32 // Define the payload size here
WGorniak 2:8d8295a51f68 13
WGorniak 2:8d8295a51f68 14 // Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation
WGorniak 2:8d8295a51f68 15 #define USE_MODEM_LORA 1
WGorniak 2:8d8295a51f68 16 #define USE_MODEM_FSK !USE_MODEM_LORA
WGorniak 2:8d8295a51f68 17
WGorniak 2:8d8295a51f68 18 #if USE_MODEM_LORA == 1
WGorniak 2:8d8295a51f68 19
WGorniak 2:8d8295a51f68 20 #define LORA_FIX_LENGTH_PAYLOAD_ON false
WGorniak 2:8d8295a51f68 21 #define LORA_FHSS_ENABLED false
WGorniak 2:8d8295a51f68 22 #define LORA_NB_SYMB_HOP 4
WGorniak 2:8d8295a51f68 23 #define LORA_IQ_INVERSION_ON false
WGorniak 2:8d8295a51f68 24 #define LORA_CRC_ENABLED true
WGorniak 2:8d8295a51f68 25
WGorniak 2:8d8295a51f68 26 #elif USE_MODEM_FSK == 1
WGorniak 2:8d8295a51f68 27
WGorniak 2:8d8295a51f68 28 #define FSK_FDEV 25000 // Hz
WGorniak 2:8d8295a51f68 29 #define FSK_DATARATE 19200 // bps
WGorniak 2:8d8295a51f68 30 #define FSK_BANDWIDTH 50000 // Hz
WGorniak 2:8d8295a51f68 31 #define FSK_AFC_BANDWIDTH 83333 // Hz
WGorniak 2:8d8295a51f68 32 #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx
WGorniak 2:8d8295a51f68 33 #define FSK_FIX_LENGTH_PAYLOAD_ON false
WGorniak 2:8d8295a51f68 34 #define FSK_CRC_ENABLED true
WGorniak 2:8d8295a51f68 35
WGorniak 2:8d8295a51f68 36 #else
WGorniak 2:8d8295a51f68 37 #error "Please define a modem in the compiler options."
WGorniak 2:8d8295a51f68 38 #endif
WGorniak 2:8d8295a51f68 39
WGorniak 2:8d8295a51f68 40
WGorniak 2:8d8295a51f68 41 RadioContex* RadioContex::thi = 0;
WGorniak 2:8d8295a51f68 42
WGorniak 2:8d8295a51f68 43 const char* RadioContex::rx_error_msg = "rx_error";
WGorniak 2:8d8295a51f68 44 const char* RadioContex::rx_timeout_msg = "rx_timeout";
WGorniak 2:8d8295a51f68 45
WGorniak 2:8d8295a51f68 46
WGorniak 2:8d8295a51f68 47 RadioContex::RadioContex (Settings* settings)
WGorniak 2:8d8295a51f68 48 : radio_ (0)
WGorniak 2:8d8295a51f68 49 {
WGorniak 2:8d8295a51f68 50 assert(thi == 0);
WGorniak 2:8d8295a51f68 51 thi = this;
WGorniak 2:8d8295a51f68 52 BufferSize = BUFFER_SIZE;
WGorniak 2:8d8295a51f68 53 State = LOWPOWER;
WGorniak 2:8d8295a51f68 54
WGorniak 2:8d8295a51f68 55 sendCntr = 0;
WGorniak 2:8d8295a51f68 56
WGorniak 4:2767f13b0a75 57 radio_ = new SX1272BRD ( RadioContex::StaticOnTxDone, RadioContex::StaticOnTxTimeout, RadioContex::StaticOnRxDone,
WGorniak 2:8d8295a51f68 58 RadioContex::StaticOnRxTimeout, RadioContex::StaticOnRxError, NULL, NULL,
WGorniak 2:8d8295a51f68 59 RF_SPI_MOSI, RF_SPI_MISO, RF_SPI_SCK, RF_SPI_CS,
WGorniak 2:8d8295a51f68 60 RF_RESET, RF_DIO0, RF_DIO1, RF_DIO2, RF_DIO3, RF_DIO4, RF_DIO5,
WGorniak 2:8d8295a51f68 61 RF_RXTX_SW );
WGorniak 2:8d8295a51f68 62
WGorniak 2:8d8295a51f68 63 // verify the connection with the board
WGorniak 2:8d8295a51f68 64 while( radio_->Read( REG_VERSION ) == 0x00 )
WGorniak 2:8d8295a51f68 65 {
WGorniak 2:8d8295a51f68 66 debug( "Radio could not be detected!\n\r", NULL );
WGorniak 2:8d8295a51f68 67 wait( 1 );
WGorniak 2:8d8295a51f68 68 }
WGorniak 2:8d8295a51f68 69
WGorniak 2:8d8295a51f68 70 radio_->SetChannel( settings->aget("freq") * 1000 );
WGorniak 2:8d8295a51f68 71
WGorniak 2:8d8295a51f68 72 #if USE_MODEM_LORA == 1
WGorniak 2:8d8295a51f68 73
WGorniak 2:8d8295a51f68 74 debug_if( LORA_FHSS_ENABLED, "> Radio start LORA FHSS Mode < \n\r");
WGorniak 2:8d8295a51f68 75 debug_if( !LORA_FHSS_ENABLED, "> Radio start LORA Mode < \n\r");
WGorniak 2:8d8295a51f68 76
WGorniak 2:8d8295a51f68 77 radio_->SetTxConfig( MODEM_LORA, settings->aget("power") , 0, settings->aget("bandwidth"),
WGorniak 2:8d8295a51f68 78 settings->aget("dataRate"), settings->aget("codeRate"),
WGorniak 2:8d8295a51f68 79 settings->aget("preambleLen"), LORA_FIX_LENGTH_PAYLOAD_ON,
WGorniak 2:8d8295a51f68 80 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
WGorniak 2:8d8295a51f68 81 LORA_IQ_INVERSION_ON, 2000000, settings->aget("paBoost"));
WGorniak 2:8d8295a51f68 82
WGorniak 2:8d8295a51f68 83 radio_->SetRxConfig( MODEM_LORA, settings->aget("bandwidth"),
WGorniak 2:8d8295a51f68 84 settings->aget("dataRate"), settings->aget("codeRate"), 0, settings->aget("preambleLen"),
WGorniak 2:8d8295a51f68 85 settings->aget("symbTimeout"), LORA_FIX_LENGTH_PAYLOAD_ON, 0,
WGorniak 2:8d8295a51f68 86 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
WGorniak 2:8d8295a51f68 87 LORA_IQ_INVERSION_ON, true );
WGorniak 2:8d8295a51f68 88
WGorniak 2:8d8295a51f68 89 #elif USE_MODEM_FSK == 1
WGorniak 2:8d8295a51f68 90
WGorniak 2:8d8295a51f68 91 debug("\n\n\r > FSK Mode < \n\n\r");
WGorniak 2:8d8295a51f68 92 radio_->SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
WGorniak 2:8d8295a51f68 93 FSK_DATARATE, 0,
WGorniak 2:8d8295a51f68 94 FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
WGorniak 2:8d8295a51f68 95 FSK_CRC_ENABLED, 0, 0, 0, 2000000 );
WGorniak 2:8d8295a51f68 96
WGorniak 2:8d8295a51f68 97 radio_->SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
WGorniak 2:8d8295a51f68 98 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
WGorniak 2:8d8295a51f68 99 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
WGorniak 2:8d8295a51f68 100 0, 0, false, true );
WGorniak 2:8d8295a51f68 101
WGorniak 2:8d8295a51f68 102 #else
WGorniak 2:8d8295a51f68 103
WGorniak 2:8d8295a51f68 104 #error "Please define a modem in the compiler options."
WGorniak 2:8d8295a51f68 105
WGorniak 2:8d8295a51f68 106 #endif
WGorniak 2:8d8295a51f68 107
WGorniak 2:8d8295a51f68 108 }
WGorniak 2:8d8295a51f68 109
WGorniak 2:8d8295a51f68 110
WGorniak 2:8d8295a51f68 111 RadioContex::States_t RadioContex::getState() const
WGorniak 2:8d8295a51f68 112 {
WGorniak 2:8d8295a51f68 113 return State;
WGorniak 2:8d8295a51f68 114 }
WGorniak 2:8d8295a51f68 115
WGorniak 2:8d8295a51f68 116
WGorniak 2:8d8295a51f68 117 bool RadioContex::setState(States_t newState)
WGorniak 2:8d8295a51f68 118 {
WGorniak 2:8d8295a51f68 119 State = newState;
WGorniak 2:8d8295a51f68 120 return true;
WGorniak 2:8d8295a51f68 121 }
WGorniak 2:8d8295a51f68 122
WGorniak 6:453b018a9ba0 123 extern std::string to_string(const int32_t val);
WGorniak 2:8d8295a51f68 124
WGorniak 2:8d8295a51f68 125 bool RadioContex::Send(std::string arg)
WGorniak 2:8d8295a51f68 126 {
WGorniak 6:453b018a9ba0 127 std::string ss(" ");
WGorniak 6:453b018a9ba0 128 ss.append(to_string(sendCntr));
WGorniak 6:453b018a9ba0 129 arg.append(ss);
WGorniak 2:8d8295a51f68 130
WGorniak 2:8d8295a51f68 131 const uint8_t* msg = (const unsigned char *)(arg.c_str());
WGorniak 2:8d8295a51f68 132 uint16_t msgSize = static_cast<uint16_t>(arg.size());
WGorniak 2:8d8295a51f68 133
WGorniak 2:8d8295a51f68 134 strcpy( ( char* )Buffer, ( char* )msg );
WGorniak 2:8d8295a51f68 135 // We fill the buffer with numbers for the payload
WGorniak 2:8d8295a51f68 136 for(int i = msgSize; i < BufferSize; i++ )
WGorniak 2:8d8295a51f68 137 {
WGorniak 2:8d8295a51f68 138 Buffer[i] = i - msgSize;
WGorniak 2:8d8295a51f68 139 }
WGorniak 2:8d8295a51f68 140 sendCntr++;
WGorniak 2:8d8295a51f68 141
WGorniak 2:8d8295a51f68 142 wait_ms( 10 );
WGorniak 2:8d8295a51f68 143 radio_->Send( Buffer, BufferSize );
WGorniak 2:8d8295a51f68 144 debug("%s\r\n", arg.c_str());
WGorniak 2:8d8295a51f68 145 return true;
WGorniak 2:8d8295a51f68 146 }
WGorniak 2:8d8295a51f68 147
WGorniak 2:8d8295a51f68 148 bool RadioContex::initReceive()
WGorniak 2:8d8295a51f68 149 {
WGorniak 2:8d8295a51f68 150 radio_->Rx( RX_TIMEOUT_VALUE );
WGorniak 2:8d8295a51f68 151 return true;
WGorniak 2:8d8295a51f68 152 }
WGorniak 2:8d8295a51f68 153
WGorniak 2:8d8295a51f68 154 bool RadioContex::pool_rx()
WGorniak 2:8d8295a51f68 155 {
WGorniak 2:8d8295a51f68 156 switch( State )
WGorniak 2:8d8295a51f68 157 {
WGorniak 2:8d8295a51f68 158 case RX:
WGorniak 2:8d8295a51f68 159 Buffer[BUFFER_SIZE-1] = 0;
WGorniak 2:8d8295a51f68 160 State = LOWPOWER;
WGorniak 2:8d8295a51f68 161 radio_->Rx( RX_TIMEOUT_VALUE );
WGorniak 2:8d8295a51f68 162 // Buffer[0] = 0;
WGorniak 2:8d8295a51f68 163 return true;
WGorniak 2:8d8295a51f68 164 case RX_TIMEOUT:
WGorniak 2:8d8295a51f68 165 case RX_ERROR:
WGorniak 2:8d8295a51f68 166 case IDLE:
WGorniak 2:8d8295a51f68 167 radio_->Rx( RX_TIMEOUT_VALUE );
WGorniak 2:8d8295a51f68 168 State = LOWPOWER;
WGorniak 2:8d8295a51f68 169 /* no break */
WGorniak 2:8d8295a51f68 170 case LOWPOWER:
WGorniak 2:8d8295a51f68 171 break;
WGorniak 2:8d8295a51f68 172 default:
WGorniak 2:8d8295a51f68 173 State = LOWPOWER;
WGorniak 2:8d8295a51f68 174 }
WGorniak 2:8d8295a51f68 175 return false;
WGorniak 2:8d8295a51f68 176 }
WGorniak 2:8d8295a51f68 177
WGorniak 2:8d8295a51f68 178
WGorniak 2:8d8295a51f68 179 Radio& RadioContex::radio()
WGorniak 2:8d8295a51f68 180 {
WGorniak 2:8d8295a51f68 181 return *radio_;
WGorniak 2:8d8295a51f68 182 }
WGorniak 2:8d8295a51f68 183
WGorniak 2:8d8295a51f68 184 RadioContex::~RadioContex ()
WGorniak 2:8d8295a51f68 185 {
WGorniak 2:8d8295a51f68 186 radio_->Reset();
WGorniak 2:8d8295a51f68 187 delete radio_;
WGorniak 2:8d8295a51f68 188 thi = 0;
WGorniak 2:8d8295a51f68 189 debug( "> Radio stop <\n\r" );
WGorniak 2:8d8295a51f68 190 // TODO Auto-generated destructor stub
WGorniak 2:8d8295a51f68 191 }
WGorniak 2:8d8295a51f68 192
WGorniak 2:8d8295a51f68 193 void RadioContex::StaticOnTxDone()
WGorniak 2:8d8295a51f68 194 {
WGorniak 2:8d8295a51f68 195 thi->OnTxDone();
WGorniak 2:8d8295a51f68 196 }
WGorniak 2:8d8295a51f68 197
WGorniak 2:8d8295a51f68 198 void RadioContex::StaticOnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
WGorniak 2:8d8295a51f68 199 {
WGorniak 2:8d8295a51f68 200 thi->OnRxDone(payload, size, rssi, snr);
WGorniak 2:8d8295a51f68 201 }
WGorniak 2:8d8295a51f68 202
WGorniak 2:8d8295a51f68 203 void RadioContex::StaticOnTxTimeout( void )
WGorniak 2:8d8295a51f68 204 {
WGorniak 2:8d8295a51f68 205 thi->OnTxTimeout();
WGorniak 2:8d8295a51f68 206 }
WGorniak 2:8d8295a51f68 207
WGorniak 2:8d8295a51f68 208 void RadioContex::StaticOnRxTimeout( void )
WGorniak 2:8d8295a51f68 209 {
WGorniak 2:8d8295a51f68 210 thi->OnRxTimeout();
WGorniak 2:8d8295a51f68 211 }
WGorniak 2:8d8295a51f68 212
WGorniak 2:8d8295a51f68 213 void RadioContex::StaticOnRxError( void )
WGorniak 2:8d8295a51f68 214 {
WGorniak 2:8d8295a51f68 215 thi->OnRxError();
WGorniak 2:8d8295a51f68 216 }
WGorniak 2:8d8295a51f68 217
WGorniak 2:8d8295a51f68 218 void RadioContex::OnTxDone( void )
WGorniak 2:8d8295a51f68 219 {
WGorniak 2:8d8295a51f68 220 radio_->Sleep( );
WGorniak 2:8d8295a51f68 221 State = TX;
WGorniak 2:8d8295a51f68 222 debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" );
WGorniak 2:8d8295a51f68 223 }
WGorniak 2:8d8295a51f68 224
WGorniak 2:8d8295a51f68 225 void RadioContex::OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
WGorniak 2:8d8295a51f68 226 {
WGorniak 2:8d8295a51f68 227 radio_->Sleep( );
WGorniak 2:8d8295a51f68 228 BufferSize = size;
WGorniak 2:8d8295a51f68 229 memcpy( Buffer, payload, BufferSize );
WGorniak 2:8d8295a51f68 230 RssiValue = rssi;
WGorniak 2:8d8295a51f68 231 SnrValue = snr;
WGorniak 2:8d8295a51f68 232 State = RX;
WGorniak 2:8d8295a51f68 233 debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
WGorniak 2:8d8295a51f68 234 }
WGorniak 2:8d8295a51f68 235
WGorniak 2:8d8295a51f68 236 void RadioContex::OnTxTimeout( void )
WGorniak 2:8d8295a51f68 237 {
WGorniak 2:8d8295a51f68 238 radio_->Sleep( );
WGorniak 2:8d8295a51f68 239 State = TX_TIMEOUT;
WGorniak 2:8d8295a51f68 240 debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
WGorniak 2:8d8295a51f68 241 }
WGorniak 2:8d8295a51f68 242
WGorniak 2:8d8295a51f68 243 void RadioContex::OnRxTimeout( void )
WGorniak 2:8d8295a51f68 244 {
WGorniak 2:8d8295a51f68 245 radio_->Sleep( );
WGorniak 2:8d8295a51f68 246 Buffer[ BufferSize ] = 0;
WGorniak 2:8d8295a51f68 247 State = RX_TIMEOUT;
WGorniak 2:8d8295a51f68 248 debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
WGorniak 2:8d8295a51f68 249 }
WGorniak 2:8d8295a51f68 250
WGorniak 2:8d8295a51f68 251 void RadioContex::OnRxError( void )
WGorniak 2:8d8295a51f68 252 {
WGorniak 2:8d8295a51f68 253 radio_->Sleep( );
WGorniak 2:8d8295a51f68 254 State = RX_ERROR;
WGorniak 2:8d8295a51f68 255 debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
WGorniak 2:8d8295a51f68 256 }
WGorniak 2:8d8295a51f68 257