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

Committer:
WGorniak
Date:
Thu Oct 01 13:13:08 2015 +0000
Revision:
6:453b018a9ba0
Parent:
4:2767f13b0a75
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