Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MTS-Serial libmDot-mbed5
Fork of Dot-AT-Firmware by
CommandTerminal.cpp
00001 #include "ctype.h" 00002 #include "CommandTerminal.h" 00003 #include "Command.h" 00004 #include "MTSLog.h" 00005 #include <cstdarg> 00006 #include <deque> 00007 #if defined(TARGET_XDOT_L151CC) 00008 #include "xdot_low_power.h" 00009 #endif 00010 00011 #if defined(TARGET_MTS_MDOT_F411RE) 00012 const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa XBee Module\r\n\n"; 00013 #else 00014 const char CommandTerminal::banner[] = "\r\n\nMultiTech Systems LoRa xDot Module\r\n\n"; 00015 #endif 00016 const char CommandTerminal::helpline[] = "Enter '?' for help\r\n"; 00017 00018 const char CommandTerminal::newline[] = "\r\n"; 00019 00020 // Command error text... 00021 const char CommandTerminal::command_error[] = "Command not found!\r\n"; 00022 00023 // Response texts... 00024 const char CommandTerminal::help[] = "\r\nHelp\r\n"; 00025 const char CommandTerminal::cmd_error[] = "Invalid command\r\n"; 00026 const char CommandTerminal::connect[] = "\r\nCONNECT\r\n"; 00027 const char CommandTerminal::no_carrier[] = "\r\nNO CARRIER\r\n"; 00028 const char CommandTerminal::done[] = "\r\nOK\r\n"; 00029 const char CommandTerminal::error[] = "\r\nERROR\r\n"; 00030 00031 // Escape sequence... 00032 const char CommandTerminal::escape_sequence[] = "+++"; 00033 00034 mts::ATSerial* CommandTerminal::_serialp = NULL; 00035 mDot* CommandTerminal::_dot = NULL; 00036 00037 CommandTerminal::RadioEvent* CommandTerminal::_events = new RadioEvent(); 00038 00039 static bool serial_data_mode = false; 00040 static bool peer_to_peer = false; 00041 00042 std::string CommandTerminal::_errorMessage = ""; 00043 00044 void CommandTerminal::setErrorMessage(const char* message) { 00045 _errorMessage.assign(message); 00046 } 00047 00048 void CommandTerminal::setErrorMessage(const std::string& message) { 00049 _errorMessage.assign(message); 00050 } 00051 00052 const Command CommandTerminal::_commands[NO_OF_COMMANDS] = { 00053 CmdAttention(), 00054 CmdIdentification(), 00055 CmdResetCpu(), 00056 CmdDummy("Enable/Disable Echo", "ATE", "ATE0: disable, ATE1: enable", "(0,1)"), 00057 CmdDummy("Enable/Disable Verbose", "ATV", "ATV0: disable, ATV1: enable", "(0,1)"), 00058 CmdDummy("Hardware Flow Control", "AT&K", "AT&K0: disable, AT&K3: enable", "(0,3)"), 00059 00060 CmdFactoryDefault(), 00061 CmdSaveConfig(), 00062 CmdDisplayConfig(), 00063 CmdDisplayStats(), 00064 CmdResetStats(), 00065 CmdSerialBaudRate(), 00066 CmdDebugBaudRate(), 00067 CmdStartUpMode(), 00068 00069 CmdFrequencyBand(), 00070 CmdFrequencySubBand(), 00071 CmdPublicNetwork(), 00072 CmdDeviceId(), 00073 CmdDeviceClass(), 00074 00075 CmdAppPort(), 00076 CmdNetworkAddress(), 00077 CmdNetworkSessionKey(), 00078 CmdDataSessionKey(), 00079 CmdUplinkCounter(), 00080 CmdDownlinkCounter(), 00081 CmdSaveSession(), 00082 CmdRestoreSession(), 00083 CmdNetworkKey(), 00084 CmdNetworkId(), 00085 00086 CmdJoinDelay(), 00087 // Remove join settings commands until valid case for changing default settings 00088 // CmdJoinRx1Offset(), 00089 // CmdJoinRx2Datarate(), 00090 // CmdJoinRx2Frequency(), 00091 CmdJoinRequest(), 00092 CmdJoinRetries(), 00093 CmdJoinByteOrder(), 00094 CmdNetworkJoinMode(), 00095 CmdPreserveSession(), 00096 CmdNetworkJoinStatus(), 00097 CmdNetworkLinkCheck(), 00098 CmdLinkCheckCount(), 00099 CmdLinkCheckThreshold(), 00100 CmdEncryption(), 00101 00102 CmdRssi(), 00103 CmdSnr(), 00104 CmdDataPending(), 00105 00106 CmdSessionDataRate(), 00107 CmdChannelMask(), 00108 00109 CmdTxDataRate(), 00110 CmdTxPower(), 00111 CmdAntennaGain(), 00112 CmdTxFrequency(), 00113 CmdTxInverted(), 00114 CmdTxWait(), 00115 CmdTxChannel(), 00116 CmdTxNextMs(), 00117 CmdTimeOnAir(), 00118 00119 CmdRxDelay(), 00120 CmdRxOutput(), 00121 CmdRxInverted(), 00122 00123 CmdErrorCorrection(), 00124 CmdCRC(), 00125 CmdAdaptiveDataRate(), 00126 00127 CmdACKAttempts(), 00128 CmdRepeat(), 00129 CmdMacCmd(), 00130 00131 CmdSendString(), 00132 CmdSendBinary(), 00133 CmdReceiveOnce(), 00134 00135 CmdDummy("Serial Data Mode", "AT+SD", "Enter serial data mode, exit with '+++'", "NONE"), 00136 CmdDummy("Sleep Mode", "AT+SLEEP", "Enter sleep mode (0:deepsleep,1:sleep)", "(0,1)"), 00137 CmdSerialClearOnError(), 00138 CmdWakeMode(), 00139 CmdWakeInterval(), 00140 CmdWakePin(), 00141 CmdWakeDelay(), 00142 CmdWakeTimeout(), 00143 CmdPing(), 00144 CmdLogLevel(), 00145 00146 CmdDummy("***** Test Commands *****", "", "", ""), 00147 CmdRxDataRate(), 00148 CmdRxFrequency(), 00149 CmdReceiveContinuous(), 00150 CmdSendStringOnInterval(), 00151 00152 #ifdef MTS_RADIO_DEBUG_COMMANDS 00153 CmdDummy("***** Debug Commands *****", "", "", ""), 00154 CmdSendContinuous(), 00155 CmdWriteProtectedConfig(), 00156 CmdDumpRegisters(), 00157 CmdEraseFlash(), 00158 CmdDisableDutyCycle(), 00159 #endif 00160 00161 }; 00162 00163 const verify_ptr_t CommandTerminal::_verify[NO_OF_COMMANDS] = { 00164 CmdDummy::verify, 00165 CmdDummy::verify, 00166 CmdDummy::verify, 00167 CmdDummy::verify, 00168 CmdDummy::verify, 00169 CmdDummy::verify, 00170 00171 CmdDummy::verify, 00172 CmdDummy::verify, 00173 CmdDummy::verify, 00174 CmdDummy::verify, 00175 CmdDummy::verify, 00176 CmdSerialBaudRate::verify, 00177 CmdDebugBaudRate::verify, 00178 CmdStartUpMode::verify, 00179 00180 CmdFrequencyBand::verify, 00181 CmdFrequencySubBand::verify, 00182 CmdPublicNetwork::verify, 00183 CmdDeviceId::verify, 00184 CmdDeviceClass::verify, 00185 00186 CmdAppPort::verify, 00187 CmdNetworkAddress::verify, 00188 CmdNetworkSessionKey::verify, 00189 CmdDataSessionKey::verify, 00190 CmdUplinkCounter::verify, 00191 CmdDownlinkCounter::verify, 00192 CmdDummy::verify, 00193 CmdDummy::verify, 00194 CmdNetworkKey::verify, 00195 CmdNetworkId::verify, 00196 00197 CmdJoinDelay::verify, 00198 // Remove join settings commands until valid case for changing default settings 00199 // CmdJoinRx1Offset::verify, 00200 // CmdJoinRx2Datarate::verify, 00201 // CmdJoinRx2Frequency::verify, 00202 CmdJoinRequest::verify, 00203 CmdJoinRetries::verify, 00204 CmdJoinByteOrder::verify, 00205 CmdNetworkJoinMode::verify, 00206 CmdPreserveSession::verify, 00207 CmdDummy::verify, 00208 CmdDummy::verify, 00209 CmdLinkCheckCount::verify, 00210 CmdLinkCheckThreshold::verify, 00211 CmdEncryption::verify, 00212 00213 CmdDummy::verify, 00214 CmdDummy::verify, 00215 CmdDummy::verify, 00216 00217 CmdSessionDataRate::verify, 00218 CmdChannelMask::verify, 00219 00220 CmdTxDataRate::verify, 00221 CmdTxPower::verify, 00222 CmdAntennaGain::verify, 00223 CmdTxFrequency::verify, 00224 CmdTxInverted::verify, 00225 CmdTxWait::verify, 00226 CmdTxChannel::verify, 00227 CmdTxNextMs::verify, 00228 CmdTimeOnAir::verify, 00229 00230 CmdRxDelay::verify, 00231 CmdRxOutput::verify, 00232 CmdRxInverted::verify, 00233 00234 CmdErrorCorrection::verify, 00235 CmdCRC::verify, 00236 CmdAdaptiveDataRate::verify, 00237 00238 CmdACKAttempts::verify, 00239 CmdRepeat::verify, 00240 CmdMacCmd::verify, 00241 00242 CmdSendString::verify, 00243 CmdSendBinary::verify, 00244 CmdReceiveOnce::verify, 00245 00246 CmdDummy::verify, 00247 CmdDummy::verify, 00248 CmdSerialClearOnError::verify, 00249 CmdWakeMode::verify, 00250 CmdWakeInterval::verify, 00251 CmdWakePin::verify, 00252 CmdWakeDelay::verify, 00253 CmdWakeTimeout::verify, 00254 CmdDummy::verify, 00255 CmdLogLevel::verify, 00256 00257 CmdDummy::verify, 00258 CmdRxDataRate::verify, 00259 CmdRxFrequency::verify, 00260 CmdReceiveContinuous::verify, 00261 CmdSendStringOnInterval::verify, 00262 00263 #ifdef MTS_RADIO_DEBUG_COMMANDS 00264 CmdDummy::verify, 00265 CmdSendContinuous::verify, 00266 CmdDummy::verify, 00267 CmdDummy::verify, 00268 CmdEraseFlash::verify, 00269 CmdDisableDutyCycle::verify, 00270 #endif 00271 00272 }; 00273 00274 const action_ptr_t CommandTerminal::_action[NO_OF_COMMANDS] = { 00275 CmdAttention::action, 00276 CmdIdentification::action, 00277 CmdResetCpu::action, 00278 CmdDummy::action, 00279 CmdDummy::action, 00280 CmdDummy::action, 00281 00282 CmdFactoryDefault::action, 00283 CmdSaveConfig::action, 00284 CmdDisplayConfig::action, 00285 CmdDisplayStats::action, 00286 CmdResetStats::action, 00287 CmdSerialBaudRate::action, 00288 CmdDebugBaudRate::action, 00289 CmdStartUpMode::action, 00290 00291 CmdFrequencyBand::action, 00292 CmdFrequencySubBand::action, 00293 CmdPublicNetwork::action, 00294 CmdDeviceId::action, 00295 CmdDeviceClass::action, 00296 00297 CmdAppPort::action, 00298 CmdNetworkAddress::action, 00299 CmdNetworkSessionKey::action, 00300 CmdDataSessionKey::action, 00301 CmdUplinkCounter::action, 00302 CmdDownlinkCounter::action, 00303 CmdSaveSession::action, 00304 CmdRestoreSession::action, 00305 CmdNetworkKey::action, 00306 CmdNetworkId::action, 00307 00308 CmdJoinDelay::action, 00309 // Remove join settings commands until valid case for changing default settings 00310 // CmdJoinRx1Offset::action, 00311 // CmdJoinRx2Datarate::action, 00312 // CmdJoinRx2Frequency::action, 00313 CmdJoinRequest::action, 00314 CmdJoinRetries::action, 00315 CmdJoinByteOrder::action, 00316 CmdNetworkJoinMode::action, 00317 CmdPreserveSession::action, 00318 CmdNetworkJoinStatus::action, 00319 CmdNetworkLinkCheck::action, 00320 CmdLinkCheckCount::action, 00321 CmdLinkCheckThreshold::action, 00322 CmdEncryption::action, 00323 00324 CmdRssi::action, 00325 CmdSnr::action, 00326 CmdDataPending::action, 00327 00328 CmdSessionDataRate::action, 00329 CmdChannelMask::action, 00330 00331 CmdTxDataRate::action, 00332 CmdTxPower::action, 00333 CmdAntennaGain::action, 00334 CmdTxFrequency::action, 00335 CmdTxInverted::action, 00336 CmdTxWait::action, 00337 CmdTxChannel::action, 00338 CmdTxNextMs::action, 00339 CmdTimeOnAir::action, 00340 00341 CmdRxDelay::action, 00342 CmdRxOutput::action, 00343 CmdRxInverted::action, 00344 00345 CmdErrorCorrection::action, 00346 CmdCRC::action, 00347 CmdAdaptiveDataRate::action, 00348 00349 CmdACKAttempts::action, 00350 CmdRepeat::action, 00351 CmdMacCmd::action, 00352 00353 CmdSendString::action, 00354 CmdSendBinary::action, 00355 CmdReceiveOnce::action, 00356 00357 CmdDummy::action, 00358 CmdDummy::action, 00359 CmdSerialClearOnError::action, 00360 CmdWakeMode::action, 00361 CmdWakeInterval::action, 00362 CmdWakePin::action, 00363 CmdWakeDelay::action, 00364 CmdWakeTimeout::action, 00365 CmdPing::action, 00366 CmdLogLevel::action, 00367 00368 CmdDummy::action, 00369 CmdRxDataRate::action, 00370 CmdRxFrequency::action, 00371 CmdReceiveContinuous::action, 00372 CmdSendStringOnInterval::action, 00373 00374 #ifdef MTS_RADIO_DEBUG_COMMANDS 00375 CmdDummy::action, 00376 CmdSendContinuous::action, 00377 CmdWriteProtectedConfig::action, 00378 CmdDumpRegisters::action, 00379 CmdEraseFlash::action, 00380 CmdDisableDutyCycle::action, 00381 #endif 00382 00383 }; 00384 00385 CommandTerminal::CommandTerminal(mts::ATSerial& serial) : 00386 _serial(serial), 00387 _mode(mDot::COMMAND_MODE), 00388 _sleep_standby(true), 00389 #if defined(TARGET_MTS_MDOT_F411RE) 00390 _xbee_on_sleep(XBEE_ON_SLEEP), 00391 #else 00392 _xbee_on_sleep(GPIO2), 00393 #endif 00394 _autoOTAEnabled(false) 00395 { 00396 _serialp = &serial; 00397 } 00398 00399 void CommandTerminal::init() { 00400 _dot->setEvents(_events); 00401 } 00402 00403 void CommandTerminal::printHelp() { 00404 const char* name = NULL; 00405 const char* text = NULL; 00406 const char* desc = NULL; 00407 const char* tab = "\t"; 00408 00409 std::string header("Command"); 00410 header.append(tab); 00411 header.append(tab); 00412 header.append("Name"); 00413 header.append(tab); 00414 header.append(tab); 00415 header.append(tab); 00416 header.append("Description"); 00417 00418 write(newline); 00419 write(header.c_str()); 00420 write(newline); 00421 write(newline); 00422 00423 for (int i = 0; i < NO_OF_COMMANDS; i++) { 00424 name = _commands[i].name(); 00425 text = _commands[i].text(); 00426 desc = _commands[i].desc(); 00427 write(text); 00428 if (strlen(text) < 8) 00429 write(tab); 00430 write(tab); 00431 write(name); 00432 if (strlen(name) < 8) 00433 write(tab); 00434 if (strlen(name) < 16) 00435 write(tab); 00436 write(tab); 00437 write(desc); 00438 write(newline); 00439 } 00440 00441 write(newline); 00442 } 00443 00444 bool CommandTerminal::writeable() { 00445 return _serialp->writeable(); 00446 } 00447 00448 bool CommandTerminal::readable() { 00449 return _serialp->readable(); 00450 } 00451 00452 char CommandTerminal::read() { 00453 char ch; 00454 _serialp->read(&ch, 1); 00455 return ch; 00456 } 00457 00458 void CommandTerminal::write(const char* message) { 00459 while (!writeable()) 00460 ; 00461 _serialp->write(message, strlen(message)); 00462 } 00463 00464 void CommandTerminal::writef(const char* format, ...) { 00465 char buff[256]; 00466 00467 va_list ap; 00468 va_start(ap, format); 00469 int size = vsnprintf(buff, 256, format, ap); 00470 while (!writeable()) 00471 ; 00472 _serialp->write(buff, size); 00473 va_end(ap); 00474 } 00475 00476 void CommandTerminal::serialLoop() { 00477 Timer serial_read_timer; 00478 std::vector<uint8_t> serial_buffer; 00479 std::vector<uint8_t> data; 00480 int timeout = 0; 00481 00482 serial_read_timer.start(); 00483 00484 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { 00485 _xbee_on_sleep = GPIO_PIN_SET; 00486 00487 timeout = _dot->getWakeDelay(); 00488 00489 // wait for timeout or start of serial data 00490 while (!readable() && serial_read_timer.read_ms() < timeout && !_serialp->escaped()) { 00491 osDelay(2); 00492 } 00493 } 00494 00495 if (!readable() && _events->SendAck()) { 00496 logDebug("SERIAL NOT READABLE and ACK REQUESTED"); 00497 goto L_SEND; 00498 } 00499 00500 if (readable() && !_serialp->escaped()) { 00501 00502 serial_read_timer.reset(); 00503 timeout = _dot->getWakeTimeout(); 00504 00505 while (serial_read_timer.read_ms() < timeout && serial_buffer.size() <= _dot->getMaxPacketLength()) { 00506 while (readable() && serial_buffer.size() < _dot->getMaxPacketLength()) { 00507 serial_buffer.push_back(read()); 00508 serial_read_timer.reset(); 00509 00510 if (_serialp->escaped()) 00511 break; 00512 } 00513 } 00514 00515 serial_read_timer.stop(), serial_read_timer.reset(); 00516 00517 if (!serial_buffer.empty()) { 00518 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) 00519 _xbee_on_sleep = GPIO_PIN_RESET; 00520 00521 L_SEND: 00522 // wait for any duty cycle limit to expire 00523 while (_dot->getNextTxMs() > 0 && !_serialp->escaped()) { 00524 osDelay(10); 00525 } 00526 00527 if (_dot->getIsIdle()) { 00528 logDebug("Received serial data, sending out radio."); 00529 00530 if (_dot->send(serial_buffer, false) != mDot::MDOT_OK) { 00531 logDebug("Send failed."); 00532 // If the data should be tossed after send failure, clear buffer 00533 if (_dot->getSerialClearOnError()) { 00534 serial_buffer.clear(); 00535 } 00536 } else { 00537 00538 // wait for send to finish 00539 while (!_dot->getIsIdle() && !_serialp->escaped()) { 00540 osDelay(10); 00541 } 00542 00543 // call recv to wait for any packet before sending again 00544 if (!_serialp->escaped()) 00545 _dot->recv(data); 00546 00547 // Clear the serial buffer if send is success 00548 serial_buffer.clear(); 00549 00550 // In class C mode pending data will be sent automatically without uplink 00551 if (_dot->getClass() != "C") { 00552 if (_dot->getDataPending()) { 00553 logDebug("Data is pending"); 00554 goto L_SEND; 00555 } 00556 if (_dot->getAckRequested()) { 00557 logDebug("Ack requested"); 00558 goto L_SEND; 00559 } 00560 } 00561 } 00562 } else { 00563 logDebug("Radio is busy, cannot send.\r\n"); 00564 osDelay(10); 00565 } 00566 00567 } else { 00568 logDebug("No data received from serial to send.\r\n"); 00569 } 00570 } 00571 00572 if (!_serialp->readable() && _dot->getStartUpMode() == mDot::SERIAL_MODE && !_serialp->escaped()) { 00573 sleep(true); 00574 } 00575 00576 if (_serialp->escaped()) { 00577 _serialp->clearEscaped(); 00578 _serialp->rxClear(); 00579 serial_data_mode = false; 00580 _mode = mDot::COMMAND_MODE; 00581 logDebug("Exit Serial Mode"); 00582 write(done); 00583 return; 00584 } 00585 00586 if (!_dot->getNetworkJoinStatus()) { 00587 serial_data_mode = false; 00588 _mode = mDot::COMMAND_MODE; 00589 logDebug("Exit Serial Mode"); 00590 write(no_carrier); 00591 return; 00592 } 00593 } 00594 00595 bool CommandTerminal::autoJoinCheck() { 00596 00597 std::string escape_buffer; 00598 int sleep = 1000; 00599 Timer tmr; 00600 tmr.start(); 00601 int cnt = 0; 00602 00603 while (!_dot->getNetworkJoinStatus()) { 00604 if (!serial_data_mode) { 00605 write("\r\nJoining network... "); 00606 } 00607 logInfo("Joining network... "); 00608 00609 if (_dot->getNextTxMs() > 0) { 00610 if (!serial_data_mode) { 00611 writef("\r\nWaiting %lu s before next join attempt\r\n", _dot->getNextTxMs() / 1000); 00612 } 00613 logInfo("Waiting %lu s before next join attempt", _dot->getNextTxMs() / 1000); 00614 00615 tmr.reset(); 00616 while (_dot->getNextTxMs() > 0 && !_serial.escaped()) { 00617 osDelay(20); 00618 } 00619 } 00620 00621 if (!_serial.escaped() && _dot->joinNetworkOnce() == mDot::MDOT_OK) { 00622 if (!serial_data_mode) { 00623 write("Network Joined\r\n"); 00624 write(done); 00625 } 00626 logInfo("Network Joined"); 00627 return false; 00628 } 00629 00630 if (!serial_data_mode) { 00631 write("Network Join failed\r\n"); 00632 write(error); 00633 } 00634 logInfo("Network Join failed"); 00635 00636 if (!_serial.escaped() && _dot->getFrequencySubBand() != 0 && _dot->getJoinRetries() > 0 && cnt++ > _dot->getJoinRetries()) { 00637 cnt = 0; 00638 00639 if (_dot->getFrequencyBand() == mDot::FB_US915 || _dot->getFrequencyBand() == mDot::FB_AU915 ) { 00640 uint8_t band = ((_dot->getFrequencySubBand()) % 8) + 1; 00641 logWarning("Join retries exhausted, switching to sub band %u", band); 00642 _dot->setFrequencySubBand(band); 00643 } 00644 } 00645 00646 tmr.reset(); 00647 while (tmr.read_ms() < sleep && !_serial.escaped()) { 00648 osDelay(10); 00649 } 00650 00651 if (_serial.escaped()) { 00652 _serial.clearEscaped(); 00653 serial_data_mode = false; 00654 _mode = mDot::COMMAND_MODE; 00655 if (!serial_data_mode) { 00656 write("Join Canceled\r\n"); 00657 write(done); 00658 } 00659 logInfo("Join Canceled\r\n"); 00660 return true; 00661 } 00662 } 00663 00664 return false; 00665 } 00666 00667 void CommandTerminal::start() { 00668 00669 char ch; 00670 bool running = true; 00671 bool echo = _dot->getEcho(); 00672 std::string command; 00673 #if defined(TARGET_MTS_MDOT_F411RE) 00674 std::deque<std::string> history; 00675 int history_index = -1; 00676 #endif 00677 std::vector<std::string> args; 00678 bool join_canceled = false; 00679 00680 _autoOTAEnabled = _dot->getJoinMode() == mDot::AUTO_OTA; 00681 00682 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { 00683 00684 serial_data_mode = true; 00685 _mode = mDot::SERIAL_MODE; 00686 00687 std::string escape_buffer; 00688 char ch; 00689 00690 if (!_dot->getStandbyFlag()) { 00691 // wake up from power-on/reset 00692 00693 int escape_timeout = 1000; 00694 Timer tmr; 00695 Timer escape_tmr; 00696 00697 // wait one second for possible escape by user pressing '+' key 00698 tmr.reset(); 00699 tmr.start(); 00700 escape_tmr.reset(); 00701 escape_tmr.start(); 00702 while (tmr.read_ms() < escape_timeout) { 00703 if (_serial.readable()) { 00704 _serial.read(&ch, 1); 00705 escape_buffer += ch; 00706 } 00707 00708 if (escape_buffer.find("+") != std::string::npos) { 00709 logInfo("Escape detected"); 00710 join_canceled = true; 00711 serial_data_mode = false; 00712 _mode = mDot::COMMAND_MODE; 00713 command.clear(); 00714 break; 00715 } 00716 00717 if (escape_tmr.read_ms() > escape_timeout) 00718 escape_buffer.clear(); 00719 00720 osDelay(1); 00721 } 00722 } 00723 00724 if (_mode == mDot::SERIAL_MODE && !_dot->getNetworkJoinStatus() && _dot->getJoinMode() == mDot::OTA) { 00725 if (_dot->joinNetworkOnce() != mDot::MDOT_OK) { 00726 serial_data_mode = false; 00727 _mode = mDot::COMMAND_MODE; 00728 00729 logWarning("Start Up Mode set to SERIAL_MODE, but join failed."); 00730 _serial.writef("Network Not Joined\r\n"); 00731 _serial.writef(error); 00732 } 00733 } 00734 } 00735 00736 if (_dot->getJoinMode() == mDot::PEER_TO_PEER) { 00737 peer_to_peer = true; 00738 } else { 00739 peer_to_peer = false; 00740 } 00741 00742 //Run terminal session 00743 while (running) { 00744 00745 // wait for input to reduce at command idle current 00746 while (!readable() || _mode == mDot::SERIAL_MODE) { 00747 if (!join_canceled && _autoOTAEnabled) { 00748 join_canceled = autoJoinCheck(); 00749 if (join_canceled) 00750 command.clear(); 00751 } 00752 00753 if (!_autoOTAEnabled || (!join_canceled && _autoOTAEnabled)) { 00754 switch (_mode) { 00755 case mDot::SERIAL_MODE: 00756 // signal wakeup, read serial and output to radio 00757 serialLoop(); 00758 continue; 00759 break; 00760 default: 00761 break; 00762 } 00763 } 00764 00765 ch = '\0'; 00766 00767 wait(0.00001); // 10 us 00768 _serial.escaped(); 00769 } 00770 00771 // read characters 00772 if (readable()) { 00773 ch = read(); 00774 00775 if (ch == '\b' || ch == 0x7f) { 00776 if (!command.empty()) { 00777 writef("\b \b"); 00778 command.erase(command.size() - 1); 00779 } 00780 continue; 00781 } else if (ch == 0x1b || ch == 0x09) { 00782 osDelay(20); 00783 // catch escape sequence, or tab 00784 char ch1 = 0x00, ch2 = 0x00; 00785 00786 if (readable()) { 00787 ch1 = read(); 00788 if (readable()) 00789 ch2 = read(); 00790 00791 #if defined(TARGET_MTS_MDOT_F411RE) 00792 if (ch1 == 0x5b && ch2 == 0x41) { 00793 // up key 00794 for (size_t i = 0; i < command.size() + 1; i++) { 00795 writef("\b \b"); 00796 } 00797 if (history.size() > 0) { 00798 if (++history_index >= int(history.size() - 1)) 00799 history_index = history.size() - 1; 00800 00801 command = history[history_index]; 00802 writef("%s", history[history_index].c_str()); 00803 } else { 00804 command.clear(); 00805 } 00806 } else if (ch1 == 0x5b && ch2 == 0x42) { 00807 00808 // down key 00809 for (size_t i = 0; i < command.size() + 1; i++) { 00810 writef("\b \b"); 00811 } 00812 00813 if (--history_index < 0) { 00814 history_index = -1; 00815 command.clear(); 00816 } else { 00817 command = history[history_index]; 00818 writef("%s", history[history_index].c_str()); 00819 } 00820 } 00821 #endif 00822 } 00823 while (readable()) 00824 read(); 00825 continue; 00826 } else { 00827 command += ch; 00828 } 00829 00830 // echo chars if enabled 00831 if (echo && !(ch == '\r' || ch == '\n')) 00832 writef("%c", ch); 00833 } 00834 00835 // look for end of command line 00836 if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) { 00837 // remove new line or cr character 00838 command.erase(command.size() - 1); 00839 write("\r"); // match standard modem output 00840 write(newline); 00841 } else { 00842 continue; 00843 } 00844 00845 // trim whitespace from command 00846 mts::Text::trim(command, "\r\n\t "); 00847 00848 if (command.size() < 1) { 00849 command.clear(); 00850 continue; 00851 } 00852 00853 // parse command and args 00854 args.clear(); 00855 00856 // find first '=' character 00857 size_t delim_index = command.find("="); 00858 if (delim_index != std::string::npos) { 00859 args.push_back(command.substr(0, delim_index)); 00860 } else { 00861 // find first ' ' character 00862 delim_index = command.find(" "); 00863 if (delim_index != std::string::npos) { 00864 args.push_back(command.substr(0, delim_index)); 00865 } else { 00866 args.push_back(command); 00867 } 00868 } 00869 00870 if (delim_index != std::string::npos) { 00871 std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ","); 00872 args.insert(args.end(), params.begin(), params.end()); 00873 } 00874 00875 args[0] = mts::Text::toUpper(args[0]); 00876 00877 // print help 00878 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) { 00879 printHelp(); 00880 command.clear(); 00881 } else if ((args[0].find("ATE?") == 0 && args[0].length() == 4) || (args[0].find("ATE") == 0 && args[0].length() == 3)) { 00882 writef("%d\r\n", _dot->getEcho()); 00883 write(done); 00884 } else if (args[0].find("ATE0") == 0 && args[0].length() == 4) { 00885 _dot->setEcho(false); 00886 write(done); 00887 echo = _dot->getEcho(); 00888 } else if (args[0].find("ATE1") == 0 && args[0].length() == 4) { 00889 _dot->setEcho(true); 00890 write(done); 00891 echo = _dot->getEcho(); 00892 } else if ((args[0].find("ATV?") == 0 && args[0].length() == 4) || (args[0].find("ATV") == 0 && args[0].length() == 3)) { 00893 writef("%d\r\n", _dot->getVerbose()); 00894 write(done); 00895 } else if (args[0].find("ATV0") == 0 && args[0].length() == 4) { 00896 _dot->setVerbose(false); 00897 write(done); 00898 } else if (args[0].find("ATV1") == 0 && args[0].length() == 4) { 00899 _dot->setVerbose(true); 00900 write(done); 00901 } else if ((args[0].find("AT&K?") == 0 && args[0].length() == 5) || (args[0].find("AT&K") == 0 && args[0].length() == 4)) { 00902 writef("%d\r\n", (_dot->getFlowControl() ? 3 : 0)); 00903 write(done); 00904 } else if (args[0].find("AT&K0") == 0 && args[0].length() == 5) { 00905 _dot->setFlowControl(false); 00906 write(done); 00907 } else if (args[0].find("AT&K3") == 0 && args[0].length() == 5) { 00908 _dot->setFlowControl(true); 00909 write(done); 00910 } else if (args[0] == "AT+SD") { 00911 if (_dot->getNetworkJoinStatus()) { 00912 logDebug("Enter Serial Mode"); 00913 write(connect); 00914 serial_data_mode = true; 00915 _mode = mDot::SERIAL_MODE; 00916 } else { 00917 logDebug("Network Not Joined"); 00918 write("Network Not Joined\r\n"); 00919 write(error); 00920 } 00921 } else if (args[0] == "AT+SLEEP") { 00922 if (args.size() > 2 && (args[1] != "?")) { 00923 write("Invalid argument\r\n"); 00924 write(error); 00925 } else { 00926 if (args.size() > 1 && args[1] == "?") { 00927 write("(0:deepsleep,1:sleep)\r\n"); 00928 write(done); 00929 } else { 00930 _sleep_standby = !(args.size() > 1 && args[1] == "1"); 00931 #if defined(TARGET_MTS_MDOT_F411RE) 00932 //Read the board ID. If all 0's, it is revision B. This hardware does not support deep sleep. 00933 DigitalIn ID2(PC_4); 00934 DigitalIn ID1(PC_5); 00935 DigitalIn ID0(PD_2); 00936 if(ID2 == 0 && ID1 == 0 && ID0 == 0 && _sleep_standby == 1){ 00937 _sleep_standby = 0; 00938 logWarning("This hardware version does not support deep sleep. Using sleep mode instead."); 00939 } 00940 #endif 00941 write(done); 00942 osDelay(5); 00943 this->sleep(_sleep_standby); 00944 osDelay(1); 00945 } 00946 } 00947 } else { 00948 bool found = false; 00949 bool query = false; 00950 00951 std::string lookfor = args[0]; 00952 00953 // per command help 00954 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0)) 00955 lookfor = mts::Text::toUpper(args[1]); 00956 00957 // trim off any trailing '?' and mark as a query command 00958 if (args[0].rfind("?") == args[0].length() - 1) { 00959 query = true; 00960 lookfor = args[0].substr(0, args[0].length() - 1); 00961 } 00962 00963 // search for command 00964 for (int i = 0; i < NO_OF_COMMANDS; i++) { 00965 00966 // match CMD or CMD? syntax if command is queryable 00967 if (lookfor == _commands[i].text() && (!query || (query && _commands[i].queryable()))) { 00968 found = true; 00969 if (args[0] == "HELP") { 00970 writef("%s%s", _commands[i].help().c_str(), newline); 00971 write(done); 00972 } 00973 00974 else if (args.size() > 1 && args[1] == "?") { 00975 writef("%s%s", _commands[i].usage().c_str(), newline); 00976 write(done); 00977 } else if (!_verify[i](args)) { 00978 writef("%s%s", _errorMessage.c_str(), newline); 00979 writef("%s", error); 00980 } else { 00981 if (_action[i](args) == 0) { 00982 writef("%s", done); 00983 } else { 00984 writef("%s%s", _errorMessage.c_str(), newline); 00985 writef("%s", error); 00986 } 00987 } 00988 } 00989 } 00990 00991 if (!found) { 00992 writef("%s", command_error); 00993 writef("%s", error); 00994 } 00995 } 00996 00997 #if defined(TARGET_MTS_MDOT_F411RE) 00998 if (history.size() == 0 || history.front() != command) 00999 history.push_front(command); 01000 history_index = -1; 01001 command.clear(); 01002 01003 while (history.size() > 10) 01004 history.pop_back(); 01005 #else 01006 command.clear(); 01007 #endif 01008 } 01009 } 01010 01011 void CommandTerminal::sleep(bool standby) { 01012 _xbee_on_sleep = GPIO_PIN_RESET; 01013 01014 _serial.rxClear(); 01015 _serial.txClear(); 01016 01017 #if defined(TARGET_XDOT_L151CC) 01018 xdot_save_gpio_state(); 01019 01020 /* GPIO Ports Clock Enable */ 01021 __GPIOA_CLK_ENABLE(); 01022 __GPIOB_CLK_ENABLE(); 01023 __GPIOC_CLK_ENABLE(); 01024 __GPIOH_CLK_ENABLE(); 01025 01026 GPIO_InitTypeDef GPIO_InitStruct; 01027 01028 // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source 01029 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12; 01030 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01031 GPIO_InitStruct.Pull = GPIO_NOPULL; 01032 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01033 01034 // I2C_SDA & I2C_SCL to analog nopull 01035 GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; 01036 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01037 GPIO_InitStruct.Pull = GPIO_NOPULL; 01038 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 01039 01040 // SPI_MOSI, SPI_MISO, SPI_SCK, & SPI_NSS to analog nopull 01041 GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 01042 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01043 GPIO_InitStruct.Pull = GPIO_NOPULL; 01044 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 01045 01046 // iterate through potential wake pins - leave the configured wake pin alone if one is needed 01047 if (_dot->getWakePin() != WAKE || _dot->getWakeMode() == mDot::RTC_ALARM) { 01048 GPIO_InitStruct.Pin = GPIO_PIN_0; 01049 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01050 GPIO_InitStruct.Pull = GPIO_NOPULL; 01051 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01052 } 01053 if (_dot->getWakePin() != GPIO0 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01054 GPIO_InitStruct.Pin = GPIO_PIN_4; 01055 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01056 GPIO_InitStruct.Pull = GPIO_NOPULL; 01057 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01058 } 01059 if (_dot->getWakePin() != GPIO1 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01060 GPIO_InitStruct.Pin = GPIO_PIN_5; 01061 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01062 GPIO_InitStruct.Pull = GPIO_NOPULL; 01063 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01064 } 01065 if (_dot->getWakePin() != GPIO2 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01066 GPIO_InitStruct.Pin = GPIO_PIN_0; 01067 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01068 GPIO_InitStruct.Pull = GPIO_NOPULL; 01069 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 01070 } 01071 if (_dot->getWakePin() != GPIO3 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01072 GPIO_InitStruct.Pin = GPIO_PIN_2; 01073 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01074 GPIO_InitStruct.Pull = GPIO_NOPULL; 01075 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 01076 } 01077 if (_dot->getWakePin() != UART1_RX || _dot->getWakeMode() == mDot::RTC_ALARM) { 01078 GPIO_InitStruct.Pin = GPIO_PIN_10; 01079 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01080 GPIO_InitStruct.Pull = GPIO_NOPULL; 01081 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01082 } 01083 #else 01084 uint32_t portA[6]; 01085 uint32_t portB[6]; 01086 uint32_t portC[6]; 01087 uint32_t portD[6]; 01088 uint32_t portH[6]; 01089 01090 //Save the GPIO state. 01091 portA[0] = GPIOA->MODER; 01092 portA[1] = GPIOA->OTYPER; 01093 portA[2] = GPIOA->OSPEEDR; 01094 portA[3] = GPIOA->PUPDR; 01095 portA[4] = GPIOA->AFR[0]; 01096 portA[5] = GPIOA->AFR[1]; 01097 01098 portB[0] = GPIOB->MODER; 01099 portB[1] = GPIOB->OTYPER; 01100 portB[2] = GPIOB->OSPEEDR; 01101 portB[3] = GPIOB->PUPDR; 01102 portB[4] = GPIOB->AFR[0]; 01103 portB[5] = GPIOB->AFR[1]; 01104 01105 portC[0] = GPIOC->MODER; 01106 portC[1] = GPIOC->OTYPER; 01107 portC[2] = GPIOC->OSPEEDR; 01108 portC[3] = GPIOC->PUPDR; 01109 portC[4] = GPIOC->AFR[0]; 01110 portC[5] = GPIOC->AFR[1]; 01111 01112 portD[0] = GPIOD->MODER; 01113 portD[1] = GPIOD->OTYPER; 01114 portD[2] = GPIOD->OSPEEDR; 01115 portD[3] = GPIOD->PUPDR; 01116 portD[4] = GPIOD->AFR[0]; 01117 portD[5] = GPIOD->AFR[1]; 01118 01119 portH[0] = GPIOH->MODER; 01120 portH[1] = GPIOH->OTYPER; 01121 portH[2] = GPIOH->OSPEEDR; 01122 portH[3] = GPIOH->PUPDR; 01123 portH[4] = GPIOH->AFR[0]; 01124 portH[5] = GPIOH->AFR[1]; 01125 01126 /* GPIO Ports Clock Enable */ 01127 __GPIOA_CLK_ENABLE(); 01128 __GPIOB_CLK_ENABLE(); 01129 __GPIOC_CLK_ENABLE(); 01130 01131 GPIO_InitTypeDef GPIO_InitStruct; 01132 01133 // Set port A pins to analog nopull 01134 GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_6 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 01135 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 01136 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01137 GPIO_InitStruct.Pull = GPIO_NOPULL; 01138 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01139 01140 // Set port B pins to analog nopull 01141 GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4; 01142 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01143 GPIO_InitStruct.Pull = GPIO_NOPULL; 01144 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 01145 01146 // Set port C pins to analog nopull 01147 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_13; 01148 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01149 GPIO_InitStruct.Pull = GPIO_NOPULL; 01150 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 01151 01152 // iterate through potential wake pins - leave the configured wake pin alone if one is needed 01153 // XBEE_DIN - PA3 01154 // XBEE_DIO2 - PA5 01155 // XBEE_DIO3 - PA4 01156 // XBEE_DIO4 - PA7 01157 // XBEE_DIO5 - PC1 01158 // XBEE_DIO6 - PA1 01159 // XBEE_DIO7 - PA0 01160 // XBEE_SLEEPRQ - PA11 01161 01162 if (_dot->getWakePin() != XBEE_DIN || _dot->getWakeMode() == mDot::RTC_ALARM) { 01163 GPIO_InitStruct.Pin = GPIO_PIN_3; 01164 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01165 GPIO_InitStruct.Pull = GPIO_NOPULL; 01166 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01167 } 01168 01169 if (_dot->getWakePin() != XBEE_DIO2 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01170 GPIO_InitStruct.Pin = GPIO_PIN_5; 01171 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01172 GPIO_InitStruct.Pull = GPIO_NOPULL; 01173 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01174 } 01175 01176 if (_dot->getWakePin() != XBEE_DIO3 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01177 GPIO_InitStruct.Pin = GPIO_PIN_4; 01178 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01179 GPIO_InitStruct.Pull = GPIO_NOPULL; 01180 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01181 } 01182 01183 if (_dot->getWakePin() != XBEE_DIO4 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01184 GPIO_InitStruct.Pin = GPIO_PIN_7; 01185 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01186 GPIO_InitStruct.Pull = GPIO_NOPULL; 01187 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01188 } 01189 01190 if (_dot->getWakePin() != XBEE_DIO5 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01191 GPIO_InitStruct.Pin = GPIO_PIN_1; 01192 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01193 GPIO_InitStruct.Pull = GPIO_NOPULL; 01194 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 01195 } 01196 01197 if (_dot->getWakePin() != XBEE_DIO6 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01198 GPIO_InitStruct.Pin = GPIO_PIN_1; 01199 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01200 GPIO_InitStruct.Pull = GPIO_NOPULL; 01201 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01202 } 01203 01204 if (_dot->getWakePin() != XBEE_DIO7 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01205 GPIO_InitStruct.Pin = GPIO_PIN_0; 01206 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01207 GPIO_InitStruct.Pull = GPIO_NOPULL; 01208 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01209 } 01210 01211 if (_dot->getWakePin() != XBEE_SLEEPRQ|| _dot->getWakeMode() == mDot::RTC_ALARM) { 01212 GPIO_InitStruct.Pin = GPIO_PIN_11; 01213 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01214 GPIO_InitStruct.Pull = GPIO_NOPULL; 01215 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01216 } 01217 01218 #endif 01219 _dot->sleep(_dot->getWakeInterval(), _dot->getWakeMode(), standby); 01220 01221 #if defined(TARGET_XDOT_L151CC) 01222 xdot_restore_gpio_state(); 01223 #else 01224 //Restore the GPIO state. 01225 GPIOA->MODER = portA[0]; 01226 GPIOA->OTYPER = portA[1]; 01227 GPIOA->OSPEEDR = portA[2]; 01228 GPIOA->PUPDR = portA[3]; 01229 GPIOA->AFR[0] = portA[4]; 01230 GPIOA->AFR[1] = portA[5]; 01231 01232 GPIOB->MODER = portB[0]; 01233 GPIOB->OTYPER = portB[1]; 01234 GPIOB->OSPEEDR = portB[2]; 01235 GPIOB->PUPDR = portB[3]; 01236 GPIOB->AFR[0] = portB[4]; 01237 GPIOB->AFR[1] = portB[5]; 01238 01239 GPIOC->MODER = portC[0]; 01240 GPIOC->OTYPER = portC[1]; 01241 GPIOC->OSPEEDR = portC[2]; 01242 GPIOC->PUPDR = portC[3]; 01243 GPIOC->AFR[0] = portC[4]; 01244 GPIOC->AFR[1] = portC[5]; 01245 01246 GPIOD->MODER = portD[0]; 01247 GPIOD->OTYPER = portD[1]; 01248 GPIOD->OSPEEDR = portD[2]; 01249 GPIOD->PUPDR = portD[3]; 01250 GPIOD->AFR[0] = portD[4]; 01251 GPIOD->AFR[1] = portD[5]; 01252 01253 GPIOH->MODER = portH[0]; 01254 GPIOH->OTYPER = portH[1]; 01255 GPIOH->OSPEEDR = portH[2]; 01256 GPIOH->PUPDR = portH[3]; 01257 GPIOH->AFR[0] = portH[4]; 01258 GPIOH->AFR[1] = portH[5]; 01259 #endif 01260 01261 _serial.rxClear(); 01262 _serial.txClear(); 01263 } 01264 01265 std::string CommandTerminal::formatPacketData(const std::vector<uint8_t>& data, const uint8_t& format) { 01266 if (format == mDot::HEXADECIMAL) 01267 return mts::Text::bin2hexString(data); 01268 else 01269 return std::string(data.begin(), data.end()); 01270 } 01271 01272 bool CommandTerminal::waitForEscape(int timeout, mDot* dot, WaitType wait) { 01273 Timer timer; 01274 01275 timer.start(); 01276 while (timer.read_ms() < timeout) { 01277 01278 if (dot != NULL) { 01279 if (wait == WAIT_SEND && (!dot->getIsTransmitting())) { 01280 return false; 01281 } 01282 } 01283 01284 if (_serialp != NULL && _serialp->escaped()) { 01285 _serialp->clearEscaped(); 01286 return true; 01287 } 01288 01289 osDelay(10); 01290 } 01291 01292 return false; 01293 } 01294 01295 void CommandTerminal::wakeup(void) { 01296 } 01297 01298 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) { 01299 mDotEvent::PacketRx(port, payload, size, rssi, snr, ctrl, retries); 01300 01301 if (serial_data_mode) { 01302 logDebug("Rx %d bytes", size); 01303 if (size > 0) { 01304 CommandTerminal::Serial()->write((char*) RxPayload, RxPayloadSize); 01305 } 01306 if (!CommandTerminal::Serial()->readable() && _dot->getAckRequested() && _dot->getClass() == "C") { 01307 _sendAck = true; 01308 } 01309 } 01310 } 01311 01312 CommandTerminal::~CommandTerminal() { 01313 delete _events; 01314 }
Generated on Tue Jul 12 2022 20:40:04 by
1.7.2
