AT command firmware for MultiTech Dot devices.

Fork of mDot_AT_firmware by MultiTech

Dot Library Not Included!

Because these example programs can be used for both mDot and xDot devices, the LoRa stack is not included. The libmDot library should be imported if building for mDot devices. The libxDot library should be imported if building for xDot devices. The AT firmware was last tested with mbed-os-5.4.7. Using a version past mbed-os-5.4.7 will cause the build to fail. The library used with the AT firmware has to match the mbed-os version.

Dot Library Version 3 Updates

Dot Library versions 3.x.x require a channel plan to be injected into the stack. The Dot-Examples and Dot-AT-Firmware do this by defining a macro called "CHANNEL_PLAN" that controls the channel plan that will be used in the examples. Available channel plans will be in the Dot Library repository in the plans folder.

Revision 20 and earlier of Dot-Examples and revision 15 and earlier of Dot-AT-Firmware should be used with Dot Library versions prior to 3.0.0.

Fota Library

Th Fota Library must be added to compile for mDot 3.1.0 with Fota support. Latest dev libraries and 3.2.0 release will include Fota with libmDot/libxDot.

AT Firmware Description

This AT Firmware is what ships on mDot and xDot devices. It provides an AT command interface for using the mDot or xDot for LoRa communication.

AT command documentation can be found on Multitech.com.

The firmware changelog can be found here. The library changelog can be found here.

Dot Libraries

Dot Library Limitations

The commit messages in libmDot-mbed5 and libmDot-dev-mbed5 specify the version of the Dot library the commit contains and the version of mbed-os it was compiled against. We recommend building your application with the version of mbed-os specified in the commit message of the version of the Dot library you're using. This will ensure that you don't run into any runtime issues caused by differences in the mbed-os versions.

Stable and development libraries are available for both mDot and xDot platforms. The library chosen must match the target platform. Compiling for the mDot platform with the xDot library or vice versa will not succeed.

mDot Library

Development library for mDot.

libmDot-dev

Stable library for mDot.

libmDot

xDot Library

Development library for xDot.

libxDot-dev

Stable library for xDot.

libxDot

