Skip to content

Commit 17757cd

Browse files
[EGD-4170] Cellular - modem reset (#929)
1 parent 37cb199 commit 17757cd

File tree

4 files changed

+71
-5
lines changed

4 files changed

+71
-5
lines changed

changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
## Current release
44

55
### Added
6+
67
* `[settings][bluetooth]` Add "Phone name" window.
78
* `[gui]` Add "ButtonOnOff" widget.
9+
* `[cellular]` Add support for modem reset
810

911
### Changed
1012

module-cellular/at/Commands.hpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ namespace at
9696
ATD, /// setup call
9797
IPR, /// set baudrate
9898
CMUX, /// setup cmux params
99+
CFUN, /// set phone functionality
99100
CMGS, /// sms
100101
QCMGS,
101102
CREG, /// network registration status
@@ -122,9 +123,14 @@ namespace at
122123
DISABLE_TIME_ZONE_UPDATE,
123124
DISABLE_TIME_ZONE_REPORTING,
124125
ENABLE_NETWORK_REGISTRATION_URC,
125-
SET_SMS_TEXT_MODE_UCS2
126+
SET_SMS_TEXT_MODE_UCS2,
127+
CFUN_RESET,
128+
CFUN_MIN_FUNCTIONALITY, /// Set minimum functionality
129+
CFUN_FULL_FUNCTIONALITY, /// Full functionality
130+
CFUN_DISABLE_TRANSMITTING, /// Disable the ME from both transmitting and receiving RF signals
126131
};
127132

133+
// below timeouts are defined in Quectel_EC25&EC21_AT_Commands_Manual_V1.3.pdf
128134
inline auto factory(AT at) -> const Cmd &
129135
{
130136
static const std::map<AT, const Cmd> fact{
@@ -164,6 +170,11 @@ namespace at
164170
{AT::ATD, {"ATD"}},
165171
{AT::IPR, {"AT+IPR="}},
166172
{AT::CMUX, {"AT+CMUX="}},
173+
{AT::CFUN, {"AT+CFUN=", 15000}},
174+
{AT::CFUN_RESET, {"AT+CFUN=1,1", 15000}},
175+
{AT::CFUN_MIN_FUNCTIONALITY, {"AT+CFUN=0", 15000}},
176+
{AT::CFUN_FULL_FUNCTIONALITY, {"AT+CFUN=1", 15000}},
177+
{AT::CFUN_DISABLE_TRANSMITTING, {"AT+CFUN=4", 15000}},
167178
{AT::CMGS, {"AT+CMGS=\""}},
168179
{AT::QCMGS, {"AT+QCMGS=\""}},
169180
{AT::CREG, {"AT+CREG?", default_doc_timeout}},

module-services/service-cellular/ServiceCellular.cpp

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,36 @@ void ServiceCellular::registerMessageHandlers()
243243
handle_CellularGetChannelMessage();
244244
}
245245

246+
bool ServiceCellular::resetCellularModule(ResetType type)
247+
{
248+
LOG_DEBUG("Cellular modem reset. Type %d", static_cast<int>(type));
249+
250+
auto channel = cmux->get(TS0710::Channel::Commands);
251+
if (!channel) {
252+
LOG_ERROR("Bad channel");
253+
return false;
254+
}
255+
256+
switch (type) {
257+
case ResetType::SoftReset:
258+
if (auto response = channel->cmd(at::AT::CFUN_RESET); response.code == at::Result::Code::OK) {
259+
return true;
260+
}
261+
LOG_ERROR("Cellular modem reset failed.");
262+
return false;
263+
case ResetType::PowerCycle:
264+
cmux->TurnOffModem();
265+
cmux->TurnOnModem();
266+
isAfterForceReboot = true;
267+
return true;
268+
case ResetType::HardReset:
269+
cmux->ResetModem();
270+
isAfterForceReboot = true;
271+
return true;
272+
}
273+
return false;
274+
}
275+
246276
void ServiceCellular::change_state(cellular::StateChange *msg)
247277
{
248278
assert(msg);
@@ -367,6 +397,11 @@ bool ServiceCellular::handle_power_up_procedure()
367397

368398
bool ServiceCellular::handle_power_up_in_progress_procedure(void)
369399
{
400+
if (isAfterForceReboot) {
401+
constexpr auto msModemUartInitTime = 12000;
402+
vTaskDelay(pdMS_TO_TICKS(msModemUartInitTime));
403+
isAfterForceReboot = false;
404+
}
370405
auto ret = cmux->BaudDetectProcedure();
371406
if (ret == TS0710::ConfState::Success) {
372407
state.set(this, cellular::State::ST::CellularConfProcedure);
@@ -406,6 +441,7 @@ bool ServiceCellular::handle_power_down_waiting()
406441
bool ServiceCellular::handle_power_down()
407442
{
408443
LOG_DEBUG("Powered Down");
444+
isAfterForceReboot = true;
409445
cmux.reset();
410446
cmux = std::make_unique<TS0710>(PortSpeed_e::PS460800, this);
411447
InitHandler();
@@ -801,11 +837,19 @@ sys::Message_t ServiceCellular::DataReceivedHandler(sys::DataMessage *msgl, sys:
801837
if (msg != nullptr) {
802838
if (board == bsp::Board::T4) {
803839
auto status_pin = msg->state;
804-
if (status_pin == value::ACTIVE && state.get() == State::ST::PowerUpProcedure) {
805-
state.set(this, State::ST::PowerUpInProgress); // and go to baud detect as usual
840+
if (status_pin == value::ACTIVE) {
841+
if (state.get() == State::ST::PowerUpProcedure) {
842+
state.set(this, State::ST::PowerUpInProgress); // and go to baud detect as usual
843+
}
844+
else {
845+
// asynchronous power toggle should fall back to PowerDown regardless the state
846+
state.set(this, State::ST::PowerDown);
847+
}
806848
}
807-
else if (status_pin == value::INACTIVE && state.get() == State::ST::PowerDownWaiting) {
808-
state.set(this, State::ST::PowerDown);
849+
else if (status_pin == value::INACTIVE) {
850+
if (isAfterForceReboot == true || state.get() == State::ST::PowerDownWaiting) {
851+
state.set(this, State::ST::PowerDown);
852+
}
809853
}
810854
}
811855
}

module-services/service-cellular/ServiceCellular.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ class ServiceCellular : public sys::Service
9898

9999
ussd::State ussdState = ussd::State::none;
100100

101+
enum class ResetType
102+
{
103+
SoftReset, //<! AT CFUN reset
104+
PowerCycle, //<! PWRKEY pin toggle
105+
HardReset //<! RESET_N pin
106+
};
107+
bool resetCellularModule(ResetType type);
108+
bool isAfterForceReboot = false;
109+
101110
/// one point of state change handling
102111
void change_state(cellular::StateChange *msg);
103112

0 commit comments

Comments
 (0)