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