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: libmDot-Custom MTS-Serial
Fork of mDot_AT_firmware_CUSTOM 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 _idle_thread(idle, NULL, osPriorityLow) 00396 { 00397 _serialp = &serial; 00398 } 00399 00400 void CommandTerminal::init() { 00401 _dot->setEvents(_events); 00402 } 00403 00404 void CommandTerminal::printHelp() { 00405 const char* name = NULL; 00406 const char* text = NULL; 00407 const char* desc = NULL; 00408 const char* tab = "\t"; 00409 00410 std::string header("Command"); 00411 header.append(tab); 00412 header.append(tab); 00413 header.append("Name"); 00414 header.append(tab); 00415 header.append(tab); 00416 header.append(tab); 00417 header.append("Description"); 00418 00419 write(newline); 00420 write(header.c_str()); 00421 write(newline); 00422 write(newline); 00423 00424 for (int i = 0; i < NO_OF_COMMANDS; i++) { 00425 name = _commands[i].name(); 00426 text = _commands[i].text(); 00427 desc = _commands[i].desc(); 00428 write(text); 00429 if (strlen(text) < 8) 00430 write(tab); 00431 write(tab); 00432 write(name); 00433 if (strlen(name) < 8) 00434 write(tab); 00435 if (strlen(name) < 16) 00436 write(tab); 00437 write(tab); 00438 write(desc); 00439 write(newline); 00440 } 00441 00442 write(newline); 00443 } 00444 00445 bool CommandTerminal::writeable() { 00446 return _serialp->writeable(); 00447 } 00448 00449 bool CommandTerminal::readable() { 00450 return _serialp->readable(); 00451 } 00452 00453 char CommandTerminal::read() { 00454 char ch; 00455 _serialp->read(&ch, 1); 00456 return ch; 00457 } 00458 00459 void CommandTerminal::write(const char* message) { 00460 while (!writeable()) 00461 ; 00462 _serialp->write(message, strlen(message)); 00463 } 00464 00465 void CommandTerminal::writef(const char* format, ...) { 00466 char buff[256]; 00467 00468 va_list ap; 00469 va_start(ap, format); 00470 int size = vsnprintf(buff, 256, format, ap); 00471 while (!writeable()) 00472 ; 00473 _serialp->write(buff, size); 00474 va_end(ap); 00475 } 00476 00477 void CommandTerminal::serialLoop() { 00478 Timer serial_read_timer; 00479 std::vector<uint8_t> serial_buffer; 00480 std::vector<uint8_t> data; 00481 int timeout = 0; 00482 00483 serial_read_timer.start(); 00484 00485 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { 00486 _xbee_on_sleep = GPIO_PIN_SET; 00487 00488 timeout = _dot->getWakeDelay(); 00489 00490 // wait for timeout or start of serial data 00491 while (!readable() && serial_read_timer.read_ms() < timeout && !_serialp->escaped()) { 00492 osDelay(2); 00493 } 00494 } 00495 00496 if (!readable() && _events->SendAck()) { 00497 logDebug("SERIAL NOT READABLE and ACK REQUESTED"); 00498 goto L_SEND; 00499 } 00500 00501 if (readable() && !_serialp->escaped()) { 00502 00503 serial_read_timer.reset(); 00504 timeout = _dot->getWakeTimeout(); 00505 00506 while (serial_read_timer.read_ms() < timeout && serial_buffer.size() <= _dot->getMaxPacketLength()) { 00507 while (readable() && serial_buffer.size() < _dot->getMaxPacketLength()) { 00508 serial_buffer.push_back(read()); 00509 serial_read_timer.reset(); 00510 00511 if (_serialp->escaped()) 00512 break; 00513 } 00514 } 00515 00516 serial_read_timer.stop(), serial_read_timer.reset(); 00517 00518 if (!serial_buffer.empty()) { 00519 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) 00520 _xbee_on_sleep = GPIO_PIN_RESET; 00521 00522 L_SEND: 00523 // wait for any duty cycle limit to expire 00524 while (_dot->getNextTxMs() > 0 && !_serialp->escaped()) { 00525 osDelay(10); 00526 } 00527 00528 if (_dot->getIsIdle()) { 00529 logDebug("Received serial data, sending out radio."); 00530 00531 if (_dot->send(serial_buffer, false) != mDot::MDOT_OK) { 00532 logDebug("Send failed."); 00533 // If the data should be tossed after send failure, clear buffer 00534 if (_dot->getSerialClearOnError()) { 00535 serial_buffer.clear(); 00536 } 00537 } else { 00538 00539 // wait for send to finish 00540 while (!_dot->getIsIdle() && !_serialp->escaped()) { 00541 osDelay(10); 00542 } 00543 00544 // call recv to wait for any packet before sending again 00545 if (!_serialp->escaped()) 00546 _dot->recv(data); 00547 00548 // Clear the serial buffer if send is success 00549 serial_buffer.clear(); 00550 00551 // In class C mode pending data will be sent automatically without uplink 00552 if (_dot->getClass() != "C") { 00553 if (_dot->getDataPending()) { 00554 logDebug("Data is pending"); 00555 goto L_SEND; 00556 } 00557 if (_dot->getAckRequested()) { 00558 logDebug("Ack requested"); 00559 goto L_SEND; 00560 } 00561 } 00562 } 00563 } else { 00564 logDebug("Radio is busy, cannot send.\r\n"); 00565 osDelay(10); 00566 } 00567 00568 } else { 00569 logDebug("No data received from serial to send.\r\n"); 00570 } 00571 } 00572 00573 if (!_serialp->readable() && _dot->getStartUpMode() == mDot::SERIAL_MODE && !_serialp->escaped()) { 00574 sleep(true); 00575 } 00576 00577 if (_serialp->escaped()) { 00578 _serialp->clearEscaped(); 00579 _serialp->rxClear(); 00580 serial_data_mode = false; 00581 _mode = mDot::COMMAND_MODE; 00582 logDebug("Exit Serial Mode"); 00583 write(done); 00584 return; 00585 } 00586 00587 if (!_dot->getNetworkJoinStatus()) { 00588 serial_data_mode = false; 00589 _mode = mDot::COMMAND_MODE; 00590 logDebug("Exit Serial Mode"); 00591 write(no_carrier); 00592 return; 00593 } 00594 } 00595 00596 bool CommandTerminal::autoJoinCheck() { 00597 00598 std::string escape_buffer; 00599 int sleep = 1000; 00600 Timer tmr; 00601 tmr.start(); 00602 int cnt = 0; 00603 00604 while (!_dot->getNetworkJoinStatus()) { 00605 if (!serial_data_mode) { 00606 write("\r\nJoining network... "); 00607 } 00608 logInfo("Joining network... "); 00609 00610 if (_dot->getNextTxMs() > 0) { 00611 if (!serial_data_mode) { 00612 writef("\r\nWaiting %lu s before next join attempt\r\n", _dot->getNextTxMs() / 1000); 00613 } 00614 logInfo("Waiting %lu s before next join attempt", _dot->getNextTxMs() / 1000); 00615 00616 tmr.reset(); 00617 while (_dot->getNextTxMs() > 0 && !_serial.escaped()) { 00618 osDelay(20); 00619 } 00620 } 00621 00622 if (!_serial.escaped() && _dot->joinNetworkOnce() == mDot::MDOT_OK) { 00623 if (!serial_data_mode) { 00624 write("Network Joined\r\n"); 00625 write(done); 00626 } 00627 logInfo("Network Joined"); 00628 return false; 00629 } 00630 00631 if (!serial_data_mode) { 00632 write("Network Join failed\r\n"); 00633 write(error); 00634 } 00635 logInfo("Network Join failed"); 00636 00637 if (!_serial.escaped() && _dot->getFrequencySubBand() != 0 && _dot->getJoinRetries() > 0 && cnt++ > _dot->getJoinRetries()) { 00638 cnt = 0; 00639 00640 if (_dot->getFrequencyBand() == mDot::FIXED ) { 00641 uint8_t band = ((_dot->getFrequencySubBand()) % 8) + 1; 00642 logWarning("Join retries exhausted, switching to sub band %u", band); 00643 _dot->setFrequencySubBand(band); 00644 } 00645 } 00646 00647 tmr.reset(); 00648 while (tmr.read_ms() < sleep && !_serial.escaped()) { 00649 osDelay(10); 00650 } 00651 00652 if (_serial.escaped()) { 00653 _serial.clearEscaped(); 00654 serial_data_mode = false; 00655 _mode = mDot::COMMAND_MODE; 00656 if (!serial_data_mode) { 00657 write("Join Canceled\r\n"); 00658 write(done); 00659 } 00660 logInfo("Join Canceled\r\n"); 00661 return true; 00662 } 00663 } 00664 00665 return false; 00666 } 00667 00668 void CommandTerminal::start() { 00669 00670 char ch; 00671 bool running = true; 00672 bool echo = _dot->getEcho(); 00673 std::string command; 00674 std::deque<std::string> history; 00675 int history_index = -1; 00676 std::vector<std::string> args; 00677 bool join_canceled = false; 00678 00679 _autoOTAEnabled = _dot->getJoinMode() == mDot::AUTO_OTA; 00680 00681 if (_dot->getStartUpMode() == mDot::SERIAL_MODE) { 00682 00683 serial_data_mode = true; 00684 _mode = mDot::SERIAL_MODE; 00685 00686 std::string escape_buffer; 00687 char ch; 00688 00689 if (!_dot->getStandbyFlag()) { 00690 // wake up from power-on/reset 00691 00692 int escape_timeout = 1000; 00693 Timer tmr; 00694 Timer escape_tmr; 00695 00696 // wait one second for possible escape by user pressing '+' key 00697 tmr.reset(); 00698 tmr.start(); 00699 escape_tmr.reset(); 00700 escape_tmr.start(); 00701 while (tmr.read_ms() < escape_timeout) { 00702 if (_serial.readable()) { 00703 _serial.read(&ch, 1); 00704 escape_buffer += ch; 00705 } 00706 00707 if (escape_buffer.find("+") != std::string::npos) { 00708 logInfo("Escape detected"); 00709 join_canceled = true; 00710 serial_data_mode = false; 00711 _mode = mDot::COMMAND_MODE; 00712 command.clear(); 00713 break; 00714 } 00715 00716 if (escape_tmr.read_ms() > escape_timeout) 00717 escape_buffer.clear(); 00718 00719 osDelay(1); 00720 } 00721 } 00722 00723 if (_mode == mDot::SERIAL_MODE && !_dot->getNetworkJoinStatus() && _dot->getJoinMode() == mDot::OTA) { 00724 if (_dot->joinNetworkOnce() != mDot::MDOT_OK) { 00725 serial_data_mode = false; 00726 _mode = mDot::COMMAND_MODE; 00727 00728 logWarning("Start Up Mode set to SERIAL_MODE, but join failed."); 00729 _serial.writef("Network Not Joined\r\n"); 00730 _serial.writef(error); 00731 } 00732 } 00733 } 00734 00735 if (_dot->getJoinMode() == mDot::PEER_TO_PEER) { 00736 peer_to_peer = true; 00737 } else { 00738 peer_to_peer = false; 00739 } 00740 00741 //Run terminal session 00742 while (running) { 00743 00744 // wait for input to reduce at command idle current 00745 while (!readable() || _mode == mDot::SERIAL_MODE) { 00746 if (!join_canceled && _autoOTAEnabled) { 00747 join_canceled = autoJoinCheck(); 00748 if (join_canceled) 00749 command.clear(); 00750 } 00751 00752 if (!_autoOTAEnabled || (!join_canceled && _autoOTAEnabled)) { 00753 switch (_mode) { 00754 case mDot::SERIAL_MODE: 00755 // signal wakeup, read serial and output to radio 00756 serialLoop(); 00757 continue; 00758 default: 00759 break; 00760 } 00761 } 00762 00763 ch = '\0'; 00764 00765 wait(0.00001); // 10 us 00766 _serial.escaped(); 00767 } 00768 00769 // read characters 00770 if (readable()) { 00771 ch = read(); 00772 00773 if (ch == '\b' || ch == 0x7f) { 00774 if (!command.empty()) { 00775 writef("\b \b"); 00776 command.erase(command.size() - 1); 00777 } 00778 continue; 00779 } else if (ch == 0x1b || ch == 0x09) { 00780 osDelay(20); 00781 // catch escape sequence, or tab 00782 char ch1 = 0x00, ch2 = 0x00; 00783 00784 if (readable()) { 00785 ch1 = read(); 00786 if (readable()) 00787 ch2 = read(); 00788 00789 if (ch1 == 0x5b && ch2 == 0x41) { 00790 // up key 00791 for (size_t i = 0; i < command.size() + 1; i++) { 00792 writef("\b \b"); 00793 } 00794 if (history.size() > 0) { 00795 if (++history_index >= int(history.size() - 1)) 00796 history_index = history.size() - 1; 00797 00798 command = history[history_index]; 00799 writef("%s", history[history_index].c_str()); 00800 } else { 00801 command.clear(); 00802 } 00803 } else if (ch1 == 0x5b && ch2 == 0x42) { 00804 00805 // down key 00806 for (size_t i = 0; i < command.size() + 1; i++) { 00807 writef("\b \b"); 00808 } 00809 00810 if (--history_index < 0) { 00811 history_index = -1; 00812 command.clear(); 00813 } else { 00814 command = history[history_index]; 00815 writef("%s", history[history_index].c_str()); 00816 } 00817 } 00818 } 00819 while (readable()) 00820 read(); 00821 continue; 00822 } else { 00823 command += ch; 00824 } 00825 00826 // echo chars if enabled 00827 if (echo && !(ch == '\r' || ch == '\n')) 00828 writef("%c", ch); 00829 } 00830 00831 // look for end of command line 00832 if (command.find("\n") != std::string::npos || command.find("\r") != std::string::npos) { 00833 // remove new line or cr character 00834 command.erase(command.size() - 1); 00835 write("\r"); // match standard modem output 00836 write(newline); 00837 } else { 00838 continue; 00839 } 00840 00841 // trim whitespace from command 00842 mts::Text::trim(command, "\r\n\t "); 00843 00844 if (command.size() < 1) { 00845 command.clear(); 00846 continue; 00847 } 00848 00849 // parse command and args 00850 args.clear(); 00851 00852 // find first '=' character 00853 size_t delim_index = command.find("="); 00854 if (delim_index != std::string::npos) { 00855 args.push_back(command.substr(0, delim_index)); 00856 } else { 00857 // find first ' ' character 00858 delim_index = command.find(" "); 00859 if (delim_index != std::string::npos) { 00860 args.push_back(command.substr(0, delim_index)); 00861 } else { 00862 args.push_back(command); 00863 } 00864 } 00865 00866 if (delim_index != std::string::npos) { 00867 std::vector<std::string> params = mts::Text::split(command.substr(delim_index + 1), ","); 00868 args.insert(args.end(), params.begin(), params.end()); 00869 } 00870 00871 args[0] = mts::Text::toUpper(args[0]); 00872 00873 // print help 00874 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0) && args.size() == 1) { 00875 printHelp(); 00876 command.clear(); 00877 } else if ((args[0].find("ATE?") == 0 && args[0].length() == 4) || (args[0].find("ATE") == 0 && args[0].length() == 3)) { 00878 writef("%d\r\n", _dot->getEcho()); 00879 write(done); 00880 } else if (args[0].find("ATE0") == 0 && args[0].length() == 4) { 00881 _dot->setEcho(false); 00882 write(done); 00883 echo = _dot->getEcho(); 00884 } else if (args[0].find("ATE1") == 0 && args[0].length() == 4) { 00885 _dot->setEcho(true); 00886 write(done); 00887 echo = _dot->getEcho(); 00888 } else if ((args[0].find("ATV?") == 0 && args[0].length() == 4) || (args[0].find("ATV") == 0 && args[0].length() == 3)) { 00889 writef("%d\r\n", _dot->getVerbose()); 00890 write(done); 00891 } else if (args[0].find("ATV0") == 0 && args[0].length() == 4) { 00892 _dot->setVerbose(false); 00893 write(done); 00894 } else if (args[0].find("ATV1") == 0 && args[0].length() == 4) { 00895 _dot->setVerbose(true); 00896 write(done); 00897 } else if ((args[0].find("AT&K?") == 0 && args[0].length() == 5) || (args[0].find("AT&K") == 0 && args[0].length() == 4)) { 00898 writef("%d\r\n", (_dot->getFlowControl() ? 3 : 0)); 00899 write(done); 00900 } else if (args[0].find("AT&K0") == 0 && args[0].length() == 5) { 00901 _dot->setFlowControl(false); 00902 write(done); 00903 } else if (args[0].find("AT&K3") == 0 && args[0].length() == 5) { 00904 _dot->setFlowControl(true); 00905 write(done); 00906 } else if (args[0] == "AT+SD") { 00907 if (_dot->getNetworkJoinStatus()) { 00908 logDebug("Enter Serial Mode"); 00909 write(connect); 00910 serial_data_mode = true; 00911 _mode = mDot::SERIAL_MODE; 00912 } else { 00913 logDebug("Network Not Joined"); 00914 write("Network Not Joined\r\n"); 00915 write(error); 00916 } 00917 } else if (args[0] == "AT+SLEEP") { 00918 if (args.size() > 2 && (args[1] != "?")) { 00919 write("Invalid argument\r\n"); 00920 write(error); 00921 } else { 00922 if (args.size() > 1 && args[1] == "?") { 00923 write("(0:deepsleep,1:sleep)\r\n"); 00924 write(done); 00925 } else { 00926 _sleep_standby = !(args.size() > 1 && args[1] == "1"); 00927 write(done); 00928 osDelay(5); 00929 this->sleep(_sleep_standby); 00930 osDelay(1); 00931 } 00932 } 00933 } else { 00934 bool found = false; 00935 bool query = false; 00936 00937 std::string lookfor = args[0]; 00938 00939 // per command help 00940 if ((args[0].find("?") == 0 || args[0].find("HELP") == 0)) 00941 lookfor = mts::Text::toUpper(args[1]); 00942 00943 // trim off any trailing '?' and mark as a query command 00944 if (args[0].rfind("?") == args[0].length() - 1) { 00945 query = true; 00946 lookfor = args[0].substr(0, args[0].length() - 1); 00947 } 00948 00949 // search for command 00950 for (int i = 0; i < NO_OF_COMMANDS; i++) { 00951 00952 // match CMD or CMD? syntax if command is queryable 00953 if (lookfor == _commands[i].text() && (!query || (query && _commands[i].queryable()))) { 00954 found = true; 00955 if (args[0] == "HELP") { 00956 writef("%s%s", _commands[i].help().c_str(), newline); 00957 write(done); 00958 } 00959 00960 else if (args.size() > 1 && args[1] == "?") { 00961 writef("%s%s", _commands[i].usage().c_str(), newline); 00962 write(done); 00963 } else if (!_verify[i](args)) { 00964 writef("%s%s", _errorMessage.c_str(), newline); 00965 writef("%s", error); 00966 } else { 00967 if (_action[i](args) == 0) { 00968 writef("%s", done); 00969 } else { 00970 writef("%s%s", _errorMessage.c_str(), newline); 00971 writef("%s", error); 00972 } 00973 } 00974 } 00975 } 00976 00977 if (!found) { 00978 writef("%s", command_error); 00979 writef("%s", error); 00980 } 00981 } 00982 00983 if (history.size() == 0 || history.front() != command) 00984 history.push_front(command); 00985 history_index = -1; 00986 command.clear(); 00987 00988 while (history.size() > 10) 00989 history.pop_back(); 00990 } 00991 } 00992 00993 void CommandTerminal::sleep(bool standby) { 00994 _xbee_on_sleep = GPIO_PIN_RESET; 00995 00996 _serial.rxClear(); 00997 _serial.txClear(); 00998 00999 #if defined(TARGET_XDOT_L151CC) 01000 xdot_save_gpio_state(); 01001 01002 /* GPIO Ports Clock Enable */ 01003 __GPIOA_CLK_ENABLE(); 01004 __GPIOB_CLK_ENABLE(); 01005 __GPIOC_CLK_ENABLE(); 01006 __GPIOH_CLK_ENABLE(); 01007 01008 GPIO_InitTypeDef GPIO_InitStruct; 01009 01010 // UART1_TX, UART1_RTS & UART1_CTS to analog nopull - RX could be a wakeup source 01011 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_11 | GPIO_PIN_12; 01012 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01013 GPIO_InitStruct.Pull = GPIO_NOPULL; 01014 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01015 01016 // I2C_SDA & I2C_SCL to analog nopull 01017 GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9; 01018 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01019 GPIO_InitStruct.Pull = GPIO_NOPULL; 01020 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 01021 01022 // SPI_MOSI, SPI_MISO, SPI_SCK, & SPI_NSS to analog nopull 01023 GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 01024 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01025 GPIO_InitStruct.Pull = GPIO_NOPULL; 01026 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 01027 01028 // iterate through potential wake pins - leave the configured wake pin alone if one is needed 01029 if (_dot->getWakePin() != WAKE || _dot->getWakeMode() == mDot::RTC_ALARM) { 01030 GPIO_InitStruct.Pin = GPIO_PIN_0; 01031 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01032 GPIO_InitStruct.Pull = GPIO_NOPULL; 01033 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01034 } 01035 if (_dot->getWakePin() != GPIO0 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01036 GPIO_InitStruct.Pin = GPIO_PIN_4; 01037 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01038 GPIO_InitStruct.Pull = GPIO_NOPULL; 01039 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01040 } 01041 if (_dot->getWakePin() != GPIO1 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01042 GPIO_InitStruct.Pin = GPIO_PIN_5; 01043 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01044 GPIO_InitStruct.Pull = GPIO_NOPULL; 01045 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01046 } 01047 if (_dot->getWakePin() != GPIO2 || _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(GPIOB, &GPIO_InitStruct); 01052 } 01053 if (_dot->getWakePin() != GPIO3 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01054 GPIO_InitStruct.Pin = GPIO_PIN_2; 01055 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01056 GPIO_InitStruct.Pull = GPIO_NOPULL; 01057 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 01058 } 01059 if (_dot->getWakePin() != UART1_RX || _dot->getWakeMode() == mDot::RTC_ALARM) { 01060 GPIO_InitStruct.Pin = GPIO_PIN_10; 01061 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01062 GPIO_InitStruct.Pull = GPIO_NOPULL; 01063 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01064 } 01065 #else 01066 uint32_t portA[6]; 01067 uint32_t portB[6]; 01068 uint32_t portC[6]; 01069 uint32_t portD[6]; 01070 uint32_t portH[6]; 01071 01072 //Save the GPIO state. 01073 portA[0] = GPIOA->MODER; 01074 portA[1] = GPIOA->OTYPER; 01075 portA[2] = GPIOA->OSPEEDR; 01076 portA[3] = GPIOA->PUPDR; 01077 portA[4] = GPIOA->AFR[0]; 01078 portA[5] = GPIOA->AFR[1]; 01079 01080 portB[0] = GPIOB->MODER; 01081 portB[1] = GPIOB->OTYPER; 01082 portB[2] = GPIOB->OSPEEDR; 01083 portB[3] = GPIOB->PUPDR; 01084 portB[4] = GPIOB->AFR[0]; 01085 portB[5] = GPIOB->AFR[1]; 01086 01087 portC[0] = GPIOC->MODER; 01088 portC[1] = GPIOC->OTYPER; 01089 portC[2] = GPIOC->OSPEEDR; 01090 portC[3] = GPIOC->PUPDR; 01091 portC[4] = GPIOC->AFR[0]; 01092 portC[5] = GPIOC->AFR[1]; 01093 01094 portD[0] = GPIOD->MODER; 01095 portD[1] = GPIOD->OTYPER; 01096 portD[2] = GPIOD->OSPEEDR; 01097 portD[3] = GPIOD->PUPDR; 01098 portD[4] = GPIOD->AFR[0]; 01099 portD[5] = GPIOD->AFR[1]; 01100 01101 portH[0] = GPIOH->MODER; 01102 portH[1] = GPIOH->OTYPER; 01103 portH[2] = GPIOH->OSPEEDR; 01104 portH[3] = GPIOH->PUPDR; 01105 portH[4] = GPIOH->AFR[0]; 01106 portH[5] = GPIOH->AFR[1]; 01107 01108 /* GPIO Ports Clock Enable */ 01109 __GPIOA_CLK_ENABLE(); 01110 __GPIOB_CLK_ENABLE(); 01111 __GPIOC_CLK_ENABLE(); 01112 01113 GPIO_InitTypeDef GPIO_InitStruct; 01114 01115 // Set port A pins to analog nopull 01116 GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_6 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 01117 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 01118 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01119 GPIO_InitStruct.Pull = GPIO_NOPULL; 01120 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01121 01122 // Set port B pins to analog nopull 01123 GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4; 01124 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01125 GPIO_InitStruct.Pull = GPIO_NOPULL; 01126 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 01127 01128 // Set port C pins to analog nopull 01129 GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_13; 01130 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01131 GPIO_InitStruct.Pull = GPIO_NOPULL; 01132 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 01133 01134 // iterate through potential wake pins - leave the configured wake pin alone if one is needed 01135 // XBEE_DIN - PA3 01136 // XBEE_DIO2 - PA5 01137 // XBEE_DIO3 - PA4 01138 // XBEE_DIO4 - PA7 01139 // XBEE_DIO5 - PC1 01140 // XBEE_DIO6 - PA1 01141 // XBEE_DIO7 - PA0 01142 // XBEE_SLEEPRQ - PA11 01143 01144 if (_dot->getWakePin() != XBEE_DIN || _dot->getWakeMode() == mDot::RTC_ALARM) { 01145 GPIO_InitStruct.Pin = GPIO_PIN_3; 01146 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01147 GPIO_InitStruct.Pull = GPIO_NOPULL; 01148 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01149 } 01150 01151 if (_dot->getWakePin() != XBEE_DIO2 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01152 GPIO_InitStruct.Pin = GPIO_PIN_5; 01153 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01154 GPIO_InitStruct.Pull = GPIO_NOPULL; 01155 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01156 } 01157 01158 if (_dot->getWakePin() != XBEE_DIO3 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01159 GPIO_InitStruct.Pin = GPIO_PIN_4; 01160 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01161 GPIO_InitStruct.Pull = GPIO_NOPULL; 01162 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01163 } 01164 01165 if (_dot->getWakePin() != XBEE_DIO4 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01166 GPIO_InitStruct.Pin = GPIO_PIN_7; 01167 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01168 GPIO_InitStruct.Pull = GPIO_NOPULL; 01169 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01170 } 01171 01172 if (_dot->getWakePin() != XBEE_DIO5 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01173 GPIO_InitStruct.Pin = GPIO_PIN_1; 01174 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01175 GPIO_InitStruct.Pull = GPIO_NOPULL; 01176 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 01177 } 01178 01179 if (_dot->getWakePin() != XBEE_DIO6 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01180 GPIO_InitStruct.Pin = GPIO_PIN_1; 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_DIO7 || _dot->getWakeMode() == mDot::RTC_ALARM) { 01187 GPIO_InitStruct.Pin = GPIO_PIN_0; 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_SLEEPRQ|| _dot->getWakeMode() == mDot::RTC_ALARM) { 01194 GPIO_InitStruct.Pin = GPIO_PIN_11; 01195 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01196 GPIO_InitStruct.Pull = GPIO_NOPULL; 01197 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 01198 } 01199 01200 #endif 01201 _dot->sleep(_dot->getWakeInterval(), _dot->getWakeMode(), standby); 01202 01203 #if defined(TARGET_XDOT_L151CC) 01204 xdot_restore_gpio_state(); 01205 #else 01206 //Restore the GPIO state. 01207 GPIOA->MODER = portA[0]; 01208 GPIOA->OTYPER = portA[1]; 01209 GPIOA->OSPEEDR = portA[2]; 01210 GPIOA->PUPDR = portA[3]; 01211 GPIOA->AFR[0] = portA[4]; 01212 GPIOA->AFR[1] = portA[5]; 01213 01214 GPIOB->MODER = portB[0]; 01215 GPIOB->OTYPER = portB[1]; 01216 GPIOB->OSPEEDR = portB[2]; 01217 GPIOB->PUPDR = portB[3]; 01218 GPIOB->AFR[0] = portB[4]; 01219 GPIOB->AFR[1] = portB[5]; 01220 01221 GPIOC->MODER = portC[0]; 01222 GPIOC->OTYPER = portC[1]; 01223 GPIOC->OSPEEDR = portC[2]; 01224 GPIOC->PUPDR = portC[3]; 01225 GPIOC->AFR[0] = portC[4]; 01226 GPIOC->AFR[1] = portC[5]; 01227 01228 GPIOD->MODER = portD[0]; 01229 GPIOD->OTYPER = portD[1]; 01230 GPIOD->OSPEEDR = portD[2]; 01231 GPIOD->PUPDR = portD[3]; 01232 GPIOD->AFR[0] = portD[4]; 01233 GPIOD->AFR[1] = portD[5]; 01234 01235 GPIOH->MODER = portH[0]; 01236 GPIOH->OTYPER = portH[1]; 01237 GPIOH->OSPEEDR = portH[2]; 01238 GPIOH->PUPDR = portH[3]; 01239 GPIOH->AFR[0] = portH[4]; 01240 GPIOH->AFR[1] = portH[5]; 01241 #endif 01242 01243 _serial.rxClear(); 01244 _serial.txClear(); 01245 } 01246 01247 std::string CommandTerminal::formatPacketData(const std::vector<uint8_t>& data, const uint8_t& format) { 01248 if (format == mDot::HEXADECIMAL) 01249 return mts::Text::bin2hexString(data); 01250 else 01251 return std::string(data.begin(), data.end()); 01252 } 01253 01254 bool CommandTerminal::waitForEscape(int timeout, mDot* dot, WaitType wait) { 01255 Timer timer; 01256 01257 timer.start(); 01258 while (timer.read_ms() < timeout) { 01259 01260 if (dot != NULL) { 01261 if (wait == WAIT_SEND && (!dot->getIsTransmitting())) { 01262 return false; 01263 } 01264 } 01265 01266 if (_serialp != NULL && _serialp->escaped()) { 01267 _serialp->clearEscaped(); 01268 return true; 01269 } 01270 01271 osDelay(10); 01272 } 01273 01274 return false; 01275 } 01276 01277 void CommandTerminal::wakeup(void) { 01278 } 01279 01280 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) { 01281 mDotEvent::PacketRx(port, payload, size, rssi, snr, ctrl, retries); 01282 01283 if (serial_data_mode) { 01284 logDebug("Rx %d bytes", size); 01285 if (size > 0) { 01286 CommandTerminal::Serial()->write((char*) RxPayload, RxPayloadSize); 01287 } 01288 if (!CommandTerminal::Serial()->readable() && _dot->getAckRequested() && _dot->getClass() == "C") { 01289 _sendAck = true; 01290 } 01291 } 01292 } 01293 01294 CommandTerminal::~CommandTerminal() { 01295 delete _events; 01296 }
Generated on Tue Jul 12 2022 20:42:48 by
1.7.2
