few changes for RTS/CTS control
Dependencies: MTS-Serial libmDot mbed-rtos mbed
Fork of mDot_AT_firmware by
CommandTerminal/CommandTerminal.cpp@2:e5eebd74d36d, 2015-07-10 (annotated)
- Committer:
- Mike Fiore
- Date:
- Fri Jul 10 09:43:56 2015 -0500
- Revision:
- 2:e5eebd74d36d
- Parent:
- 1:e52ae6584f1c
- Child:
- 4:666017851052
update from rev 6d77074fdfa315ba86bedecc44515b11bfa6e9a0 - add support for commas in payloads of +SEND and +SENDI
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Mike Fiore |
1:e52ae6584f1c | 1 | #include "ctype.h" |
Mike Fiore |
1:e52ae6584f1c | 2 | #include "CommandTerminal.h" |
Mike Fiore |
1:e52ae6584f1c | 3 | #include "Command.h" |
Mike Fiore |
1:e52ae6584f1c | 4 | #include <cstdarg> |
Mike Fiore |
1:e52ae6584f1c | 5 | |
Mike Fiore |
1:e52ae6584f1c | 6 | extern "C" { |
Mike Fiore |
1:e52ae6584f1c | 7 | #include "wakeup.h" |
Mike Fiore |
1:e52ae6584f1c | 8 | extern void pin_function(PinName pin, int data); |
Mike Fiore |
1:e52ae6584f1c | 9 | } |
Mike Fiore |
1:e52ae6584f1c | 10 | |
Mike Fiore |
1:e52ae6584f1c | 11 | const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa XBee Module\r\n\n"; |
Mike Fiore |
1:e52ae6584f1c | 12 | const char CommandTerminal::helpline[] = "Enter '?' for help\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 13 | |
Mike Fiore |
1:e52ae6584f1c | 14 | const char CommandTerminal::newline[] = "\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 15 | |
Mike Fiore |
1:e52ae6584f1c | 16 | // Command error text... |
Mike Fiore |
1:e52ae6584f1c | 17 | const char CommandTerminal::command_error[] = "Command not found!\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 18 | |
Mike Fiore |
1:e52ae6584f1c | 19 | // Response texts... |
Mike Fiore |
1:e52ae6584f1c | 20 | const char CommandTerminal::help[] = "\r\nHelp\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 21 | const char CommandTerminal::cmd_error[] = "Invalid command\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 22 | const char CommandTerminal::done[] = "\r\nOK\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 23 | const char CommandTerminal::error[] = "\r\nERROR\r\n"; |
Mike Fiore |
1:e52ae6584f1c | 24 | |
Mike Fiore |
1:e52ae6584f1c | 25 | // Escape sequence... |
Mike Fiore |
1:e52ae6584f1c | 26 | const char CommandTerminal::escape_sequence[] = "+++"; |
Mike Fiore |
1:e52ae6584f1c | 27 | |
Mike Fiore |
1:e52ae6584f1c | 28 | mts::MTSSerial* CommandTerminal::_serialp = NULL; |
Mike Fiore |
1:e52ae6584f1c | 29 | |
Mike Fiore |
1:e52ae6584f1c | 30 | void CommandTerminal::addCommand(Command* cmd) { |
Mike Fiore |
1:e52ae6584f1c | 31 | _commands.push_back(cmd); |
Mike Fiore |
1:e52ae6584f1c | 32 | } |
Mike Fiore |
1:e52ae6584f1c | 33 | |
Mike Fiore |
1:e52ae6584f1c | 34 | CommandTerminal::CommandTerminal(mts::MTSSerial& serial, mDot* dot) |
Mike Fiore |
1:e52ae6584f1c | 35 | : |
Mike Fiore |
1:e52ae6584f1c | 36 | _serial(serial), |
Mike Fiore |
1:e52ae6584f1c | 37 | _dot(dot), |
Mike Fiore |
1:e52ae6584f1c | 38 | _mode(mDot::COMMAND_MODE), |
Mike Fiore |
1:e52ae6584f1c | 39 | _sleep_standby(false), |
Mike Fiore |
1:e52ae6584f1c | 40 | _xbee_on_sleep(XBEE_ON_SLEEP), |
Mike Fiore |
1:e52ae6584f1c | 41 | _serial_up(false) { |
Mike Fiore |
1:e52ae6584f1c | 42 | |
Mike Fiore |
1:e52ae6584f1c | 43 | _serialp = &serial; |
Mike Fiore |
1:e52ae6584f1c | 44 | |
Mike Fiore |
1:e52ae6584f1c | 45 | wakeup_init(_dot->getSerialWakeInterval()); |
Mike Fiore |
1:e52ae6584f1c | 46 | |
Mike Fiore |
1:e52ae6584f1c | 47 | addCommand(new CmdAttention(_dot)); |
Mike Fiore |
1:e52ae6584f1c | 48 | addCommand(new CmdIdentification(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 49 | addCommand(new CmdResetCpu(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 50 | addCommand(new CmdDummy(_dot, "Enable/Disable Echo", "ATE0/1", "ATE0: disable, ATE1: enable")); |
Mike Fiore |
1:e52ae6584f1c | 51 | addCommand(new CmdDummy(_dot, "Enable/Disable Verbose", "ATV0/1", "ATV0: disable, ATV1: enable")); |
Mike Fiore |
1:e52ae6584f1c | 52 | |
Mike Fiore |
1:e52ae6584f1c | 53 | addCommand(new CmdFactoryDefault(_dot)); |
Mike Fiore |
1:e52ae6584f1c | 54 | addCommand(new CmdSaveConfig(_dot)); |
Mike Fiore |
1:e52ae6584f1c | 55 | addCommand(new CmdDisplayConfig(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 56 | addCommand(new CmdDisplayStats(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 57 | addCommand(new CmdSerialBaudRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 58 | addCommand(new CmdDebugBaudRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 59 | addCommand(new CmdStartUpMode(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 60 | |
Mike Fiore |
1:e52ae6584f1c | 61 | addCommand(new CmdFrequencyBand(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 62 | addCommand(new CmdFrequencySubBand(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 63 | addCommand(new CmdPublicNetwork(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 64 | addCommand(new CmdDeviceId(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 65 | |
Mike Fiore |
1:e52ae6584f1c | 66 | addCommand(new CmdNetworkAddress(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 67 | addCommand(new CmdNetworkSessionKey(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 68 | addCommand(new CmdDataSessionKey(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 69 | addCommand(new CmdNetworkKey(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 70 | addCommand(new CmdNetworkId(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 71 | |
Mike Fiore |
1:e52ae6584f1c | 72 | addCommand(new CmdJoinRequest(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 73 | addCommand(new CmdJoinRetries(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 74 | addCommand(new CmdNetworkJoinMode(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 75 | addCommand(new CmdNetworkJoinStatus(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 76 | addCommand(new CmdNetworkLinkCheck(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 77 | addCommand(new CmdLinkCheckCount(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 78 | addCommand(new CmdLinkCheckThreshold(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 79 | addCommand(new CmdEncryption(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 80 | |
Mike Fiore |
1:e52ae6584f1c | 81 | addCommand(new CmdRssi(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 82 | addCommand(new CmdSnr(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 83 | addCommand(new CmdDataPending(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 84 | |
Mike Fiore |
1:e52ae6584f1c | 85 | addCommand(new CmdTxDataRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 86 | addCommand(new CmdTxPower(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 87 | addCommand(new CmdTxFrequency(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 88 | addCommand(new CmdTxInverted(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 89 | addCommand(new CmdTxWait(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 90 | addCommand(new CmdTxChannel(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 91 | addCommand(new CmdTxNextMs(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 92 | addCommand(new CmdTimeOnAir(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 93 | |
Mike Fiore |
1:e52ae6584f1c | 94 | addCommand(new CmdRxDataRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 95 | addCommand(new CmdRxFrequency(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 96 | addCommand(new CmdRxOutput(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 97 | addCommand(new CmdRxInverted(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 98 | |
Mike Fiore |
1:e52ae6584f1c | 99 | addCommand(new CmdErrorCorrection(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 100 | addCommand(new CmdCRC(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 101 | addCommand(new CmdAdaptiveDataRate(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 102 | |
Mike Fiore |
1:e52ae6584f1c | 103 | addCommand(new CmdACKAttempts(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 104 | |
Mike Fiore |
1:e52ae6584f1c | 105 | addCommand(new CmdSendString(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 106 | addCommand(new CmdSendStringHighBW(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 107 | addCommand(new CmdSendBinary(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 108 | addCommand(new CmdSendStringOnInterval(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 109 | addCommand(new CmdReceiveOnce(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 110 | addCommand(new CmdReceiveContinuous(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 111 | |
Mike Fiore |
1:e52ae6584f1c | 112 | addCommand(new CmdDummy(_dot, "Serial Data Mode", "AT+SD", "Reads serial data and sends Lora packets (escape sequence: +++)")); |
Mike Fiore |
1:e52ae6584f1c | 113 | addCommand(new CmdSerialWakeInterval(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 114 | addCommand(new CmdSerialWakeDelay(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 115 | addCommand(new CmdSerialReceiveTimeout(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 116 | addCommand(new CmdPing(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 117 | addCommand(new CmdLogLevel(_dot, serial)); |
Mike Fiore |
1:e52ae6584f1c | 118 | } |
Mike Fiore |
1:e52ae6584f1c | 119 | |
Mike Fiore |
1:e52ae6584f1c | 120 | void CommandTerminal::printHelp() { |
Mike Fiore |
1:e52ae6584f1c | 121 | const char* name = NULL; |
Mike Fiore |
1:e52ae6584f1c | 122 | const char* text = NULL; |
Mike Fiore |
1:e52ae6584f1c | 123 | const char* desc = NULL; |
Mike Fiore |
1:e52ae6584f1c | 124 | const char* tab = "\t"; |
Mike Fiore |
1:e52ae6584f1c | 125 | |
Mike Fiore |
1:e52ae6584f1c | 126 | std::string header("Command"); |
Mike Fiore |
1:e52ae6584f1c | 127 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 128 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 129 | header.append("Name"); |
Mike Fiore |
1:e52ae6584f1c | 130 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 131 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 132 | header.append(tab); |
Mike Fiore |
1:e52ae6584f1c | 133 | header.append("Description"); |
Mike Fiore |
1:e52ae6584f1c | 134 | |
Mike Fiore |
1:e52ae6584f1c | 135 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 136 | write(header.c_str()); |
Mike Fiore |
1:e52ae6584f1c | 137 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 138 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 139 | for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end(); ++it) { |
Mike Fiore |
1:e52ae6584f1c | 140 | name = (*it)->name(); |
Mike Fiore |
1:e52ae6584f1c | 141 | text = (*it)->text(); |
Mike Fiore |
1:e52ae6584f1c | 142 | desc = (*it)->desc(); |
Mike Fiore |
1:e52ae6584f1c | 143 | write(text); |
Mike Fiore |
1:e52ae6584f1c | 144 | if (strlen(text) < 8) |
Mike Fiore |
1:e52ae6584f1c | 145 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 146 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 147 | write(name); |
Mike Fiore |
1:e52ae6584f1c | 148 | if (strlen(name) < 8) |
Mike Fiore |
1:e52ae6584f1c | 149 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 150 | if (strlen(name) < 16) |
Mike Fiore |
1:e52ae6584f1c | 151 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 152 | write(tab); |
Mike Fiore |
1:e52ae6584f1c | 153 | write(desc); |
Mike Fiore |
1:e52ae6584f1c | 154 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 155 | } |
Mike Fiore |
1:e52ae6584f1c | 156 | |
Mike Fiore |
1:e52ae6584f1c | 157 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 158 | } |
Mike Fiore |
1:e52ae6584f1c | 159 | |
Mike Fiore |
1:e52ae6584f1c | 160 | bool CommandTerminal::writeable() { |
Mike Fiore |
1:e52ae6584f1c | 161 | return _serial.writeable(); |
Mike Fiore |
1:e52ae6584f1c | 162 | } |
Mike Fiore |
1:e52ae6584f1c | 163 | |
Mike Fiore |
1:e52ae6584f1c | 164 | bool CommandTerminal::readable() { |
Mike Fiore |
1:e52ae6584f1c | 165 | return _serial.readable(); |
Mike Fiore |
1:e52ae6584f1c | 166 | } |
Mike Fiore |
1:e52ae6584f1c | 167 | |
Mike Fiore |
1:e52ae6584f1c | 168 | char CommandTerminal::read() { |
Mike Fiore |
1:e52ae6584f1c | 169 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 170 | _serial.read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 171 | return ch; |
Mike Fiore |
1:e52ae6584f1c | 172 | } |
Mike Fiore |
1:e52ae6584f1c | 173 | |
Mike Fiore |
1:e52ae6584f1c | 174 | void CommandTerminal::write(const char* message) { |
Mike Fiore |
1:e52ae6584f1c | 175 | while (!writeable()) |
Mike Fiore |
1:e52ae6584f1c | 176 | ; |
Mike Fiore |
1:e52ae6584f1c | 177 | _serial.write(message, strlen(message)); |
Mike Fiore |
1:e52ae6584f1c | 178 | } |
Mike Fiore |
1:e52ae6584f1c | 179 | |
Mike Fiore |
1:e52ae6584f1c | 180 | void CommandTerminal::writef(const char* format, ...) { |
Mike Fiore |
1:e52ae6584f1c | 181 | char buff[256]; |
Mike Fiore |
1:e52ae6584f1c | 182 | |
Mike Fiore |
1:e52ae6584f1c | 183 | va_list ap; |
Mike Fiore |
1:e52ae6584f1c | 184 | va_start(ap, format); |
Mike Fiore |
1:e52ae6584f1c | 185 | int size = vsnprintf(buff, 256, format, ap); |
Mike Fiore |
1:e52ae6584f1c | 186 | while (!writeable()) |
Mike Fiore |
1:e52ae6584f1c | 187 | ; |
Mike Fiore |
1:e52ae6584f1c | 188 | _serial.write(buff, size); |
Mike Fiore |
1:e52ae6584f1c | 189 | va_end(ap); |
Mike Fiore |
1:e52ae6584f1c | 190 | } |
Mike Fiore |
1:e52ae6584f1c | 191 | |
Mike Fiore |
1:e52ae6584f1c | 192 | void CommandTerminal::serial_loop() { |
Mike Fiore |
1:e52ae6584f1c | 193 | Timer serial_read_timer; |
Mike Fiore |
1:e52ae6584f1c | 194 | std::vector<uint8_t> serial_buffer; |
Mike Fiore |
1:e52ae6584f1c | 195 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 196 | Timer escape_timer; |
Mike Fiore |
1:e52ae6584f1c | 197 | int escape_delay = 100; |
Mike Fiore |
1:e52ae6584f1c | 198 | uint8_t max_send_size; |
Mike Fiore |
1:e52ae6584f1c | 199 | |
Mike Fiore |
1:e52ae6584f1c | 200 | _serial_up = true; |
Mike Fiore |
1:e52ae6584f1c | 201 | _xbee_on_sleep = GPIO_PIN_SET; |
Mike Fiore |
1:e52ae6584f1c | 202 | |
Mike Fiore |
1:e52ae6584f1c | 203 | if (_dot->getFrequencyBand() == mDot::FB_915) |
Mike Fiore |
1:e52ae6584f1c | 204 | max_send_size = mDot::MaxLengths_915[_dot->getTxDataRate()]; |
Mike Fiore |
1:e52ae6584f1c | 205 | else |
Mike Fiore |
1:e52ae6584f1c | 206 | max_send_size = mDot::MaxLengths_868[_dot->getTxDataRate()]; |
Mike Fiore |
1:e52ae6584f1c | 207 | |
Mike Fiore |
1:e52ae6584f1c | 208 | DEBUG_PRINTF("Awake\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 209 | wakeup(_sleep_standby); |
Mike Fiore |
1:e52ae6584f1c | 210 | |
Mike Fiore |
1:e52ae6584f1c | 211 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 212 | |
Mike Fiore |
1:e52ae6584f1c | 213 | if (readable()) { |
Mike Fiore |
1:e52ae6584f1c | 214 | ch = read(); |
Mike Fiore |
1:e52ae6584f1c | 215 | serial_buffer.push_back(ch); |
Mike Fiore |
1:e52ae6584f1c | 216 | |
Mike Fiore |
1:e52ae6584f1c | 217 | if (escape_timer.read_ms() > escape_delay && ch == '+') { |
Mike Fiore |
1:e52ae6584f1c | 218 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 219 | escape_timer.reset(); |
Mike Fiore |
1:e52ae6584f1c | 220 | } else { |
Mike Fiore |
1:e52ae6584f1c | 221 | _serial_up = true; |
Mike Fiore |
1:e52ae6584f1c | 222 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 223 | } |
Mike Fiore |
1:e52ae6584f1c | 224 | |
Mike Fiore |
1:e52ae6584f1c | 225 | if (escape_buffer.length() == 3 && escape_buffer.find(escape_sequence) == 0) { |
Mike Fiore |
1:e52ae6584f1c | 226 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
1:e52ae6584f1c | 227 | DEBUG_PRINTF("Exit serial mode\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 228 | escape_timer.stop(); |
Mike Fiore |
1:e52ae6584f1c | 229 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 230 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 231 | return; |
Mike Fiore |
1:e52ae6584f1c | 232 | } |
Mike Fiore |
1:e52ae6584f1c | 233 | } |
Mike Fiore |
1:e52ae6584f1c | 234 | |
Mike Fiore |
1:e52ae6584f1c | 235 | if (_serial_up) { |
Mike Fiore |
1:e52ae6584f1c | 236 | osDelay(_dot->getSerialWakeDelay()); |
Mike Fiore |
1:e52ae6584f1c | 237 | |
Mike Fiore |
1:e52ae6584f1c | 238 | serial_read_timer.start(); |
Mike Fiore |
1:e52ae6584f1c | 239 | while (_serial_up && serial_read_timer.read_ms() < _dot->getSerialReceiveTimeout()) { |
Mike Fiore |
1:e52ae6584f1c | 240 | while (readable() && serial_buffer.size() < max_send_size) { |
Mike Fiore |
1:e52ae6584f1c | 241 | serial_buffer.push_back(read()); |
Mike Fiore |
1:e52ae6584f1c | 242 | serial_read_timer.reset(); |
Mike Fiore |
1:e52ae6584f1c | 243 | } |
Mike Fiore |
1:e52ae6584f1c | 244 | } |
Mike Fiore |
1:e52ae6584f1c | 245 | serial_read_timer.stop(), serial_read_timer.reset(); |
Mike Fiore |
1:e52ae6584f1c | 246 | |
Mike Fiore |
1:e52ae6584f1c | 247 | if (!serial_buffer.empty()) { |
Mike Fiore |
1:e52ae6584f1c | 248 | _serial_up = false; |
Mike Fiore |
1:e52ae6584f1c | 249 | _xbee_on_sleep = GPIO_PIN_RESET; |
Mike Fiore |
1:e52ae6584f1c | 250 | if (!_dot->getIsTransmitting()) { |
Mike Fiore |
1:e52ae6584f1c | 251 | std::vector<uint8_t> recv_buffer; |
Mike Fiore |
1:e52ae6584f1c | 252 | DEBUG_PRINTF("Received serial data, sending out radio.\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 253 | |
Mike Fiore |
1:e52ae6584f1c | 254 | if (!_dot->send(serial_buffer)) |
Mike Fiore |
1:e52ae6584f1c | 255 | DEBUG_PRINTF("Send failed.\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 256 | if (_dot->recv(recv_buffer)) |
Mike Fiore |
1:e52ae6584f1c | 257 | _serial.writef("%s\r\n", formatPacketData(recv_buffer, _dot->getRxOutput()).c_str()); |
Mike Fiore |
1:e52ae6584f1c | 258 | } else { |
Mike Fiore |
1:e52ae6584f1c | 259 | DEBUG_PRINTF("Radio is busy, cannot send.\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 260 | } |
Mike Fiore |
1:e52ae6584f1c | 261 | |
Mike Fiore |
1:e52ae6584f1c | 262 | serial_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 263 | } else { |
Mike Fiore |
1:e52ae6584f1c | 264 | DEBUG_PRINTF("No data received from serial to send.\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 265 | } |
Mike Fiore |
1:e52ae6584f1c | 266 | _serial_up = false; |
Mike Fiore |
1:e52ae6584f1c | 267 | } |
Mike Fiore |
1:e52ae6584f1c | 268 | sleep(_sleep_standby); |
Mike Fiore |
1:e52ae6584f1c | 269 | } |
Mike Fiore |
1:e52ae6584f1c | 270 | |
Mike Fiore |
1:e52ae6584f1c | 271 | bool CommandTerminal::autoJoinCheck() { |
Mike Fiore |
1:e52ae6584f1c | 272 | |
Mike Fiore |
1:e52ae6584f1c | 273 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 274 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 275 | int sleep = 1000; |
Mike Fiore |
1:e52ae6584f1c | 276 | int escape_timeout = 1000; |
Mike Fiore |
1:e52ae6584f1c | 277 | Timer tmr; |
Mike Fiore |
1:e52ae6584f1c | 278 | Timer escape_tmr; |
Mike Fiore |
1:e52ae6584f1c | 279 | int cnt = 0; |
Mike Fiore |
1:e52ae6584f1c | 280 | |
Mike Fiore |
1:e52ae6584f1c | 281 | while (!_dot->getNetworkJoinStatus()) { |
Mike Fiore |
1:e52ae6584f1c | 282 | wakeup(_sleep_standby); |
Mike Fiore |
1:e52ae6584f1c | 283 | write("\r\nJoining network... "); |
Mike Fiore |
1:e52ae6584f1c | 284 | |
Mike Fiore |
1:e52ae6584f1c | 285 | // wait one second for possible escape |
Mike Fiore |
1:e52ae6584f1c | 286 | tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 287 | tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 288 | escape_tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 289 | escape_tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 290 | while (tmr.read_ms() < 1000) { |
Mike Fiore |
1:e52ae6584f1c | 291 | if (_serial.readable()) { |
Mike Fiore |
1:e52ae6584f1c | 292 | _serial.read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 293 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 294 | } |
Mike Fiore |
1:e52ae6584f1c | 295 | |
Mike Fiore |
1:e52ae6584f1c | 296 | if (escape_buffer.find(escape_sequence) != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 297 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
1:e52ae6584f1c | 298 | write("Join Canceled\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 299 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 300 | return true; |
Mike Fiore |
1:e52ae6584f1c | 301 | } |
Mike Fiore |
1:e52ae6584f1c | 302 | |
Mike Fiore |
1:e52ae6584f1c | 303 | if (escape_tmr.read_ms() > escape_timeout) |
Mike Fiore |
1:e52ae6584f1c | 304 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 305 | } |
Mike Fiore |
1:e52ae6584f1c | 306 | |
Mike Fiore |
1:e52ae6584f1c | 307 | if (_dot->joinNetworkOnce() == mDot::MDOT_OK) { |
Mike Fiore |
1:e52ae6584f1c | 308 | write("Network Joined\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 309 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 310 | return false; |
Mike Fiore |
1:e52ae6584f1c | 311 | } |
Mike Fiore |
1:e52ae6584f1c | 312 | |
Mike Fiore |
1:e52ae6584f1c | 313 | write("Network Join failed\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 314 | write(error); |
Mike Fiore |
1:e52ae6584f1c | 315 | |
Mike Fiore |
1:e52ae6584f1c | 316 | if (cnt++ > _dot->getJoinRetries()) { |
Mike Fiore |
1:e52ae6584f1c | 317 | cnt = 0; |
Mike Fiore |
1:e52ae6584f1c | 318 | |
Mike Fiore |
1:e52ae6584f1c | 319 | if (_dot->getFrequencyBand() == mDot::FB_915) { |
Mike Fiore |
1:e52ae6584f1c | 320 | uint8_t band = ((_dot->getFrequencySubBand()) % 8) + 1; |
Mike Fiore |
1:e52ae6584f1c | 321 | DEBUG_PRINTF("Join retries exhausted, switching to sub band %u\r\n", band); |
Mike Fiore |
1:e52ae6584f1c | 322 | _dot->setFrequencySubBand(band); |
Mike Fiore |
1:e52ae6584f1c | 323 | } |
Mike Fiore |
1:e52ae6584f1c | 324 | |
Mike Fiore |
1:e52ae6584f1c | 325 | if (sleep < 60 * 60 * 1000) |
Mike Fiore |
1:e52ae6584f1c | 326 | sleep *= 2; |
Mike Fiore |
1:e52ae6584f1c | 327 | } |
Mike Fiore |
1:e52ae6584f1c | 328 | |
Mike Fiore |
1:e52ae6584f1c | 329 | tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 330 | tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 331 | escape_tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 332 | escape_tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 333 | while (tmr.read_ms() < sleep) { |
Mike Fiore |
1:e52ae6584f1c | 334 | if (_serial.readable()) { |
Mike Fiore |
1:e52ae6584f1c | 335 | _serial.read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 336 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 337 | } |
Mike Fiore |
1:e52ae6584f1c | 338 | |
Mike Fiore |
1:e52ae6584f1c | 339 | if (escape_buffer.find(escape_sequence) != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 340 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
1:e52ae6584f1c | 341 | return true; |
Mike Fiore |
1:e52ae6584f1c | 342 | } |
Mike Fiore |
1:e52ae6584f1c | 343 | |
Mike Fiore |
1:e52ae6584f1c | 344 | if (escape_tmr.read_ms() > escape_timeout) |
Mike Fiore |
1:e52ae6584f1c | 345 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 346 | } |
Mike Fiore |
1:e52ae6584f1c | 347 | |
Mike Fiore |
1:e52ae6584f1c | 348 | } |
Mike Fiore |
1:e52ae6584f1c | 349 | |
Mike Fiore |
1:e52ae6584f1c | 350 | return false; |
Mike Fiore |
1:e52ae6584f1c | 351 | } |
Mike Fiore |
1:e52ae6584f1c | 352 | |
Mike Fiore |
1:e52ae6584f1c | 353 | void CommandTerminal::start() { |
Mike Fiore |
1:e52ae6584f1c | 354 | |
Mike Fiore |
1:e52ae6584f1c | 355 | _dot->resetNetworkSession(); |
Mike Fiore |
1:e52ae6584f1c | 356 | |
Mike Fiore |
1:e52ae6584f1c | 357 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 358 | bool running = true; |
Mike Fiore |
1:e52ae6584f1c | 359 | bool echo = _dot->getEcho(); |
Mike Fiore |
1:e52ae6584f1c | 360 | std::string command; |
Mike Fiore |
1:e52ae6584f1c | 361 | std::vector<std::string> args; |
Mike Fiore |
1:e52ae6584f1c | 362 | |
Mike Fiore |
1:e52ae6584f1c | 363 | if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { |
Mike Fiore |
1:e52ae6584f1c | 364 | command = "AT+SD\n"; |
Mike Fiore |
1:e52ae6584f1c | 365 | |
Mike Fiore |
1:e52ae6584f1c | 366 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 367 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 368 | |
Mike Fiore |
1:e52ae6584f1c | 369 | int escape_timeout = 1000; |
Mike Fiore |
1:e52ae6584f1c | 370 | Timer tmr; |
Mike Fiore |
1:e52ae6584f1c | 371 | Timer escape_tmr; |
Mike Fiore |
1:e52ae6584f1c | 372 | |
Mike Fiore |
1:e52ae6584f1c | 373 | // wait one second for possible escape |
Mike Fiore |
1:e52ae6584f1c | 374 | tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 375 | tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 376 | escape_tmr.reset(); |
Mike Fiore |
1:e52ae6584f1c | 377 | escape_tmr.start(); |
Mike Fiore |
1:e52ae6584f1c | 378 | while (tmr.read_ms() < escape_timeout) { |
Mike Fiore |
1:e52ae6584f1c | 379 | if (_serial.readable()) { |
Mike Fiore |
1:e52ae6584f1c | 380 | _serial.read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 381 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 382 | } |
Mike Fiore |
1:e52ae6584f1c | 383 | |
Mike Fiore |
1:e52ae6584f1c | 384 | if (escape_buffer.find(escape_sequence) != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 385 | _mode = mDot::COMMAND_MODE; |
Mike Fiore |
1:e52ae6584f1c | 386 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 387 | break; |
Mike Fiore |
1:e52ae6584f1c | 388 | } |
Mike Fiore |
1:e52ae6584f1c | 389 | |
Mike Fiore |
1:e52ae6584f1c | 390 | if (escape_tmr.read_ms() > escape_timeout) |
Mike Fiore |
1:e52ae6584f1c | 391 | escape_buffer.clear(); |
Mike Fiore |
1:e52ae6584f1c | 392 | |
Mike Fiore |
1:e52ae6584f1c | 393 | osDelay(1); |
Mike Fiore |
1:e52ae6584f1c | 394 | } |
Mike Fiore |
1:e52ae6584f1c | 395 | |
Mike Fiore |
1:e52ae6584f1c | 396 | } |
Mike Fiore |
1:e52ae6584f1c | 397 | |
Mike Fiore |
1:e52ae6584f1c | 398 | bool join_canceled = false; |
Mike Fiore |
1:e52ae6584f1c | 399 | |
Mike Fiore |
1:e52ae6584f1c | 400 | //Run terminal session |
Mike Fiore |
1:e52ae6584f1c | 401 | while (running) { |
Mike Fiore |
1:e52ae6584f1c | 402 | if (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA) { |
Mike Fiore |
1:e52ae6584f1c | 403 | join_canceled = autoJoinCheck(); |
Mike Fiore |
1:e52ae6584f1c | 404 | if (join_canceled) |
Mike Fiore |
1:e52ae6584f1c | 405 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 406 | } |
Mike Fiore |
1:e52ae6584f1c | 407 | |
Mike Fiore |
1:e52ae6584f1c | 408 | if (_dot->getJoinMode() != mDot::AUTO_OTA || (!join_canceled && _dot->getJoinMode() == mDot::AUTO_OTA)) { |
Mike Fiore |
1:e52ae6584f1c | 409 | switch (_mode) { |
Mike Fiore |
1:e52ae6584f1c | 410 | case mDot::SERIAL_MODE: |
Mike Fiore |
1:e52ae6584f1c | 411 | // signal wakeup, read serial and output to radio |
Mike Fiore |
1:e52ae6584f1c | 412 | serial_loop(); |
Mike Fiore |
1:e52ae6584f1c | 413 | continue; |
Mike Fiore |
1:e52ae6584f1c | 414 | break; |
Mike Fiore |
1:e52ae6584f1c | 415 | default: |
Mike Fiore |
1:e52ae6584f1c | 416 | break; |
Mike Fiore |
1:e52ae6584f1c | 417 | } |
Mike Fiore |
1:e52ae6584f1c | 418 | } |
Mike Fiore |
1:e52ae6584f1c | 419 | |
Mike Fiore |
1:e52ae6584f1c | 420 | ch = '\0'; |
Mike Fiore |
1:e52ae6584f1c | 421 | |
Mike Fiore |
1:e52ae6584f1c | 422 | // read characters |
Mike Fiore |
1:e52ae6584f1c | 423 | if (readable()) { |
Mike Fiore |
1:e52ae6584f1c | 424 | ch = read(); |
Mike Fiore |
1:e52ae6584f1c | 425 | |
Mike Fiore |
1:e52ae6584f1c | 426 | if (ch == '\b') { |
Mike Fiore |
1:e52ae6584f1c | 427 | if (!command.empty()) { |
Mike Fiore |
1:e52ae6584f1c | 428 | writef("\b \b"); |
Mike Fiore |
1:e52ae6584f1c | 429 | command.erase(command.size() - 1); |
Mike Fiore |
1:e52ae6584f1c | 430 | } |
Mike Fiore |
1:e52ae6584f1c | 431 | continue; |
Mike Fiore |
1:e52ae6584f1c | 432 | } else { |
Mike Fiore |
1:e52ae6584f1c | 433 | command += ch; |
Mike Fiore |
1:e52ae6584f1c | 434 | } |
Mike Fiore |
1:e52ae6584f1c | 435 | |
Mike Fiore |
1:e52ae6584f1c | 436 | // echo chars if enabled |
Mike Fiore |
1:e52ae6584f1c | 437 | if (echo && !(ch == '\r' || ch == '\n')) |
Mike Fiore |
1:e52ae6584f1c | 438 | writef("%c", ch); |
Mike Fiore |
1:e52ae6584f1c | 439 | } |
Mike Fiore |
1:e52ae6584f1c | 440 | |
Mike Fiore |
1:e52ae6584f1c | 441 | // look for end of command line |
Mike Fiore |
1:e52ae6584f1c | 442 | if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 443 | // remove new line or cr character |
Mike Fiore |
1:e52ae6584f1c | 444 | command.erase(command.size() - 1); |
Mike Fiore |
1:e52ae6584f1c | 445 | write("\r"); // match standard modem output |
Mike Fiore |
1:e52ae6584f1c | 446 | write(newline); |
Mike Fiore |
1:e52ae6584f1c | 447 | } else { |
Mike Fiore |
1:e52ae6584f1c | 448 | continue; |
Mike Fiore |
1:e52ae6584f1c | 449 | } |
Mike Fiore |
1:e52ae6584f1c | 450 | |
Mike Fiore |
1:e52ae6584f1c | 451 | // trim whitespace from command |
Mike Fiore |
1:e52ae6584f1c | 452 | mts::Text::trim(command, "\r\n\t "); |
Mike Fiore |
1:e52ae6584f1c | 453 | |
Mike Fiore |
1:e52ae6584f1c | 454 | if (command.size() < 1) { |
Mike Fiore |
1:e52ae6584f1c | 455 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 456 | continue; |
Mike Fiore |
1:e52ae6584f1c | 457 | } |
Mike Fiore |
1:e52ae6584f1c | 458 | |
Mike Fiore |
1:e52ae6584f1c | 459 | // parse command and args |
Mike Fiore |
1:e52ae6584f1c | 460 | args.clear(); |
Mike Fiore |
1:e52ae6584f1c | 461 | |
Mike Fiore |
1:e52ae6584f1c | 462 | // find first '=' character |
Mike Fiore |
1:e52ae6584f1c | 463 | size_t delim_index = command.find("="); |
Mike Fiore |
1:e52ae6584f1c | 464 | if (delim_index != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 465 | args.push_back(command.substr(0, delim_index)); |
Mike Fiore |
1:e52ae6584f1c | 466 | } else { |
Mike Fiore |
1:e52ae6584f1c | 467 | // find first ' ' character |
Mike Fiore |
1:e52ae6584f1c | 468 | delim_index = command.find(" "); |
Mike Fiore |
1:e52ae6584f1c | 469 | if (delim_index != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 470 | args.push_back(command.substr(0, delim_index)); |
Mike Fiore |
1:e52ae6584f1c | 471 | } else { |
Mike Fiore |
1:e52ae6584f1c | 472 | args.push_back(command); |
Mike Fiore |
1:e52ae6584f1c | 473 | } |
Mike Fiore |
1:e52ae6584f1c | 474 | } |
Mike Fiore |
1:e52ae6584f1c | 475 | |
Mike Fiore |
1:e52ae6584f1c | 476 | if (delim_index != std::string::npos) { |
Mike Fiore |
1:e52ae6584f1c | 477 | std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ","); |
Mike Fiore |
1:e52ae6584f1c | 478 | args.insert(args.end(), params.begin(), params.end()); |
Mike Fiore |
1:e52ae6584f1c | 479 | } |
Mike Fiore |
1:e52ae6584f1c | 480 | |
Mike Fiore |
1:e52ae6584f1c | 481 | args[0] = mts::Text::toUpper(args[0]); |
Mike Fiore |
1:e52ae6584f1c | 482 | |
Mike Fiore |
1:e52ae6584f1c | 483 | // print help |
Mike Fiore |
1:e52ae6584f1c | 484 | if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) { |
Mike Fiore |
1:e52ae6584f1c | 485 | printHelp(); |
Mike Fiore |
1:e52ae6584f1c | 486 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 487 | } else if (args[0].find("ATE0") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 488 | _dot->setEcho(false); |
Mike Fiore |
1:e52ae6584f1c | 489 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 490 | echo = _dot->getEcho(); |
Mike Fiore |
1:e52ae6584f1c | 491 | } else if (args[0].find("ATE1") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 492 | _dot->setEcho(true); |
Mike Fiore |
1:e52ae6584f1c | 493 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 494 | echo = _dot->getEcho(); |
Mike Fiore |
1:e52ae6584f1c | 495 | } else if (args[0].find("ATV0") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 496 | _dot->setVerbose(false); |
Mike Fiore |
1:e52ae6584f1c | 497 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 498 | } else if (args[0].find("ATV1") == 0 && args[0].length() == 4) { |
Mike Fiore |
1:e52ae6584f1c | 499 | _dot->setVerbose(true); |
Mike Fiore |
1:e52ae6584f1c | 500 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 501 | } else if (args[0] == "AT+SD") { |
Mike Fiore |
1:e52ae6584f1c | 502 | DEBUG_PRINTF("Enter Serial Mode\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 503 | _mode = mDot::SERIAL_MODE; |
Mike Fiore |
1:e52ae6584f1c | 504 | } else { |
Mike Fiore |
1:e52ae6584f1c | 505 | bool found = false; |
Mike Fiore |
1:e52ae6584f1c | 506 | bool query = false; |
Mike Fiore |
1:e52ae6584f1c | 507 | |
Mike Fiore |
1:e52ae6584f1c | 508 | std::string lookfor = args[0]; |
Mike Fiore |
1:e52ae6584f1c | 509 | |
Mike Fiore |
1:e52ae6584f1c | 510 | // per command help |
Mike Fiore |
1:e52ae6584f1c | 511 | if ((args[0].find("?") == 0 || args[0].find("HELP") == 0)) |
Mike Fiore |
1:e52ae6584f1c | 512 | lookfor = mts::Text::toUpper(args[1]); |
Mike Fiore |
1:e52ae6584f1c | 513 | |
Mike Fiore |
1:e52ae6584f1c | 514 | // trim off any trailing '?' and mark as a query command |
Mike Fiore |
1:e52ae6584f1c | 515 | if (args[0].rfind("?") == args[0].length() - 1) { |
Mike Fiore |
1:e52ae6584f1c | 516 | query = true; |
Mike Fiore |
1:e52ae6584f1c | 517 | lookfor = args[0].substr(0, args[0].length() - 1); |
Mike Fiore |
1:e52ae6584f1c | 518 | } |
Mike Fiore |
1:e52ae6584f1c | 519 | |
Mike Fiore |
1:e52ae6584f1c | 520 | // search for command |
Mike Fiore |
1:e52ae6584f1c | 521 | for (std::vector<Command*>::iterator it = _commands.begin(); it != _commands.end() && !found; ++it) { |
Mike Fiore |
1:e52ae6584f1c | 522 | Command* cmd = *it; |
Mike Fiore |
1:e52ae6584f1c | 523 | |
Mike Fiore |
1:e52ae6584f1c | 524 | // match CMD or CMD? syntax if command is queryable |
Mike Fiore |
1:e52ae6584f1c | 525 | if (lookfor == cmd->text() && (!query || (query && cmd->queryable()))) { |
Mike Fiore |
1:e52ae6584f1c | 526 | found = true; |
Mike Fiore |
1:e52ae6584f1c | 527 | if (args[0] == "HELP") { |
Mike Fiore |
1:e52ae6584f1c | 528 | writef("%s%s", cmd->help(), newline); |
Mike Fiore |
1:e52ae6584f1c | 529 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 530 | } |
Mike Fiore |
1:e52ae6584f1c | 531 | |
Mike Fiore |
1:e52ae6584f1c | 532 | else if (args.size() > 1 && args[1] == "?") { |
Mike Fiore |
1:e52ae6584f1c | 533 | writef("%s%s", cmd->usage().c_str(), newline); |
Mike Fiore |
1:e52ae6584f1c | 534 | write(done); |
Mike Fiore |
1:e52ae6584f1c | 535 | } else if (!cmd->verify(args)) { |
Mike Fiore |
1:e52ae6584f1c | 536 | writef("%s%s", cmd->errorMessage().c_str(), newline); |
Mike Fiore |
1:e52ae6584f1c | 537 | writef("%s", error); |
Mike Fiore |
1:e52ae6584f1c | 538 | } else { |
Mike Fiore |
1:e52ae6584f1c | 539 | if (cmd->action(args) == 0) { |
Mike Fiore |
1:e52ae6584f1c | 540 | writef("%s", done); |
Mike Fiore |
1:e52ae6584f1c | 541 | } else { |
Mike Fiore |
1:e52ae6584f1c | 542 | writef("%s%s", cmd->errorMessage().c_str(), newline); |
Mike Fiore |
1:e52ae6584f1c | 543 | writef("%s", error); |
Mike Fiore |
1:e52ae6584f1c | 544 | } |
Mike Fiore |
1:e52ae6584f1c | 545 | } |
Mike Fiore |
1:e52ae6584f1c | 546 | } |
Mike Fiore |
1:e52ae6584f1c | 547 | } |
Mike Fiore |
1:e52ae6584f1c | 548 | |
Mike Fiore |
1:e52ae6584f1c | 549 | if (!found) { |
Mike Fiore |
1:e52ae6584f1c | 550 | writef("%s", command_error); |
Mike Fiore |
1:e52ae6584f1c | 551 | writef("%s", error); |
Mike Fiore |
1:e52ae6584f1c | 552 | } |
Mike Fiore |
1:e52ae6584f1c | 553 | } |
Mike Fiore |
1:e52ae6584f1c | 554 | |
Mike Fiore |
1:e52ae6584f1c | 555 | command.clear(); |
Mike Fiore |
1:e52ae6584f1c | 556 | |
Mike Fiore |
1:e52ae6584f1c | 557 | } |
Mike Fiore |
1:e52ae6584f1c | 558 | } |
Mike Fiore |
1:e52ae6584f1c | 559 | |
Mike Fiore |
1:e52ae6584f1c | 560 | std::string CommandTerminal::formatPacketData(const std::vector<uint8_t>& data, const uint8_t& format) { |
Mike Fiore |
2:e5eebd74d36d | 561 | if (format == mDot::HEXADECIMAL) |
Mike Fiore |
1:e52ae6584f1c | 562 | return mts::Text::bin2hexString(data); |
Mike Fiore |
2:e5eebd74d36d | 563 | else |
Mike Fiore |
2:e5eebd74d36d | 564 | return std::string(data.begin(), data.end()); |
Mike Fiore |
1:e52ae6584f1c | 565 | } |
Mike Fiore |
1:e52ae6584f1c | 566 | |
Mike Fiore |
1:e52ae6584f1c | 567 | void CommandTerminal::sleep(bool standby) { |
Mike Fiore |
1:e52ae6584f1c | 568 | _serial_up = false; |
Mike Fiore |
1:e52ae6584f1c | 569 | _xbee_on_sleep = GPIO_PIN_RESET; |
Mike Fiore |
1:e52ae6584f1c | 570 | |
Mike Fiore |
1:e52ae6584f1c | 571 | HAL_PWREx_EnableMainRegulatorLowVoltage(); |
Mike Fiore |
1:e52ae6584f1c | 572 | HAL_PWREx_EnableFlashPowerDown(); |
Mike Fiore |
1:e52ae6584f1c | 573 | HAL_PWREx_EnableLowRegulatorLowVoltage(); |
Mike Fiore |
1:e52ae6584f1c | 574 | |
Mike Fiore |
1:e52ae6584f1c | 575 | DEBUG_PRINTF("Sleep\r\n"); |
Mike Fiore |
1:e52ae6584f1c | 576 | _dot->sleep(); |
Mike Fiore |
1:e52ae6584f1c | 577 | |
Mike Fiore |
1:e52ae6584f1c | 578 | if (standby) { |
Mike Fiore |
1:e52ae6584f1c | 579 | |
Mike Fiore |
1:e52ae6584f1c | 580 | DEBUG_PRINTF("RECORD UPLINK: %lu\r\n", _dot->getUpLinkCounter()); |
Mike Fiore |
1:e52ae6584f1c | 581 | |
Mike Fiore |
1:e52ae6584f1c | 582 | RTC_WriteBackupRegister(RTC_BKP_DR0, _dot->getUpLinkCounter()); |
Mike Fiore |
1:e52ae6584f1c | 583 | |
Mike Fiore |
1:e52ae6584f1c | 584 | HAL_PWR_EnableBkUpAccess(); |
Mike Fiore |
1:e52ae6584f1c | 585 | |
Mike Fiore |
1:e52ae6584f1c | 586 | HAL_EnableDBGStandbyMode(); |
Mike Fiore |
1:e52ae6584f1c | 587 | |
Mike Fiore |
1:e52ae6584f1c | 588 | HAL_PWR_DisableWakeUpPin (PWR_WAKEUP_PIN1); |
Mike Fiore |
1:e52ae6584f1c | 589 | |
Mike Fiore |
1:e52ae6584f1c | 590 | __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); // InterruptIn wakeon_serial(XBEE_DIN); |
Mike Fiore |
1:e52ae6584f1c | 591 | // Application is reloaded after wake-up from standby |
Mike Fiore |
1:e52ae6584f1c | 592 | HAL_PWR_EnterSTANDBYMode (); |
Mike Fiore |
1:e52ae6584f1c | 593 | |
Mike Fiore |
1:e52ae6584f1c | 594 | } else { |
Mike Fiore |
1:e52ae6584f1c | 595 | pin_function(PA_0, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 596 | pin_function(PA_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 597 | // pin_function(PA_2, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 598 | // pin_function(PA_3, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 599 | pin_function(PA_4, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 600 | pin_function(PA_5, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 601 | pin_function(PA_6, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 602 | pin_function(PA_7, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 603 | // pin_function(PA_8, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 604 | // pin_function(PA_9, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 605 | // pin_function(PA_10, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 606 | pin_function(PA_11, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 607 | pin_function(PA_12, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 608 | pin_function(PA_15, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 609 | |
Mike Fiore |
1:e52ae6584f1c | 610 | pin_function(PB_0, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 611 | pin_function(PB_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 612 | pin_function(PB_2, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 613 | |
Mike Fiore |
1:e52ae6584f1c | 614 | pin_function(PC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 615 | pin_function(PC_4, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 616 | pin_function(PC_5, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 617 | pin_function(PC_9, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 618 | // pin_function(PC_13, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 619 | |
Mike Fiore |
1:e52ae6584f1c | 620 | pin_function(PD_2, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); |
Mike Fiore |
1:e52ae6584f1c | 621 | |
Mike Fiore |
1:e52ae6584f1c | 622 | HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); |
Mike Fiore |
1:e52ae6584f1c | 623 | } |
Mike Fiore |
1:e52ae6584f1c | 624 | |
Mike Fiore |
1:e52ae6584f1c | 625 | wakeup_clear(); |
Mike Fiore |
1:e52ae6584f1c | 626 | EXTI->PR = (1 << 22); |
Mike Fiore |
1:e52ae6584f1c | 627 | |
Mike Fiore |
1:e52ae6584f1c | 628 | // After wake-up from STOP reconfigure the PLL |
Mike Fiore |
1:e52ae6584f1c | 629 | SetSysClock(); |
Mike Fiore |
1:e52ae6584f1c | 630 | } |
Mike Fiore |
1:e52ae6584f1c | 631 | |
Mike Fiore |
1:e52ae6584f1c | 632 | bool CommandTerminal::waitForEscape(int timeout, mDot* dot, WaitType wait) { |
Mike Fiore |
1:e52ae6584f1c | 633 | Timer timer; |
Mike Fiore |
1:e52ae6584f1c | 634 | Timer escape_timer; |
Mike Fiore |
1:e52ae6584f1c | 635 | std::string escape_buffer; |
Mike Fiore |
1:e52ae6584f1c | 636 | int escape_timeout = 1000; |
Mike Fiore |
1:e52ae6584f1c | 637 | |
Mike Fiore |
1:e52ae6584f1c | 638 | timer.start(); |
Mike Fiore |
1:e52ae6584f1c | 639 | while (timer.read_ms() < timeout) { |
Mike Fiore |
1:e52ae6584f1c | 640 | |
Mike Fiore |
1:e52ae6584f1c | 641 | if (dot != NULL) { |
Mike Fiore |
1:e52ae6584f1c | 642 | if (wait == WAIT_SEND && (!dot->getIsTransmitting())) { |
Mike Fiore |
1:e52ae6584f1c | 643 | return false; |
Mike Fiore |
1:e52ae6584f1c | 644 | } |
Mike Fiore |
1:e52ae6584f1c | 645 | } |
Mike Fiore |
1:e52ae6584f1c | 646 | |
Mike Fiore |
1:e52ae6584f1c | 647 | if (_serialp != NULL && _serialp->readable()) { |
Mike Fiore |
1:e52ae6584f1c | 648 | if (escape_buffer == "") |
Mike Fiore |
1:e52ae6584f1c | 649 | escape_timer.start(); |
Mike Fiore |
1:e52ae6584f1c | 650 | char ch; |
Mike Fiore |
1:e52ae6584f1c | 651 | _serialp->read(&ch, 1); |
Mike Fiore |
1:e52ae6584f1c | 652 | escape_buffer += ch; |
Mike Fiore |
1:e52ae6584f1c | 653 | if (escape_buffer == CommandTerminal::escape_sequence) |
Mike Fiore |
1:e52ae6584f1c | 654 | return true; |
Mike Fiore |
1:e52ae6584f1c | 655 | } |
Mike Fiore |
1:e52ae6584f1c | 656 | if (escape_timer.read_ms() > escape_timeout) { |
Mike Fiore |
1:e52ae6584f1c | 657 | escape_buffer = ""; |
Mike Fiore |
1:e52ae6584f1c | 658 | escape_timer.stop(), escape_timer.reset(); |
Mike Fiore |
1:e52ae6584f1c | 659 | } |
Mike Fiore |
1:e52ae6584f1c | 660 | |
Mike Fiore |
1:e52ae6584f1c | 661 | osDelay(10); |
Mike Fiore |
1:e52ae6584f1c | 662 | } |
Mike Fiore |
1:e52ae6584f1c | 663 | |
Mike Fiore |
1:e52ae6584f1c | 664 | return false; |
Mike Fiore |
1:e52ae6584f1c | 665 | } |
Mike Fiore |
1:e52ae6584f1c | 666 | |
Mike Fiore |
1:e52ae6584f1c | 667 | void CommandTerminal::wakeup(bool standby) { |
Mike Fiore |
1:e52ae6584f1c | 668 | HAL_PWREx_DisableMainRegulatorLowVoltage(); |
Mike Fiore |
1:e52ae6584f1c | 669 | HAL_PWREx_DisableFlashPowerDown(); |
Mike Fiore |
1:e52ae6584f1c | 670 | HAL_PWREx_DisableLowRegulatorLowVoltage(); |
Mike Fiore |
1:e52ae6584f1c | 671 | |
Mike Fiore |
1:e52ae6584f1c | 672 | if (standby) { |
Mike Fiore |
1:e52ae6584f1c | 673 | HAL_DisableDBGStandbyMode(); |
Mike Fiore |
1:e52ae6584f1c | 674 | |
Mike Fiore |
1:e52ae6584f1c | 675 | HAL_PWR_EnableWakeUpPin (PWR_WAKEUP_PIN1); |
Mike Fiore |
1:e52ae6584f1c | 676 | } |
Mike Fiore |
1:e52ae6584f1c | 677 | |
Mike Fiore |
1:e52ae6584f1c | 678 | _dot->wakeup(); |
Mike Fiore |
1:e52ae6584f1c | 679 | |
Mike Fiore |
1:e52ae6584f1c | 680 | } |