M module-bsp/board/rt1051/bsp/cellular/rt1051_cellular.cpp => module-bsp/board/rt1051/bsp/cellular/rt1051_cellular.cpp +7 -3
@@ 9,6 9,7 @@
#include "dma_config.h"
#include "fsl_cache.h"
#include <common_data/EventStore.hpp>
+#include <ticks.hpp>
#include <algorithm>
@@ 246,9 247,7 @@ namespace bsp
sendXfer.data = static_cast<uint8_t *>(buf);
sendXfer.dataSize = nbytes;
- if (isInSleepMode) {
- ExitSleep();
- }
+ ExitSleep();
uartDmaHandle.userData = xTaskGetCurrentTaskHandle();
SCB_CleanInvalidateDCache();
@@ 342,6 341,7 @@ namespace bsp
ssize_t RT1051Cellular::Read(void *buf, size_t nbytes)
{
+ ExitSleep();
ssize_t ret = xStreamBufferReceive(uartRxStreamBuffer, buf, nbytes, 0);
#if _RT1051_UART_DEBUG
if (ret > 0) {
@@ 420,6 420,7 @@ namespace bsp
// Host sleep information must be before UART disable
InformModemHostAsleep();
+
if (driverLPUART) {
driverLPUART->Disable();
}
@@ 428,6 429,9 @@ namespace bsp
void RT1051Cellular::ExitSleep()
{
+ // reset sleep timer countdown
+ lastCommunicationTimestamp = cpp_freertos::Ticks::TicksToMs(cpp_freertos::Ticks::GetTicks());
+
if (isInSleepMode) {
isInSleepMode = false;
M module-bsp/bsp/cellular/bsp_cellular.cpp => module-bsp/bsp/cellular/bsp_cellular.cpp +5 -0
@@ 36,4 36,9 @@ namespace bsp{
return driverLPUART;
}
+ [[nodiscard]] auto Cellular::GetLastCommunicationTimestamp() const noexcept -> TickType_t
+ {
+ return lastCommunicationTimestamp;
+ }
+
}
M module-bsp/bsp/cellular/bsp_cellular.hpp => module-bsp/bsp/cellular/bsp_cellular.hpp +2 -0
@@ 56,9 56,11 @@ namespace cellular
virtual bsp::cellular::antenna GetAntenna() = 0;
[[nodiscard]] auto GetCellularDevice() const noexcept -> std::shared_ptr<devices::Device>;
+ [[nodiscard]] auto GetLastCommunicationTimestamp() const noexcept -> TickType_t;
protected:
bool isInitialized = false;
+ TickType_t lastCommunicationTimestamp;
std::shared_ptr<drivers::DriverLPUART> driverLPUART;
};
namespace cellular
M module-cellular/Modem/TS0710/TS0710.cpp => module-cellular/Modem/TS0710/TS0710.cpp +6 -0
@@ 597,6 597,12 @@ void TS0710::RegisterCellularDevice(void)
auto deviceRegistrationMsg = std::make_shared<sys::DeviceRegistrationMessage>(pv_cellular->GetCellularDevice());
pv_parent->bus.sendUnicast(std::move(deviceRegistrationMsg), service::name::system_manager);
}
+
+[[nodiscard]] auto TS0710::GetLastCommunicationTimestamp() const noexcept -> TickType_t
+{
+ return pv_cellular->GetLastCommunicationTimestamp();
+}
+
TS0710::ConfState TS0710::SetupEchoCanceller(EchoCancellerStrength strength)
{
M module-cellular/Modem/TS0710/TS0710.h => module-cellular/Modem/TS0710/TS0710.h +1 -0
@@ 441,6 441,7 @@ class TS0710
void EnterSleepMode(void);
void ExitSleepMode(void);
void RegisterCellularDevice(void);
+ [[nodiscard]] auto GetLastCommunicationTimestamp() const noexcept -> TickType_t;
};
#endif //_TS0710_H
M module-services/service-cellular/CellularCall.cpp => module-services/service-cellular/CellularCall.cpp +7 -0
@@ 39,6 39,9 @@ namespace CellularCall
if (!call.isValid()) {
LOG_ERROR("startCallAction failed");
clear();
+ if (cpuSentinel) {
+ cpuSentinel->ReleaseMinimumFrequency();
+ }
return false;
}
@@ 62,6 65,10 @@ namespace CellularCall
return false;
}
+ if (cpuSentinel) {
+ cpuSentinel->ReleaseMinimumFrequency();
+ }
+
if (isActiveCall) {
auto endTime = utils::time::Timestamp();
call.duration = (endTime - startActiveTime).get();
M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +20 -4
@@ 93,6 93,7 @@
#include "checkSmsCenter.hpp"
#include <service-desktop/Constants.hpp>
#include <module-utils/gsl/gsl_util>
+#include <ticks.hpp>
const char *ServiceCellular::serviceName = "ServiceCellular";
@@ 185,6 186,8 @@ ServiceCellular::ServiceCellular()
this, "state", std::chrono::milliseconds{1000}, [&](sys::Timer &) { handleStateTimer(); });
ussdTimer = sys::TimerFactory::createPeriodicTimer(
this, "ussd", std::chrono::milliseconds{1000}, [this](sys::Timer &) { handleUSSDTimer(); });
+ sleepTimer = sys::TimerFactory::createPeriodicTimer(
+ this, "sleep", constants::sleepTimerInterval, [this](sys::Timer &) { SleepTimerHandler(); });
ongoingCall.setStartCallAction([=](const CalllogRecord &rec) {
auto call = DBServiceAPI::CalllogAdd(this, rec);
@@ 240,6 243,20 @@ static bool isSettingsAutomaticTimeSyncEnabled()
return true;
}
+void ServiceCellular::SleepTimerHandler()
+{
+ auto currentTime = cpp_freertos::Ticks::TicksToMs(cpp_freertos::Ticks::GetTicks());
+ auto lastCommunicationTimestamp = cmux->GetLastCommunicationTimestamp();
+ auto timeOfInactivity = currentTime >= lastCommunicationTimestamp
+ ? currentTime - lastCommunicationTimestamp
+ : std::numeric_limits<TickType_t>::max() - lastCommunicationTimestamp + currentTime;
+
+ if (!ongoingCall.isValid() && timeOfInactivity >= constants::enterSleepModeTime.count()) {
+ cmux->EnterSleepMode();
+ cpuSentinel->ReleaseMinimumFrequency();
+ }
+}
+
void ServiceCellular::CallStateTimerHandler()
{
LOG_DEBUG("CallStateTimerHandler");
@@ 269,10 286,6 @@ sys::ReturnCodes ServiceCellular::InitHandler()
cmux->RegisterCellularDevice();
- // temporarily limit the minimum CPU frequency
- // due to problems with the UART of the GSM modem
- cpuSentinel->HoldMinimumFrequency(bsp::CpuFrequencyHz::Level_4);
-
return sys::ReturnCodes::Success;
}
@@ 1806,6 1819,7 @@ bool ServiceCellular::handle_fatal_failure()
bool ServiceCellular::handle_ready()
{
LOG_DEBUG("%s", state.c_str());
+ sleepTimer.start();
return true;
}
@@ 2532,6 2546,8 @@ auto ServiceCellular::handleSimNotReadyNotification(sys::Message *msg) -> std::s
auto ServiceCellular::handleUrcIncomingNotification(sys::Message *msg) -> std::shared_ptr<sys::ResponseMessage>
{
+ // when handling URC, the CPU frequency does not go below a certain level
+ cpuSentinel->HoldMinimumFrequency(bsp::CpuFrequencyHz::Level_4);
cmux->ExitSleepMode();
return std::make_shared<CellularResponseMessage>(true);
}
M module-services/service-cellular/service-cellular/ServiceCellular.hpp => module-services/service-cellular/service-cellular/ServiceCellular.hpp +13 -0
@@ 55,6 55,14 @@ namespace packet_data
class PacketData;
class PDPContext;
} // namespace packet_data
+
+namespace constants
+{
+ using namespace std::chrono_literals;
+ inline constexpr std::chrono::milliseconds sleepTimerInterval{500ms};
+ inline constexpr std::chrono::milliseconds enterSleepModeTime{5s};
+} // namespace constants
+
class ServiceCellular : public sys::Service
{
@@ 171,6 179,11 @@ class ServiceCellular : public sys::Service
sys::TimerHandle callStateTimer;
sys::TimerHandle stateTimer;
sys::TimerHandle ussdTimer;
+
+ // used to enter modem sleep mode
+ sys::TimerHandle sleepTimer;
+
+ void SleepTimerHandler();
void CallStateTimerHandler();
DLC_channel::Callback_t notificationCallback = nullptr;