From 2eafcfbc5c5eb6efdd87171282dfb5b44032cc93 Mon Sep 17 00:00:00 2001 From: markaj-nordic <98948394+markaj-nordic@users.noreply.github.com> Date: Thu, 24 Mar 2022 13:28:56 +0100 Subject: [PATCH] [nrfconnect] Optimized external flash power consumption. (#16219) Signed-off-by: markaj-nordic --- .../nrfconnect/main/AppTask.cpp | 6 +-- .../nrfconnect/main/include/AppTask.h | 3 +- .../lighting-app/nrfconnect/main/AppTask.cpp | 9 ++--- examples/lock-app/nrfconnect/main/AppTask.cpp | 9 ++--- .../nrfconnect/util/include/OTAUtil.h | 37 +++++++++++++++++ examples/pump-app/nrfconnect/main/AppTask.cpp | 9 ++--- .../nrfconnect/main/AppTask.cpp | 9 ++--- .../nrfconnect/OTAImageProcessorImpl.cpp | 40 +++++++++++++++++++ .../nrfconnect/OTAImageProcessorImpl.h | 25 +++++++++++- 9 files changed, 121 insertions(+), 26 deletions(-) create mode 100644 examples/platform/nrfconnect/util/include/OTAUtil.h diff --git a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp index e7590fd6d575b9..60317685df384a 100644 --- a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp @@ -147,9 +147,9 @@ CHIP_ERROR AppTask::Init() void AppTask::InitOTARequestor() { #if CONFIG_CHIP_OTA_REQUESTOR - mOTAImageProcessor.SetOTADownloader(&mBDXDownloader); - mBDXDownloader.SetImageProcessorDelegate(&mOTAImageProcessor); - mOTARequestorDriver.Init(&mOTARequestor, &mOTAImageProcessor); + OTAImageProcessorNrf::Get().SetOTADownloader(&mBDXDownloader); + mBDXDownloader.SetImageProcessorDelegate(&OTAImageProcessorNrf::Get()); + mOTARequestorDriver.Init(&mOTARequestor, &OTAImageProcessorNrf::Get()); mOTARequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); mOTARequestor.Init(chip::Server::GetInstance(), mOTARequestorStorage, mOTARequestorDriver, mBDXDownloader); chip::SetRequestorInstance(&mOTARequestor); diff --git a/examples/all-clusters-app/nrfconnect/main/include/AppTask.h b/examples/all-clusters-app/nrfconnect/main/include/AppTask.h index b05a7d30ff3d3d..6f0e00ea247a78 100644 --- a/examples/all-clusters-app/nrfconnect/main/include/AppTask.h +++ b/examples/all-clusters-app/nrfconnect/main/include/AppTask.h @@ -20,11 +20,11 @@ #include #if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" #include #include #include #include -#include #endif struct k_timer; @@ -76,7 +76,6 @@ class AppTask #if CONFIG_CHIP_OTA_REQUESTOR chip::DefaultOTARequestorStorage mOTARequestorStorage; chip::DeviceLayer::GenericOTARequestorDriver mOTARequestorDriver; - chip::DeviceLayer::OTAImageProcessorImpl mOTAImageProcessor; chip::BDXDownloader mBDXDownloader; chip::OTARequestor mOTARequestor; #endif diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index 8aae4a4487aeb5..c8f1adbebb1859 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -40,11 +40,11 @@ #include #if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" #include #include #include #include -#include #endif #include @@ -88,7 +88,6 @@ bool sHaveBLEConnections = false; #if CONFIG_CHIP_OTA_REQUESTOR DefaultOTARequestorStorage sRequestorStorage; GenericOTARequestorDriver sOTARequestorDriver; -OTAImageProcessorImpl sOTAImageProcessor; chip::BDXDownloader sBDXDownloader; chip::OTARequestor sOTARequestor; #endif @@ -202,9 +201,9 @@ CHIP_ERROR AppTask::Init() void AppTask::InitOTARequestor() { #if CONFIG_CHIP_OTA_REQUESTOR - sOTAImageProcessor.SetOTADownloader(&sBDXDownloader); - sBDXDownloader.SetImageProcessorDelegate(&sOTAImageProcessor); - sOTARequestorDriver.Init(&sOTARequestor, &sOTAImageProcessor); + OTAImageProcessorNrf::Get().SetOTADownloader(&sBDXDownloader); + sBDXDownloader.SetImageProcessorDelegate(&OTAImageProcessorNrf::Get()); + sOTARequestorDriver.Init(&sOTARequestor, &OTAImageProcessorNrf::Get()); sRequestorStorage.Init(Server::GetInstance().GetPersistentStorage()); sOTARequestor.Init(Server::GetInstance(), sRequestorStorage, sOTARequestorDriver, sBDXDownloader); chip::SetRequestorInstance(&sOTARequestor); diff --git a/examples/lock-app/nrfconnect/main/AppTask.cpp b/examples/lock-app/nrfconnect/main/AppTask.cpp index 6ca2aa26d525e4..1accdfe81fe6bb 100644 --- a/examples/lock-app/nrfconnect/main/AppTask.cpp +++ b/examples/lock-app/nrfconnect/main/AppTask.cpp @@ -36,11 +36,11 @@ #include #if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" #include #include #include #include -#include #endif #include @@ -77,7 +77,6 @@ bool sHaveBLEConnections = false; #if CONFIG_CHIP_OTA_REQUESTOR DefaultOTARequestorStorage sRequestorStorage; GenericOTARequestorDriver sOTARequestorDriver; -OTAImageProcessorImpl sOTAImageProcessor; chip::BDXDownloader sBDXDownloader; chip::OTARequestor sOTARequestor; #endif @@ -183,9 +182,9 @@ CHIP_ERROR AppTask::Init() void AppTask::InitOTARequestor() { #if CONFIG_CHIP_OTA_REQUESTOR - sOTAImageProcessor.SetOTADownloader(&sBDXDownloader); - sBDXDownloader.SetImageProcessorDelegate(&sOTAImageProcessor); - sOTARequestorDriver.Init(&sOTARequestor, &sOTAImageProcessor); + OTAImageProcessorNrf::Get().SetOTADownloader(&sBDXDownloader); + sBDXDownloader.SetImageProcessorDelegate(&OTAImageProcessorNrf::Get()); + sOTARequestorDriver.Init(&sOTARequestor, &OTAImageProcessorNrf::Get()); sRequestorStorage.Init(Server::GetInstance().GetPersistentStorage()); sOTARequestor.Init(Server::GetInstance(), sRequestorStorage, sOTARequestorDriver, sBDXDownloader); chip::SetRequestorInstance(&sOTARequestor); diff --git a/examples/platform/nrfconnect/util/include/OTAUtil.h b/examples/platform/nrfconnect/util/include/OTAUtil.h new file mode 100644 index 00000000000000..e8dac963145df7 --- /dev/null +++ b/examples/platform/nrfconnect/util/include/OTAUtil.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#ifdef CONFIG_CHIP_OTA_REQUESTOR +namespace OTAImageProcessorNrf { +// compile-time factory method +inline chip::DeviceLayer::OTAImageProcessorImpl & Get() +{ +#if CONFIG_PM_DEVICE && CONFIG_NORDIC_QSPI_NOR + static chip::DeviceLayer::ExtFlashHandler sQSPIHandler; + static chip::DeviceLayer::OTAImageProcessorImplPMDevice sOTAImageProcessor{ sQSPIHandler }; +#else + static chip::DeviceLayer::OTAImageProcessorImpl sOTAImageProcessor; +#endif + return sOTAImageProcessor; +} +} // namespace OTAImageProcessorNrf + +#endif diff --git a/examples/pump-app/nrfconnect/main/AppTask.cpp b/examples/pump-app/nrfconnect/main/AppTask.cpp index 4e8b9012b14406..7e62ce1b054fda 100644 --- a/examples/pump-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-app/nrfconnect/main/AppTask.cpp @@ -37,11 +37,11 @@ #include #if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" #include #include #include #include -#include #endif #include @@ -80,7 +80,6 @@ bool sHaveBLEConnections = false; #if CONFIG_CHIP_OTA_REQUESTOR DefaultOTARequestorStorage sRequestorStorage; GenericOTARequestorDriver sOTARequestorDriver; -OTAImageProcessorImpl sOTAImageProcessor; chip::BDXDownloader sBDXDownloader; chip::OTARequestor sOTARequestor; #endif @@ -180,9 +179,9 @@ CHIP_ERROR AppTask::Init() void AppTask::InitOTARequestor() { #if CONFIG_CHIP_OTA_REQUESTOR - sOTAImageProcessor.SetOTADownloader(&sBDXDownloader); - sBDXDownloader.SetImageProcessorDelegate(&sOTAImageProcessor); - sOTARequestorDriver.Init(&sOTARequestor, &sOTAImageProcessor); + OTAImageProcessorNrf::Get().SetOTADownloader(&sBDXDownloader); + sBDXDownloader.SetImageProcessorDelegate(&OTAImageProcessorNrf::Get()); + sOTARequestorDriver.Init(&sOTARequestor, &OTAImageProcessorNrf::Get()); sRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); sOTARequestor.Init(chip::Server::GetInstance(), sRequestorStorage, sOTARequestorDriver, sBDXDownloader); chip::SetRequestorInstance(&sOTARequestor); diff --git a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp index 1c7d92c9c0dd3d..c5e28e1f7c12fe 100644 --- a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp @@ -37,11 +37,11 @@ #include #if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" #include #include #include #include -#include #endif #include @@ -77,7 +77,6 @@ bool sHaveBLEConnections = false; #if CONFIG_CHIP_OTA_REQUESTOR DefaultOTARequestorStorage sRequestorStorage; GenericOTARequestorDriver sOTARequestorDriver; -OTAImageProcessorImpl sOTAImageProcessor; chip::BDXDownloader sBDXDownloader; chip::OTARequestor sOTARequestor; #endif @@ -177,9 +176,9 @@ CHIP_ERROR AppTask::Init() void AppTask::InitOTARequestor() { #if CONFIG_CHIP_OTA_REQUESTOR - sOTAImageProcessor.SetOTADownloader(&sBDXDownloader); - sBDXDownloader.SetImageProcessorDelegate(&sOTAImageProcessor); - sOTARequestorDriver.Init(&sOTARequestor, &sOTAImageProcessor); + OTAImageProcessorNrf::Get().SetOTADownloader(&sBDXDownloader); + sBDXDownloader.SetImageProcessorDelegate(&OTAImageProcessorNrf::Get()); + sOTARequestorDriver.Init(&sOTARequestor, &OTAImageProcessorNrf::Get()); sRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); sOTARequestor.Init(chip::Server::GetInstance(), sRequestorStorage, sOTARequestorDriver, sBDXDownloader); chip::SetRequestorInstance(&sOTARequestor); diff --git a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp index dd3f4f16040fc7..f7e3e6c8f4190a 100644 --- a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp +++ b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include namespace chip { @@ -141,5 +142,44 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) return CHIP_NO_ERROR; } +// external flash power consumption optimization +void ExtFlashHandler::DoAction(Action action) +{ +#if CONFIG_PM_DEVICE && CONFIG_NORDIC_QSPI_NOR && !CONFIG_SOC_NRF52840 // nRF52 is optimized per default + // utilize the QSPI driver sleep power mode + const auto * qspi_dev = device_get_binding(DT_LABEL(DT_INST(0, nordic_qspi_nor))); + if (qspi_dev) + { + const auto requestedAction = Action::WAKE_UP == action ? PM_DEVICE_ACTION_RESUME : PM_DEVICE_ACTION_SUSPEND; + (void) pm_device_action_run(qspi_dev, requestedAction); // not much can be done in case of a failure + } +#endif +} + +OTAImageProcessorImplPMDevice::OTAImageProcessorImplPMDevice(ExtFlashHandler & aHandler) : mHandler(aHandler) +{ + mHandler.DoAction(ExtFlashHandler::Action::SLEEP); +} + +CHIP_ERROR OTAImageProcessorImplPMDevice::PrepareDownload() +{ + mHandler.DoAction(ExtFlashHandler::Action::WAKE_UP); + return OTAImageProcessorImpl::PrepareDownload(); +} + +CHIP_ERROR OTAImageProcessorImplPMDevice::Abort() +{ + auto status = OTAImageProcessorImpl::Abort(); + mHandler.DoAction(ExtFlashHandler::Action::SLEEP); + return status; +} + +CHIP_ERROR OTAImageProcessorImplPMDevice::Apply() +{ + auto status = OTAImageProcessorImpl::Apply(); + mHandler.DoAction(ExtFlashHandler::Action::SLEEP); + return status; +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/nrfconnect/OTAImageProcessorImpl.h b/src/platform/nrfconnect/OTAImageProcessorImpl.h index 6d3ddd1d454f7f..acdd0c89e0d710 100644 --- a/src/platform/nrfconnect/OTAImageProcessorImpl.h +++ b/src/platform/nrfconnect/OTAImageProcessorImpl.h @@ -1,5 +1,4 @@ /* - * * Copyright (c) 2021 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -53,5 +52,29 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface uint8_t mBuffer[kBufferSize]; }; +class ExtFlashHandler +{ +public: + enum class Action : uint8_t + { + WAKE_UP, + SLEEP + }; + virtual ~ExtFlashHandler() {} + virtual void DoAction(Action action); +}; + +class OTAImageProcessorImplPMDevice : public OTAImageProcessorImpl +{ +public: + explicit OTAImageProcessorImplPMDevice(ExtFlashHandler & aHandler); + CHIP_ERROR PrepareDownload() override; + CHIP_ERROR Abort() override; + CHIP_ERROR Apply() override; + +private: + ExtFlashHandler & mHandler; +}; + } // namespace DeviceLayer } // namespace chip