Committer:
Jason Reiss
Date:
Fri Aug 12 11:08:59 2022 -0500
Revision:
35:e17e00b8e022
Parent:
34:3b696c2b1e4b
Child:
36:b586cd6e91f3
Update AT Version to 4.1.5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Mike Fiore 1:e52ae6584f1c 1 #include "ctype.h"
Jason Reiss 27:5fafd3b26ac3 2 #include "CommandFactory.h"
Mike Fiore 1:e52ae6584f1c 3 #include "CommandTerminal.h"
Mike Fiore 1:e52ae6584f1c 4 #include "Command.h"
Mike Fiore 4:666017851052 5 #include "MTSLog.h"
jenkins@jenkinsdm1 16:d5cf2af81a6d 6 #include "ChannelPlan.h"
Mike Fiore 1:e52ae6584f1c 7 #include <cstdarg>
Mike Fiore 4:666017851052 8 #include <deque>
Jason Reiss 28:c222ca8383f4 9 #include "mts_at_version.h"
Jason Reiss 28:c222ca8383f4 10
Mike Fiore 14:f9a77400b622 11 #if defined(TARGET_XDOT_L151CC)
Mike Fiore 14:f9a77400b622 12 #include "xdot_low_power.h"
Mike Fiore 14:f9a77400b622 13 #endif
Mike Fiore 1:e52ae6584f1c 14
Mike Fiore 14:f9a77400b622 15 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 1:e52ae6584f1c 16 const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa XBee Module\r\n\n";
Mike Fiore 14:f9a77400b622 17 #else
Mike Fiore 14:f9a77400b622 18 const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa xDot Module\r\n\n";
Mike Fiore 14:f9a77400b622 19 #endif
Mike Fiore 1:e52ae6584f1c 20 const char CommandTerminal::helpline[] = "Enter '?' for help\r\n";
Mike Fiore 1:e52ae6584f1c 21
Mike Fiore 1:e52ae6584f1c 22 const char CommandTerminal::newline[] = "\r\n";
Mike Fiore 1:e52ae6584f1c 23
Mike Fiore 1:e52ae6584f1c 24 // Command error text...
Mike Fiore 1:e52ae6584f1c 25 const char CommandTerminal::command_error[] = "Command not found!\r\n";
Mike Fiore 1:e52ae6584f1c 26
Mike Fiore 1:e52ae6584f1c 27 // Response texts...
Mike Fiore 1:e52ae6584f1c 28 const char CommandTerminal::help[] = "\r\nHelp\r\n";
Mike Fiore 1:e52ae6584f1c 29 const char CommandTerminal::cmd_error[] = "Invalid command\r\n";
Mike Fiore 9:ff62b20f7000 30 const char CommandTerminal::connect[] = "\r\nCONNECT\r\n";
Mike Fiore 9:ff62b20f7000 31 const char CommandTerminal::no_carrier[] = "\r\nNO CARRIER\r\n";
Mike Fiore 1:e52ae6584f1c 32 const char CommandTerminal::done[] = "\r\nOK\r\n";
Mike Fiore 1:e52ae6584f1c 33 const char CommandTerminal::error[] = "\r\nERROR\r\n";
Mike Fiore 1:e52ae6584f1c 34
Mike Fiore 1:e52ae6584f1c 35 // Escape sequence...
Mike Fiore 1:e52ae6584f1c 36 const char CommandTerminal::escape_sequence[] = "+++";
Mike Fiore 1:e52ae6584f1c 37
Mike Fiore 9:ff62b20f7000 38 mts::ATSerial* CommandTerminal::_serialp = NULL;
Mike Fiore 14:f9a77400b622 39 mDot* CommandTerminal::_dot = NULL;
Mike Fiore 14:f9a77400b622 40
Mike Fiore 14:f9a77400b622 41 CommandTerminal::RadioEvent* CommandTerminal::_events = new RadioEvent();
Mike Fiore 9:ff62b20f7000 42
Mike Fiore 9:ff62b20f7000 43 static bool serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 44 static bool peer_to_peer = false;
Jason Reiss 27:5fafd3b26ac3 45 static bool command_processing = false;
Jason Reiss 27:5fafd3b26ac3 46 static bool urc_enabled = false;
Mike Fiore 1:e52ae6584f1c 47
Mike Fiore 14:f9a77400b622 48 std::string CommandTerminal::_errorMessage = "";
Mike Fiore 14:f9a77400b622 49
jenkins@jenkinsdm1 18:63f098f042b2 50 static uint8_t _battery_level = 0xFF;
jenkins@jenkinsdm1 18:63f098f042b2 51
Jason Reiss 23:4f0a981c0349 52 static uint8_t f_data[252]; //max payload 242 plus 10 bytes for format
Jason Reiss 23:4f0a981c0349 53 static uint32_t _rxAddress = 0;
Jason Reiss 28:c222ca8383f4 54 static uint32_t _rxFcnt = 0;
Jason Reiss 23:4f0a981c0349 55
Jason Reiss 27:5fafd3b26ac3 56 #if defined(TARGET_MTS_MDOT_F411RE)
Jason Reiss 27:5fafd3b26ac3 57 DigitalOut _packet_rx_pin(D12);
Jason Reiss 27:5fafd3b26ac3 58 DigitalOut _join_status_pin(A2);
Jason Reiss 27:5fafd3b26ac3 59 #else
Jason Reiss 27:5fafd3b26ac3 60 DigitalOut _packet_rx_pin(GPIO1);
Jason Reiss 27:5fafd3b26ac3 61 DigitalOut _join_status_pin(GPIO0);
Jason Reiss 27:5fafd3b26ac3 62 #endif
Jason Reiss 27:5fafd3b26ac3 63
Mike Fiore 14:f9a77400b622 64 void CommandTerminal::setErrorMessage(const char* message) {
Mike Fiore 14:f9a77400b622 65 _errorMessage.assign(message);
Mike Fiore 14:f9a77400b622 66 }
Mike Fiore 14:f9a77400b622 67
Mike Fiore 14:f9a77400b622 68 void CommandTerminal::setErrorMessage(const std::string& message) {
Mike Fiore 14:f9a77400b622 69 _errorMessage.assign(message);
Mike Fiore 1:e52ae6584f1c 70 }
Jason Reiss 23:4f0a981c0349 71
Mike Fiore 14:f9a77400b622 72 CommandTerminal::CommandTerminal(mts::ATSerial& serial) :
Mike Fiore 14:f9a77400b622 73 _serial(serial),
Mike Fiore 14:f9a77400b622 74 _mode(mDot::COMMAND_MODE),
Mike Fiore 14:f9a77400b622 75 _sleep_standby(true),
Mike Fiore 14:f9a77400b622 76 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 14:f9a77400b622 77 _xbee_on_sleep(XBEE_ON_SLEEP),
Mike Fiore 14:f9a77400b622 78 #else
Mike Fiore 14:f9a77400b622 79 _xbee_on_sleep(GPIO2),
Mike Fiore 14:f9a77400b622 80 #endif
Mike Fiore 14:f9a77400b622 81 _autoOTAEnabled(false)
Mike Fiore 14:f9a77400b622 82 {
Mike Fiore 14:f9a77400b622 83 _serialp = &serial;
Mike Fiore 14:f9a77400b622 84 }
Mike Fiore 14:f9a77400b622 85
Jason Reiss 28:c222ca8383f4 86 void free_mem() {
Jason Reiss 28:c222ca8383f4 87 // In order to get free mem within RTOS
Jason Reiss 28:c222ca8383f4 88 // we need to get the main thread's stack pointer
Jason Reiss 28:c222ca8383f4 89 // and subtract it with the top of the heap
Jason Reiss 28:c222ca8383f4 90 // ------+-------------------+ Last Address of RAM (INITIAL_SP)
Jason Reiss 28:c222ca8383f4 91 // | Scheduler Stack |
Jason Reiss 28:c222ca8383f4 92 // +-------------------+
Jason Reiss 28:c222ca8383f4 93 // | Main Thread Stack |
Jason Reiss 28:c222ca8383f4 94 // | | |
Jason Reiss 28:c222ca8383f4 95 // | v |
Jason Reiss 28:c222ca8383f4 96 // +-------------------+ <- bottom_of_stack/__get_MSP()
Jason Reiss 28:c222ca8383f4 97 // RAM | |
Jason Reiss 28:c222ca8383f4 98 // | Available RAM |
Jason Reiss 28:c222ca8383f4 99 // | |
Jason Reiss 28:c222ca8383f4 100 // +-------------------+ <- top_of_heap
Jason Reiss 28:c222ca8383f4 101 // | ^ |
Jason Reiss 28:c222ca8383f4 102 // | | |
Jason Reiss 28:c222ca8383f4 103 // | Heap |
Jason Reiss 28:c222ca8383f4 104 // +-------------------+ <- __end__ / HEAP_START (linker defined var)
Jason Reiss 28:c222ca8383f4 105 // | ZI |
Jason Reiss 28:c222ca8383f4 106 // +-------------------+
Jason Reiss 28:c222ca8383f4 107 // | ZI: Shell Stack |
Jason Reiss 28:c222ca8383f4 108 // +-------------------+
Jason Reiss 28:c222ca8383f4 109 // | ZI: Idle Stack |
Jason Reiss 28:c222ca8383f4 110 // +-------------------+
Jason Reiss 28:c222ca8383f4 111 // | ZI: Timer Stack |
Jason Reiss 28:c222ca8383f4 112 // +-------------------+
Jason Reiss 28:c222ca8383f4 113 // | RW |
Jason Reiss 28:c222ca8383f4 114 // ------+===================+ First Address of RAM
Jason Reiss 28:c222ca8383f4 115 // | |
Jason Reiss 28:c222ca8383f4 116 // Flash | |
Jason Reiss 28:c222ca8383f4 117 //
Jason Reiss 28:c222ca8383f4 118
Jason Reiss 28:c222ca8383f4 119 uint32_t bottom_of_stack = __get_MSP();
Jason Reiss 28:c222ca8383f4 120 char* top_of_heap = (char *) malloc(sizeof(char));
Jason Reiss 28:c222ca8383f4 121 uint32_t diff = bottom_of_stack - (uint32_t) top_of_heap;
Jason Reiss 28:c222ca8383f4 122
Jason Reiss 28:c222ca8383f4 123 free((void *) top_of_heap);
Jason Reiss 28:c222ca8383f4 124
Jason Reiss 28:c222ca8383f4 125 CommandTerminal::Serial()->writef("%lu bytes\r\n", diff);
Jason Reiss 28:c222ca8383f4 126 }
Jason Reiss 28:c222ca8383f4 127
Mike Fiore 14:f9a77400b622 128 void CommandTerminal::init() {
Mike Fiore 14:f9a77400b622 129 _dot->setEvents(_events);
Jason Reiss 34:3b696c2b1e4b 130 _serial.rxClear();
Jason Reiss 34:3b696c2b1e4b 131 _serial.txClear();
Mike Fiore 1:e52ae6584f1c 132 }
Mike Fiore 1:e52ae6584f1c 133
Jason Reiss 28:c222ca8383f4 134 #if MTS_CMD_TERM_VERBOSE
Mike Fiore 1:e52ae6584f1c 135 void CommandTerminal::printHelp() {
Mike Fiore 1:e52ae6584f1c 136 const char* name = NULL;
Mike Fiore 1:e52ae6584f1c 137 const char* text = NULL;
Mike Fiore 1:e52ae6584f1c 138 const char* desc = NULL;
Mike Fiore 1:e52ae6584f1c 139 const char* tab = "\t";
Mike Fiore 1:e52ae6584f1c 140
Mike Fiore 1:e52ae6584f1c 141 std::string header("Command");
Mike Fiore 1:e52ae6584f1c 142 header.append(tab);
Mike Fiore 1:e52ae6584f1c 143 header.append(tab);
Mike Fiore 1:e52ae6584f1c 144 header.append("Name");
Mike Fiore 1:e52ae6584f1c 145 header.append(tab);
Mike Fiore 1:e52ae6584f1c 146 header.append(tab);
Mike Fiore 1:e52ae6584f1c 147 header.append(tab);
Mike Fiore 1:e52ae6584f1c 148 header.append("Description");
Mike Fiore 1:e52ae6584f1c 149
Mike Fiore 1:e52ae6584f1c 150 write(newline);
Mike Fiore 1:e52ae6584f1c 151 write(header.c_str());
Mike Fiore 1:e52ae6584f1c 152 write(newline);
Mike Fiore 1:e52ae6584f1c 153 write(newline);
Mike Fiore 14:f9a77400b622 154
jenkins@jenkinsdm1 18:63f098f042b2 155 Command *cmd = NULL;
Jason Reiss 27:5fafd3b26ac3 156 for (int i = 0; i < CommandFactory::NUMBER_OF_CMDS; i++) {
Jason Reiss 27:5fafd3b26ac3 157 cmd = CommandFactory::Create(static_cast<CommandFactory::CmdId_t>(i));
jenkins@jenkinsdm1 18:63f098f042b2 158 name = cmd->name();
jenkins@jenkinsdm1 18:63f098f042b2 159 text = cmd->text();
jenkins@jenkinsdm1 18:63f098f042b2 160 desc = cmd->desc();
Mike Fiore 1:e52ae6584f1c 161 write(text);
Mike Fiore 1:e52ae6584f1c 162 if (strlen(text) < 8)
Mike Fiore 1:e52ae6584f1c 163 write(tab);
Mike Fiore 1:e52ae6584f1c 164 write(tab);
Mike Fiore 1:e52ae6584f1c 165 write(name);
Mike Fiore 1:e52ae6584f1c 166 if (strlen(name) < 8)
Mike Fiore 1:e52ae6584f1c 167 write(tab);
Mike Fiore 1:e52ae6584f1c 168 if (strlen(name) < 16)
Mike Fiore 1:e52ae6584f1c 169 write(tab);
Mike Fiore 1:e52ae6584f1c 170 write(tab);
Mike Fiore 1:e52ae6584f1c 171 write(desc);
Mike Fiore 1:e52ae6584f1c 172 write(newline);
jenkins@jenkinsdm1 18:63f098f042b2 173
jenkins@jenkinsdm1 18:63f098f042b2 174 delete cmd;
Mike Fiore 1:e52ae6584f1c 175 }
Mike Fiore 1:e52ae6584f1c 176
Mike Fiore 1:e52ae6584f1c 177 write(newline);
Mike Fiore 1:e52ae6584f1c 178 }
Jason Reiss 28:c222ca8383f4 179 #endif
Mike Fiore 1:e52ae6584f1c 180
Mike Fiore 1:e52ae6584f1c 181 bool CommandTerminal::writeable() {
Mike Fiore 14:f9a77400b622 182 return _serialp->writeable();
Mike Fiore 1:e52ae6584f1c 183 }
Mike Fiore 1:e52ae6584f1c 184
Mike Fiore 1:e52ae6584f1c 185 bool CommandTerminal::readable() {
Mike Fiore 14:f9a77400b622 186 return _serialp->readable();
Mike Fiore 1:e52ae6584f1c 187 }
Mike Fiore 1:e52ae6584f1c 188
Mike Fiore 1:e52ae6584f1c 189 char CommandTerminal::read() {
Mike Fiore 1:e52ae6584f1c 190 char ch;
Jason Reiss 28:c222ca8383f4 191 _serialp->read(ch);
Mike Fiore 1:e52ae6584f1c 192 return ch;
Mike Fiore 1:e52ae6584f1c 193 }
Mike Fiore 1:e52ae6584f1c 194
Mike Fiore 1:e52ae6584f1c 195 void CommandTerminal::write(const char* message) {
Mike Fiore 1:e52ae6584f1c 196 while (!writeable())
Mike Fiore 1:e52ae6584f1c 197 ;
Mike Fiore 14:f9a77400b622 198 _serialp->write(message, strlen(message));
Mike Fiore 1:e52ae6584f1c 199 }
Mike Fiore 1:e52ae6584f1c 200
Mike Fiore 1:e52ae6584f1c 201 void CommandTerminal::writef(const char* format, ...) {
Jason Reiss 34:3b696c2b1e4b 202 char buff[512];
Mike Fiore 1:e52ae6584f1c 203
Mike Fiore 1:e52ae6584f1c 204 va_list ap;
Mike Fiore 1:e52ae6584f1c 205 va_start(ap, format);
Mike Fiore 1:e52ae6584f1c 206 int size = vsnprintf(buff, 256, format, ap);
Mike Fiore 1:e52ae6584f1c 207 while (!writeable())
Mike Fiore 1:e52ae6584f1c 208 ;
Mike Fiore 14:f9a77400b622 209 _serialp->write(buff, size);
Mike Fiore 1:e52ae6584f1c 210 va_end(ap);
Mike Fiore 1:e52ae6584f1c 211 }
Mike Fiore 1:e52ae6584f1c 212
Mike Fiore 9:ff62b20f7000 213 void CommandTerminal::serialLoop() {
Mike Fiore 1:e52ae6584f1c 214 Timer serial_read_timer;
Mike Fiore 1:e52ae6584f1c 215 std::vector<uint8_t> serial_buffer;
Mike Fiore 9:ff62b20f7000 216 std::vector<uint8_t> data;
Jason Reiss 28:c222ca8383f4 217 std::chrono::milliseconds timeout(0);
Jason Reiss 28:c222ca8383f4 218 std::chrono::milliseconds elapsed_time_ms;
Mike Fiore 1:e52ae6584f1c 219
Mike Fiore 9:ff62b20f7000 220 serial_read_timer.start();
Mike Fiore 1:e52ae6584f1c 221
Mike Fiore 9:ff62b20f7000 222 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) {
Mike Fiore 9:ff62b20f7000 223 _xbee_on_sleep = GPIO_PIN_SET;
Mike Fiore 1:e52ae6584f1c 224
Jason Reiss 28:c222ca8383f4 225 timeout = std::chrono::milliseconds(_dot->getWakeDelay());
Jason Reiss 28:c222ca8383f4 226 elapsed_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(serial_read_timer.elapsed_time());
Mike Fiore 1:e52ae6584f1c 227
Mike Fiore 9:ff62b20f7000 228 // wait for timeout or start of serial data
Jason Reiss 28:c222ca8383f4 229 while (!readable() && elapsed_time_ms < timeout && !_serialp->escaped()) {
Jason Reiss 28:c222ca8383f4 230 ThisThread::sleep_for(2ms);
Jason Reiss 28:c222ca8383f4 231 elapsed_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(serial_read_timer.elapsed_time());
Mike Fiore 1:e52ae6584f1c 232 }
Mike Fiore 1:e52ae6584f1c 233 }
Mike Fiore 1:e52ae6584f1c 234
Mike Fiore 14:f9a77400b622 235 if (!readable() && _events->SendAck()) {
Mike Fiore 14:f9a77400b622 236 logDebug("SERIAL NOT READABLE and ACK REQUESTED");
Mike Fiore 14:f9a77400b622 237 goto L_SEND;
Mike Fiore 14:f9a77400b622 238 }
Mike Fiore 14:f9a77400b622 239
Mike Fiore 14:f9a77400b622 240 if (readable() && !_serialp->escaped()) {
Mike Fiore 6:e27eaad36a0c 241
Mike Fiore 6:e27eaad36a0c 242 serial_read_timer.reset();
Jason Reiss 28:c222ca8383f4 243 timeout = std::chrono::milliseconds(_dot->getWakeTimeout());
Jason Reiss 28:c222ca8383f4 244
Jason Reiss 28:c222ca8383f4 245 while (true) {
Jason Reiss 28:c222ca8383f4 246 elapsed_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(serial_read_timer.elapsed_time());
Jason Reiss 28:c222ca8383f4 247 if ((elapsed_time_ms >= timeout) ) {
Mike Fiore 9:ff62b20f7000 248
Jason Reiss 28:c222ca8383f4 249 break;
Jason Reiss 28:c222ca8383f4 250 }
Jason Reiss 28:c222ca8383f4 251 if (serial_buffer.size() >= _dot->getNextTxMaxSize()) {
Jason Reiss 28:c222ca8383f4 252 break;
Jason Reiss 28:c222ca8383f4 253 }
Jason Reiss 28:c222ca8383f4 254 if (_serialp->escaped()) {
Jason Reiss 28:c222ca8383f4 255 break;
Jason Reiss 28:c222ca8383f4 256 }
Jason Reiss 28:c222ca8383f4 257 if (readable()) {
Mike Fiore 1:e52ae6584f1c 258 serial_buffer.push_back(read());
Mike Fiore 1:e52ae6584f1c 259 serial_read_timer.reset();
Jason Reiss 28:c222ca8383f4 260 } else {
Jason Reiss 28:c222ca8383f4 261 ThisThread::sleep_for(5ms);
Mike Fiore 1:e52ae6584f1c 262 }
Mike Fiore 1:e52ae6584f1c 263 }
Mike Fiore 9:ff62b20f7000 264
Mike Fiore 1:e52ae6584f1c 265 serial_read_timer.stop(), serial_read_timer.reset();
Mike Fiore 1:e52ae6584f1c 266
Mike Fiore 1:e52ae6584f1c 267 if (!serial_buffer.empty()) {
Mike Fiore 9:ff62b20f7000 268 if (_dot->getStartUpMode() == mDot::SERIAL_MODE)
Mike Fiore 14:f9a77400b622 269 _xbee_on_sleep = GPIO_PIN_RESET;
Mike Fiore 9:ff62b20f7000 270
Mike Fiore 14:f9a77400b622 271 L_SEND:
Mike Fiore 9:ff62b20f7000 272 // wait for any duty cycle limit to expire
Mike Fiore 14:f9a77400b622 273 while (_dot->getNextTxMs() > 0 && !_serialp->escaped()) {
Jason Reiss 28:c222ca8383f4 274 ThisThread::sleep_for(10ms);
Mike Fiore 9:ff62b20f7000 275 }
Mike Fiore 9:ff62b20f7000 276
Mike Fiore 14:f9a77400b622 277 if (_dot->getIsIdle()) {
Mike Fiore 9:ff62b20f7000 278 logDebug("Received serial data, sending out radio.");
Jason Reiss 27:5fafd3b26ac3 279 if(_dot->getRxOutput() == mDot::EXTENDED || _dot->getRxOutput() == mDot::EXTENDED_HEX) {
Jason Reiss 23:4f0a981c0349 280 formatPacketSDSend(serial_buffer);
Jason Reiss 23:4f0a981c0349 281 }
Jason Reiss 28:c222ca8383f4 282
Mike Fiore 9:ff62b20f7000 283 if (_dot->send(serial_buffer, false) != mDot::MDOT_OK) {
Mike Fiore 9:ff62b20f7000 284 logDebug("Send failed.");
Mike Fiore 9:ff62b20f7000 285 // If the data should be tossed after send failure, clear buffer
Mike Fiore 9:ff62b20f7000 286 if (_dot->getSerialClearOnError()) {
Mike Fiore 9:ff62b20f7000 287 serial_buffer.clear();
Mike Fiore 9:ff62b20f7000 288 }
Mike Fiore 9:ff62b20f7000 289 } else {
Mike Fiore 1:e52ae6584f1c 290
Mike Fiore 9:ff62b20f7000 291 // wait for send to finish
Jason Reiss 27:5fafd3b26ac3 292 do {
Jason Reiss 28:c222ca8383f4 293 ThisThread::sleep_for(50ms);
Jason Reiss 27:5fafd3b26ac3 294 } while (!_dot->getIsIdle() && !_serialp->escaped());
Mike Fiore 9:ff62b20f7000 295
Mike Fiore 9:ff62b20f7000 296 // call recv to wait for any packet before sending again
Jason Reiss 23:4f0a981c0349 297 if (!_serialp->escaped()) {
Jason Reiss 23:4f0a981c0349 298 data.clear();
Mike Fiore 9:ff62b20f7000 299 _dot->recv(data);
Jason Reiss 23:4f0a981c0349 300 }
Mike Fiore 9:ff62b20f7000 301
Mike Fiore 9:ff62b20f7000 302 // Clear the serial buffer if send is success
Mike Fiore 9:ff62b20f7000 303 serial_buffer.clear();
Mike Fiore 14:f9a77400b622 304
Jason Reiss 27:5fafd3b26ac3 305 // In P2P and Class B & C mode pending data will be sent automatically without uplink
Jason Reiss 27:5fafd3b26ac3 306 if (peer_to_peer != true && _dot->getClass() == "A") {
Mike Fiore 14:f9a77400b622 307 if (_dot->getDataPending()) {
Mike Fiore 14:f9a77400b622 308 logDebug("Data is pending");
Mike Fiore 14:f9a77400b622 309 goto L_SEND;
Mike Fiore 14:f9a77400b622 310 }
Mike Fiore 14:f9a77400b622 311 if (_dot->getAckRequested()) {
Mike Fiore 14:f9a77400b622 312 logDebug("Ack requested");
Mike Fiore 14:f9a77400b622 313 goto L_SEND;
Mike Fiore 14:f9a77400b622 314 }
Jason Reiss 23:4f0a981c0349 315 if (_dot->hasMacCommands()) {
Jason Reiss 23:4f0a981c0349 316 logDebug("Pending MAC answers");
Jason Reiss 23:4f0a981c0349 317 goto L_SEND;
Jason Reiss 23:4f0a981c0349 318 }
Mike Fiore 14:f9a77400b622 319 }
Mike Fiore 9:ff62b20f7000 320 }
Mike Fiore 1:e52ae6584f1c 321 } else {
Mike Fiore 6:e27eaad36a0c 322 logDebug("Radio is busy, cannot send.\r\n");
Jason Reiss 28:c222ca8383f4 323 ThisThread::sleep_for(10ms);
Mike Fiore 1:e52ae6584f1c 324 }
Mike Fiore 1:e52ae6584f1c 325
Mike Fiore 1:e52ae6584f1c 326 } else {
Mike Fiore 6:e27eaad36a0c 327 logDebug("No data received from serial to send.\r\n");
Jason Reiss 34:3b696c2b1e4b 328 ThisThread::sleep_for(10ms);
Mike Fiore 1:e52ae6584f1c 329 }
Mike Fiore 9:ff62b20f7000 330 }
Mike Fiore 9:ff62b20f7000 331
Mike Fiore 14:f9a77400b622 332 if (!_serialp->readable() && _dot->getStartUpMode() == mDot::SERIAL_MODE && !_serialp->escaped()) {
Mike Fiore 14:f9a77400b622 333 sleep(true);
Mike Fiore 1:e52ae6584f1c 334 }
Mike Fiore 9:ff62b20f7000 335
Mike Fiore 14:f9a77400b622 336 if (_serialp->escaped()) {
Mike Fiore 14:f9a77400b622 337 _serialp->clearEscaped();
Mike Fiore 14:f9a77400b622 338 _serialp->rxClear();
Mike Fiore 9:ff62b20f7000 339 serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 340 _mode = mDot::COMMAND_MODE;
Mike Fiore 9:ff62b20f7000 341 logDebug("Exit Serial Mode");
Mike Fiore 9:ff62b20f7000 342 write(done);
Mike Fiore 9:ff62b20f7000 343 return;
Mike Fiore 9:ff62b20f7000 344 }
Mike Fiore 9:ff62b20f7000 345
Mike Fiore 9:ff62b20f7000 346 if (!_dot->getNetworkJoinStatus()) {
Mike Fiore 9:ff62b20f7000 347 serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 348 _mode = mDot::COMMAND_MODE;
Mike Fiore 9:ff62b20f7000 349 logDebug("Exit Serial Mode");
Mike Fiore 9:ff62b20f7000 350 write(no_carrier);
Mike Fiore 9:ff62b20f7000 351 return;
Mike Fiore 9:ff62b20f7000 352 }
Mike Fiore 1:e52ae6584f1c 353 }
Mike Fiore 1:e52ae6584f1c 354
Mike Fiore 1:e52ae6584f1c 355 bool CommandTerminal::autoJoinCheck() {
Mike Fiore 1:e52ae6584f1c 356
Mike Fiore 1:e52ae6584f1c 357 std::string escape_buffer;
Mike Fiore 1:e52ae6584f1c 358 int sleep = 1000;
Mike Fiore 1:e52ae6584f1c 359 Timer tmr;
Mike Fiore 9:ff62b20f7000 360 tmr.start();
Mike Fiore 1:e52ae6584f1c 361 int cnt = 0;
Mike Fiore 1:e52ae6584f1c 362
Mike Fiore 1:e52ae6584f1c 363 while (!_dot->getNetworkJoinStatus()) {
Mike Fiore 14:f9a77400b622 364 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 365 write("\r\nJoining network... ");
Mike Fiore 14:f9a77400b622 366 }
Mike Fiore 14:f9a77400b622 367 logInfo("Joining network... ");
Mike Fiore 1:e52ae6584f1c 368
Mike Fiore 9:ff62b20f7000 369 if (_dot->getNextTxMs() > 0) {
Mike Fiore 14:f9a77400b622 370 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 371 writef("\r\nWaiting %lu s before next join attempt\r\n", _dot->getNextTxMs() / 1000);
Mike Fiore 14:f9a77400b622 372 }
Mike Fiore 14:f9a77400b622 373 logInfo("Waiting %lu s before next join attempt", _dot->getNextTxMs() / 1000);
Mike Fiore 9:ff62b20f7000 374
Mike Fiore 9:ff62b20f7000 375 tmr.reset();
Mike Fiore 9:ff62b20f7000 376 while (_dot->getNextTxMs() > 0 && !_serial.escaped()) {
Mike Fiore 14:f9a77400b622 377 osDelay(20);
Mike Fiore 1:e52ae6584f1c 378 }
Mike Fiore 1:e52ae6584f1c 379 }
Mike Fiore 1:e52ae6584f1c 380
Mike Fiore 9:ff62b20f7000 381 if (!_serial.escaped() && _dot->joinNetworkOnce() == mDot::MDOT_OK) {
Mike Fiore 14:f9a77400b622 382 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 383 write("Network Joined\r\n");
Mike Fiore 14:f9a77400b622 384 write(done);
Mike Fiore 14:f9a77400b622 385 }
Mike Fiore 14:f9a77400b622 386 logInfo("Network Joined");
Mike Fiore 1:e52ae6584f1c 387 return false;
Mike Fiore 1:e52ae6584f1c 388 }
Mike Fiore 1:e52ae6584f1c 389
Mike Fiore 14:f9a77400b622 390 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 391 write("Network Join failed\r\n");
Mike Fiore 14:f9a77400b622 392 write(error);
Mike Fiore 14:f9a77400b622 393 }
Mike Fiore 14:f9a77400b622 394 logInfo("Network Join failed");
Mike Fiore 1:e52ae6584f1c 395
Mike Fiore 14:f9a77400b622 396 if (!_serial.escaped() && _dot->getFrequencySubBand() != 0 && _dot->getJoinRetries() > 0 && cnt++ > _dot->getJoinRetries()) {
Mike Fiore 1:e52ae6584f1c 397 cnt = 0;
Mike Fiore 1:e52ae6584f1c 398
jenkins@jenkinsdm1 16:d5cf2af81a6d 399 if (lora::ChannelPlan::IsPlanFixed(_dot->getFrequencyBand())) {
Mike Fiore 1:e52ae6584f1c 400 uint8_t band = ((_dot->getFrequencySubBand()) % 8) + 1;
Mike Fiore 9:ff62b20f7000 401 logWarning("Join retries exhausted, switching to sub band %u", band);
Mike Fiore 1:e52ae6584f1c 402 _dot->setFrequencySubBand(band);
Mike Fiore 1:e52ae6584f1c 403 }
Mike Fiore 1:e52ae6584f1c 404 }
Mike Fiore 1:e52ae6584f1c 405
Mike Fiore 1:e52ae6584f1c 406 tmr.reset();
Mike Fiore 9:ff62b20f7000 407 while (tmr.read_ms() < sleep && !_serial.escaped()) {
Mike Fiore 9:ff62b20f7000 408 osDelay(10);
Mike Fiore 1:e52ae6584f1c 409 }
Mike Fiore 1:e52ae6584f1c 410
Mike Fiore 9:ff62b20f7000 411 if (_serial.escaped()) {
Mike Fiore 9:ff62b20f7000 412 _serial.clearEscaped();
Mike Fiore 9:ff62b20f7000 413 serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 414 _mode = mDot::COMMAND_MODE;
Mike Fiore 14:f9a77400b622 415 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 416 write("Join Canceled\r\n");
Mike Fiore 14:f9a77400b622 417 write(done);
Mike Fiore 14:f9a77400b622 418 }
Mike Fiore 14:f9a77400b622 419 logInfo("Join Canceled\r\n");
Mike Fiore 9:ff62b20f7000 420 return true;
Mike Fiore 9:ff62b20f7000 421 }
Mike Fiore 1:e52ae6584f1c 422 }
Mike Fiore 1:e52ae6584f1c 423
Mike Fiore 1:e52ae6584f1c 424 return false;
Mike Fiore 1:e52ae6584f1c 425 }
Mike Fiore 1:e52ae6584f1c 426
Jason Reiss 28:c222ca8383f4 427 #define CMD_DEFS_COUNT (13)
Jason Reiss 28:c222ca8383f4 428 #define CMD_DEFS_VARIANT_SIZE (4)
Jason Reiss 28:c222ca8383f4 429 #define CMD_DEFS_LABEL_SIZE (7)
Jason Reiss 28:c222ca8383f4 430
Jason Reiss 28:c222ca8383f4 431 struct CommandDefinition {
Jason Reiss 28:c222ca8383f4 432 const char label[CMD_DEFS_LABEL_SIZE];
Jason Reiss 28:c222ca8383f4 433 const char var[CMD_DEFS_VARIANT_SIZE];
Jason Reiss 28:c222ca8383f4 434 uint8_t max_args;
Jason Reiss 28:c222ca8383f4 435 CommandFactory::CmdId_t id;
Jason Reiss 28:c222ca8383f4 436 };
Jason Reiss 28:c222ca8383f4 437
Jason Reiss 28:c222ca8383f4 438 // Table of commands handled locally
Jason Reiss 28:c222ca8383f4 439 static const CommandDefinition cmd_defs[CMD_DEFS_COUNT] = {
Jason Reiss 28:c222ca8383f4 440 {"", "", 0, CommandFactory::eAT},
Jason Reiss 28:c222ca8383f4 441 {"E", "?01", 0, CommandFactory::eATE},
Jason Reiss 28:c222ca8383f4 442 {"V", "?01", 0, CommandFactory::eATVERBOSE},
Jason Reiss 28:c222ca8383f4 443 {"&K", "?03", 0, CommandFactory::eATK},
Jason Reiss 28:c222ca8383f4 444 {"+URC", "?", 1, CommandFactory::eURC},
Jason Reiss 28:c222ca8383f4 445 {"+LW", "?", 0, CommandFactory::eLW},
Jason Reiss 28:c222ca8383f4 446 {"+SD", "?", 0, CommandFactory::eSD},
Jason Reiss 34:3b696c2b1e4b 447 {"&WP", "", 0, CommandFactory::eATWP},
Jason Reiss 28:c222ca8383f4 448 {"&W", "", 0, CommandFactory::eATW},
Jason Reiss 28:c222ca8383f4 449 {"+SS", "", 0, CommandFactory::eSS},
Jason Reiss 28:c222ca8383f4 450 {"+DP", "?", 0, CommandFactory::eDP},
Jason Reiss 28:c222ca8383f4 451 {"+SLEEP", "", 1, CommandFactory::eSLEEP},
Jason Reiss 28:c222ca8383f4 452 {"+MEM", "?", 0, CommandFactory::eMEM}
Jason Reiss 28:c222ca8383f4 453 };
Jason Reiss 28:c222ca8383f4 454
Jason Reiss 28:c222ca8383f4 455
Jason Reiss 28:c222ca8383f4 456
Mike Fiore 1:e52ae6584f1c 457 void CommandTerminal::start() {
Mike Fiore 1:e52ae6584f1c 458
Mike Fiore 1:e52ae6584f1c 459 char ch;
Mike Fiore 1:e52ae6584f1c 460 bool running = true;
Mike Fiore 1:e52ae6584f1c 461 bool echo = _dot->getEcho();
Mike Fiore 1:e52ae6584f1c 462 std::string command;
Mike Fiore 14:f9a77400b622 463 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 4:666017851052 464 std::deque<std::string> history;
Mike Fiore 4:666017851052 465 int history_index = -1;
Mike Fiore 14:f9a77400b622 466 #endif
Mike Fiore 1:e52ae6584f1c 467 std::vector<std::string> args;
Mike Fiore 9:ff62b20f7000 468 bool join_canceled = false;
Mike Fiore 1:e52ae6584f1c 469
Mike Fiore 14:f9a77400b622 470 _autoOTAEnabled = _dot->getJoinMode() == mDot::AUTO_OTA;
Mike Fiore 14:f9a77400b622 471
Jason Reiss 34:3b696c2b1e4b 472 if (_dot->getStartUpMode() == mDot::SERIAL_MODE || CommandTerminal::Dot()->getTestModeEnabled()) {
Mike Fiore 9:ff62b20f7000 473
Mike Fiore 9:ff62b20f7000 474 serial_data_mode = true;
Mike Fiore 9:ff62b20f7000 475 _mode = mDot::SERIAL_MODE;
Mike Fiore 1:e52ae6584f1c 476
Mike Fiore 1:e52ae6584f1c 477 std::string escape_buffer;
Mike Fiore 1:e52ae6584f1c 478 char ch;
Mike Fiore 1:e52ae6584f1c 479
Mike Fiore 9:ff62b20f7000 480 if (!_dot->getStandbyFlag()) {
Mike Fiore 9:ff62b20f7000 481 // wake up from power-on/reset
Mike Fiore 9:ff62b20f7000 482
Mike Fiore 9:ff62b20f7000 483 int escape_timeout = 1000;
Mike Fiore 9:ff62b20f7000 484 Timer tmr;
Mike Fiore 9:ff62b20f7000 485 Timer escape_tmr;
Mike Fiore 1:e52ae6584f1c 486
Mike Fiore 9:ff62b20f7000 487 // wait one second for possible escape by user pressing '+' key
Mike Fiore 9:ff62b20f7000 488 tmr.reset();
Mike Fiore 9:ff62b20f7000 489 tmr.start();
Mike Fiore 9:ff62b20f7000 490 escape_tmr.reset();
Mike Fiore 9:ff62b20f7000 491 escape_tmr.start();
Mike Fiore 9:ff62b20f7000 492 while (tmr.read_ms() < escape_timeout) {
Mike Fiore 9:ff62b20f7000 493 if (_serial.readable()) {
Mike Fiore 9:ff62b20f7000 494 _serial.read(&ch, 1);
Mike Fiore 9:ff62b20f7000 495 escape_buffer += ch;
Mike Fiore 9:ff62b20f7000 496 }
Mike Fiore 1:e52ae6584f1c 497
Mike Fiore 9:ff62b20f7000 498 if (escape_buffer.find("+") != std::string::npos) {
Mike Fiore 9:ff62b20f7000 499 logInfo("Escape detected");
Mike Fiore 9:ff62b20f7000 500 join_canceled = true;
Mike Fiore 9:ff62b20f7000 501 serial_data_mode = false;
Jason Reiss 34:3b696c2b1e4b 502 CommandTerminal::Dot()->setTestModeEnabled(false);
Mike Fiore 9:ff62b20f7000 503 _mode = mDot::COMMAND_MODE;
Mike Fiore 9:ff62b20f7000 504 command.clear();
Mike Fiore 9:ff62b20f7000 505 break;
Mike Fiore 9:ff62b20f7000 506 }
Mike Fiore 9:ff62b20f7000 507
Mike Fiore 9:ff62b20f7000 508 if (escape_tmr.read_ms() > escape_timeout)
Mike Fiore 9:ff62b20f7000 509 escape_buffer.clear();
Mike Fiore 9:ff62b20f7000 510
Mike Fiore 9:ff62b20f7000 511 osDelay(1);
Mike Fiore 1:e52ae6584f1c 512 }
Mike Fiore 1:e52ae6584f1c 513 }
Mike Fiore 1:e52ae6584f1c 514
Jason Reiss 34:3b696c2b1e4b 515 if (_dot->getTestModeEnabled()) {
Jason Reiss 34:3b696c2b1e4b 516 Fota::getInstance()->enable(false);
Jason Reiss 34:3b696c2b1e4b 517 }
Jason Reiss 34:3b696c2b1e4b 518
Jason Reiss 34:3b696c2b1e4b 519 if ((_mode == mDot::SERIAL_MODE || CommandTerminal::Dot()->getTestModeEnabled()) && !_dot->getNetworkJoinStatus() && _dot->getJoinMode() == mDot::OTA) {
Mike Fiore 9:ff62b20f7000 520 if (_dot->joinNetworkOnce() != mDot::MDOT_OK) {
Mike Fiore 9:ff62b20f7000 521 serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 522 _mode = mDot::COMMAND_MODE;
Mike Fiore 9:ff62b20f7000 523
Mike Fiore 9:ff62b20f7000 524 logWarning("Start Up Mode set to SERIAL_MODE, but join failed.");
Mike Fiore 9:ff62b20f7000 525 _serial.writef("Network Not Joined\r\n");
Mike Fiore 9:ff62b20f7000 526 _serial.writef(error);
Mike Fiore 9:ff62b20f7000 527 }
Mike Fiore 9:ff62b20f7000 528 }
Mike Fiore 1:e52ae6584f1c 529 }
Mike Fiore 1:e52ae6584f1c 530
Jason Reiss 34:3b696c2b1e4b 531 if (CommandTerminal::Dot()->getTestModeEnabled() && _dot->getNetworkJoinStatus()) {
Jason Reiss 34:3b696c2b1e4b 532 while (CommandTerminal::Dot()->getTestModeEnabled() && !_events->PacketReceived) {
Jason Reiss 34:3b696c2b1e4b 533 std::vector<uint8_t> data;
Jason Reiss 34:3b696c2b1e4b 534 CommandTerminal::Dot()->send(data, false);
Jason Reiss 34:3b696c2b1e4b 535 osDelay(5000);
Jason Reiss 34:3b696c2b1e4b 536 }
Jason Reiss 34:3b696c2b1e4b 537 }
Jason Reiss 34:3b696c2b1e4b 538
Mike Fiore 9:ff62b20f7000 539 if (_dot->getJoinMode() == mDot::PEER_TO_PEER) {
Mike Fiore 9:ff62b20f7000 540 peer_to_peer = true;
Jason Reiss 27:5fafd3b26ac3 541 Fota::getInstance()->enable(false);
Jason Reiss 27:5fafd3b26ac3 542 CommandTerminal::Dot()->clearMacCommands();
Jason Reiss 27:5fafd3b26ac3 543 CommandTerminal::Dot()->setTxDataRate(CommandTerminal::Dot()->getTxDataRate());
Mike Fiore 9:ff62b20f7000 544 } else {
Mike Fiore 9:ff62b20f7000 545 peer_to_peer = false;
Mike Fiore 9:ff62b20f7000 546 }
Mike Fiore 1:e52ae6584f1c 547 //Run terminal session
Mike Fiore 1:e52ae6584f1c 548 while (running) {
Jason Reiss 28:c222ca8383f4 549
Jason Reiss 34:3b696c2b1e4b 550 if (_events != NULL && CommandTerminal::Dot()->getTestModeEnabled() && !_serial.escaped()) {
Jason Reiss 34:3b696c2b1e4b 551 if (_dot->getNextTxMs() > 0) {
Jason Reiss 34:3b696c2b1e4b 552 osDelay(2000);
Jason Reiss 34:3b696c2b1e4b 553 } else if (!_dot->getNetworkJoinStatus() && _dot->getJoinMode() == mDot::OTA) {
Jason Reiss 34:3b696c2b1e4b 554 if (_dot->joinNetworkOnce() != mDot::MDOT_OK) {
Jason Reiss 34:3b696c2b1e4b 555 serial_data_mode = false;
Jason Reiss 34:3b696c2b1e4b 556 _mode = mDot::COMMAND_MODE;
Jason Reiss 34:3b696c2b1e4b 557
Jason Reiss 34:3b696c2b1e4b 558 logWarning("Start Up Mode set to SERIAL_MODE, but join failed.");
Jason Reiss 34:3b696c2b1e4b 559 _serial.writef("Network Not Joined\r\n");
Jason Reiss 34:3b696c2b1e4b 560 _serial.writef(error);
Jason Reiss 34:3b696c2b1e4b 561 }
Jason Reiss 34:3b696c2b1e4b 562 } else if (_events->PacketReceived) {
Jason Reiss 34:3b696c2b1e4b 563 _events->handleTestModePacket();
Jason Reiss 34:3b696c2b1e4b 564 _events->PacketReceived = false;
Jason Reiss 34:3b696c2b1e4b 565
Jason Reiss 34:3b696c2b1e4b 566 } else {
Jason Reiss 34:3b696c2b1e4b 567 while (CommandTerminal::Dot()->getTestModeEnabled() && !_events->PacketReceived && !_serial.escaped()) {
Jason Reiss 34:3b696c2b1e4b 568 std::vector<uint8_t> data;
Jason Reiss 34:3b696c2b1e4b 569 CommandTerminal::Dot()->send(data, false);
Jason Reiss 34:3b696c2b1e4b 570 osDelay(5000);
Jason Reiss 34:3b696c2b1e4b 571 }
Jason Reiss 34:3b696c2b1e4b 572 }
Jason Reiss 34:3b696c2b1e4b 573 continue;
Jason Reiss 28:c222ca8383f4 574 }
Jason Reiss 28:c222ca8383f4 575
Jason Reiss 28:c222ca8383f4 576 // wait for input to reduce at command idle current
Mike Fiore 9:ff62b20f7000 577 while (!readable() || _mode == mDot::SERIAL_MODE) {
Mike Fiore 14:f9a77400b622 578 if (!join_canceled && _autoOTAEnabled) {
Mike Fiore 9:ff62b20f7000 579 join_canceled = autoJoinCheck();
Mike Fiore 9:ff62b20f7000 580 if (join_canceled)
Mike Fiore 9:ff62b20f7000 581 command.clear();
Mike Fiore 9:ff62b20f7000 582 }
Mike Fiore 1:e52ae6584f1c 583
Mike Fiore 14:f9a77400b622 584 if (!_autoOTAEnabled || (!join_canceled && _autoOTAEnabled)) {
Mike Fiore 9:ff62b20f7000 585 switch (_mode) {
Mike Fiore 9:ff62b20f7000 586 case mDot::SERIAL_MODE:
Mike Fiore 9:ff62b20f7000 587 // signal wakeup, read serial and output to radio
Mike Fiore 9:ff62b20f7000 588 serialLoop();
Mike Fiore 9:ff62b20f7000 589 continue;
Mike Fiore 9:ff62b20f7000 590 break;
Mike Fiore 9:ff62b20f7000 591 default:
Mike Fiore 9:ff62b20f7000 592 break;
Mike Fiore 9:ff62b20f7000 593 }
Mike Fiore 1:e52ae6584f1c 594 }
Mike Fiore 9:ff62b20f7000 595
Mike Fiore 9:ff62b20f7000 596 ch = '\0';
Mike Fiore 1:e52ae6584f1c 597
Jason Reiss 27:5fafd3b26ac3 598 if (_mode != mDot::SERIAL_MODE) {
Jason Reiss 28:c222ca8383f4 599 ThisThread::sleep_for(10ms);
Jason Reiss 27:5fafd3b26ac3 600 }
Mike Fiore 9:ff62b20f7000 601 _serial.escaped();
Mike Fiore 9:ff62b20f7000 602 }
Mike Fiore 1:e52ae6584f1c 603
Mike Fiore 1:e52ae6584f1c 604 // read characters
Mike Fiore 1:e52ae6584f1c 605 if (readable()) {
Mike Fiore 1:e52ae6584f1c 606 ch = read();
Mike Fiore 1:e52ae6584f1c 607
Mike Fiore 4:666017851052 608 if (ch == '\b' || ch == 0x7f) {
Mike Fiore 1:e52ae6584f1c 609 if (!command.empty()) {
Mike Fiore 1:e52ae6584f1c 610 writef("\b \b");
Mike Fiore 1:e52ae6584f1c 611 command.erase(command.size() - 1);
Mike Fiore 1:e52ae6584f1c 612 }
Mike Fiore 1:e52ae6584f1c 613 continue;
Mike Fiore 4:666017851052 614 } else if (ch == 0x1b || ch == 0x09) {
Mike Fiore 4:666017851052 615 osDelay(20);
Mike Fiore 4:666017851052 616 // catch escape sequence, or tab
Mike Fiore 9:ff62b20f7000 617 char ch1 = 0x00, ch2 = 0x00;
Mike Fiore 4:666017851052 618
Mike Fiore 4:666017851052 619 if (readable()) {
Mike Fiore 4:666017851052 620 ch1 = read();
Mike Fiore 4:666017851052 621 if (readable())
Mike Fiore 4:666017851052 622 ch2 = read();
Mike Fiore 4:666017851052 623
Mike Fiore 14:f9a77400b622 624 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 4:666017851052 625 if (ch1 == 0x5b && ch2 == 0x41) {
Mike Fiore 4:666017851052 626 // up key
Mike Fiore 9:ff62b20f7000 627 for (size_t i = 0; i < command.size() + 1; i++) {
Mike Fiore 4:666017851052 628 writef("\b \b");
Mike Fiore 4:666017851052 629 }
Mike Fiore 4:666017851052 630 if (history.size() > 0) {
Mike Fiore 9:ff62b20f7000 631 if (++history_index >= int(history.size() - 1))
Mike Fiore 4:666017851052 632 history_index = history.size() - 1;
Mike Fiore 4:666017851052 633
Mike Fiore 4:666017851052 634 command = history[history_index];
Mike Fiore 4:666017851052 635 writef("%s", history[history_index].c_str());
Mike Fiore 4:666017851052 636 } else {
Mike Fiore 4:666017851052 637 command.clear();
Mike Fiore 4:666017851052 638 }
Mike Fiore 4:666017851052 639 } else if (ch1 == 0x5b && ch2 == 0x42) {
Mike Fiore 4:666017851052 640
Mike Fiore 4:666017851052 641 // down key
Mike Fiore 9:ff62b20f7000 642 for (size_t i = 0; i < command.size() + 1; i++) {
Mike Fiore 4:666017851052 643 writef("\b \b");
Mike Fiore 4:666017851052 644 }
Mike Fiore 4:666017851052 645
Mike Fiore 4:666017851052 646 if (--history_index < 0) {
Mike Fiore 4:666017851052 647 history_index = -1;
Mike Fiore 4:666017851052 648 command.clear();
Mike Fiore 4:666017851052 649 } else {
Mike Fiore 4:666017851052 650 command = history[history_index];
Mike Fiore 4:666017851052 651 writef("%s", history[history_index].c_str());
Mike Fiore 4:666017851052 652 }
Mike Fiore 4:666017851052 653 }
Mike Fiore 14:f9a77400b622 654 #endif
Mike Fiore 4:666017851052 655 }
Mike Fiore 9:ff62b20f7000 656 while (readable())
Mike Fiore 9:ff62b20f7000 657 read();
Mike Fiore 4:666017851052 658 continue;
Mike Fiore 1:e52ae6584f1c 659 } else {
Mike Fiore 1:e52ae6584f1c 660 command += ch;
Mike Fiore 1:e52ae6584f1c 661 }
Mike Fiore 1:e52ae6584f1c 662
Mike Fiore 1:e52ae6584f1c 663 // echo chars if enabled
Mike Fiore 1:e52ae6584f1c 664 if (echo && !(ch == '\r' || ch == '\n'))
Mike Fiore 1:e52ae6584f1c 665 writef("%c", ch);
Mike Fiore 1:e52ae6584f1c 666 }
Mike Fiore 1:e52ae6584f1c 667
Mike Fiore 1:e52ae6584f1c 668 // look for end of command line
Mike Fiore 1:e52ae6584f1c 669 if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 670 // remove new line or cr character
Mike Fiore 1:e52ae6584f1c 671 command.erase(command.size() - 1);
Mike Fiore 1:e52ae6584f1c 672 write("\r"); // match standard modem output
Mike Fiore 1:e52ae6584f1c 673 write(newline);
Mike Fiore 1:e52ae6584f1c 674 } else {
Mike Fiore 1:e52ae6584f1c 675 continue;
Mike Fiore 1:e52ae6584f1c 676 }
Mike Fiore 1:e52ae6584f1c 677
Mike Fiore 1:e52ae6584f1c 678 // trim whitespace from command
Mike Fiore 1:e52ae6584f1c 679 mts::Text::trim(command, "\r\n\t ");
Mike Fiore 1:e52ae6584f1c 680
Mike Fiore 1:e52ae6584f1c 681 if (command.size() < 1) {
Mike Fiore 1:e52ae6584f1c 682 command.clear();
Mike Fiore 1:e52ae6584f1c 683 continue;
Mike Fiore 1:e52ae6584f1c 684 }
Mike Fiore 1:e52ae6584f1c 685
Jason Reiss 27:5fafd3b26ac3 686 _packet_rx_pin = 0;
Jason Reiss 27:5fafd3b26ac3 687 command_processing = true;
Jason Reiss 27:5fafd3b26ac3 688
Mike Fiore 1:e52ae6584f1c 689 // parse command and args
Mike Fiore 1:e52ae6584f1c 690 args.clear();
Mike Fiore 1:e52ae6584f1c 691
Mike Fiore 1:e52ae6584f1c 692 // find first '=' character
Mike Fiore 1:e52ae6584f1c 693 size_t delim_index = command.find("=");
Mike Fiore 1:e52ae6584f1c 694 if (delim_index != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 695 args.push_back(command.substr(0, delim_index));
Mike Fiore 1:e52ae6584f1c 696 } else {
Mike Fiore 1:e52ae6584f1c 697 // find first ' ' character
Mike Fiore 1:e52ae6584f1c 698 delim_index = command.find(" ");
Mike Fiore 1:e52ae6584f1c 699 if (delim_index != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 700 args.push_back(command.substr(0, delim_index));
Mike Fiore 1:e52ae6584f1c 701 } else {
Mike Fiore 1:e52ae6584f1c 702 args.push_back(command);
Mike Fiore 1:e52ae6584f1c 703 }
Mike Fiore 1:e52ae6584f1c 704 }
Mike Fiore 1:e52ae6584f1c 705
Mike Fiore 1:e52ae6584f1c 706 if (delim_index != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 707 std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ",");
Mike Fiore 1:e52ae6584f1c 708 args.insert(args.end(), params.begin(), params.end());
Mike Fiore 1:e52ae6584f1c 709 }
Mike Fiore 1:e52ae6584f1c 710
Mike Fiore 1:e52ae6584f1c 711 args[0] = mts::Text::toUpper(args[0]);
Jason Reiss 28:c222ca8383f4 712 bool handled = false;
Mike Fiore 1:e52ae6584f1c 713
Mike Fiore 1:e52ae6584f1c 714 // print help
Mike Fiore 1:e52ae6584f1c 715 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) {
Jason Reiss 28:c222ca8383f4 716 #if MTS_CMD_TERM_VERBOSE
Mike Fiore 1:e52ae6584f1c 717 printHelp();
Jason Reiss 28:c222ca8383f4 718 #endif
Mike Fiore 1:e52ae6584f1c 719 command.clear();
Jason Reiss 28:c222ca8383f4 720 handled = true;
Jason Reiss 28:c222ca8383f4 721 } else if (args[0].find("AT") == 0) {
Jason Reiss 28:c222ca8383f4 722 const CommandDefinition* def = NULL; // Command to handle if matched
Jason Reiss 28:c222ca8383f4 723 char variant = '\0'; // Variant character
Jason Reiss 28:c222ca8383f4 724 for (int d = 0; (d < CMD_DEFS_COUNT) && (def == NULL); ++d) {
Jason Reiss 28:c222ca8383f4 725 size_t label_size = 2 + strlen(cmd_defs[d].label);
Jason Reiss 28:c222ca8383f4 726 if (args[0].find(cmd_defs[d].label) == 2) {
Jason Reiss 28:c222ca8383f4 727 // Label found following "AT"
Jason Reiss 28:c222ca8383f4 728 for (int v = 0; v < CMD_DEFS_VARIANT_SIZE; ++v) {
Jason Reiss 28:c222ca8383f4 729 if ((args[0][label_size] == cmd_defs[d].var[v]) &&
Jason Reiss 28:c222ca8383f4 730 (args[0][label_size] == '\0' || args[0][label_size + 1] == '\0')) {
Jason Reiss 28:c222ca8383f4 731 // Check for variant characters following label, this includes a NULL
Jason Reiss 28:c222ca8383f4 732 def = &cmd_defs[d];
Jason Reiss 28:c222ca8383f4 733 variant = cmd_defs[d].var[v];
Jason Reiss 28:c222ca8383f4 734 break;
Jason Reiss 28:c222ca8383f4 735 }
Mike Fiore 14:f9a77400b622 736 }
Mike Fiore 4:666017851052 737 }
Mike Fiore 4:666017851052 738 }
Jason Reiss 28:c222ca8383f4 739 if (def != NULL) {
Jason Reiss 28:c222ca8383f4 740 handled = true;
Jason Reiss 28:c222ca8383f4 741 if (args.size() == 2 && args[1].length() == 1 && args[1][0] == '?') {
Jason Reiss 28:c222ca8383f4 742 handled = false;
Jason Reiss 28:c222ca8383f4 743 } else if (args.size() - 1 > def->max_args) {
Jason Reiss 28:c222ca8383f4 744 #if MTS_CMD_TERM_VERBOSE
Jason Reiss 28:c222ca8383f4 745 write("Invalid argument\r\n");
Jason Reiss 28:c222ca8383f4 746 #endif
Jason Reiss 28:c222ca8383f4 747 write(error);
Jason Reiss 28:c222ca8383f4 748 } else {
Jason Reiss 28:c222ca8383f4 749 switch (def->id) {
Jason Reiss 28:c222ca8383f4 750 case CommandFactory::eAT:
Jason Reiss 28:c222ca8383f4 751 write(done);
Jason Reiss 28:c222ca8383f4 752 break;
Jason Reiss 28:c222ca8383f4 753 case CommandFactory::eATE:
Jason Reiss 28:c222ca8383f4 754 if (variant == '1' || variant == '0') {
Jason Reiss 28:c222ca8383f4 755 _dot->setEcho(variant == '1');
Jason Reiss 28:c222ca8383f4 756 echo = _dot->getEcho();
Jason Reiss 28:c222ca8383f4 757 } else {
Jason Reiss 28:c222ca8383f4 758 writef("%d\r\n", _dot->getEcho());
Jason Reiss 28:c222ca8383f4 759 }
Jason Reiss 28:c222ca8383f4 760 write(done);
Jason Reiss 28:c222ca8383f4 761 break;
Jason Reiss 28:c222ca8383f4 762 case CommandFactory::eATVERBOSE:
Jason Reiss 28:c222ca8383f4 763 if (variant == '1' || variant == '0') {
Jason Reiss 28:c222ca8383f4 764 _dot->setVerbose(variant == '1');
Jason Reiss 28:c222ca8383f4 765 } else {
Jason Reiss 28:c222ca8383f4 766 writef("%d\r\n", _dot->getVerbose());
Jason Reiss 28:c222ca8383f4 767 }
Jason Reiss 28:c222ca8383f4 768 write(done);
Jason Reiss 28:c222ca8383f4 769 break;
Jason Reiss 28:c222ca8383f4 770 case CommandFactory::eATK:
Jason Reiss 28:c222ca8383f4 771 if (variant == '3' || variant == '0') {
Jason Reiss 28:c222ca8383f4 772 _dot->setFlowControl(variant == '3');
Jason Reiss 28:c222ca8383f4 773 } else {
Jason Reiss 28:c222ca8383f4 774 writef("%d\r\n", (_dot->getFlowControl() ? 3 : 0));
Jason Reiss 28:c222ca8383f4 775 }
Jason Reiss 28:c222ca8383f4 776 write(done);
Jason Reiss 28:c222ca8383f4 777 break;
Jason Reiss 28:c222ca8383f4 778 case CommandFactory::eURC:
Jason Reiss 28:c222ca8383f4 779 if (args.size() == 1) {
Jason Reiss 28:c222ca8383f4 780 writef("%d\r\n", urc_enabled);
Jason Reiss 28:c222ca8383f4 781 write(done);
Jason Reiss 28:c222ca8383f4 782 } else if (args[1].length() == 1) {
Jason Reiss 28:c222ca8383f4 783 if (args[1][0] != '?' && args[1][0] != '0' && args[1][0] != '1') {
Jason Reiss 28:c222ca8383f4 784 #if MTS_CMD_TERM_VERBOSE
Jason Reiss 28:c222ca8383f4 785 write("Invalid argument\r\n");
Jason Reiss 28:c222ca8383f4 786 #endif
Jason Reiss 28:c222ca8383f4 787 write(error);
Jason Reiss 28:c222ca8383f4 788 } else if (args[1][0] == '?') {
Jason Reiss 28:c222ca8383f4 789 #if MTS_CMD_TERM_VERBOSE
Jason Reiss 28:c222ca8383f4 790 write("(0:disable,1:enable)\r\n");
Jason Reiss 28:c222ca8383f4 791 write(done);
Jason Reiss 28:c222ca8383f4 792 #else
Jason Reiss 28:c222ca8383f4 793 write(error);
Jason Reiss 28:c222ca8383f4 794 #endif
Jason Reiss 28:c222ca8383f4 795 } else {
Jason Reiss 28:c222ca8383f4 796 urc_enabled = (args[1][0] == '1');
Jason Reiss 28:c222ca8383f4 797 write(done);
Jason Reiss 28:c222ca8383f4 798 }
Jason Reiss 28:c222ca8383f4 799 } else {
Jason Reiss 28:c222ca8383f4 800 write(error);
Jason Reiss 28:c222ca8383f4 801 }
Jason Reiss 28:c222ca8383f4 802 break;
Jason Reiss 28:c222ca8383f4 803 case CommandFactory::eLW:
Jason Reiss 28:c222ca8383f4 804 writef("%s\r\n", _dot->getMACVersion());
Jason Reiss 28:c222ca8383f4 805 write(done);
Jason Reiss 28:c222ca8383f4 806 break;
Jason Reiss 28:c222ca8383f4 807 case CommandFactory::eMEM:
Jason Reiss 28:c222ca8383f4 808 free_mem();
Jason Reiss 28:c222ca8383f4 809 write(done);
Jason Reiss 28:c222ca8383f4 810 break;
Jason Reiss 28:c222ca8383f4 811 case CommandFactory::eSD:
Jason Reiss 28:c222ca8383f4 812 if (_dot->getNetworkJoinStatus()) {
Jason Reiss 28:c222ca8383f4 813 logDebug("Enter Serial Mode");
Jason Reiss 28:c222ca8383f4 814 write(connect);
Jason Reiss 28:c222ca8383f4 815 serial_data_mode = true;
Jason Reiss 28:c222ca8383f4 816 _serialp->clearEscaped();
Jason Reiss 28:c222ca8383f4 817 _mode = mDot::SERIAL_MODE;
Jason Reiss 28:c222ca8383f4 818 } else {
Jason Reiss 28:c222ca8383f4 819 logDebug("Network Not Joined");
Jason Reiss 28:c222ca8383f4 820 write("Network Not Joined\r\n");
Jason Reiss 28:c222ca8383f4 821 write(error);
Jason Reiss 28:c222ca8383f4 822 }
Jason Reiss 28:c222ca8383f4 823 break;
Jason Reiss 28:c222ca8383f4 824 case CommandFactory::eATW:
Jason Reiss 28:c222ca8383f4 825 if (!_dot->saveConfig()) {
Jason Reiss 28:c222ca8383f4 826 #if MTS_CMD_TERM_VERBOSE
Jason Reiss 28:c222ca8383f4 827 write("Failed to save to flash");
Jason Reiss 28:c222ca8383f4 828 #endif
Jason Reiss 28:c222ca8383f4 829 write(error);
Jason Reiss 28:c222ca8383f4 830 } else {
Jason Reiss 28:c222ca8383f4 831 write(done);
Jason Reiss 28:c222ca8383f4 832 }
Jason Reiss 28:c222ca8383f4 833 break;
Jason Reiss 28:c222ca8383f4 834 case CommandFactory::eATWP:
Jason Reiss 28:c222ca8383f4 835 if (!_dot->saveProtectedConfig()) {
Jason Reiss 28:c222ca8383f4 836 #if MTS_CMD_TERM_VERBOSE
Jason Reiss 28:c222ca8383f4 837 write("Failed to save to flash");
Jason Reiss 28:c222ca8383f4 838 #endif
Jason Reiss 28:c222ca8383f4 839 write(error);
Jason Reiss 28:c222ca8383f4 840 } else {
Jason Reiss 28:c222ca8383f4 841 write(done);
Jason Reiss 28:c222ca8383f4 842 }
Jason Reiss 28:c222ca8383f4 843 break;
Jason Reiss 28:c222ca8383f4 844 case CommandFactory::eSS:
Jason Reiss 28:c222ca8383f4 845 _dot->saveNetworkSession();
Jason Reiss 28:c222ca8383f4 846 write(done);
Jason Reiss 28:c222ca8383f4 847 break;
Jason Reiss 28:c222ca8383f4 848 case CommandFactory::eDP:
Jason Reiss 34:3b696c2b1e4b 849 writef("%d\r\n",
Jason Reiss 34:3b696c2b1e4b 850 _dot->getDataPending() ||
Jason Reiss 34:3b696c2b1e4b 851 _dot->hasMacCommands() ||
Jason Reiss 34:3b696c2b1e4b 852 _dot->getAckRequested());
Jason Reiss 28:c222ca8383f4 853 write(done);
Jason Reiss 28:c222ca8383f4 854 break;
Jason Reiss 28:c222ca8383f4 855 case CommandFactory::eSLEEP: {
Jason Reiss 28:c222ca8383f4 856 bool temp_sleep_standby;
Jason Reiss 28:c222ca8383f4 857 bool valid = false;
Jason Reiss 28:c222ca8383f4 858 if ((args.size() > 1) && (args[1].length() == 1)) {
Jason Reiss 28:c222ca8383f4 859 if ((args[1][0] != '?' && args[1][0] != '0' && args[1][0] != '1')) {
Jason Reiss 28:c222ca8383f4 860 #if MTS_CMD_TERM_VERBOSE
Jason Reiss 28:c222ca8383f4 861 write("Invalid argument\r\n");
Jason Reiss 28:c222ca8383f4 862 #endif
Jason Reiss 28:c222ca8383f4 863 write(error);
Jason Reiss 28:c222ca8383f4 864 } else if (args[1][0] == '?') {
Jason Reiss 28:c222ca8383f4 865 #if MTS_CMD_TERM_VERBOSE
Jason Reiss 28:c222ca8383f4 866 write("(0:deepsleep,1:sleep)\r\n");
Jason Reiss 28:c222ca8383f4 867 write(done);
Jason Reiss 28:c222ca8383f4 868 #else
Jason Reiss 28:c222ca8383f4 869 write(error);
Jason Reiss 28:c222ca8383f4 870 #endif
Jason Reiss 28:c222ca8383f4 871 } else {
Jason Reiss 28:c222ca8383f4 872 valid = true;
Jason Reiss 28:c222ca8383f4 873 temp_sleep_standby = (args[1][0] == '0');
Jason Reiss 28:c222ca8383f4 874 }
Jason Reiss 28:c222ca8383f4 875 } else if (args.size() == 1) {
Jason Reiss 28:c222ca8383f4 876 valid = true;
Jason Reiss 28:c222ca8383f4 877 temp_sleep_standby = _sleep_standby;
Jason Reiss 28:c222ca8383f4 878 } else {
Jason Reiss 28:c222ca8383f4 879 write(error);
Jason Reiss 28:c222ca8383f4 880 }
Jason Reiss 28:c222ca8383f4 881
Jason Reiss 28:c222ca8383f4 882 if (valid) {
Jason Reiss 28:c222ca8383f4 883 if (!_dot->getIsIdle()) {
Jason Reiss 28:c222ca8383f4 884 write("Dot is not idle\r\n");
Jason Reiss 28:c222ca8383f4 885 write(error);
Jason Reiss 28:c222ca8383f4 886 } else {
Jason Reiss 28:c222ca8383f4 887 _sleep_standby = temp_sleep_standby;
Jason Reiss 28:c222ca8383f4 888 #if defined(TARGET_MTS_MDOT_F411RE)
Jason Reiss 28:c222ca8383f4 889 //Read the board ID. If all 0's, it is revision B. This hardware does not support deep sleep.
Jason Reiss 28:c222ca8383f4 890 DigitalIn ID2(PC_4);
Jason Reiss 28:c222ca8383f4 891 DigitalIn ID1(PC_5);
Jason Reiss 28:c222ca8383f4 892 DigitalIn ID0(PD_2);
Jason Reiss 28:c222ca8383f4 893 if(ID2 == 0 && ID1 == 0 && ID0 == 0 && _sleep_standby == 1){
Jason Reiss 28:c222ca8383f4 894 _sleep_standby = 0;
Jason Reiss 28:c222ca8383f4 895 logWarning("This hardware version does not support deep sleep. Using sleep mode instead.");
Jason Reiss 28:c222ca8383f4 896 }
Jason Reiss 28:c222ca8383f4 897 #endif
Jason Reiss 28:c222ca8383f4 898 write(done);
Jason Reiss 28:c222ca8383f4 899 if (_dot->getBaud() < 9600)
Jason Reiss 28:c222ca8383f4 900 osDelay(20);
Jason Reiss 28:c222ca8383f4 901 else if (_dot->getBaud() > 57600)
Jason Reiss 28:c222ca8383f4 902 osDelay(2);
Jason Reiss 28:c222ca8383f4 903 else
Jason Reiss 28:c222ca8383f4 904 osDelay(5);
Jason Reiss 28:c222ca8383f4 905 this->sleep(_sleep_standby);
Jason Reiss 28:c222ca8383f4 906 osDelay(1);
Jason Reiss 28:c222ca8383f4 907 }
Jason Reiss 28:c222ca8383f4 908 }
Jason Reiss 28:c222ca8383f4 909 break;
Jason Reiss 28:c222ca8383f4 910 }
Jason Reiss 28:c222ca8383f4 911 default:
Jason Reiss 28:c222ca8383f4 912 handled = false;
Jason Reiss 28:c222ca8383f4 913 // Unhandled command
Jason Reiss 28:c222ca8383f4 914 // Will only reach here if the table contains commands that do not have explicit cases
Jason Reiss 28:c222ca8383f4 915 break;
Jason Reiss 28:c222ca8383f4 916 }
Jason Reiss 28:c222ca8383f4 917 }
Jason Reiss 28:c222ca8383f4 918 #ifdef MTS_RADIO_DEBUG_COMMANDS
Jason Reiss 28:c222ca8383f4 919 } else if (args[0].find("AT+TM!") == 0 && args[0].length() == 6) {
Jason Reiss 28:c222ca8383f4 920 handled = true;
Jason Reiss 28:c222ca8383f4 921 if ((args.size() > 1) && (args[1].length() == 1)) {
Jason Reiss 28:c222ca8383f4 922 if (args[1][0] == '0' || args[1][0] == '1') {
Jason Reiss 28:c222ca8383f4 923 _dot->setTestModeEnabled(args[1][0] == '1');
Jason Reiss 34:3b696c2b1e4b 924 _dot->saveConfig();
Jason Reiss 28:c222ca8383f4 925 write(done);
Jason Reiss 28:c222ca8383f4 926 } else {
Jason Reiss 28:c222ca8383f4 927 write(error);
Jason Reiss 28:c222ca8383f4 928 }
Jason Reiss 28:c222ca8383f4 929 } else {
Jason Reiss 28:c222ca8383f4 930 writef("%d\r\n", _dot->getTestModeEnabled());
Jason Reiss 28:c222ca8383f4 931 write(done);
Jason Reiss 28:c222ca8383f4 932 }
Jason Reiss 28:c222ca8383f4 933 #endif
Jason Reiss 28:c222ca8383f4 934 }
Jason Reiss 28:c222ca8383f4 935 }
Jason Reiss 28:c222ca8383f4 936
Jason Reiss 28:c222ca8383f4 937 if (!handled) {
Mike Fiore 1:e52ae6584f1c 938 bool found = false;
Mike Fiore 1:e52ae6584f1c 939 bool query = false;
Mike Fiore 1:e52ae6584f1c 940
Mike Fiore 1:e52ae6584f1c 941 std::string lookfor = args[0];
Mike Fiore 1:e52ae6584f1c 942
Jason Reiss 28:c222ca8383f4 943 #if MTS_CMD_TERM_VERBOSE
Mike Fiore 1:e52ae6584f1c 944 // per command help
Jason Reiss 28:c222ca8383f4 945 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0)) {
Mike Fiore 1:e52ae6584f1c 946 lookfor = mts::Text::toUpper(args[1]);
Jason Reiss 28:c222ca8383f4 947 }
Jason Reiss 28:c222ca8383f4 948 #endif
Mike Fiore 1:e52ae6584f1c 949 // trim off any trailing '?' and mark as a query command
Mike Fiore 1:e52ae6584f1c 950 if (args[0].rfind("?") == args[0].length() - 1) {
Mike Fiore 1:e52ae6584f1c 951 query = true;
Mike Fiore 1:e52ae6584f1c 952 lookfor = args[0].substr(0, args[0].length() - 1);
Mike Fiore 1:e52ae6584f1c 953 }
Mike Fiore 1:e52ae6584f1c 954
Mike Fiore 1:e52ae6584f1c 955 // search for command
jenkins@jenkinsdm1 18:63f098f042b2 956 Command *cmd = NULL;
Jason Reiss 27:5fafd3b26ac3 957 for (int i = 0; i < CommandFactory::NUMBER_OF_CMDS; i++) {
Jason Reiss 27:5fafd3b26ac3 958 cmd = CommandFactory::Create(static_cast<CommandFactory::CmdId_t>(i));
Mike Fiore 1:e52ae6584f1c 959
Mike Fiore 1:e52ae6584f1c 960 // match CMD or CMD? syntax if command is queryable
jenkins@jenkinsdm1 18:63f098f042b2 961 if (lookfor == cmd->text() && (!query || (query && cmd->queryable()))) {
Mike Fiore 1:e52ae6584f1c 962 found = true;
Jason Reiss 28:c222ca8383f4 963 _errorMessage.clear();
Jason Reiss 28:c222ca8383f4 964 #if MTS_CMD_TERM_VERBOSE
Mike Fiore 1:e52ae6584f1c 965 if (args[0] == "HELP") {
jenkins@jenkinsdm1 18:63f098f042b2 966 writef("%s%s", cmd->help().c_str(), newline);
Mike Fiore 1:e52ae6584f1c 967 write(done);
Mike Fiore 1:e52ae6584f1c 968 }
Mike Fiore 1:e52ae6584f1c 969 else if (args.size() > 1 && args[1] == "?") {
jenkins@jenkinsdm1 18:63f098f042b2 970 writef("%s%s", cmd->usage().c_str(), newline);
Mike Fiore 1:e52ae6584f1c 971 write(done);
jenkins@jenkinsdm1 18:63f098f042b2 972 } else if (!cmd->verify(args)) {
Jason Reiss 28:c222ca8383f4 973 #else
Jason Reiss 28:c222ca8383f4 974 if (args.size() > 1 && args[1] == "?") {
Jason Reiss 28:c222ca8383f4 975 write(error);
Jason Reiss 28:c222ca8383f4 976 } else if (!cmd->verify(args)) {
Jason Reiss 28:c222ca8383f4 977 #endif
Jason Reiss 28:c222ca8383f4 978 if (!_errorMessage.empty()) {
Jason Reiss 28:c222ca8383f4 979 writef("%s%s", _errorMessage.c_str(), newline);
Jason Reiss 28:c222ca8383f4 980 }
Jason Reiss 28:c222ca8383f4 981 write(error);
Mike Fiore 1:e52ae6584f1c 982 } else {
Jason Reiss 28:c222ca8383f4 983 _errorMessage.clear();
jenkins@jenkinsdm1 18:63f098f042b2 984 if (cmd->action(args) == 0) {
Mike Fiore 1:e52ae6584f1c 985 writef("%s", done);
Mike Fiore 1:e52ae6584f1c 986 } else {
Jason Reiss 28:c222ca8383f4 987 // Action was not successful
Jason Reiss 28:c222ca8383f4 988 if (_errorMessage.empty()) {
Jason Reiss 28:c222ca8383f4 989 // If no error message was set, check for error recorded in mdot
Jason Reiss 28:c222ca8383f4 990 std::string dot_error = _dot->getLastError();
Jason Reiss 28:c222ca8383f4 991 if (!dot_error.empty()) {
Jason Reiss 28:c222ca8383f4 992 writef("%s%s", dot_error.c_str(), newline);
Jason Reiss 28:c222ca8383f4 993 }
Jason Reiss 28:c222ca8383f4 994 } else {
Jason Reiss 28:c222ca8383f4 995 // Command set an error message
Jason Reiss 28:c222ca8383f4 996 writef("%s%s", _errorMessage.c_str(), newline);
Jason Reiss 28:c222ca8383f4 997 }
Jason Reiss 28:c222ca8383f4 998 write(error);
Mike Fiore 1:e52ae6584f1c 999 }
Mike Fiore 1:e52ae6584f1c 1000 }
Mike Fiore 1:e52ae6584f1c 1001 }
jenkins@jenkinsdm1 18:63f098f042b2 1002
jenkins@jenkinsdm1 18:63f098f042b2 1003 delete cmd;
Jason Reiss 28:c222ca8383f4 1004
Jason Reiss 28:c222ca8383f4 1005 if (found) {
Jason Reiss 28:c222ca8383f4 1006 break;
Jason Reiss 28:c222ca8383f4 1007 }
Mike Fiore 1:e52ae6584f1c 1008 }
Mike Fiore 1:e52ae6584f1c 1009
Mike Fiore 1:e52ae6584f1c 1010 if (!found) {
Jason Reiss 28:c222ca8383f4 1011 write(command_error);
Jason Reiss 28:c222ca8383f4 1012 write(error);
Mike Fiore 1:e52ae6584f1c 1013 }
Mike Fiore 1:e52ae6584f1c 1014 }
Mike Fiore 1:e52ae6584f1c 1015
Jason Reiss 28:c222ca8383f4 1016
Jason Reiss 27:5fafd3b26ac3 1017 _join_status_pin = CommandTerminal::Dot()->getNetworkJoinStatus();
Jason Reiss 27:5fafd3b26ac3 1018 command_processing = false;
Jason Reiss 27:5fafd3b26ac3 1019
Jason Reiss 27:5fafd3b26ac3 1020
Mike Fiore 14:f9a77400b622 1021 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 4:666017851052 1022 if (history.size() == 0 || history.front() != command)
Mike Fiore 4:666017851052 1023 history.push_front(command);
Mike Fiore 4:666017851052 1024 history_index = -1;
Mike Fiore 1:e52ae6584f1c 1025 command.clear();
Mike Fiore 1:e52ae6584f1c 1026
Mike Fiore 4:666017851052 1027 while (history.size() > 10)
Mike Fiore 4:666017851052 1028 history.pop_back();
Mike Fiore 14:f9a77400b622 1029 #else
Mike Fiore 14:f9a77400b622 1030 command.clear();
Mike Fiore 14:f9a77400b622 1031 #endif
Mike Fiore 1:e52ae6584f1c 1032 }
Mike Fiore 1:e52ae6584f1c 1033 }
Mike Fiore 1:e52ae6584f1c 1034
Mike Fiore 1:e52ae6584f1c 1035 void CommandTerminal::sleep(bool standby) {
Mike Fiore 1:e52ae6584f1c 1036 _xbee_on_sleep = GPIO_PIN_RESET;
Mike Fiore 1:e52ae6584f1c 1037
Mike Fiore 4:666017851052 1038 _serial.rxClear();
Mike Fiore 4:666017851052 1039 _serial.txClear();
Mike Fiore 1:e52ae6584f1c 1040
Mike Fiore 14:f9a77400b622 1041 #if defined(TARGET_XDOT_L151CC)
Mike Fiore 14:f9a77400b622 1042 xdot_save_gpio_state();
Mike Fiore 14:f9a77400b622 1043
Mike Fiore 14:f9a77400b622 1044 /* GPIO Ports Clock Enable */
Mike Fiore 14:f9a77400b622 1045 __GPIOA_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 1046 __GPIOB_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 1047 __GPIOC_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 1048 __GPIOH_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 1049
Mike Fiore 14:f9a77400b622 1050 GPIO_InitTypeDef GPIO_InitStruct;
Mike Fiore 14:f9a77400b622 1051
Mike Fiore 14:f9a77400b622 1052 // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source
Mike Fiore 14:f9a77400b622 1053 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12;
Mike Fiore 14:f9a77400b622 1054 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1055 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1056 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1057
Mike Fiore 14:f9a77400b622 1058 // I2C_SDA & I2C_SCL to analog nopull
Mike Fiore 14:f9a77400b622 1059 GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
Mike Fiore 14:f9a77400b622 1060 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1061 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1062 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1063
Mike Fiore 14:f9a77400b622 1064 // SPI_MOSI, SPI_MISO, SPI_SCK, & SPI_NSS to analog nopull
Mike Fiore 14:f9a77400b622 1065 GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
Mike Fiore 14:f9a77400b622 1066 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1067 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1068 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1069
Mike Fiore 14:f9a77400b622 1070 // iterate through potential wake pins - leave the configured wake pin alone if one is needed
Mike Fiore 14:f9a77400b622 1071 if (_dot->getWakePin() != WAKE || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1072 GPIO_InitStruct.Pin = GPIO_PIN_0;
Mike Fiore 14:f9a77400b622 1073 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1074 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1075 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1076 }
Mike Fiore 14:f9a77400b622 1077 if (_dot->getWakePin() != GPIO0 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1078 GPIO_InitStruct.Pin = GPIO_PIN_4;
Mike Fiore 14:f9a77400b622 1079 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1080 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1081 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1082 }
Mike Fiore 14:f9a77400b622 1083 if (_dot->getWakePin() != GPIO1 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1084 GPIO_InitStruct.Pin = GPIO_PIN_5;
Mike Fiore 14:f9a77400b622 1085 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1086 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1087 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1088 }
Mike Fiore 14:f9a77400b622 1089 if (_dot->getWakePin() != GPIO2 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1090 GPIO_InitStruct.Pin = GPIO_PIN_0;
Mike Fiore 14:f9a77400b622 1091 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1092 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1093 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1094 }
Mike Fiore 14:f9a77400b622 1095 if (_dot->getWakePin() != GPIO3 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1096 GPIO_InitStruct.Pin = GPIO_PIN_2;
Mike Fiore 14:f9a77400b622 1097 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1098 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1099 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1100 }
Mike Fiore 14:f9a77400b622 1101 if (_dot->getWakePin() != UART1_RX || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1102 GPIO_InitStruct.Pin = GPIO_PIN_10;
Mike Fiore 14:f9a77400b622 1103 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1104 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1105 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1106 }
Mike Fiore 14:f9a77400b622 1107 #else
Mike Fiore 14:f9a77400b622 1108 uint32_t portA[6];
Mike Fiore 14:f9a77400b622 1109 uint32_t portB[6];
Mike Fiore 14:f9a77400b622 1110 uint32_t portC[6];
Mike Fiore 14:f9a77400b622 1111 uint32_t portD[6];
Mike Fiore 14:f9a77400b622 1112 uint32_t portH[6];
Mike Fiore 14:f9a77400b622 1113
Mike Fiore 14:f9a77400b622 1114 //Save the GPIO state.
Mike Fiore 14:f9a77400b622 1115 portA[0] = GPIOA->MODER;
Mike Fiore 14:f9a77400b622 1116 portA[1] = GPIOA->OTYPER;
Mike Fiore 14:f9a77400b622 1117 portA[2] = GPIOA->OSPEEDR;
Mike Fiore 14:f9a77400b622 1118 portA[3] = GPIOA->PUPDR;
Mike Fiore 14:f9a77400b622 1119 portA[4] = GPIOA->AFR[0];
Mike Fiore 14:f9a77400b622 1120 portA[5] = GPIOA->AFR[1];
Mike Fiore 14:f9a77400b622 1121
Mike Fiore 14:f9a77400b622 1122 portB[0] = GPIOB->MODER;
Mike Fiore 14:f9a77400b622 1123 portB[1] = GPIOB->OTYPER;
Mike Fiore 14:f9a77400b622 1124 portB[2] = GPIOB->OSPEEDR;
Mike Fiore 14:f9a77400b622 1125 portB[3] = GPIOB->PUPDR;
Mike Fiore 14:f9a77400b622 1126 portB[4] = GPIOB->AFR[0];
Mike Fiore 14:f9a77400b622 1127 portB[5] = GPIOB->AFR[1];
Mike Fiore 14:f9a77400b622 1128
Mike Fiore 14:f9a77400b622 1129 portC[0] = GPIOC->MODER;
Mike Fiore 14:f9a77400b622 1130 portC[1] = GPIOC->OTYPER;
Mike Fiore 14:f9a77400b622 1131 portC[2] = GPIOC->OSPEEDR;
Mike Fiore 14:f9a77400b622 1132 portC[3] = GPIOC->PUPDR;
Mike Fiore 14:f9a77400b622 1133 portC[4] = GPIOC->AFR[0];
Mike Fiore 14:f9a77400b622 1134 portC[5] = GPIOC->AFR[1];
Mike Fiore 14:f9a77400b622 1135
Mike Fiore 14:f9a77400b622 1136 portD[0] = GPIOD->MODER;
Mike Fiore 14:f9a77400b622 1137 portD[1] = GPIOD->OTYPER;
Mike Fiore 14:f9a77400b622 1138 portD[2] = GPIOD->OSPEEDR;
Mike Fiore 14:f9a77400b622 1139 portD[3] = GPIOD->PUPDR;
Mike Fiore 14:f9a77400b622 1140 portD[4] = GPIOD->AFR[0];
Mike Fiore 14:f9a77400b622 1141 portD[5] = GPIOD->AFR[1];
Mike Fiore 14:f9a77400b622 1142
Mike Fiore 14:f9a77400b622 1143 portH[0] = GPIOH->MODER;
Mike Fiore 14:f9a77400b622 1144 portH[1] = GPIOH->OTYPER;
Mike Fiore 14:f9a77400b622 1145 portH[2] = GPIOH->OSPEEDR;
Mike Fiore 14:f9a77400b622 1146 portH[3] = GPIOH->PUPDR;
Mike Fiore 14:f9a77400b622 1147 portH[4] = GPIOH->AFR[0];
Mike Fiore 14:f9a77400b622 1148 portH[5] = GPIOH->AFR[1];
Mike Fiore 14:f9a77400b622 1149
Mike Fiore 14:f9a77400b622 1150 /* GPIO Ports Clock Enable */
Mike Fiore 14:f9a77400b622 1151 __GPIOA_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 1152 __GPIOB_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 1153 __GPIOC_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 1154
Mike Fiore 14:f9a77400b622 1155 GPIO_InitTypeDef GPIO_InitStruct;
Mike Fiore 14:f9a77400b622 1156
Mike Fiore 14:f9a77400b622 1157 // Set port A pins to analog nopull
Jason Reiss 23:4f0a981c0349 1158 GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_6 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10
Mike Fiore 14:f9a77400b622 1159 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
Mike Fiore 14:f9a77400b622 1160 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1161 GPIO_InitStruct.Pull = GPIO_NOPULL;
Jason Reiss 23:4f0a981c0349 1162 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1163
Mike Fiore 14:f9a77400b622 1164 // Set port B pins to analog nopull
Mike Fiore 14:f9a77400b622 1165 GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4;
Mike Fiore 14:f9a77400b622 1166 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1167 GPIO_InitStruct.Pull = GPIO_NOPULL;
Jason Reiss 23:4f0a981c0349 1168 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1169
Mike Fiore 14:f9a77400b622 1170 // Set port C pins to analog nopull
Mike Fiore 14:f9a77400b622 1171 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_13;
Mike Fiore 14:f9a77400b622 1172 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1173 GPIO_InitStruct.Pull = GPIO_NOPULL;
Jason Reiss 23:4f0a981c0349 1174 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1175
Mike Fiore 14:f9a77400b622 1176 // iterate through potential wake pins - leave the configured wake pin alone if one is needed
Mike Fiore 14:f9a77400b622 1177 // XBEE_DIN - PA3
Mike Fiore 14:f9a77400b622 1178 // XBEE_DIO2 - PA5
Mike Fiore 14:f9a77400b622 1179 // XBEE_DIO3 - PA4
Mike Fiore 14:f9a77400b622 1180 // XBEE_DIO4 - PA7
Mike Fiore 14:f9a77400b622 1181 // XBEE_DIO5 - PC1
Mike Fiore 14:f9a77400b622 1182 // XBEE_DIO6 - PA1
Mike Fiore 14:f9a77400b622 1183 // XBEE_DIO7 - PA0
Mike Fiore 14:f9a77400b622 1184 // XBEE_SLEEPRQ - PA11
Jason Reiss 23:4f0a981c0349 1185
Mike Fiore 14:f9a77400b622 1186 if (_dot->getWakePin() != XBEE_DIN || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1187 GPIO_InitStruct.Pin = GPIO_PIN_3;
Mike Fiore 14:f9a77400b622 1188 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1189 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1190 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1191 }
Mike Fiore 14:f9a77400b622 1192
Mike Fiore 14:f9a77400b622 1193 if (_dot->getWakePin() != XBEE_DIO2 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1194 GPIO_InitStruct.Pin = GPIO_PIN_5;
Mike Fiore 14:f9a77400b622 1195 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1196 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1197 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1198 }
Mike Fiore 14:f9a77400b622 1199
Mike Fiore 14:f9a77400b622 1200 if (_dot->getWakePin() != XBEE_DIO3 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1201 GPIO_InitStruct.Pin = GPIO_PIN_4;
Mike Fiore 14:f9a77400b622 1202 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1203 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1204 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1205 }
Mike Fiore 14:f9a77400b622 1206
Mike Fiore 14:f9a77400b622 1207 if (_dot->getWakePin() != XBEE_DIO4 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1208 GPIO_InitStruct.Pin = GPIO_PIN_7;
Mike Fiore 14:f9a77400b622 1209 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1210 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1211 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1212 }
Mike Fiore 14:f9a77400b622 1213
Mike Fiore 14:f9a77400b622 1214 if (_dot->getWakePin() != XBEE_DIO5 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1215 GPIO_InitStruct.Pin = GPIO_PIN_1;
Mike Fiore 14:f9a77400b622 1216 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1217 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1218 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1219 }
Mike Fiore 14:f9a77400b622 1220
Mike Fiore 14:f9a77400b622 1221 if (_dot->getWakePin() != XBEE_DIO6 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1222 GPIO_InitStruct.Pin = GPIO_PIN_1;
Mike Fiore 14:f9a77400b622 1223 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1224 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1225 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1226 }
Mike Fiore 14:f9a77400b622 1227
Mike Fiore 14:f9a77400b622 1228 if (_dot->getWakePin() != XBEE_DIO7 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1229 GPIO_InitStruct.Pin = GPIO_PIN_0;
Mike Fiore 14:f9a77400b622 1230 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1231 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1232 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1233 }
Mike Fiore 14:f9a77400b622 1234
Mike Fiore 14:f9a77400b622 1235 if (_dot->getWakePin() != XBEE_SLEEPRQ|| _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 1236 GPIO_InitStruct.Pin = GPIO_PIN_11;
Mike Fiore 14:f9a77400b622 1237 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 1238 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 1239 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 1240 }
Jason Reiss 23:4f0a981c0349 1241
Mike Fiore 14:f9a77400b622 1242 #endif
Mike Fiore 4:666017851052 1243 _dot->sleep(_dot->getWakeInterval(), _dot->getWakeMode(), standby);
Mike Fiore 14:f9a77400b622 1244
Mike Fiore 14:f9a77400b622 1245 #if defined(TARGET_XDOT_L151CC)
Mike Fiore 14:f9a77400b622 1246 xdot_restore_gpio_state();
Mike Fiore 14:f9a77400b622 1247 #else
Mike Fiore 14:f9a77400b622 1248 //Restore the GPIO state.
Mike Fiore 14:f9a77400b622 1249 GPIOA->MODER = portA[0];
Mike Fiore 14:f9a77400b622 1250 GPIOA->OTYPER = portA[1];
Mike Fiore 14:f9a77400b622 1251 GPIOA->OSPEEDR = portA[2];
Mike Fiore 14:f9a77400b622 1252 GPIOA->PUPDR = portA[3];
Mike Fiore 14:f9a77400b622 1253 GPIOA->AFR[0] = portA[4];
Mike Fiore 14:f9a77400b622 1254 GPIOA->AFR[1] = portA[5];
Mike Fiore 14:f9a77400b622 1255
Mike Fiore 14:f9a77400b622 1256 GPIOB->MODER = portB[0];
Mike Fiore 14:f9a77400b622 1257 GPIOB->OTYPER = portB[1];
Mike Fiore 14:f9a77400b622 1258 GPIOB->OSPEEDR = portB[2];
Mike Fiore 14:f9a77400b622 1259 GPIOB->PUPDR = portB[3];
Mike Fiore 14:f9a77400b622 1260 GPIOB->AFR[0] = portB[4];
Mike Fiore 14:f9a77400b622 1261 GPIOB->AFR[1] = portB[5];
Mike Fiore 14:f9a77400b622 1262
Mike Fiore 14:f9a77400b622 1263 GPIOC->MODER = portC[0];
Mike Fiore 14:f9a77400b622 1264 GPIOC->OTYPER = portC[1];
Mike Fiore 14:f9a77400b622 1265 GPIOC->OSPEEDR = portC[2];
Mike Fiore 14:f9a77400b622 1266 GPIOC->PUPDR = portC[3];
Mike Fiore 14:f9a77400b622 1267 GPIOC->AFR[0] = portC[4];
Mike Fiore 14:f9a77400b622 1268 GPIOC->AFR[1] = portC[5];
Mike Fiore 14:f9a77400b622 1269
Mike Fiore 14:f9a77400b622 1270 GPIOD->MODER = portD[0];
Mike Fiore 14:f9a77400b622 1271 GPIOD->OTYPER = portD[1];
Mike Fiore 14:f9a77400b622 1272 GPIOD->OSPEEDR = portD[2];
Mike Fiore 14:f9a77400b622 1273 GPIOD->PUPDR = portD[3];
Mike Fiore 14:f9a77400b622 1274 GPIOD->AFR[0] = portD[4];
Mike Fiore 14:f9a77400b622 1275 GPIOD->AFR[1] = portD[5];
Mike Fiore 14:f9a77400b622 1276
Mike Fiore 14:f9a77400b622 1277 GPIOH->MODER = portH[0];
Mike Fiore 14:f9a77400b622 1278 GPIOH->OTYPER = portH[1];
Mike Fiore 14:f9a77400b622 1279 GPIOH->OSPEEDR = portH[2];
Mike Fiore 14:f9a77400b622 1280 GPIOH->PUPDR = portH[3];
Mike Fiore 14:f9a77400b622 1281 GPIOH->AFR[0] = portH[4];
Mike Fiore 14:f9a77400b622 1282 GPIOH->AFR[1] = portH[5];
Mike Fiore 14:f9a77400b622 1283 #endif
Mike Fiore 14:f9a77400b622 1284
Mike Fiore 14:f9a77400b622 1285 _serial.rxClear();
Mike Fiore 14:f9a77400b622 1286 _serial.txClear();
Jason Reiss 23:4f0a981c0349 1287 Fota::getInstance()->fixEventQueue();
Mike Fiore 14:f9a77400b622 1288 }
Mike Fiore 14:f9a77400b622 1289
Mike Fiore 14:f9a77400b622 1290 std::string CommandTerminal::formatPacketData(const std::vector<uint8_t>& data, const uint8_t& format) {
Jason Reiss 23:4f0a981c0349 1291 switch(format) {
Jason Reiss 23:4f0a981c0349 1292 case(mDot::HEXADECIMAL):
Jason Reiss 23:4f0a981c0349 1293 return mts::Text::bin2hexString(data);
Jason Reiss 23:4f0a981c0349 1294
Jason Reiss 23:4f0a981c0349 1295 case(mDot::BINARY):
Jason Reiss 23:4f0a981c0349 1296 return std::string(data.begin(), data.end());
Jason Reiss 23:4f0a981c0349 1297
Jason Reiss 23:4f0a981c0349 1298 case(mDot::EXTENDED):
Jason Reiss 27:5fafd3b26ac3 1299 return formatPacket(data, false);
Jason Reiss 27:5fafd3b26ac3 1300
Jason Reiss 27:5fafd3b26ac3 1301 case(mDot::EXTENDED_HEX):
Jason Reiss 27:5fafd3b26ac3 1302 return formatPacket(data, true);
Jason Reiss 23:4f0a981c0349 1303
Jason Reiss 23:4f0a981c0349 1304 default:
Jason Reiss 23:4f0a981c0349 1305 return "";
Jason Reiss 23:4f0a981c0349 1306 }
Mike Fiore 1:e52ae6584f1c 1307 }
Mike Fiore 1:e52ae6584f1c 1308
Mike Fiore 1:e52ae6584f1c 1309 bool CommandTerminal::waitForEscape(int timeout, mDot* dot, WaitType wait) {
Mike Fiore 1:e52ae6584f1c 1310 Timer timer;
Mike Fiore 1:e52ae6584f1c 1311
Mike Fiore 1:e52ae6584f1c 1312 timer.start();
Mike Fiore 1:e52ae6584f1c 1313 while (timer.read_ms() < timeout) {
Mike Fiore 1:e52ae6584f1c 1314
Mike Fiore 1:e52ae6584f1c 1315 if (dot != NULL) {
Mike Fiore 1:e52ae6584f1c 1316 if (wait == WAIT_SEND && (!dot->getIsTransmitting())) {
Mike Fiore 1:e52ae6584f1c 1317 return false;
Mike Fiore 1:e52ae6584f1c 1318 }
Mike Fiore 1:e52ae6584f1c 1319 }
Mike Fiore 1:e52ae6584f1c 1320
Mike Fiore 9:ff62b20f7000 1321 if (_serialp != NULL && _serialp->escaped()) {
Mike Fiore 9:ff62b20f7000 1322 _serialp->clearEscaped();
Mike Fiore 9:ff62b20f7000 1323 return true;
Mike Fiore 1:e52ae6584f1c 1324 }
Mike Fiore 1:e52ae6584f1c 1325
Mike Fiore 1:e52ae6584f1c 1326 osDelay(10);
Mike Fiore 1:e52ae6584f1c 1327 }
Mike Fiore 1:e52ae6584f1c 1328
Mike Fiore 1:e52ae6584f1c 1329 return false;
Mike Fiore 1:e52ae6584f1c 1330 }
Mike Fiore 1:e52ae6584f1c 1331
Mike Fiore 9:ff62b20f7000 1332 void CommandTerminal::wakeup(void) {
Mike Fiore 9:ff62b20f7000 1333 }
Mike Fiore 9:ff62b20f7000 1334
Jason Reiss 27:5fafd3b26ac3 1335 void CommandTerminal::RadioEvent::RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int16_t snr, lora::DownlinkControl ctrl, uint8_t slot) {
Jason Reiss 27:5fafd3b26ac3 1336 mDotEvent::RxDone(payload, size, rssi, snr, ctrl, slot);
Jason Reiss 27:5fafd3b26ac3 1337 logDebug("RadioEvent - RxDone");
Jason Reiss 27:5fafd3b26ac3 1338 }
Jason Reiss 27:5fafd3b26ac3 1339
Jason Reiss 27:5fafd3b26ac3 1340 void CommandTerminal::RadioEvent::RxTimeout(uint8_t slot) {
Jason Reiss 27:5fafd3b26ac3 1341 mDotEvent::RxTimeout(slot);
Jason Reiss 27:5fafd3b26ac3 1342 _packet_rx_pin = 0;
Jason Reiss 27:5fafd3b26ac3 1343 }
Jason Reiss 27:5fafd3b26ac3 1344
Jason Reiss 28:c222ca8383f4 1345 void CommandTerminal::RadioEvent::PacketRx(uint8_t port, uint8_t *payload, uint16_t size, int16_t rssi, int16_t snr, lora::DownlinkControl ctrl, uint8_t slot, uint8_t retries, uint32_t address, uint32_t fcnt, bool dupRx) {
Jason Reiss 28:c222ca8383f4 1346 mDotEvent::PacketRx(port, payload, size, rssi, snr, ctrl, slot, retries, address, fcnt, dupRx);
Jason Reiss 27:5fafd3b26ac3 1347 _rxAddress = address;
Jason Reiss 28:c222ca8383f4 1348 _rxFcnt = fcnt;
Jason Reiss 27:5fafd3b26ac3 1349
jenkins@jenkinsdm1 18:63f098f042b2 1350 if(port == 200 || port == 201 || port == 202) {
Jason Reiss 23:4f0a981c0349 1351 Fota::getInstance()->processCmd(payload, port, size);
Jason Reiss 27:5fafd3b26ac3 1352 if (CommandTerminal::Dot()->getRxOutput() < mDot::EXTENDED) {
Jason Reiss 27:5fafd3b26ac3 1353 return;
Jason Reiss 27:5fafd3b26ac3 1354 }
jenkins@jenkinsdm1 18:63f098f042b2 1355 }
Jason Reiss 27:5fafd3b26ac3 1356
Jason Reiss 27:5fafd3b26ac3 1357 _packet_rx_pin = 1;
Jason Reiss 27:5fafd3b26ac3 1358
jenkins@jenkinsdm1 18:63f098f042b2 1359 if (serial_data_mode && port != 0) {
Mike Fiore 14:f9a77400b622 1360 if (size > 0) {
Jason Reiss 27:5fafd3b26ac3 1361 while (!CommandTerminal::Serial()->writeable()) ;
Jason Reiss 27:5fafd3b26ac3 1362 if (CommandTerminal::Dot()->getRxOutput() >= mDot::EXTENDED) {
Jason Reiss 27:5fafd3b26ac3 1363 formatPacket(RxPayload, size, CommandTerminal::Dot()->getRxOutput() == mDot::EXTENDED_HEX);
Jason Reiss 23:4f0a981c0349 1364 } else {
Jason Reiss 23:4f0a981c0349 1365 CommandTerminal::Serial()->write((char*) RxPayload, RxPayloadSize);
Jason Reiss 23:4f0a981c0349 1366 }
Mike Fiore 9:ff62b20f7000 1367 }
Jason Reiss 23:4f0a981c0349 1368 if (!CommandTerminal::Serial()->readable()
Jason Reiss 23:4f0a981c0349 1369 && (_dot->getAckRequested()
Jason Reiss 27:5fafd3b26ac3 1370 || (peer_to_peer == false && _dot->hasMacCommands()))
Jason Reiss 27:5fafd3b26ac3 1371 && (peer_to_peer || _dot->getClass() == "C" || _dot->getSettings()->Session.Class == lora::CLASS_B)) {
Mike Fiore 14:f9a77400b622 1372 _sendAck = true;
Mike Fiore 9:ff62b20f7000 1373 }
Jason Reiss 27:5fafd3b26ac3 1374 } else if (urc_enabled) {
Jason Reiss 27:5fafd3b26ac3 1375 if (!command_processing) {
Jason Reiss 27:5fafd3b26ac3 1376 while (!CommandTerminal::Serial()->writeable()) ;
Jason Reiss 27:5fafd3b26ac3 1377 if (CommandTerminal::Dot()->getRxOutput() >= mDot::EXTENDED) {
Jason Reiss 27:5fafd3b26ac3 1378 formatPacket(RxPayload, size, CommandTerminal::Dot()->getRxOutput() == mDot::EXTENDED_HEX);
Jason Reiss 27:5fafd3b26ac3 1379 } else {
Jason Reiss 28:c222ca8383f4 1380 CommandTerminal::Serial()->write("RECV\r\n", 6);
Jason Reiss 27:5fafd3b26ac3 1381 }
Jason Reiss 27:5fafd3b26ac3 1382 }
Mike Fiore 9:ff62b20f7000 1383 }
Mike Fiore 1:e52ae6584f1c 1384 }
Mike Fiore 9:ff62b20f7000 1385
Jason Reiss 28:c222ca8383f4 1386 void CommandTerminal::RadioEvent::handleTestModePacket() {
Jason Reiss 28:c222ca8383f4 1387 #ifdef MTS_RADIO_DEBUG_COMMANDS
Jason Reiss 28:c222ca8383f4 1388 static uint32_t last_rx_seq = 0;
Jason Reiss 28:c222ca8383f4 1389 bool start_test = false;
Jason Reiss 28:c222ca8383f4 1390
Jason Reiss 28:c222ca8383f4 1391 std::string packet = mts::Text::bin2hexString(RxPayload, RxPayloadSize);
Jason Reiss 28:c222ca8383f4 1392
Jason Reiss 28:c222ca8383f4 1393 CommandTerminal::Dot()->getSettings()->Test.TestMode = true;
Jason Reiss 28:c222ca8383f4 1394
Jason Reiss 28:c222ca8383f4 1395 last_rx_seq = CommandTerminal::Dot()->getSettings()->Session.UplinkCounter;
Jason Reiss 28:c222ca8383f4 1396
Jason Reiss 28:c222ca8383f4 1397 uint16_t testDownlinkCounter = 0;
Jason Reiss 28:c222ca8383f4 1398 uint32_t txPeriod = 5000;
Jason Reiss 28:c222ca8383f4 1399 bool testConfirmed = false;
Jason Reiss 28:c222ca8383f4 1400
Jason Reiss 28:c222ca8383f4 1401 // init counter
Jason Reiss 28:c222ca8383f4 1402 std::vector<uint8_t> data;
Jason Reiss 28:c222ca8383f4 1403 uint8_t savedPort = CommandTerminal::Dot()->getAppPort();
Jason Reiss 28:c222ca8383f4 1404 uint8_t savedAcks = CommandTerminal::Dot()->getAck();
Jason Reiss 28:c222ca8383f4 1405 bool savedAdr = CommandTerminal::Dot()->getAdr();
Jason Reiss 28:c222ca8383f4 1406
Jason Reiss 28:c222ca8383f4 1407 CommandTerminal::Dot()->setAck(0);
Jason Reiss 28:c222ca8383f4 1408 CommandTerminal::Dot()->setAdr(true);
Jason Reiss 28:c222ca8383f4 1409 CommandTerminal::Dot()->setAppPort(224);
Jason Reiss 28:c222ca8383f4 1410
Jason Reiss 28:c222ca8383f4 1411 Timer sentTimer;
Jason Reiss 28:c222ca8383f4 1412 sentTimer.start();
Jason Reiss 28:c222ca8383f4 1413 while (CommandTerminal::Dot()->getSettings()->Test.TestMode) {
Jason Reiss 28:c222ca8383f4 1414 TEST_START:
Jason Reiss 34:3b696c2b1e4b 1415 // if (waitingForBeacon && BeaconLocked) {
Jason Reiss 34:3b696c2b1e4b 1416 // logInfo("send BeaconRxStatusInd");
Jason Reiss 34:3b696c2b1e4b 1417 // data.clear();
Jason Reiss 34:3b696c2b1e4b 1418 // data.push_back(0x40);
Jason Reiss 34:3b696c2b1e4b 1419 // for (size_t i = 0; i < sizeof(BeaconData); ++i) {
Jason Reiss 34:3b696c2b1e4b 1420 // data.push_back(((uint8_t*)&BeaconData)[i]);
Jason Reiss 34:3b696c2b1e4b 1421 // }
Jason Reiss 34:3b696c2b1e4b 1422 // } else
Jason Reiss 34:3b696c2b1e4b 1423
Jason Reiss 28:c222ca8383f4 1424 if (RxPort == 224) {
Jason Reiss 28:c222ca8383f4 1425 data.clear();
Jason Reiss 28:c222ca8383f4 1426
Jason Reiss 34:3b696c2b1e4b 1427 std::string packet = mts::Text::bin2hexString(RxPayload, RxPayloadSize);
Jason Reiss 34:3b696c2b1e4b 1428 logDebug("Test Mode AppPort : %d", CommandTerminal::Dot()->getAppPort());
Jason Reiss 34:3b696c2b1e4b 1429 logDebug("Test Mode Packet : %s", packet.c_str());
Jason Reiss 34:3b696c2b1e4b 1430
Jason Reiss 28:c222ca8383f4 1431 switch (RxPayload[0]) {
Jason Reiss 28:c222ca8383f4 1432 case 0x00: { // PackageVersionReq
Jason Reiss 28:c222ca8383f4 1433 data.push_back(0x00);
Jason Reiss 28:c222ca8383f4 1434 data.push_back(0x06);
Jason Reiss 28:c222ca8383f4 1435 data.push_back(0x01);
Jason Reiss 28:c222ca8383f4 1436 break;
Jason Reiss 28:c222ca8383f4 1437 }
Jason Reiss 28:c222ca8383f4 1438 case 0x01: { // DutResetReq
Jason Reiss 28:c222ca8383f4 1439 if (RxPayloadSize == 1) {
Jason Reiss 28:c222ca8383f4 1440 CommandTerminal::Dot()->resetCpu();
Jason Reiss 28:c222ca8383f4 1441 }
Jason Reiss 28:c222ca8383f4 1442 break;
Jason Reiss 28:c222ca8383f4 1443 }
Jason Reiss 28:c222ca8383f4 1444 case 0x02: { // DutJoinReq
Jason Reiss 28:c222ca8383f4 1445 if (RxPayloadSize == 1) {
Jason Reiss 28:c222ca8383f4 1446 CommandTerminal::Dot()->joinNetworkOnce();
Jason Reiss 34:3b696c2b1e4b 1447 return;
Jason Reiss 28:c222ca8383f4 1448 }
Jason Reiss 28:c222ca8383f4 1449 break;
Jason Reiss 28:c222ca8383f4 1450 }
Jason Reiss 28:c222ca8383f4 1451 case 0x03: { // SwitchClassReq
Jason Reiss 28:c222ca8383f4 1452 std::string cls = "A";
Jason Reiss 28:c222ca8383f4 1453 if (RxPayload[1] > 0 && RxPayload[1] < 3) {
Jason Reiss 28:c222ca8383f4 1454 cls = RxPayload[1] == 0x01 ? "B" : "C";
Jason Reiss 28:c222ca8383f4 1455 }
Jason Reiss 28:c222ca8383f4 1456 CommandTerminal::Dot()->setClass(cls);
Jason Reiss 28:c222ca8383f4 1457 break;
Jason Reiss 28:c222ca8383f4 1458 }
Jason Reiss 28:c222ca8383f4 1459 case 0x04: { // ADR Enabled/Disable
Jason Reiss 28:c222ca8383f4 1460 if (RxPayload[1] == 1)
Jason Reiss 28:c222ca8383f4 1461 CommandTerminal::Dot()->setAdr(true);
Jason Reiss 28:c222ca8383f4 1462 else
Jason Reiss 28:c222ca8383f4 1463 CommandTerminal::Dot()->setAdr(false);
Jason Reiss 28:c222ca8383f4 1464 break;
Jason Reiss 28:c222ca8383f4 1465 }
Jason Reiss 28:c222ca8383f4 1466 case 0x05: { // RegionalDutyCycleCtrlReq
Jason Reiss 28:c222ca8383f4 1467 if (RxPayload[1] == 0)
Jason Reiss 28:c222ca8383f4 1468 CommandTerminal::Dot()->setDisableDutyCycle(true);
Jason Reiss 28:c222ca8383f4 1469 else
Jason Reiss 28:c222ca8383f4 1470 CommandTerminal::Dot()->setDisableDutyCycle(false);
Jason Reiss 28:c222ca8383f4 1471
Jason Reiss 28:c222ca8383f4 1472 break;
Jason Reiss 28:c222ca8383f4 1473 }
Jason Reiss 28:c222ca8383f4 1474 case 0x06: { // TxPeriodicityChangeReq
Jason Reiss 28:c222ca8383f4 1475 if (RxPayload[1] < 2)
Jason Reiss 28:c222ca8383f4 1476 // 0, 1 => 5s
Jason Reiss 28:c222ca8383f4 1477 txPeriod = 5000U;
Jason Reiss 28:c222ca8383f4 1478 else if (RxPayload[1] < 8)
Jason Reiss 28:c222ca8383f4 1479 // 2 - 7 => 10s - 60s
Jason Reiss 28:c222ca8383f4 1480 txPeriod = (RxPayload[1] - 1) * 10000U;
Jason Reiss 28:c222ca8383f4 1481 else if (RxPayload[1] < 11) {
Jason Reiss 28:c222ca8383f4 1482 // 8, 9, 10 => 120s, 240s, 480s
Jason Reiss 28:c222ca8383f4 1483 txPeriod = 120 * (1 << (RxPayload[1] - 8)) * 1000U;
Jason Reiss 28:c222ca8383f4 1484 }
Jason Reiss 28:c222ca8383f4 1485 break;
Jason Reiss 28:c222ca8383f4 1486 }
Jason Reiss 28:c222ca8383f4 1487 case 0x07: { // TxFramesCtrl
Jason Reiss 28:c222ca8383f4 1488 if (RxPayload[1] == 0) {
Jason Reiss 28:c222ca8383f4 1489 // NO-OP
Jason Reiss 28:c222ca8383f4 1490 } else if (RxPayload[1] == 1) {
Jason Reiss 28:c222ca8383f4 1491 testConfirmed = false;
Jason Reiss 28:c222ca8383f4 1492 CommandTerminal::Dot()->getSettings()->Network.AckEnabled = 0;
Jason Reiss 28:c222ca8383f4 1493 } else if (RxPayload[1] == 2) {
Jason Reiss 28:c222ca8383f4 1494 testConfirmed = true;
Jason Reiss 34:3b696c2b1e4b 1495 // if ADR has set nbTrans then use the current setting
Jason Reiss 34:3b696c2b1e4b 1496 CommandTerminal::Dot()->getSettings()->Network.AckEnabled = 1;
Jason Reiss 34:3b696c2b1e4b 1497 if (CommandTerminal::Dot()->getSettings()->Session.Redundancy == 0) {
Jason Reiss 34:3b696c2b1e4b 1498 CommandTerminal::Dot()->getSettings()->Session.Redundancy = 1;
Jason Reiss 34:3b696c2b1e4b 1499 }
Jason Reiss 28:c222ca8383f4 1500 }
Jason Reiss 28:c222ca8383f4 1501 break;
Jason Reiss 28:c222ca8383f4 1502 }
Jason Reiss 28:c222ca8383f4 1503 case 0x08: { // EchoPayloadReq
Jason Reiss 28:c222ca8383f4 1504 data.push_back(0x08);
Jason Reiss 28:c222ca8383f4 1505 for (size_t i = 1; i < RxPayloadSize; i++) {
Jason Reiss 28:c222ca8383f4 1506 data.push_back(RxPayload[i] + 1);
Jason Reiss 28:c222ca8383f4 1507 }
Jason Reiss 28:c222ca8383f4 1508 break;
Jason Reiss 28:c222ca8383f4 1509 }
Jason Reiss 28:c222ca8383f4 1510 case 0x09: { // RxAppCntReq
Jason Reiss 28:c222ca8383f4 1511 data.push_back(0x09);
Jason Reiss 34:3b696c2b1e4b 1512 data.push_back(testDownlinkCounter & 0xFF);
Jason Reiss 28:c222ca8383f4 1513 data.push_back(testDownlinkCounter >> 8);
Jason Reiss 28:c222ca8383f4 1514 break;
Jason Reiss 28:c222ca8383f4 1515 }
Jason Reiss 28:c222ca8383f4 1516 case 0x0A: { // RxAppCntResetReq
Jason Reiss 28:c222ca8383f4 1517 testDownlinkCounter = 0;
Jason Reiss 28:c222ca8383f4 1518 break;
Jason Reiss 28:c222ca8383f4 1519 }
Jason Reiss 28:c222ca8383f4 1520 case 0x20: { // LinkCheckReq
Jason Reiss 28:c222ca8383f4 1521 CommandTerminal::Dot()->addMacCommand(lora::MOTE_MAC_LINK_CHECK_REQ, 0, 0);
Jason Reiss 28:c222ca8383f4 1522 break;
Jason Reiss 28:c222ca8383f4 1523 }
Jason Reiss 28:c222ca8383f4 1524 case 0x21: { // DeviceTimeReq
Jason Reiss 28:c222ca8383f4 1525 CommandTerminal::Dot()->addDeviceTimeRequest();
Jason Reiss 28:c222ca8383f4 1526 break;
Jason Reiss 28:c222ca8383f4 1527 }
Jason Reiss 28:c222ca8383f4 1528 case 0x22: { // PingSlotInfo
Jason Reiss 28:c222ca8383f4 1529 CommandTerminal::Dot()->setPingPeriodicity(RxPayload[1]);
Jason Reiss 28:c222ca8383f4 1530 CommandTerminal::Dot()->addMacCommand(lora::MOTE_MAC_PING_SLOT_INFO_REQ, RxPayload[1], 0);
Jason Reiss 28:c222ca8383f4 1531 break;
Jason Reiss 28:c222ca8383f4 1532 }
Jason Reiss 28:c222ca8383f4 1533 case 0x7D: { // TxCw
Jason Reiss 28:c222ca8383f4 1534 uint32_t freq = 0;
Jason Reiss 28:c222ca8383f4 1535 uint16_t timeout = 0;
Jason Reiss 28:c222ca8383f4 1536 uint8_t power = 0;
Jason Reiss 28:c222ca8383f4 1537
Jason Reiss 34:3b696c2b1e4b 1538 timeout = RxPayload[2] << 8 | RxPayload[1];
Jason Reiss 34:3b696c2b1e4b 1539 freq = (RxPayload[5] << 16 | RxPayload[4] << 8 | RxPayload[2]) * 100;
Jason Reiss 28:c222ca8383f4 1540 power = RxPayload[6];
Jason Reiss 28:c222ca8383f4 1541
Jason Reiss 28:c222ca8383f4 1542 CommandTerminal::Dot()->sendContinuous(true, timeout * 1000, freq, power);
Jason Reiss 28:c222ca8383f4 1543 break;
Jason Reiss 28:c222ca8383f4 1544 }
Jason Reiss 28:c222ca8383f4 1545 case 0x7E: { // DutFPort224DisableReq
Jason Reiss 28:c222ca8383f4 1546 _dot->setTestModeEnabled(false);
Jason Reiss 28:c222ca8383f4 1547 CommandTerminal::Dot()->getSettings()->Test.TestMode = false;
Jason Reiss 28:c222ca8383f4 1548 _dot->saveConfig();
Jason Reiss 34:3b696c2b1e4b 1549 CommandTerminal::Dot()->resetCpu();
Jason Reiss 28:c222ca8383f4 1550 break;
Jason Reiss 28:c222ca8383f4 1551 }
Jason Reiss 28:c222ca8383f4 1552 case 0x7F: { // DutVersionReq
Jason Reiss 28:c222ca8383f4 1553 std::string version = AT_APPLICATION_VERSION;
Jason Reiss 28:c222ca8383f4 1554 int temp = 0;
Jason Reiss 28:c222ca8383f4 1555
Jason Reiss 28:c222ca8383f4 1556 data.push_back(0x7F);
Jason Reiss 28:c222ca8383f4 1557 int ret = sscanf(&version[0], "%d", &temp);
Jason Reiss 28:c222ca8383f4 1558 data.push_back(temp); // AT_APP_VERSION_MAJOR; // MAJOR
Jason Reiss 28:c222ca8383f4 1559 ret = sscanf(&version[2], "%d", &temp);
Jason Reiss 28:c222ca8383f4 1560 data.push_back(temp); // AT_APP_VERSION_MINOR; // MINOR
Jason Reiss 28:c222ca8383f4 1561 ret = sscanf(&version[4], "%d", &temp);
Jason Reiss 28:c222ca8383f4 1562 data.push_back(temp); // AT_APP_VERSION_PATCH; // PATCH
Jason Reiss 34:3b696c2b1e4b 1563 if (version.size() > 7) {
Jason Reiss 34:3b696c2b1e4b 1564 ret = sscanf(&version[6], "%d", &temp);
Jason Reiss 34:3b696c2b1e4b 1565 data.push_back(temp); // AT_APP_VERSION_PATCH; // PATCH
Jason Reiss 34:3b696c2b1e4b 1566 } else {
Jason Reiss 34:3b696c2b1e4b 1567 data.push_back(0); // AT_APP_VERSION_PATCH; // PATCH
Jason Reiss 34:3b696c2b1e4b 1568 }
Jason Reiss 34:3b696c2b1e4b 1569 version = LW_VERSION;
Jason Reiss 34:3b696c2b1e4b 1570 ret = sscanf(&version[0], "%d", &temp);
Jason Reiss 34:3b696c2b1e4b 1571 data.push_back(temp); // AT_APP_VERSION_MAJOR; // MAJOR
Jason Reiss 34:3b696c2b1e4b 1572 ret = sscanf(&version[2], "%d", &temp);
Jason Reiss 34:3b696c2b1e4b 1573 data.push_back(temp); // AT_APP_VERSION_MINOR; // MINOR
Jason Reiss 34:3b696c2b1e4b 1574 ret = sscanf(&version[4], "%d", &temp);
Jason Reiss 34:3b696c2b1e4b 1575 data.push_back(temp); // AT_APP_VERSION_PATCH; // PATCH
Jason Reiss 34:3b696c2b1e4b 1576 if (version.size() > 7) {
Jason Reiss 34:3b696c2b1e4b 1577 ret = sscanf(&version[6], "%d", &temp);
Jason Reiss 34:3b696c2b1e4b 1578 data.push_back(temp); // AT_APP_VERSION_PATCH; // PATCH
Jason Reiss 34:3b696c2b1e4b 1579 } else {
Jason Reiss 34:3b696c2b1e4b 1580 data.push_back(0); // AT_APP_VERSION_PATCH; // PATCH
Jason Reiss 34:3b696c2b1e4b 1581 }
Jason Reiss 34:3b696c2b1e4b 1582 version = RP_VERSION;
Jason Reiss 34:3b696c2b1e4b 1583 ret = sscanf(&version[0], "%d", &temp);
Jason Reiss 34:3b696c2b1e4b 1584 data.push_back(temp); // AT_APP_VERSION_MAJOR; // MAJOR
Jason Reiss 34:3b696c2b1e4b 1585 ret = sscanf(&version[2], "%d", &temp);
Jason Reiss 34:3b696c2b1e4b 1586 data.push_back(temp); // AT_APP_VERSION_MINOR; // MINOR
Jason Reiss 34:3b696c2b1e4b 1587 ret = sscanf(&version[4], "%d", &temp);
Jason Reiss 34:3b696c2b1e4b 1588 data.push_back(temp); // AT_APP_VERSION_PATCH; // PATCH
Jason Reiss 34:3b696c2b1e4b 1589 if (version.size() > 7) {
Jason Reiss 34:3b696c2b1e4b 1590 ret = sscanf(&version[6], "%d", &temp);
Jason Reiss 34:3b696c2b1e4b 1591 data.push_back(temp); // AT_APP_VERSION_PATCH; // PATCH
Jason Reiss 34:3b696c2b1e4b 1592 } else {
Jason Reiss 34:3b696c2b1e4b 1593 data.push_back(0); // AT_APP_VERSION_PATCH; // PATCH
Jason Reiss 34:3b696c2b1e4b 1594 }
Jason Reiss 28:c222ca8383f4 1595 break;
Jason Reiss 28:c222ca8383f4 1596 }
Jason Reiss 28:c222ca8383f4 1597 default: {
Jason Reiss 28:c222ca8383f4 1598 break;
Jason Reiss 28:c222ca8383f4 1599 }
Jason Reiss 28:c222ca8383f4 1600 }
Jason Reiss 28:c222ca8383f4 1601 }
Jason Reiss 28:c222ca8383f4 1602
Jason Reiss 28:c222ca8383f4 1603 do {
Jason Reiss 34:3b696c2b1e4b 1604 while (std::chrono::duration_cast<std::chrono::milliseconds>(sentTimer.elapsed_time()).count() < txPeriod
Jason Reiss 34:3b696c2b1e4b 1605 || CommandTerminal::Dot()->getNextTxMs() > 0) {
Jason Reiss 34:3b696c2b1e4b 1606 // if (waitingForBeacon && BeaconLocked) {
Jason Reiss 34:3b696c2b1e4b 1607 // goto TEST_START;
Jason Reiss 34:3b696c2b1e4b 1608 // }
Jason Reiss 34:3b696c2b1e4b 1609 osDelay(1000);
Jason Reiss 34:3b696c2b1e4b 1610 }
Jason Reiss 28:c222ca8383f4 1611
Jason Reiss 28:c222ca8383f4 1612 sentTimer.reset();
Jason Reiss 28:c222ca8383f4 1613
Jason Reiss 34:3b696c2b1e4b 1614 if (data.size() == 0) {
Jason Reiss 34:3b696c2b1e4b 1615 CommandTerminal::Dot()->setAppPort(1);
Jason Reiss 34:3b696c2b1e4b 1616 data.push_back(0xFF);
Jason Reiss 34:3b696c2b1e4b 1617 } else {
Jason Reiss 34:3b696c2b1e4b 1618 CommandTerminal::Dot()->setAppPort(224);
Jason Reiss 34:3b696c2b1e4b 1619 }
Jason Reiss 34:3b696c2b1e4b 1620
Jason Reiss 28:c222ca8383f4 1621 if (CommandTerminal::Dot()->send(data, testConfirmed) == mDot::MDOT_MAX_PAYLOAD_EXCEEDED) {
Jason Reiss 28:c222ca8383f4 1622 data.clear();
Jason Reiss 28:c222ca8383f4 1623 RxPort = 0;
Jason Reiss 28:c222ca8383f4 1624 goto TEST_START;
Jason Reiss 28:c222ca8383f4 1625 }
Jason Reiss 28:c222ca8383f4 1626
Jason Reiss 28:c222ca8383f4 1627 if (PacketReceived) {
Jason Reiss 28:c222ca8383f4 1628 last_rx_seq = CommandTerminal::Dot()->getSettings()->Session.UplinkCounter;
Jason Reiss 28:c222ca8383f4 1629 }
Jason Reiss 28:c222ca8383f4 1630
Jason Reiss 28:c222ca8383f4 1631 data.clear();
Jason Reiss 28:c222ca8383f4 1632
Jason Reiss 34:3b696c2b1e4b 1633 } while (!AckReceived && CommandTerminal::Dot()->recv(data) != mDot::MDOT_OK);
Jason Reiss 28:c222ca8383f4 1634
Jason Reiss 34:3b696c2b1e4b 1635 if (AckReceived || (PacketReceived && (RxPort != 0 || RxPayloadSize == 0))) {
Jason Reiss 28:c222ca8383f4 1636 testDownlinkCounter++;
Jason Reiss 34:3b696c2b1e4b 1637 logDebug("Incremented downlink cnt %d", testDownlinkCounter);
Jason Reiss 34:3b696c2b1e4b 1638 }
Jason Reiss 34:3b696c2b1e4b 1639
Jason Reiss 34:3b696c2b1e4b 1640 PacketReceived = false;
Jason Reiss 34:3b696c2b1e4b 1641 AckReceived = false;
Jason Reiss 28:c222ca8383f4 1642 }
Jason Reiss 28:c222ca8383f4 1643 #endif
Jason Reiss 28:c222ca8383f4 1644 }
Jason Reiss 28:c222ca8383f4 1645
jenkins@jenkinsdm1 18:63f098f042b2 1646 uint8_t CommandTerminal::getBatteryLevel() {
jenkins@jenkinsdm1 18:63f098f042b2 1647 return _battery_level;
jenkins@jenkinsdm1 18:63f098f042b2 1648 }
jenkins@jenkinsdm1 18:63f098f042b2 1649
Jason Reiss 23:4f0a981c0349 1650 void CommandTerminal::setBatteryLevel(uint8_t battery_level) {
jenkins@jenkinsdm1 18:63f098f042b2 1651 _battery_level = battery_level;
jenkins@jenkinsdm1 18:63f098f042b2 1652 }
jenkins@jenkinsdm1 18:63f098f042b2 1653
Jason Reiss 27:5fafd3b26ac3 1654 void CommandTerminal::formatPacket(uint8_t* payload, uint16_t size, bool hex) {
Jason Reiss 23:4f0a981c0349 1655
Jason Reiss 23:4f0a981c0349 1656 if(_dot->getAckRequested()) {
Jason Reiss 23:4f0a981c0349 1657 f_data[0] = 0;
Jason Reiss 23:4f0a981c0349 1658 } else {
Jason Reiss 23:4f0a981c0349 1659 f_data[0] = 1;
Jason Reiss 23:4f0a981c0349 1660 }
Jason Reiss 23:4f0a981c0349 1661
Jason Reiss 23:4f0a981c0349 1662 f_data[1] = _rxAddress & 0xFF;
Jason Reiss 23:4f0a981c0349 1663 f_data[2] = (_rxAddress >> 8) & 0xFF;
Jason Reiss 23:4f0a981c0349 1664 f_data[3] = (_rxAddress >> 16) & 0xFF;
Jason Reiss 23:4f0a981c0349 1665 f_data[4] = (_rxAddress >> 24) & 0xFF;
Jason Reiss 28:c222ca8383f4 1666 f_data[5] = _rxFcnt & 0xFF;
Jason Reiss 28:c222ca8383f4 1667 f_data[6] = (_rxFcnt >> 8) & 0xFF;
Jason Reiss 28:c222ca8383f4 1668 f_data[7] = (_rxFcnt >> 16) & 0xFF;
Jason Reiss 28:c222ca8383f4 1669 f_data[8] = (_rxFcnt >> 24) & 0xFF;
Jason Reiss 23:4f0a981c0349 1670 f_data[9] = _events->RxPort;
Jason Reiss 23:4f0a981c0349 1671
Jason Reiss 23:4f0a981c0349 1672 for(int i = 0; i < size; i++)
Jason Reiss 23:4f0a981c0349 1673 f_data[i+10] = payload[i];
Jason Reiss 23:4f0a981c0349 1674
Jason Reiss 27:5fafd3b26ac3 1675 if (hex) {
Jason Reiss 27:5fafd3b26ac3 1676 std::string data = "RECV " + mts::Text::bin2hexString(f_data, size + 10) + "\r\n";
Jason Reiss 27:5fafd3b26ac3 1677 CommandTerminal::Serial()->write(data.c_str(), data.size());
Jason Reiss 27:5fafd3b26ac3 1678 } else {
Jason Reiss 27:5fafd3b26ac3 1679 CommandTerminal::Serial()->write((char*)f_data, size + 10);
Jason Reiss 27:5fafd3b26ac3 1680 }
Jason Reiss 23:4f0a981c0349 1681 }
Jason Reiss 23:4f0a981c0349 1682
Jason Reiss 23:4f0a981c0349 1683
Jason Reiss 27:5fafd3b26ac3 1684 std::string CommandTerminal::formatPacket(std::vector<uint8_t> payload, bool hex) {
Jason Reiss 23:4f0a981c0349 1685
Jason Reiss 23:4f0a981c0349 1686 if(_dot->getAckRequested()) {
Jason Reiss 23:4f0a981c0349 1687 f_data[0] = 0;
Jason Reiss 23:4f0a981c0349 1688 } else {
Jason Reiss 23:4f0a981c0349 1689 f_data[0] = 1;
Jason Reiss 23:4f0a981c0349 1690 }
Jason Reiss 23:4f0a981c0349 1691
Jason Reiss 23:4f0a981c0349 1692 f_data[1] = _rxAddress & 0xFF;
Jason Reiss 23:4f0a981c0349 1693 f_data[2] = (_rxAddress >> 8) & 0xFF;
Jason Reiss 23:4f0a981c0349 1694 f_data[3] = (_rxAddress >> 16) & 0xFF;
Jason Reiss 23:4f0a981c0349 1695 f_data[4] = (_rxAddress >> 24) & 0xFF;
Jason Reiss 28:c222ca8383f4 1696 f_data[5] = _rxFcnt & 0xFF;
Jason Reiss 28:c222ca8383f4 1697 f_data[6] = (_rxFcnt >> 8) & 0xFF;
Jason Reiss 28:c222ca8383f4 1698 f_data[7] = (_rxFcnt >> 16) & 0xFF;
Jason Reiss 28:c222ca8383f4 1699 f_data[8] = (_rxFcnt >> 24) & 0xFF;
Jason Reiss 23:4f0a981c0349 1700 f_data[9] = _events->RxPort;
Jason Reiss 23:4f0a981c0349 1701
Jason Reiss 27:5fafd3b26ac3 1702 for(size_t i = 0; i < payload.size(); i++)
Jason Reiss 23:4f0a981c0349 1703 f_data[i+10] = payload.at(i);
Jason Reiss 23:4f0a981c0349 1704
Jason Reiss 27:5fafd3b26ac3 1705 if (hex) {
Jason Reiss 27:5fafd3b26ac3 1706 return mts::Text::bin2hexString(f_data, payload.size() + 10);
Jason Reiss 27:5fafd3b26ac3 1707 } else {
Jason Reiss 27:5fafd3b26ac3 1708 return std::string((char*)f_data, payload.size() + 10);
Jason Reiss 27:5fafd3b26ac3 1709 }
Jason Reiss 27:5fafd3b26ac3 1710
Jason Reiss 23:4f0a981c0349 1711 }
Jason Reiss 23:4f0a981c0349 1712
Jason Reiss 23:4f0a981c0349 1713
Jason Reiss 23:4f0a981c0349 1714
Jason Reiss 23:4f0a981c0349 1715 void CommandTerminal::formatPacketSDSend(std::vector<uint8_t> &payload) {
Jason Reiss 27:5fafd3b26ac3 1716 if (_dot->getRxOutput() == mDot::EXTENDED_HEX) {
Jason Reiss 27:5fafd3b26ac3 1717 int temp;
Jason Reiss 27:5fafd3b26ac3 1718 std::vector<uint8_t> converted;
Jason Reiss 27:5fafd3b26ac3 1719
Jason Reiss 27:5fafd3b26ac3 1720 for (size_t i=0; i < payload.size(); i+=2) {
Jason Reiss 27:5fafd3b26ac3 1721 if (sscanf((char*)&payload[i], "%2x", &temp) == 1) {
Jason Reiss 27:5fafd3b26ac3 1722 converted.push_back((uint8_t)temp);
Jason Reiss 27:5fafd3b26ac3 1723 }
Jason Reiss 27:5fafd3b26ac3 1724 }
Jason Reiss 27:5fafd3b26ac3 1725
Jason Reiss 27:5fafd3b26ac3 1726 payload = converted;
Jason Reiss 27:5fafd3b26ac3 1727 }
Jason Reiss 27:5fafd3b26ac3 1728
Jason Reiss 23:4f0a981c0349 1729 if(payload.size() >= 3) {
Jason Reiss 23:4f0a981c0349 1730 _dot->setAppPort(payload[0]);
Jason Reiss 23:4f0a981c0349 1731 _dot->setRepeat(0);
Jason Reiss 23:4f0a981c0349 1732 _dot->setAck(0);
Jason Reiss 23:4f0a981c0349 1733 switch(payload[1]) {
Jason Reiss 23:4f0a981c0349 1734 case 0:
Jason Reiss 23:4f0a981c0349 1735 _dot->setAck(payload[2]);
Jason Reiss 23:4f0a981c0349 1736 break;
Jason Reiss 23:4f0a981c0349 1737 case 1:
Jason Reiss 23:4f0a981c0349 1738 _dot->setRepeat(payload[2]);
Jason Reiss 23:4f0a981c0349 1739 break;
Jason Reiss 23:4f0a981c0349 1740 default:
Jason Reiss 23:4f0a981c0349 1741 break;
Jason Reiss 23:4f0a981c0349 1742 }
Jason Reiss 23:4f0a981c0349 1743 payload.erase(payload.begin(), payload.begin()+3);
Jason Reiss 23:4f0a981c0349 1744 }
Jason Reiss 27:5fafd3b26ac3 1745
Jason Reiss 23:4f0a981c0349 1746 }
Jason Reiss 23:4f0a981c0349 1747
Jason Reiss 23:4f0a981c0349 1748
Jason Reiss 23:4f0a981c0349 1749
Mike Fiore 9:ff62b20f7000 1750 CommandTerminal::~CommandTerminal() {
Mike Fiore 9:ff62b20f7000 1751 delete _events;
Mike Fiore 9:ff62b20f7000 1752 }