mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-07-19 20:44:44 -04:00
[EGD-4170] Cellular - modem reset (#929)
This commit is contained in:
@@ -3,8 +3,10 @@
|
||||
## Current release
|
||||
|
||||
### Added
|
||||
|
||||
* `[settings][bluetooth]` Add "Phone name" window.
|
||||
* `[gui]` Add "ButtonOnOff" widget.
|
||||
* `[cellular]` Add support for modem reset
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -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}},
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user