[EGD-4170] Cellular - modem reset (#929)

This commit is contained in:
Hubert Chrzaniuk
2020-10-29 08:36:41 +01:00
committed by GitHub
parent c9df89318a
commit 180bfbadcd
4 changed files with 71 additions and 5 deletions

View File

@@ -3,8 +3,10 @@
## Current release
### Added
* `[settings][bluetooth]` Add "Phone name" window.
* `[gui]` Add "ButtonOnOff" widget.
* `[cellular]` Add support for modem reset
### Changed

View File

@@ -96,6 +96,7 @@ namespace at
ATD, /// setup call
IPR, /// set baudrate
CMUX, /// setup cmux params
CFUN, /// set phone functionality
CMGS, /// sms
QCMGS,
CREG, /// network registration status
@@ -122,9 +123,14 @@ namespace at
DISABLE_TIME_ZONE_UPDATE,
DISABLE_TIME_ZONE_REPORTING,
ENABLE_NETWORK_REGISTRATION_URC,
SET_SMS_TEXT_MODE_UCS2
SET_SMS_TEXT_MODE_UCS2,
CFUN_RESET,
CFUN_MIN_FUNCTIONALITY, /// Set minimum functionality
CFUN_FULL_FUNCTIONALITY, /// Full functionality
CFUN_DISABLE_TRANSMITTING, /// Disable the ME from both transmitting and receiving RF signals
};
// below timeouts are defined in Quectel_EC25&EC21_AT_Commands_Manual_V1.3.pdf
inline auto factory(AT at) -> const Cmd &
{
static const std::map<AT, const Cmd> fact{
@@ -164,6 +170,11 @@ namespace at
{AT::ATD, {"ATD"}},
{AT::IPR, {"AT+IPR="}},
{AT::CMUX, {"AT+CMUX="}},
{AT::CFUN, {"AT+CFUN=", 15000}},
{AT::CFUN_RESET, {"AT+CFUN=1,1", 15000}},
{AT::CFUN_MIN_FUNCTIONALITY, {"AT+CFUN=0", 15000}},
{AT::CFUN_FULL_FUNCTIONALITY, {"AT+CFUN=1", 15000}},
{AT::CFUN_DISABLE_TRANSMITTING, {"AT+CFUN=4", 15000}},
{AT::CMGS, {"AT+CMGS=\""}},
{AT::QCMGS, {"AT+QCMGS=\""}},
{AT::CREG, {"AT+CREG?", default_doc_timeout}},

View File

@@ -243,6 +243,36 @@ void ServiceCellular::registerMessageHandlers()
handle_CellularGetChannelMessage();
}
bool ServiceCellular::resetCellularModule(ResetType type)
{
LOG_DEBUG("Cellular modem reset. Type %d", static_cast<int>(type));
auto channel = cmux->get(TS0710::Channel::Commands);
if (!channel) {
LOG_ERROR("Bad channel");
return false;
}
switch (type) {
case ResetType::SoftReset:
if (auto response = channel->cmd(at::AT::CFUN_RESET); response.code == at::Result::Code::OK) {
return true;
}
LOG_ERROR("Cellular modem reset failed.");
return false;
case ResetType::PowerCycle:
cmux->TurnOffModem();
cmux->TurnOnModem();
isAfterForceReboot = true;
return true;
case ResetType::HardReset:
cmux->ResetModem();
isAfterForceReboot = true;
return true;
}
return false;
}
void ServiceCellular::change_state(cellular::StateChange *msg)
{
assert(msg);
@@ -367,6 +397,11 @@ bool ServiceCellular::handle_power_up_procedure()
bool ServiceCellular::handle_power_up_in_progress_procedure(void)
{
if (isAfterForceReboot) {
constexpr auto msModemUartInitTime = 12000;
vTaskDelay(pdMS_TO_TICKS(msModemUartInitTime));
isAfterForceReboot = false;
}
auto ret = cmux->BaudDetectProcedure();
if (ret == TS0710::ConfState::Success) {
state.set(this, cellular::State::ST::CellularConfProcedure);
@@ -406,6 +441,7 @@ bool ServiceCellular::handle_power_down_waiting()
bool ServiceCellular::handle_power_down()
{
LOG_DEBUG("Powered Down");
isAfterForceReboot = true;
cmux.reset();
cmux = std::make_unique<TS0710>(PortSpeed_e::PS460800, this);
InitHandler();
@@ -801,11 +837,19 @@ sys::Message_t ServiceCellular::DataReceivedHandler(sys::DataMessage *msgl, sys:
if (msg != nullptr) {
if (board == bsp::Board::T4) {
auto status_pin = msg->state;
if (status_pin == value::ACTIVE && state.get() == State::ST::PowerUpProcedure) {
state.set(this, State::ST::PowerUpInProgress); // and go to baud detect as usual
if (status_pin == value::ACTIVE) {
if (state.get() == State::ST::PowerUpProcedure) {
state.set(this, State::ST::PowerUpInProgress); // and go to baud detect as usual
}
else {
// asynchronous power toggle should fall back to PowerDown regardless the state
state.set(this, State::ST::PowerDown);
}
}
else if (status_pin == value::INACTIVE && state.get() == State::ST::PowerDownWaiting) {
state.set(this, State::ST::PowerDown);
else if (status_pin == value::INACTIVE) {
if (isAfterForceReboot == true || state.get() == State::ST::PowerDownWaiting) {
state.set(this, State::ST::PowerDown);
}
}
}
}

View File

@@ -98,6 +98,15 @@ class ServiceCellular : public sys::Service
ussd::State ussdState = ussd::State::none;
enum class ResetType
{
SoftReset, //<! AT CFUN reset
PowerCycle, //<! PWRKEY pin toggle
HardReset //<! RESET_N pin
};
bool resetCellularModule(ResetType type);
bool isAfterForceReboot = false;
/// one point of state change handling
void change_state(cellular::StateChange *msg);