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:
jreiss
Date:
Fri Mar 08 20:14:37 2019 +0000
Revision:
20:704ce2249f5a
Parent:
19:7d87f36bca8a
Child:
22:a13ac7df92c0
Remove FOTA commands if not mDot

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Mike Fiore 1:e52ae6584f1c 1 #include "ctype.h"
jenkins@jenkinsdm1 18:63f098f042b2 2 #include "CmdFactory.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>
Mike Fiore 14:f9a77400b622 9 #if defined(TARGET_XDOT_L151CC)
Mike Fiore 14:f9a77400b622 10 #include "xdot_low_power.h"
Mike Fiore 14:f9a77400b622 11 #endif
Mike Fiore 1:e52ae6584f1c 12
Mike Fiore 14:f9a77400b622 13 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 1:e52ae6584f1c 14 const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa XBee Module\r\n\n";
Mike Fiore 14:f9a77400b622 15 #else
Mike Fiore 14:f9a77400b622 16 const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa xDot Module\r\n\n";
Mike Fiore 14:f9a77400b622 17 #endif
Mike Fiore 1:e52ae6584f1c 18 const char CommandTerminal::helpline[] = "Enter '?' for help\r\n";
Mike Fiore 1:e52ae6584f1c 19
Mike Fiore 1:e52ae6584f1c 20 const char CommandTerminal::newline[] = "\r\n";
Mike Fiore 1:e52ae6584f1c 21
Mike Fiore 1:e52ae6584f1c 22 // Command error text...
Mike Fiore 1:e52ae6584f1c 23 const char CommandTerminal::command_error[] = "Command not found!\r\n";
Mike Fiore 1:e52ae6584f1c 24
Mike Fiore 1:e52ae6584f1c 25 // Response texts...
Mike Fiore 1:e52ae6584f1c 26 const char CommandTerminal::help[] = "\r\nHelp\r\n";
Mike Fiore 1:e52ae6584f1c 27 const char CommandTerminal::cmd_error[] = "Invalid command\r\n";
Mike Fiore 9:ff62b20f7000 28 const char CommandTerminal::connect[] = "\r\nCONNECT\r\n";
Mike Fiore 9:ff62b20f7000 29 const char CommandTerminal::no_carrier[] = "\r\nNO CARRIER\r\n";
Mike Fiore 1:e52ae6584f1c 30 const char CommandTerminal::done[] = "\r\nOK\r\n";
Mike Fiore 1:e52ae6584f1c 31 const char CommandTerminal::error[] = "\r\nERROR\r\n";
Mike Fiore 1:e52ae6584f1c 32
Mike Fiore 1:e52ae6584f1c 33 // Escape sequence...
Mike Fiore 1:e52ae6584f1c 34 const char CommandTerminal::escape_sequence[] = "+++";
Mike Fiore 1:e52ae6584f1c 35
Mike Fiore 9:ff62b20f7000 36 mts::ATSerial* CommandTerminal::_serialp = NULL;
Mike Fiore 14:f9a77400b622 37 mDot* CommandTerminal::_dot = NULL;
Mike Fiore 14:f9a77400b622 38
Mike Fiore 14:f9a77400b622 39 CommandTerminal::RadioEvent* CommandTerminal::_events = new RadioEvent();
Mike Fiore 9:ff62b20f7000 40
Mike Fiore 9:ff62b20f7000 41 static bool serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 42 static bool peer_to_peer = false;
Mike Fiore 1:e52ae6584f1c 43
Mike Fiore 14:f9a77400b622 44 std::string CommandTerminal::_errorMessage = "";
Mike Fiore 14:f9a77400b622 45
jenkins@jenkinsdm1 18:63f098f042b2 46 static uint8_t _battery_level = 0xFF;
jenkins@jenkinsdm1 18:63f098f042b2 47
Mike Fiore 14:f9a77400b622 48 void CommandTerminal::setErrorMessage(const char* message) {
Mike Fiore 14:f9a77400b622 49 _errorMessage.assign(message);
Mike Fiore 14:f9a77400b622 50 }
Mike Fiore 14:f9a77400b622 51
Mike Fiore 14:f9a77400b622 52 void CommandTerminal::setErrorMessage(const std::string& message) {
Mike Fiore 14:f9a77400b622 53 _errorMessage.assign(message);
Mike Fiore 1:e52ae6584f1c 54 }
jenkins@jenkinsdm1 18:63f098f042b2 55
Mike Fiore 14:f9a77400b622 56 CommandTerminal::CommandTerminal(mts::ATSerial& serial) :
Mike Fiore 14:f9a77400b622 57 _serial(serial),
Mike Fiore 14:f9a77400b622 58 _mode(mDot::COMMAND_MODE),
Mike Fiore 14:f9a77400b622 59 _sleep_standby(true),
Mike Fiore 14:f9a77400b622 60 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 14:f9a77400b622 61 _xbee_on_sleep(XBEE_ON_SLEEP),
Mike Fiore 14:f9a77400b622 62 #else
Mike Fiore 14:f9a77400b622 63 _xbee_on_sleep(GPIO2),
Mike Fiore 14:f9a77400b622 64 #endif
Mike Fiore 14:f9a77400b622 65 _autoOTAEnabled(false)
Mike Fiore 14:f9a77400b622 66 {
Mike Fiore 14:f9a77400b622 67 _serialp = &serial;
Mike Fiore 14:f9a77400b622 68 }
Mike Fiore 14:f9a77400b622 69
Mike Fiore 14:f9a77400b622 70 void CommandTerminal::init() {
Mike Fiore 14:f9a77400b622 71 _dot->setEvents(_events);
Mike Fiore 1:e52ae6584f1c 72 }
Mike Fiore 1:e52ae6584f1c 73
Mike Fiore 1:e52ae6584f1c 74 void CommandTerminal::printHelp() {
Mike Fiore 1:e52ae6584f1c 75 const char* name = NULL;
Mike Fiore 1:e52ae6584f1c 76 const char* text = NULL;
Mike Fiore 1:e52ae6584f1c 77 const char* desc = NULL;
Mike Fiore 1:e52ae6584f1c 78 const char* tab = "\t";
Mike Fiore 1:e52ae6584f1c 79
Mike Fiore 1:e52ae6584f1c 80 std::string header("Command");
Mike Fiore 1:e52ae6584f1c 81 header.append(tab);
Mike Fiore 1:e52ae6584f1c 82 header.append(tab);
Mike Fiore 1:e52ae6584f1c 83 header.append("Name");
Mike Fiore 1:e52ae6584f1c 84 header.append(tab);
Mike Fiore 1:e52ae6584f1c 85 header.append(tab);
Mike Fiore 1:e52ae6584f1c 86 header.append(tab);
Mike Fiore 1:e52ae6584f1c 87 header.append("Description");
Mike Fiore 1:e52ae6584f1c 88
Mike Fiore 1:e52ae6584f1c 89 write(newline);
Mike Fiore 1:e52ae6584f1c 90 write(header.c_str());
Mike Fiore 1:e52ae6584f1c 91 write(newline);
Mike Fiore 1:e52ae6584f1c 92 write(newline);
Mike Fiore 14:f9a77400b622 93
jenkins@jenkinsdm1 18:63f098f042b2 94 Command *cmd = NULL;
jenkins@jenkinsdm1 18:63f098f042b2 95 for (int i = 0; i < CmdFactory::NUMBER_OF_CMDS; i++) {
jenkins@jenkinsdm1 18:63f098f042b2 96 cmd = CmdFactory::Create(static_cast<CmdFactory::CmdId_t>(i));
jenkins@jenkinsdm1 18:63f098f042b2 97 name = cmd->name();
jenkins@jenkinsdm1 18:63f098f042b2 98 text = cmd->text();
jenkins@jenkinsdm1 18:63f098f042b2 99 desc = cmd->desc();
Mike Fiore 1:e52ae6584f1c 100 write(text);
Mike Fiore 1:e52ae6584f1c 101 if (strlen(text) < 8)
Mike Fiore 1:e52ae6584f1c 102 write(tab);
Mike Fiore 1:e52ae6584f1c 103 write(tab);
Mike Fiore 1:e52ae6584f1c 104 write(name);
Mike Fiore 1:e52ae6584f1c 105 if (strlen(name) < 8)
Mike Fiore 1:e52ae6584f1c 106 write(tab);
Mike Fiore 1:e52ae6584f1c 107 if (strlen(name) < 16)
Mike Fiore 1:e52ae6584f1c 108 write(tab);
Mike Fiore 1:e52ae6584f1c 109 write(tab);
Mike Fiore 1:e52ae6584f1c 110 write(desc);
Mike Fiore 1:e52ae6584f1c 111 write(newline);
jenkins@jenkinsdm1 18:63f098f042b2 112
jenkins@jenkinsdm1 18:63f098f042b2 113 delete cmd;
Mike Fiore 1:e52ae6584f1c 114 }
Mike Fiore 1:e52ae6584f1c 115
Mike Fiore 1:e52ae6584f1c 116 write(newline);
Mike Fiore 1:e52ae6584f1c 117 }
Mike Fiore 1:e52ae6584f1c 118
Mike Fiore 1:e52ae6584f1c 119 bool CommandTerminal::writeable() {
Mike Fiore 14:f9a77400b622 120 return _serialp->writeable();
Mike Fiore 1:e52ae6584f1c 121 }
Mike Fiore 1:e52ae6584f1c 122
Mike Fiore 1:e52ae6584f1c 123 bool CommandTerminal::readable() {
Mike Fiore 14:f9a77400b622 124 return _serialp->readable();
Mike Fiore 1:e52ae6584f1c 125 }
Mike Fiore 1:e52ae6584f1c 126
Mike Fiore 1:e52ae6584f1c 127 char CommandTerminal::read() {
Mike Fiore 1:e52ae6584f1c 128 char ch;
Mike Fiore 14:f9a77400b622 129 _serialp->read(&ch, 1);
Mike Fiore 1:e52ae6584f1c 130 return ch;
Mike Fiore 1:e52ae6584f1c 131 }
Mike Fiore 1:e52ae6584f1c 132
Mike Fiore 1:e52ae6584f1c 133 void CommandTerminal::write(const char* message) {
Mike Fiore 1:e52ae6584f1c 134 while (!writeable())
Mike Fiore 1:e52ae6584f1c 135 ;
Mike Fiore 14:f9a77400b622 136 _serialp->write(message, strlen(message));
Mike Fiore 1:e52ae6584f1c 137 }
Mike Fiore 1:e52ae6584f1c 138
Mike Fiore 1:e52ae6584f1c 139 void CommandTerminal::writef(const char* format, ...) {
Mike Fiore 1:e52ae6584f1c 140 char buff[256];
Mike Fiore 1:e52ae6584f1c 141
Mike Fiore 1:e52ae6584f1c 142 va_list ap;
Mike Fiore 1:e52ae6584f1c 143 va_start(ap, format);
Mike Fiore 1:e52ae6584f1c 144 int size = vsnprintf(buff, 256, format, ap);
Mike Fiore 1:e52ae6584f1c 145 while (!writeable())
Mike Fiore 1:e52ae6584f1c 146 ;
Mike Fiore 14:f9a77400b622 147 _serialp->write(buff, size);
Mike Fiore 1:e52ae6584f1c 148 va_end(ap);
Mike Fiore 1:e52ae6584f1c 149 }
Mike Fiore 1:e52ae6584f1c 150
Mike Fiore 9:ff62b20f7000 151 void CommandTerminal::serialLoop() {
Mike Fiore 1:e52ae6584f1c 152 Timer serial_read_timer;
Mike Fiore 1:e52ae6584f1c 153 std::vector<uint8_t> serial_buffer;
Mike Fiore 9:ff62b20f7000 154 std::vector<uint8_t> data;
Mike Fiore 9:ff62b20f7000 155 int timeout = 0;
Mike Fiore 1:e52ae6584f1c 156
Mike Fiore 9:ff62b20f7000 157 serial_read_timer.start();
Mike Fiore 1:e52ae6584f1c 158
Mike Fiore 9:ff62b20f7000 159 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) {
Mike Fiore 9:ff62b20f7000 160 _xbee_on_sleep = GPIO_PIN_SET;
Mike Fiore 1:e52ae6584f1c 161
Mike Fiore 9:ff62b20f7000 162 timeout = _dot->getWakeDelay();
Mike Fiore 1:e52ae6584f1c 163
Mike Fiore 9:ff62b20f7000 164 // wait for timeout or start of serial data
Mike Fiore 14:f9a77400b622 165 while (!readable() && serial_read_timer.read_ms() < timeout && !_serialp->escaped()) {
Mike Fiore 9:ff62b20f7000 166 osDelay(2);
Mike Fiore 1:e52ae6584f1c 167 }
Mike Fiore 1:e52ae6584f1c 168 }
Mike Fiore 1:e52ae6584f1c 169
Mike Fiore 14:f9a77400b622 170 if (!readable() && _events->SendAck()) {
Mike Fiore 14:f9a77400b622 171 logDebug("SERIAL NOT READABLE and ACK REQUESTED");
Mike Fiore 14:f9a77400b622 172 goto L_SEND;
Mike Fiore 14:f9a77400b622 173 }
Mike Fiore 14:f9a77400b622 174
Mike Fiore 14:f9a77400b622 175 if (readable() && !_serialp->escaped()) {
Mike Fiore 6:e27eaad36a0c 176
Mike Fiore 6:e27eaad36a0c 177 serial_read_timer.reset();
Mike Fiore 6:e27eaad36a0c 178 timeout = _dot->getWakeTimeout();
Mike Fiore 9:ff62b20f7000 179
Mike Fiore 9:ff62b20f7000 180 while (serial_read_timer.read_ms() < timeout && serial_buffer.size() <= _dot->getMaxPacketLength()) {
Mike Fiore 9:ff62b20f7000 181 while (readable() && serial_buffer.size() < _dot->getMaxPacketLength()) {
Mike Fiore 1:e52ae6584f1c 182 serial_buffer.push_back(read());
Mike Fiore 1:e52ae6584f1c 183 serial_read_timer.reset();
Mike Fiore 9:ff62b20f7000 184
Mike Fiore 14:f9a77400b622 185 if (_serialp->escaped())
Mike Fiore 9:ff62b20f7000 186 break;
Mike Fiore 1:e52ae6584f1c 187 }
Mike Fiore 1:e52ae6584f1c 188 }
Mike Fiore 9:ff62b20f7000 189
Mike Fiore 1:e52ae6584f1c 190 serial_read_timer.stop(), serial_read_timer.reset();
Mike Fiore 1:e52ae6584f1c 191
Mike Fiore 1:e52ae6584f1c 192 if (!serial_buffer.empty()) {
Mike Fiore 9:ff62b20f7000 193 if (_dot->getStartUpMode() == mDot::SERIAL_MODE)
Mike Fiore 14:f9a77400b622 194 _xbee_on_sleep = GPIO_PIN_RESET;
Mike Fiore 9:ff62b20f7000 195
Mike Fiore 14:f9a77400b622 196 L_SEND:
Mike Fiore 9:ff62b20f7000 197 // wait for any duty cycle limit to expire
Mike Fiore 14:f9a77400b622 198 while (_dot->getNextTxMs() > 0 && !_serialp->escaped()) {
Mike Fiore 9:ff62b20f7000 199 osDelay(10);
Mike Fiore 9:ff62b20f7000 200 }
Mike Fiore 9:ff62b20f7000 201
Mike Fiore 14:f9a77400b622 202 if (_dot->getIsIdle()) {
Mike Fiore 9:ff62b20f7000 203 logDebug("Received serial data, sending out radio.");
Mike Fiore 9:ff62b20f7000 204
Mike Fiore 9:ff62b20f7000 205 if (_dot->send(serial_buffer, false) != mDot::MDOT_OK) {
Mike Fiore 9:ff62b20f7000 206 logDebug("Send failed.");
Mike Fiore 9:ff62b20f7000 207 // If the data should be tossed after send failure, clear buffer
Mike Fiore 9:ff62b20f7000 208 if (_dot->getSerialClearOnError()) {
Mike Fiore 9:ff62b20f7000 209 serial_buffer.clear();
Mike Fiore 9:ff62b20f7000 210 }
Mike Fiore 9:ff62b20f7000 211 } else {
Mike Fiore 1:e52ae6584f1c 212
Mike Fiore 9:ff62b20f7000 213 // wait for send to finish
Mike Fiore 14:f9a77400b622 214 while (!_dot->getIsIdle() && !_serialp->escaped()) {
Mike Fiore 9:ff62b20f7000 215 osDelay(10);
Mike Fiore 14:f9a77400b622 216 }
Mike Fiore 9:ff62b20f7000 217
Mike Fiore 9:ff62b20f7000 218 // call recv to wait for any packet before sending again
Mike Fiore 14:f9a77400b622 219 if (!_serialp->escaped())
Mike Fiore 9:ff62b20f7000 220 _dot->recv(data);
Mike Fiore 9:ff62b20f7000 221
Mike Fiore 9:ff62b20f7000 222 // Clear the serial buffer if send is success
Mike Fiore 9:ff62b20f7000 223 serial_buffer.clear();
Mike Fiore 14:f9a77400b622 224
Mike Fiore 14:f9a77400b622 225 // In class C mode pending data will be sent automatically without uplink
Mike Fiore 14:f9a77400b622 226 if (_dot->getClass() != "C") {
Mike Fiore 14:f9a77400b622 227 if (_dot->getDataPending()) {
Mike Fiore 14:f9a77400b622 228 logDebug("Data is pending");
Mike Fiore 14:f9a77400b622 229 goto L_SEND;
Mike Fiore 14:f9a77400b622 230 }
Mike Fiore 14:f9a77400b622 231 if (_dot->getAckRequested()) {
Mike Fiore 14:f9a77400b622 232 logDebug("Ack requested");
Mike Fiore 14:f9a77400b622 233 goto L_SEND;
Mike Fiore 14:f9a77400b622 234 }
Mike Fiore 14:f9a77400b622 235 }
Mike Fiore 9:ff62b20f7000 236 }
Mike Fiore 1:e52ae6584f1c 237 } else {
Mike Fiore 6:e27eaad36a0c 238 logDebug("Radio is busy, cannot send.\r\n");
Mike Fiore 9:ff62b20f7000 239 osDelay(10);
Mike Fiore 1:e52ae6584f1c 240 }
Mike Fiore 1:e52ae6584f1c 241
Mike Fiore 1:e52ae6584f1c 242 } else {
Mike Fiore 6:e27eaad36a0c 243 logDebug("No data received from serial to send.\r\n");
Mike Fiore 1:e52ae6584f1c 244 }
Mike Fiore 9:ff62b20f7000 245 }
Mike Fiore 9:ff62b20f7000 246
Mike Fiore 14:f9a77400b622 247 if (!_serialp->readable() && _dot->getStartUpMode() == mDot::SERIAL_MODE && !_serialp->escaped()) {
Mike Fiore 14:f9a77400b622 248 sleep(true);
Mike Fiore 1:e52ae6584f1c 249 }
Mike Fiore 9:ff62b20f7000 250
Mike Fiore 14:f9a77400b622 251 if (_serialp->escaped()) {
Mike Fiore 14:f9a77400b622 252 _serialp->clearEscaped();
Mike Fiore 14:f9a77400b622 253 _serialp->rxClear();
Mike Fiore 9:ff62b20f7000 254 serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 255 _mode = mDot::COMMAND_MODE;
Mike Fiore 9:ff62b20f7000 256 logDebug("Exit Serial Mode");
Mike Fiore 9:ff62b20f7000 257 write(done);
Mike Fiore 9:ff62b20f7000 258 return;
Mike Fiore 9:ff62b20f7000 259 }
Mike Fiore 9:ff62b20f7000 260
Mike Fiore 9:ff62b20f7000 261 if (!_dot->getNetworkJoinStatus()) {
Mike Fiore 9:ff62b20f7000 262 serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 263 _mode = mDot::COMMAND_MODE;
Mike Fiore 9:ff62b20f7000 264 logDebug("Exit Serial Mode");
Mike Fiore 9:ff62b20f7000 265 write(no_carrier);
Mike Fiore 9:ff62b20f7000 266 return;
Mike Fiore 9:ff62b20f7000 267 }
Mike Fiore 1:e52ae6584f1c 268 }
Mike Fiore 1:e52ae6584f1c 269
Mike Fiore 1:e52ae6584f1c 270 bool CommandTerminal::autoJoinCheck() {
Mike Fiore 1:e52ae6584f1c 271
Mike Fiore 1:e52ae6584f1c 272 std::string escape_buffer;
Mike Fiore 1:e52ae6584f1c 273 int sleep = 1000;
Mike Fiore 1:e52ae6584f1c 274 Timer tmr;
Mike Fiore 9:ff62b20f7000 275 tmr.start();
Mike Fiore 1:e52ae6584f1c 276 int cnt = 0;
Mike Fiore 1:e52ae6584f1c 277
Mike Fiore 1:e52ae6584f1c 278 while (!_dot->getNetworkJoinStatus()) {
Mike Fiore 14:f9a77400b622 279 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 280 write("\r\nJoining network... ");
Mike Fiore 14:f9a77400b622 281 }
Mike Fiore 14:f9a77400b622 282 logInfo("Joining network... ");
Mike Fiore 1:e52ae6584f1c 283
Mike Fiore 9:ff62b20f7000 284 if (_dot->getNextTxMs() > 0) {
Mike Fiore 14:f9a77400b622 285 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 286 writef("\r\nWaiting %lu s before next join attempt\r\n", _dot->getNextTxMs() / 1000);
Mike Fiore 14:f9a77400b622 287 }
Mike Fiore 14:f9a77400b622 288 logInfo("Waiting %lu s before next join attempt", _dot->getNextTxMs() / 1000);
Mike Fiore 9:ff62b20f7000 289
Mike Fiore 9:ff62b20f7000 290 tmr.reset();
Mike Fiore 9:ff62b20f7000 291 while (_dot->getNextTxMs() > 0 && !_serial.escaped()) {
Mike Fiore 14:f9a77400b622 292 osDelay(20);
Mike Fiore 1:e52ae6584f1c 293 }
Mike Fiore 1:e52ae6584f1c 294 }
Mike Fiore 1:e52ae6584f1c 295
Mike Fiore 9:ff62b20f7000 296 if (!_serial.escaped() && _dot->joinNetworkOnce() == mDot::MDOT_OK) {
Mike Fiore 14:f9a77400b622 297 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 298 write("Network Joined\r\n");
Mike Fiore 14:f9a77400b622 299 write(done);
Mike Fiore 14:f9a77400b622 300 }
Mike Fiore 14:f9a77400b622 301 logInfo("Network Joined");
Mike Fiore 1:e52ae6584f1c 302 return false;
Mike Fiore 1:e52ae6584f1c 303 }
Mike Fiore 1:e52ae6584f1c 304
Mike Fiore 14:f9a77400b622 305 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 306 write("Network Join failed\r\n");
Mike Fiore 14:f9a77400b622 307 write(error);
Mike Fiore 14:f9a77400b622 308 }
Mike Fiore 14:f9a77400b622 309 logInfo("Network Join failed");
Mike Fiore 1:e52ae6584f1c 310
Mike Fiore 14:f9a77400b622 311 if (!_serial.escaped() && _dot->getFrequencySubBand() != 0 && _dot->getJoinRetries() > 0 && cnt++ > _dot->getJoinRetries()) {
Mike Fiore 1:e52ae6584f1c 312 cnt = 0;
Mike Fiore 1:e52ae6584f1c 313
jenkins@jenkinsdm1 16:d5cf2af81a6d 314 if (lora::ChannelPlan::IsPlanFixed(_dot->getFrequencyBand())) {
Mike Fiore 1:e52ae6584f1c 315 uint8_t band = ((_dot->getFrequencySubBand()) % 8) + 1;
Mike Fiore 9:ff62b20f7000 316 logWarning("Join retries exhausted, switching to sub band %u", band);
Mike Fiore 1:e52ae6584f1c 317 _dot->setFrequencySubBand(band);
Mike Fiore 1:e52ae6584f1c 318 }
Mike Fiore 1:e52ae6584f1c 319 }
Mike Fiore 1:e52ae6584f1c 320
Mike Fiore 1:e52ae6584f1c 321 tmr.reset();
Mike Fiore 9:ff62b20f7000 322 while (tmr.read_ms() < sleep && !_serial.escaped()) {
Mike Fiore 9:ff62b20f7000 323 osDelay(10);
Mike Fiore 1:e52ae6584f1c 324 }
Mike Fiore 1:e52ae6584f1c 325
Mike Fiore 9:ff62b20f7000 326 if (_serial.escaped()) {
Mike Fiore 9:ff62b20f7000 327 _serial.clearEscaped();
Mike Fiore 9:ff62b20f7000 328 serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 329 _mode = mDot::COMMAND_MODE;
Mike Fiore 14:f9a77400b622 330 if (!serial_data_mode) {
Mike Fiore 14:f9a77400b622 331 write("Join Canceled\r\n");
Mike Fiore 14:f9a77400b622 332 write(done);
Mike Fiore 14:f9a77400b622 333 }
Mike Fiore 14:f9a77400b622 334 logInfo("Join Canceled\r\n");
Mike Fiore 9:ff62b20f7000 335 return true;
Mike Fiore 9:ff62b20f7000 336 }
Mike Fiore 1:e52ae6584f1c 337 }
Mike Fiore 1:e52ae6584f1c 338
Mike Fiore 1:e52ae6584f1c 339 return false;
Mike Fiore 1:e52ae6584f1c 340 }
Mike Fiore 1:e52ae6584f1c 341
Mike Fiore 1:e52ae6584f1c 342 void CommandTerminal::start() {
Mike Fiore 1:e52ae6584f1c 343
Mike Fiore 1:e52ae6584f1c 344 char ch;
Mike Fiore 1:e52ae6584f1c 345 bool running = true;
Mike Fiore 1:e52ae6584f1c 346 bool echo = _dot->getEcho();
Mike Fiore 1:e52ae6584f1c 347 std::string command;
Mike Fiore 14:f9a77400b622 348 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 4:666017851052 349 std::deque<std::string> history;
Mike Fiore 4:666017851052 350 int history_index = -1;
Mike Fiore 14:f9a77400b622 351 #endif
Mike Fiore 1:e52ae6584f1c 352 std::vector<std::string> args;
Mike Fiore 9:ff62b20f7000 353 bool join_canceled = false;
Mike Fiore 1:e52ae6584f1c 354
Mike Fiore 14:f9a77400b622 355 _autoOTAEnabled = _dot->getJoinMode() == mDot::AUTO_OTA;
Mike Fiore 14:f9a77400b622 356
Mike Fiore 1:e52ae6584f1c 357 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) {
Mike Fiore 9:ff62b20f7000 358
Mike Fiore 9:ff62b20f7000 359 serial_data_mode = true;
Mike Fiore 9:ff62b20f7000 360 _mode = mDot::SERIAL_MODE;
Mike Fiore 1:e52ae6584f1c 361
Mike Fiore 1:e52ae6584f1c 362 std::string escape_buffer;
Mike Fiore 1:e52ae6584f1c 363 char ch;
Mike Fiore 1:e52ae6584f1c 364
Mike Fiore 9:ff62b20f7000 365 if (!_dot->getStandbyFlag()) {
Mike Fiore 9:ff62b20f7000 366 // wake up from power-on/reset
Mike Fiore 9:ff62b20f7000 367
Mike Fiore 9:ff62b20f7000 368 int escape_timeout = 1000;
Mike Fiore 9:ff62b20f7000 369 Timer tmr;
Mike Fiore 9:ff62b20f7000 370 Timer escape_tmr;
Mike Fiore 1:e52ae6584f1c 371
Mike Fiore 9:ff62b20f7000 372 // wait one second for possible escape by user pressing '+' key
Mike Fiore 9:ff62b20f7000 373 tmr.reset();
Mike Fiore 9:ff62b20f7000 374 tmr.start();
Mike Fiore 9:ff62b20f7000 375 escape_tmr.reset();
Mike Fiore 9:ff62b20f7000 376 escape_tmr.start();
Mike Fiore 9:ff62b20f7000 377 while (tmr.read_ms() < escape_timeout) {
Mike Fiore 9:ff62b20f7000 378 if (_serial.readable()) {
Mike Fiore 9:ff62b20f7000 379 _serial.read(&ch, 1);
Mike Fiore 9:ff62b20f7000 380 escape_buffer += ch;
Mike Fiore 9:ff62b20f7000 381 }
Mike Fiore 1:e52ae6584f1c 382
Mike Fiore 9:ff62b20f7000 383 if (escape_buffer.find("+") != std::string::npos) {
Mike Fiore 9:ff62b20f7000 384 logInfo("Escape detected");
Mike Fiore 9:ff62b20f7000 385 join_canceled = true;
Mike Fiore 9:ff62b20f7000 386 serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 387 _mode = mDot::COMMAND_MODE;
Mike Fiore 9:ff62b20f7000 388 command.clear();
Mike Fiore 9:ff62b20f7000 389 break;
Mike Fiore 9:ff62b20f7000 390 }
Mike Fiore 9:ff62b20f7000 391
Mike Fiore 9:ff62b20f7000 392 if (escape_tmr.read_ms() > escape_timeout)
Mike Fiore 9:ff62b20f7000 393 escape_buffer.clear();
Mike Fiore 9:ff62b20f7000 394
Mike Fiore 9:ff62b20f7000 395 osDelay(1);
Mike Fiore 1:e52ae6584f1c 396 }
Mike Fiore 1:e52ae6584f1c 397 }
Mike Fiore 1:e52ae6584f1c 398
Mike Fiore 9:ff62b20f7000 399 if (_mode == mDot::SERIAL_MODE && !_dot->getNetworkJoinStatus() && _dot->getJoinMode() == mDot::OTA) {
Mike Fiore 9:ff62b20f7000 400 if (_dot->joinNetworkOnce() != mDot::MDOT_OK) {
Mike Fiore 9:ff62b20f7000 401 serial_data_mode = false;
Mike Fiore 9:ff62b20f7000 402 _mode = mDot::COMMAND_MODE;
Mike Fiore 9:ff62b20f7000 403
Mike Fiore 9:ff62b20f7000 404 logWarning("Start Up Mode set to SERIAL_MODE, but join failed.");
Mike Fiore 9:ff62b20f7000 405 _serial.writef("Network Not Joined\r\n");
Mike Fiore 9:ff62b20f7000 406 _serial.writef(error);
Mike Fiore 9:ff62b20f7000 407 }
Mike Fiore 9:ff62b20f7000 408 }
Mike Fiore 1:e52ae6584f1c 409 }
Mike Fiore 1:e52ae6584f1c 410
Mike Fiore 9:ff62b20f7000 411 if (_dot->getJoinMode() == mDot::PEER_TO_PEER) {
Mike Fiore 9:ff62b20f7000 412 peer_to_peer = true;
Mike Fiore 9:ff62b20f7000 413 } else {
Mike Fiore 9:ff62b20f7000 414 peer_to_peer = false;
Mike Fiore 9:ff62b20f7000 415 }
Mike Fiore 1:e52ae6584f1c 416 //Run terminal session
Mike Fiore 1:e52ae6584f1c 417 while (running) {
jenkins@jenkinsdm1 18:63f098f042b2 418 // wait for input to reduce at command idle current
Mike Fiore 9:ff62b20f7000 419 while (!readable() || _mode == mDot::SERIAL_MODE) {
Mike Fiore 14:f9a77400b622 420 if (!join_canceled && _autoOTAEnabled) {
Mike Fiore 9:ff62b20f7000 421 join_canceled = autoJoinCheck();
Mike Fiore 9:ff62b20f7000 422 if (join_canceled)
Mike Fiore 9:ff62b20f7000 423 command.clear();
Mike Fiore 9:ff62b20f7000 424 }
Mike Fiore 1:e52ae6584f1c 425
Mike Fiore 14:f9a77400b622 426 if (!_autoOTAEnabled || (!join_canceled && _autoOTAEnabled)) {
Mike Fiore 9:ff62b20f7000 427 switch (_mode) {
Mike Fiore 9:ff62b20f7000 428 case mDot::SERIAL_MODE:
Mike Fiore 9:ff62b20f7000 429 // signal wakeup, read serial and output to radio
Mike Fiore 9:ff62b20f7000 430 serialLoop();
Mike Fiore 9:ff62b20f7000 431 continue;
Mike Fiore 9:ff62b20f7000 432 break;
Mike Fiore 9:ff62b20f7000 433 default:
Mike Fiore 9:ff62b20f7000 434 break;
Mike Fiore 9:ff62b20f7000 435 }
Mike Fiore 1:e52ae6584f1c 436 }
Mike Fiore 9:ff62b20f7000 437
Mike Fiore 9:ff62b20f7000 438 ch = '\0';
Mike Fiore 1:e52ae6584f1c 439
Mike Fiore 9:ff62b20f7000 440 wait(0.00001); // 10 us
Mike Fiore 9:ff62b20f7000 441 _serial.escaped();
Mike Fiore 9:ff62b20f7000 442 }
Mike Fiore 1:e52ae6584f1c 443
Mike Fiore 1:e52ae6584f1c 444 // read characters
Mike Fiore 1:e52ae6584f1c 445 if (readable()) {
Mike Fiore 1:e52ae6584f1c 446 ch = read();
Mike Fiore 1:e52ae6584f1c 447
Mike Fiore 4:666017851052 448 if (ch == '\b' || ch == 0x7f) {
Mike Fiore 1:e52ae6584f1c 449 if (!command.empty()) {
Mike Fiore 1:e52ae6584f1c 450 writef("\b \b");
Mike Fiore 1:e52ae6584f1c 451 command.erase(command.size() - 1);
Mike Fiore 1:e52ae6584f1c 452 }
Mike Fiore 1:e52ae6584f1c 453 continue;
Mike Fiore 4:666017851052 454 } else if (ch == 0x1b || ch == 0x09) {
Mike Fiore 4:666017851052 455 osDelay(20);
Mike Fiore 4:666017851052 456 // catch escape sequence, or tab
Mike Fiore 9:ff62b20f7000 457 char ch1 = 0x00, ch2 = 0x00;
Mike Fiore 4:666017851052 458
Mike Fiore 4:666017851052 459 if (readable()) {
Mike Fiore 4:666017851052 460 ch1 = read();
Mike Fiore 4:666017851052 461 if (readable())
Mike Fiore 4:666017851052 462 ch2 = read();
Mike Fiore 4:666017851052 463
Mike Fiore 14:f9a77400b622 464 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 4:666017851052 465 if (ch1 == 0x5b && ch2 == 0x41) {
Mike Fiore 4:666017851052 466 // up key
Mike Fiore 9:ff62b20f7000 467 for (size_t i = 0; i < command.size() + 1; i++) {
Mike Fiore 4:666017851052 468 writef("\b \b");
Mike Fiore 4:666017851052 469 }
Mike Fiore 4:666017851052 470 if (history.size() > 0) {
Mike Fiore 9:ff62b20f7000 471 if (++history_index >= int(history.size() - 1))
Mike Fiore 4:666017851052 472 history_index = history.size() - 1;
Mike Fiore 4:666017851052 473
Mike Fiore 4:666017851052 474 command = history[history_index];
Mike Fiore 4:666017851052 475 writef("%s", history[history_index].c_str());
Mike Fiore 4:666017851052 476 } else {
Mike Fiore 4:666017851052 477 command.clear();
Mike Fiore 4:666017851052 478 }
Mike Fiore 4:666017851052 479 } else if (ch1 == 0x5b && ch2 == 0x42) {
Mike Fiore 4:666017851052 480
Mike Fiore 4:666017851052 481 // down key
Mike Fiore 9:ff62b20f7000 482 for (size_t i = 0; i < command.size() + 1; i++) {
Mike Fiore 4:666017851052 483 writef("\b \b");
Mike Fiore 4:666017851052 484 }
Mike Fiore 4:666017851052 485
Mike Fiore 4:666017851052 486 if (--history_index < 0) {
Mike Fiore 4:666017851052 487 history_index = -1;
Mike Fiore 4:666017851052 488 command.clear();
Mike Fiore 4:666017851052 489 } else {
Mike Fiore 4:666017851052 490 command = history[history_index];
Mike Fiore 4:666017851052 491 writef("%s", history[history_index].c_str());
Mike Fiore 4:666017851052 492 }
Mike Fiore 4:666017851052 493 }
Mike Fiore 14:f9a77400b622 494 #endif
Mike Fiore 4:666017851052 495 }
Mike Fiore 9:ff62b20f7000 496 while (readable())
Mike Fiore 9:ff62b20f7000 497 read();
Mike Fiore 4:666017851052 498 continue;
Mike Fiore 1:e52ae6584f1c 499 } else {
Mike Fiore 1:e52ae6584f1c 500 command += ch;
Mike Fiore 1:e52ae6584f1c 501 }
Mike Fiore 1:e52ae6584f1c 502
Mike Fiore 1:e52ae6584f1c 503 // echo chars if enabled
Mike Fiore 1:e52ae6584f1c 504 if (echo && !(ch == '\r' || ch == '\n'))
Mike Fiore 1:e52ae6584f1c 505 writef("%c", ch);
Mike Fiore 1:e52ae6584f1c 506 }
Mike Fiore 1:e52ae6584f1c 507
Mike Fiore 1:e52ae6584f1c 508 // look for end of command line
Mike Fiore 1:e52ae6584f1c 509 if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 510 // remove new line or cr character
Mike Fiore 1:e52ae6584f1c 511 command.erase(command.size() - 1);
Mike Fiore 1:e52ae6584f1c 512 write("\r"); // match standard modem output
Mike Fiore 1:e52ae6584f1c 513 write(newline);
Mike Fiore 1:e52ae6584f1c 514 } else {
Mike Fiore 1:e52ae6584f1c 515 continue;
Mike Fiore 1:e52ae6584f1c 516 }
Mike Fiore 1:e52ae6584f1c 517
Mike Fiore 1:e52ae6584f1c 518 // trim whitespace from command
Mike Fiore 1:e52ae6584f1c 519 mts::Text::trim(command, "\r\n\t ");
Mike Fiore 1:e52ae6584f1c 520
Mike Fiore 1:e52ae6584f1c 521 if (command.size() < 1) {
Mike Fiore 1:e52ae6584f1c 522 command.clear();
Mike Fiore 1:e52ae6584f1c 523 continue;
Mike Fiore 1:e52ae6584f1c 524 }
Mike Fiore 1:e52ae6584f1c 525
Mike Fiore 1:e52ae6584f1c 526 // parse command and args
Mike Fiore 1:e52ae6584f1c 527 args.clear();
Mike Fiore 1:e52ae6584f1c 528
Mike Fiore 1:e52ae6584f1c 529 // find first '=' character
Mike Fiore 1:e52ae6584f1c 530 size_t delim_index = command.find("=");
Mike Fiore 1:e52ae6584f1c 531 if (delim_index != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 532 args.push_back(command.substr(0, delim_index));
Mike Fiore 1:e52ae6584f1c 533 } else {
Mike Fiore 1:e52ae6584f1c 534 // find first ' ' character
Mike Fiore 1:e52ae6584f1c 535 delim_index = command.find(" ");
Mike Fiore 1:e52ae6584f1c 536 if (delim_index != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 537 args.push_back(command.substr(0, delim_index));
Mike Fiore 1:e52ae6584f1c 538 } else {
Mike Fiore 1:e52ae6584f1c 539 args.push_back(command);
Mike Fiore 1:e52ae6584f1c 540 }
Mike Fiore 1:e52ae6584f1c 541 }
Mike Fiore 1:e52ae6584f1c 542
Mike Fiore 1:e52ae6584f1c 543 if (delim_index != std::string::npos) {
Mike Fiore 1:e52ae6584f1c 544 std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ",");
Mike Fiore 1:e52ae6584f1c 545 args.insert(args.end(), params.begin(), params.end());
Mike Fiore 1:e52ae6584f1c 546 }
Mike Fiore 1:e52ae6584f1c 547
Mike Fiore 1:e52ae6584f1c 548 args[0] = mts::Text::toUpper(args[0]);
Mike Fiore 1:e52ae6584f1c 549
Mike Fiore 1:e52ae6584f1c 550 // print help
Mike Fiore 1:e52ae6584f1c 551 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) {
Mike Fiore 1:e52ae6584f1c 552 printHelp();
Mike Fiore 1:e52ae6584f1c 553 command.clear();
Mike Fiore 9:ff62b20f7000 554 } else if ((args[0].find("ATE?") == 0 && args[0].length() == 4) || (args[0].find("ATE") == 0 && args[0].length() == 3)) {
Mike Fiore 9:ff62b20f7000 555 writef("%d\r\n", _dot->getEcho());
Mike Fiore 9:ff62b20f7000 556 write(done);
Mike Fiore 1:e52ae6584f1c 557 } else if (args[0].find("ATE0") == 0 && args[0].length() == 4) {
Mike Fiore 1:e52ae6584f1c 558 _dot->setEcho(false);
Mike Fiore 1:e52ae6584f1c 559 write(done);
Mike Fiore 1:e52ae6584f1c 560 echo = _dot->getEcho();
Mike Fiore 1:e52ae6584f1c 561 } else if (args[0].find("ATE1") == 0 && args[0].length() == 4) {
Mike Fiore 1:e52ae6584f1c 562 _dot->setEcho(true);
Mike Fiore 1:e52ae6584f1c 563 write(done);
Mike Fiore 1:e52ae6584f1c 564 echo = _dot->getEcho();
Mike Fiore 9:ff62b20f7000 565 } else if ((args[0].find("ATV?") == 0 && args[0].length() == 4) || (args[0].find("ATV") == 0 && args[0].length() == 3)) {
Mike Fiore 9:ff62b20f7000 566 writef("%d\r\n", _dot->getVerbose());
Mike Fiore 9:ff62b20f7000 567 write(done);
Mike Fiore 1:e52ae6584f1c 568 } else if (args[0].find("ATV0") == 0 && args[0].length() == 4) {
Mike Fiore 1:e52ae6584f1c 569 _dot->setVerbose(false);
Mike Fiore 1:e52ae6584f1c 570 write(done);
Mike Fiore 1:e52ae6584f1c 571 } else if (args[0].find("ATV1") == 0 && args[0].length() == 4) {
Mike Fiore 1:e52ae6584f1c 572 _dot->setVerbose(true);
Mike Fiore 1:e52ae6584f1c 573 write(done);
Mike Fiore 9:ff62b20f7000 574 } else if ((args[0].find("AT&K?") == 0 && args[0].length() == 5) || (args[0].find("AT&K") == 0 && args[0].length() == 4)) {
Mike Fiore 9:ff62b20f7000 575 writef("%d\r\n", (_dot->getFlowControl() ? 3 : 0));
Mike Fiore 9:ff62b20f7000 576 write(done);
Mike Fiore 9:ff62b20f7000 577 } else if (args[0].find("AT&K0") == 0 && args[0].length() == 5) {
Mike Fiore 9:ff62b20f7000 578 _dot->setFlowControl(false);
Mike Fiore 9:ff62b20f7000 579 write(done);
Mike Fiore 9:ff62b20f7000 580 } else if (args[0].find("AT&K3") == 0 && args[0].length() == 5) {
Mike Fiore 9:ff62b20f7000 581 _dot->setFlowControl(true);
Mike Fiore 9:ff62b20f7000 582 write(done);
Mike Fiore 1:e52ae6584f1c 583 } else if (args[0] == "AT+SD") {
Mike Fiore 9:ff62b20f7000 584 if (_dot->getNetworkJoinStatus()) {
Mike Fiore 9:ff62b20f7000 585 logDebug("Enter Serial Mode");
Mike Fiore 9:ff62b20f7000 586 write(connect);
Mike Fiore 9:ff62b20f7000 587 serial_data_mode = true;
Mike Fiore 9:ff62b20f7000 588 _mode = mDot::SERIAL_MODE;
Mike Fiore 9:ff62b20f7000 589 } else {
Mike Fiore 9:ff62b20f7000 590 logDebug("Network Not Joined");
Mike Fiore 9:ff62b20f7000 591 write("Network Not Joined\r\n");
Mike Fiore 9:ff62b20f7000 592 write(error);
Mike Fiore 9:ff62b20f7000 593 }
Mike Fiore 4:666017851052 594 } else if (args[0] == "AT+SLEEP") {
Mike Fiore 9:ff62b20f7000 595 if (args.size() > 2 && (args[1] != "?")) {
Mike Fiore 4:666017851052 596 write("Invalid argument\r\n");
Mike Fiore 4:666017851052 597 write(error);
Mike Fiore 4:666017851052 598 } else {
Mike Fiore 4:666017851052 599 if (args.size() > 1 && args[1] == "?") {
Mike Fiore 9:ff62b20f7000 600 write("(0:deepsleep,1:sleep)\r\n");
Mike Fiore 4:666017851052 601 write(done);
Mike Fiore 4:666017851052 602 } else {
Mike Fiore 4:666017851052 603 _sleep_standby = !(args.size() > 1 && args[1] == "1");
Mike Fiore 14:f9a77400b622 604 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 14:f9a77400b622 605 //Read the board ID. If all 0's, it is revision B. This hardware does not support deep sleep.
Mike Fiore 14:f9a77400b622 606 DigitalIn ID2(PC_4);
Mike Fiore 14:f9a77400b622 607 DigitalIn ID1(PC_5);
Mike Fiore 14:f9a77400b622 608 DigitalIn ID0(PD_2);
Mike Fiore 14:f9a77400b622 609 if(ID2 == 0 && ID1 == 0 && ID0 == 0 && _sleep_standby == 1){
Mike Fiore 14:f9a77400b622 610 _sleep_standby = 0;
Mike Fiore 14:f9a77400b622 611 logWarning("This hardware version does not support deep sleep. Using sleep mode instead.");
Mike Fiore 14:f9a77400b622 612 }
Mike Fiore 14:f9a77400b622 613 #endif
Mike Fiore 9:ff62b20f7000 614 write(done);
Mike Fiore 14:f9a77400b622 615 osDelay(5);
Mike Fiore 4:666017851052 616 this->sleep(_sleep_standby);
Mike Fiore 14:f9a77400b622 617 osDelay(1);
Mike Fiore 4:666017851052 618 }
Mike Fiore 4:666017851052 619 }
Mike Fiore 1:e52ae6584f1c 620 } else {
Mike Fiore 1:e52ae6584f1c 621 bool found = false;
Mike Fiore 1:e52ae6584f1c 622 bool query = false;
Mike Fiore 1:e52ae6584f1c 623
Mike Fiore 1:e52ae6584f1c 624 std::string lookfor = args[0];
Mike Fiore 1:e52ae6584f1c 625
Mike Fiore 1:e52ae6584f1c 626 // per command help
Mike Fiore 1:e52ae6584f1c 627 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0))
Mike Fiore 1:e52ae6584f1c 628 lookfor = mts::Text::toUpper(args[1]);
Mike Fiore 1:e52ae6584f1c 629
Mike Fiore 1:e52ae6584f1c 630 // trim off any trailing '?' and mark as a query command
Mike Fiore 1:e52ae6584f1c 631 if (args[0].rfind("?") == args[0].length() - 1) {
Mike Fiore 1:e52ae6584f1c 632 query = true;
Mike Fiore 1:e52ae6584f1c 633 lookfor = args[0].substr(0, args[0].length() - 1);
Mike Fiore 1:e52ae6584f1c 634 }
Mike Fiore 1:e52ae6584f1c 635
Mike Fiore 1:e52ae6584f1c 636 // search for command
jenkins@jenkinsdm1 18:63f098f042b2 637 Command *cmd = NULL;
jenkins@jenkinsdm1 18:63f098f042b2 638 for (int i = 0; i < CmdFactory::NUMBER_OF_CMDS; i++) {
jenkins@jenkinsdm1 18:63f098f042b2 639 cmd = CmdFactory::Create(static_cast<CmdFactory::CmdId_t>(i));
Mike Fiore 1:e52ae6584f1c 640
Mike Fiore 1:e52ae6584f1c 641 // match CMD or CMD? syntax if command is queryable
jenkins@jenkinsdm1 18:63f098f042b2 642 if (lookfor == cmd->text() && (!query || (query && cmd->queryable()))) {
Mike Fiore 1:e52ae6584f1c 643 found = true;
Mike Fiore 1:e52ae6584f1c 644 if (args[0] == "HELP") {
jenkins@jenkinsdm1 18:63f098f042b2 645 writef("%s%s", cmd->help().c_str(), newline);
Mike Fiore 1:e52ae6584f1c 646 write(done);
Mike Fiore 1:e52ae6584f1c 647 }
Mike Fiore 1:e52ae6584f1c 648
Mike Fiore 1:e52ae6584f1c 649 else if (args.size() > 1 && args[1] == "?") {
jenkins@jenkinsdm1 18:63f098f042b2 650 writef("%s%s", cmd->usage().c_str(), newline);
Mike Fiore 1:e52ae6584f1c 651 write(done);
jenkins@jenkinsdm1 18:63f098f042b2 652 } else if (!cmd->verify(args)) {
Mike Fiore 14:f9a77400b622 653 writef("%s%s", _errorMessage.c_str(), newline);
Mike Fiore 1:e52ae6584f1c 654 writef("%s", error);
Mike Fiore 1:e52ae6584f1c 655 } else {
jenkins@jenkinsdm1 18:63f098f042b2 656 if (cmd->action(args) == 0) {
Mike Fiore 1:e52ae6584f1c 657 writef("%s", done);
Mike Fiore 1:e52ae6584f1c 658 } else {
Mike Fiore 14:f9a77400b622 659 writef("%s%s", _errorMessage.c_str(), newline);
Mike Fiore 1:e52ae6584f1c 660 writef("%s", error);
Mike Fiore 1:e52ae6584f1c 661 }
Mike Fiore 1:e52ae6584f1c 662 }
Mike Fiore 1:e52ae6584f1c 663 }
jenkins@jenkinsdm1 18:63f098f042b2 664
jenkins@jenkinsdm1 18:63f098f042b2 665 delete cmd;
Mike Fiore 1:e52ae6584f1c 666 }
Mike Fiore 1:e52ae6584f1c 667
Mike Fiore 1:e52ae6584f1c 668 if (!found) {
Mike Fiore 1:e52ae6584f1c 669 writef("%s", command_error);
Mike Fiore 1:e52ae6584f1c 670 writef("%s", error);
Mike Fiore 1:e52ae6584f1c 671 }
Mike Fiore 1:e52ae6584f1c 672 }
Mike Fiore 1:e52ae6584f1c 673
Mike Fiore 14:f9a77400b622 674 #if defined(TARGET_MTS_MDOT_F411RE)
Mike Fiore 4:666017851052 675 if (history.size() == 0 || history.front() != command)
Mike Fiore 4:666017851052 676 history.push_front(command);
Mike Fiore 4:666017851052 677 history_index = -1;
Mike Fiore 1:e52ae6584f1c 678 command.clear();
Mike Fiore 1:e52ae6584f1c 679
Mike Fiore 4:666017851052 680 while (history.size() > 10)
Mike Fiore 4:666017851052 681 history.pop_back();
Mike Fiore 14:f9a77400b622 682 #else
Mike Fiore 14:f9a77400b622 683 command.clear();
Mike Fiore 14:f9a77400b622 684 #endif
Mike Fiore 1:e52ae6584f1c 685 }
Mike Fiore 1:e52ae6584f1c 686 }
Mike Fiore 1:e52ae6584f1c 687
Mike Fiore 1:e52ae6584f1c 688 void CommandTerminal::sleep(bool standby) {
Mike Fiore 1:e52ae6584f1c 689 _xbee_on_sleep = GPIO_PIN_RESET;
Mike Fiore 1:e52ae6584f1c 690
Mike Fiore 4:666017851052 691 _serial.rxClear();
Mike Fiore 4:666017851052 692 _serial.txClear();
Mike Fiore 1:e52ae6584f1c 693
Mike Fiore 14:f9a77400b622 694 #if defined(TARGET_XDOT_L151CC)
Mike Fiore 14:f9a77400b622 695 xdot_save_gpio_state();
Mike Fiore 14:f9a77400b622 696
Mike Fiore 14:f9a77400b622 697 /* GPIO Ports Clock Enable */
Mike Fiore 14:f9a77400b622 698 __GPIOA_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 699 __GPIOB_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 700 __GPIOC_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 701 __GPIOH_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 702
Mike Fiore 14:f9a77400b622 703 GPIO_InitTypeDef GPIO_InitStruct;
Mike Fiore 14:f9a77400b622 704
Mike Fiore 14:f9a77400b622 705 // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source
Mike Fiore 14:f9a77400b622 706 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12;
Mike Fiore 14:f9a77400b622 707 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 708 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 709 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 710
Mike Fiore 14:f9a77400b622 711 // I2C_SDA & I2C_SCL to analog nopull
Mike Fiore 14:f9a77400b622 712 GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
Mike Fiore 14:f9a77400b622 713 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 714 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 715 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 716
Mike Fiore 14:f9a77400b622 717 // SPI_MOSI, SPI_MISO, SPI_SCK, & SPI_NSS to analog nopull
Mike Fiore 14:f9a77400b622 718 GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
Mike Fiore 14:f9a77400b622 719 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 720 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 721 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 722
Mike Fiore 14:f9a77400b622 723 // iterate through potential wake pins - leave the configured wake pin alone if one is needed
Mike Fiore 14:f9a77400b622 724 if (_dot->getWakePin() != WAKE || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 725 GPIO_InitStruct.Pin = GPIO_PIN_0;
Mike Fiore 14:f9a77400b622 726 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 727 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 728 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 729 }
Mike Fiore 14:f9a77400b622 730 if (_dot->getWakePin() != GPIO0 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 731 GPIO_InitStruct.Pin = GPIO_PIN_4;
Mike Fiore 14:f9a77400b622 732 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 733 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 734 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 735 }
Mike Fiore 14:f9a77400b622 736 if (_dot->getWakePin() != GPIO1 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 737 GPIO_InitStruct.Pin = GPIO_PIN_5;
Mike Fiore 14:f9a77400b622 738 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 739 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 740 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 741 }
Mike Fiore 14:f9a77400b622 742 if (_dot->getWakePin() != GPIO2 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 743 GPIO_InitStruct.Pin = GPIO_PIN_0;
Mike Fiore 14:f9a77400b622 744 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 745 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 746 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 747 }
Mike Fiore 14:f9a77400b622 748 if (_dot->getWakePin() != GPIO3 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 749 GPIO_InitStruct.Pin = GPIO_PIN_2;
Mike Fiore 14:f9a77400b622 750 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 751 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 752 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 753 }
Mike Fiore 14:f9a77400b622 754 if (_dot->getWakePin() != UART1_RX || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 755 GPIO_InitStruct.Pin = GPIO_PIN_10;
Mike Fiore 14:f9a77400b622 756 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 757 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 758 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 759 }
Mike Fiore 14:f9a77400b622 760 #else
Mike Fiore 14:f9a77400b622 761 uint32_t portA[6];
Mike Fiore 14:f9a77400b622 762 uint32_t portB[6];
Mike Fiore 14:f9a77400b622 763 uint32_t portC[6];
Mike Fiore 14:f9a77400b622 764 uint32_t portD[6];
Mike Fiore 14:f9a77400b622 765 uint32_t portH[6];
Mike Fiore 14:f9a77400b622 766
Mike Fiore 14:f9a77400b622 767 //Save the GPIO state.
Mike Fiore 14:f9a77400b622 768 portA[0] = GPIOA->MODER;
Mike Fiore 14:f9a77400b622 769 portA[1] = GPIOA->OTYPER;
Mike Fiore 14:f9a77400b622 770 portA[2] = GPIOA->OSPEEDR;
Mike Fiore 14:f9a77400b622 771 portA[3] = GPIOA->PUPDR;
Mike Fiore 14:f9a77400b622 772 portA[4] = GPIOA->AFR[0];
Mike Fiore 14:f9a77400b622 773 portA[5] = GPIOA->AFR[1];
Mike Fiore 14:f9a77400b622 774
Mike Fiore 14:f9a77400b622 775 portB[0] = GPIOB->MODER;
Mike Fiore 14:f9a77400b622 776 portB[1] = GPIOB->OTYPER;
Mike Fiore 14:f9a77400b622 777 portB[2] = GPIOB->OSPEEDR;
Mike Fiore 14:f9a77400b622 778 portB[3] = GPIOB->PUPDR;
Mike Fiore 14:f9a77400b622 779 portB[4] = GPIOB->AFR[0];
Mike Fiore 14:f9a77400b622 780 portB[5] = GPIOB->AFR[1];
Mike Fiore 14:f9a77400b622 781
Mike Fiore 14:f9a77400b622 782 portC[0] = GPIOC->MODER;
Mike Fiore 14:f9a77400b622 783 portC[1] = GPIOC->OTYPER;
Mike Fiore 14:f9a77400b622 784 portC[2] = GPIOC->OSPEEDR;
Mike Fiore 14:f9a77400b622 785 portC[3] = GPIOC->PUPDR;
Mike Fiore 14:f9a77400b622 786 portC[4] = GPIOC->AFR[0];
Mike Fiore 14:f9a77400b622 787 portC[5] = GPIOC->AFR[1];
Mike Fiore 14:f9a77400b622 788
Mike Fiore 14:f9a77400b622 789 portD[0] = GPIOD->MODER;
Mike Fiore 14:f9a77400b622 790 portD[1] = GPIOD->OTYPER;
Mike Fiore 14:f9a77400b622 791 portD[2] = GPIOD->OSPEEDR;
Mike Fiore 14:f9a77400b622 792 portD[3] = GPIOD->PUPDR;
Mike Fiore 14:f9a77400b622 793 portD[4] = GPIOD->AFR[0];
Mike Fiore 14:f9a77400b622 794 portD[5] = GPIOD->AFR[1];
Mike Fiore 14:f9a77400b622 795
Mike Fiore 14:f9a77400b622 796 portH[0] = GPIOH->MODER;
Mike Fiore 14:f9a77400b622 797 portH[1] = GPIOH->OTYPER;
Mike Fiore 14:f9a77400b622 798 portH[2] = GPIOH->OSPEEDR;
Mike Fiore 14:f9a77400b622 799 portH[3] = GPIOH->PUPDR;
Mike Fiore 14:f9a77400b622 800 portH[4] = GPIOH->AFR[0];
Mike Fiore 14:f9a77400b622 801 portH[5] = GPIOH->AFR[1];
Mike Fiore 14:f9a77400b622 802
Mike Fiore 14:f9a77400b622 803 /* GPIO Ports Clock Enable */
Mike Fiore 14:f9a77400b622 804 __GPIOA_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 805 __GPIOB_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 806 __GPIOC_CLK_ENABLE();
Mike Fiore 14:f9a77400b622 807
Mike Fiore 14:f9a77400b622 808 GPIO_InitTypeDef GPIO_InitStruct;
Mike Fiore 14:f9a77400b622 809
Mike Fiore 14:f9a77400b622 810 // Set port A pins to analog nopull
Mike Fiore 14:f9a77400b622 811 GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_6 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10
Mike Fiore 14:f9a77400b622 812 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
Mike Fiore 14:f9a77400b622 813 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 814 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 815 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 816
Mike Fiore 14:f9a77400b622 817 // Set port B pins to analog nopull
Mike Fiore 14:f9a77400b622 818 GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4;
Mike Fiore 14:f9a77400b622 819 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 820 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 821 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 822
Mike Fiore 14:f9a77400b622 823 // Set port C pins to analog nopull
Mike Fiore 14:f9a77400b622 824 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_13;
Mike Fiore 14:f9a77400b622 825 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 826 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 827 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 828
Mike Fiore 14:f9a77400b622 829 // iterate through potential wake pins - leave the configured wake pin alone if one is needed
Mike Fiore 14:f9a77400b622 830 // XBEE_DIN - PA3
Mike Fiore 14:f9a77400b622 831 // XBEE_DIO2 - PA5
Mike Fiore 14:f9a77400b622 832 // XBEE_DIO3 - PA4
Mike Fiore 14:f9a77400b622 833 // XBEE_DIO4 - PA7
Mike Fiore 14:f9a77400b622 834 // XBEE_DIO5 - PC1
Mike Fiore 14:f9a77400b622 835 // XBEE_DIO6 - PA1
Mike Fiore 14:f9a77400b622 836 // XBEE_DIO7 - PA0
Mike Fiore 14:f9a77400b622 837 // XBEE_SLEEPRQ - PA11
Mike Fiore 14:f9a77400b622 838
Mike Fiore 14:f9a77400b622 839 if (_dot->getWakePin() != XBEE_DIN || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 840 GPIO_InitStruct.Pin = GPIO_PIN_3;
Mike Fiore 14:f9a77400b622 841 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 842 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 843 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 844 }
Mike Fiore 14:f9a77400b622 845
Mike Fiore 14:f9a77400b622 846 if (_dot->getWakePin() != XBEE_DIO2 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 847 GPIO_InitStruct.Pin = GPIO_PIN_5;
Mike Fiore 14:f9a77400b622 848 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 849 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 850 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 851 }
Mike Fiore 14:f9a77400b622 852
Mike Fiore 14:f9a77400b622 853 if (_dot->getWakePin() != XBEE_DIO3 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 854 GPIO_InitStruct.Pin = GPIO_PIN_4;
Mike Fiore 14:f9a77400b622 855 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 856 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 857 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 858 }
Mike Fiore 14:f9a77400b622 859
Mike Fiore 14:f9a77400b622 860 if (_dot->getWakePin() != XBEE_DIO4 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 861 GPIO_InitStruct.Pin = GPIO_PIN_7;
Mike Fiore 14:f9a77400b622 862 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 863 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 864 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 865 }
Mike Fiore 14:f9a77400b622 866
Mike Fiore 14:f9a77400b622 867 if (_dot->getWakePin() != XBEE_DIO5 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 868 GPIO_InitStruct.Pin = GPIO_PIN_1;
Mike Fiore 14:f9a77400b622 869 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 870 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 871 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 872 }
Mike Fiore 14:f9a77400b622 873
Mike Fiore 14:f9a77400b622 874 if (_dot->getWakePin() != XBEE_DIO6 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 875 GPIO_InitStruct.Pin = GPIO_PIN_1;
Mike Fiore 14:f9a77400b622 876 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 877 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 878 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 879 }
Mike Fiore 14:f9a77400b622 880
Mike Fiore 14:f9a77400b622 881 if (_dot->getWakePin() != XBEE_DIO7 || _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 882 GPIO_InitStruct.Pin = GPIO_PIN_0;
Mike Fiore 14:f9a77400b622 883 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 884 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 885 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 886 }
Mike Fiore 14:f9a77400b622 887
Mike Fiore 14:f9a77400b622 888 if (_dot->getWakePin() != XBEE_SLEEPRQ|| _dot->getWakeMode() == mDot::RTC_ALARM) {
Mike Fiore 14:f9a77400b622 889 GPIO_InitStruct.Pin = GPIO_PIN_11;
Mike Fiore 14:f9a77400b622 890 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
Mike Fiore 14:f9a77400b622 891 GPIO_InitStruct.Pull = GPIO_NOPULL;
Mike Fiore 14:f9a77400b622 892 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Mike Fiore 14:f9a77400b622 893 }
Mike Fiore 14:f9a77400b622 894
Mike Fiore 14:f9a77400b622 895 #endif
Mike Fiore 4:666017851052 896 _dot->sleep(_dot->getWakeInterval(), _dot->getWakeMode(), standby);
Mike Fiore 14:f9a77400b622 897
Mike Fiore 14:f9a77400b622 898 #if defined(TARGET_XDOT_L151CC)
Mike Fiore 14:f9a77400b622 899 xdot_restore_gpio_state();
Mike Fiore 14:f9a77400b622 900 #else
Mike Fiore 14:f9a77400b622 901 //Restore the GPIO state.
Mike Fiore 14:f9a77400b622 902 GPIOA->MODER = portA[0];
Mike Fiore 14:f9a77400b622 903 GPIOA->OTYPER = portA[1];
Mike Fiore 14:f9a77400b622 904 GPIOA->OSPEEDR = portA[2];
Mike Fiore 14:f9a77400b622 905 GPIOA->PUPDR = portA[3];
Mike Fiore 14:f9a77400b622 906 GPIOA->AFR[0] = portA[4];
Mike Fiore 14:f9a77400b622 907 GPIOA->AFR[1] = portA[5];
Mike Fiore 14:f9a77400b622 908
Mike Fiore 14:f9a77400b622 909 GPIOB->MODER = portB[0];
Mike Fiore 14:f9a77400b622 910 GPIOB->OTYPER = portB[1];
Mike Fiore 14:f9a77400b622 911 GPIOB->OSPEEDR = portB[2];
Mike Fiore 14:f9a77400b622 912 GPIOB->PUPDR = portB[3];
Mike Fiore 14:f9a77400b622 913 GPIOB->AFR[0] = portB[4];
Mike Fiore 14:f9a77400b622 914 GPIOB->AFR[1] = portB[5];
Mike Fiore 14:f9a77400b622 915
Mike Fiore 14:f9a77400b622 916 GPIOC->MODER = portC[0];
Mike Fiore 14:f9a77400b622 917 GPIOC->OTYPER = portC[1];
Mike Fiore 14:f9a77400b622 918 GPIOC->OSPEEDR = portC[2];
Mike Fiore 14:f9a77400b622 919 GPIOC->PUPDR = portC[3];
Mike Fiore 14:f9a77400b622 920 GPIOC->AFR[0] = portC[4];
Mike Fiore 14:f9a77400b622 921 GPIOC->AFR[1] = portC[5];
Mike Fiore 14:f9a77400b622 922
Mike Fiore 14:f9a77400b622 923 GPIOD->MODER = portD[0];
Mike Fiore 14:f9a77400b622 924 GPIOD->OTYPER = portD[1];
Mike Fiore 14:f9a77400b622 925 GPIOD->OSPEEDR = portD[2];
Mike Fiore 14:f9a77400b622 926 GPIOD->PUPDR = portD[3];
Mike Fiore 14:f9a77400b622 927 GPIOD->AFR[0] = portD[4];
Mike Fiore 14:f9a77400b622 928 GPIOD->AFR[1] = portD[5];
Mike Fiore 14:f9a77400b622 929
Mike Fiore 14:f9a77400b622 930 GPIOH->MODER = portH[0];
Mike Fiore 14:f9a77400b622 931 GPIOH->OTYPER = portH[1];
Mike Fiore 14:f9a77400b622 932 GPIOH->OSPEEDR = portH[2];
Mike Fiore 14:f9a77400b622 933 GPIOH->PUPDR = portH[3];
Mike Fiore 14:f9a77400b622 934 GPIOH->AFR[0] = portH[4];
Mike Fiore 14:f9a77400b622 935 GPIOH->AFR[1] = portH[5];
Mike Fiore 14:f9a77400b622 936 #endif
Mike Fiore 14:f9a77400b622 937
Mike Fiore 14:f9a77400b622 938 _serial.rxClear();
Mike Fiore 14:f9a77400b622 939 _serial.txClear();
jreiss 20:704ce2249f5a 940 #if defined(TARGET_MTS_MDOT_F411RE)
jreiss 19:7d87f36bca8a 941 Fota::getInstance()->fixEventQueue();
jreiss 20:704ce2249f5a 942 #endif
Mike Fiore 14:f9a77400b622 943 }
Mike Fiore 14:f9a77400b622 944
Mike Fiore 14:f9a77400b622 945 std::string CommandTerminal::formatPacketData(const std::vector<uint8_t>& data, const uint8_t& format) {
Mike Fiore 14:f9a77400b622 946 if (format == mDot::HEXADECIMAL)
Mike Fiore 14:f9a77400b622 947 return mts::Text::bin2hexString(data);
Mike Fiore 14:f9a77400b622 948 else
Mike Fiore 14:f9a77400b622 949 return std::string(data.begin(), data.end());
Mike Fiore 1:e52ae6584f1c 950 }
Mike Fiore 1:e52ae6584f1c 951
Mike Fiore 1:e52ae6584f1c 952 bool CommandTerminal::waitForEscape(int timeout, mDot* dot, WaitType wait) {
Mike Fiore 1:e52ae6584f1c 953 Timer timer;
Mike Fiore 1:e52ae6584f1c 954
Mike Fiore 1:e52ae6584f1c 955 timer.start();
Mike Fiore 1:e52ae6584f1c 956 while (timer.read_ms() < timeout) {
Mike Fiore 1:e52ae6584f1c 957
Mike Fiore 1:e52ae6584f1c 958 if (dot != NULL) {
Mike Fiore 1:e52ae6584f1c 959 if (wait == WAIT_SEND && (!dot->getIsTransmitting())) {
Mike Fiore 1:e52ae6584f1c 960 return false;
Mike Fiore 1:e52ae6584f1c 961 }
Mike Fiore 1:e52ae6584f1c 962 }
Mike Fiore 1:e52ae6584f1c 963
Mike Fiore 9:ff62b20f7000 964 if (_serialp != NULL && _serialp->escaped()) {
Mike Fiore 9:ff62b20f7000 965 _serialp->clearEscaped();
Mike Fiore 9:ff62b20f7000 966 return true;
Mike Fiore 1:e52ae6584f1c 967 }
Mike Fiore 1:e52ae6584f1c 968
Mike Fiore 1:e52ae6584f1c 969 osDelay(10);
Mike Fiore 1:e52ae6584f1c 970 }
Mike Fiore 1:e52ae6584f1c 971
Mike Fiore 1:e52ae6584f1c 972 return false;
Mike Fiore 1:e52ae6584f1c 973 }
Mike Fiore 1:e52ae6584f1c 974
Mike Fiore 9:ff62b20f7000 975 void CommandTerminal::wakeup(void) {
Mike Fiore 9:ff62b20f7000 976 }
Mike Fiore 9:ff62b20f7000 977
jenkins@jenkinsdm1 18:63f098f042b2 978 void CommandTerminal::RadioEvent::PacketRx(uint8_t port, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr, lora::DownlinkControl ctrl, uint8_t slot, uint8_t retries, uint32_t address, bool dupRx) {
jenkins@jenkinsdm1 18:63f098f042b2 979 mDotEvent::PacketRx(port, payload, size, rssi, snr, ctrl, slot, retries, address, dupRx);
jreiss 20:704ce2249f5a 980 #if defined(TARGET_MTS_MDOT_F411RE)
jenkins@jenkinsdm1 18:63f098f042b2 981 if(port == 200 || port == 201 || port == 202) {
jreiss 19:7d87f36bca8a 982 Fota::getInstance()->processCmd(payload, port, size);
jenkins@jenkinsdm1 18:63f098f042b2 983 }
jreiss 20:704ce2249f5a 984 #endif
jenkins@jenkinsdm1 18:63f098f042b2 985 if (serial_data_mode && port != 0) {
Mike Fiore 14:f9a77400b622 986 logDebug("Rx %d bytes", size);
Mike Fiore 14:f9a77400b622 987 if (size > 0) {
Mike Fiore 14:f9a77400b622 988 CommandTerminal::Serial()->write((char*) RxPayload, RxPayloadSize);
Mike Fiore 9:ff62b20f7000 989 }
Mike Fiore 14:f9a77400b622 990 if (!CommandTerminal::Serial()->readable() && _dot->getAckRequested() && _dot->getClass() == "C") {
Mike Fiore 14:f9a77400b622 991 _sendAck = true;
Mike Fiore 9:ff62b20f7000 992 }
Mike Fiore 9:ff62b20f7000 993 }
Mike Fiore 1:e52ae6584f1c 994 }
Mike Fiore 9:ff62b20f7000 995
jenkins@jenkinsdm1 18:63f098f042b2 996 uint8_t CommandTerminal::getBatteryLevel() {
jenkins@jenkinsdm1 18:63f098f042b2 997 return _battery_level;
jenkins@jenkinsdm1 18:63f098f042b2 998 }
jenkins@jenkinsdm1 18:63f098f042b2 999
jenkins@jenkinsdm1 18:63f098f042b2 1000 void CommandTerminal::setBatteryLevel(uint8_t battery_level) {
jenkins@jenkinsdm1 18:63f098f042b2 1001 _battery_level = battery_level;
jenkins@jenkinsdm1 18:63f098f042b2 1002 }
jenkins@jenkinsdm1 18:63f098f042b2 1003
Mike Fiore 9:ff62b20f7000 1004 CommandTerminal::~CommandTerminal() {
Mike Fiore 9:ff62b20f7000 1005 delete _events;
Mike Fiore 9:ff62b20f7000 1006 }