From 32c6769cb684b99d6154c41fa72a421ce1e23c0c Mon Sep 17 00:00:00 2001 From: Lefucjusz Date: Mon, 8 Jan 2024 13:47:02 +0100 Subject: [PATCH] [BH-1657][BH-1833][BH-1854] Add WFI and SDRAM self-refresh mode * Added mechanism enabling CPU to enter WFI mode when the OS is in idle, what results in large power consumption reduction. * Added mechanism to switch SDRAM to self-refresh mode before entering WFI, what resulted in further power consumption reduction. --- board/rt1051/ldscripts/sections.ld | 26 +- harmony_changelog.md | 4 +- .../windows/advanced/CPUModeTestWindow.cpp | 2 +- module-bsp/board/linux/lpm/LinuxLPM.cpp | 23 ++ module-bsp/board/linux/lpm/LinuxLPM.h | 8 + module-bsp/board/rt1051/bellpx/CMakeLists.txt | 2 + module-bsp/board/rt1051/bellpx/board.cpp | 20 +- module-bsp/board/rt1051/bellpx/brownout.cpp | 23 +- .../rt1051/bellpx/bsp/lpm/EnterSleepMode.c | 29 ++ .../rt1051/bellpx/bsp/lpm/EnterSleepMode.h | 13 + .../board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp | 21 ++ .../board/rt1051/bellpx/bsp/lpm/RT1051LPM.hpp | 5 + .../rt1051/bellpx/bsp/lpm/WfiController.cpp | 175 ++++++++++++ .../rt1051/bellpx/bsp/lpm/WfiController.hpp | 14 + .../rt1051/bellpx/bsp/switches/switches.cpp | 6 +- .../board/rt1051/bellpx/clock_config.cpp | 3 + module-bsp/board/rt1051/bellpx/irq_gpio.cpp | 4 - .../board/rt1051/bsp/lpm/RT1051LPMCommon.cpp | 29 +- .../board/rt1051/bsp/lpm/RT1051LPMCommon.hpp | 5 +- module-bsp/board/rt1051/common/board.cpp | 254 +++++++++--------- .../rt1051/common/startup_mimxrt1052.cpp | 18 +- .../board/rt1051/os/fsl_runtimestat_gpt.c | 18 +- .../rt1051/os/include/fsl_runtimestat_gpt.h | 19 ++ module-bsp/board/rt1051/os/include/macros.h | 9 +- module-bsp/board/rt1051/puretx/board.cpp | 15 +- .../board/rt1051/puretx/bsp/lpm/RT1051LPM.cpp | 17 ++ .../board/rt1051/puretx/bsp/lpm/RT1051LPM.hpp | 5 + module-bsp/bsp/bsp.hpp | 17 +- module-bsp/bsp/lpm/bsp_lpm.hpp | 7 + module-platform/rt1051/src/RT1051Platform.cpp | 8 +- .../service-bluetooth/ServiceBluetooth.cpp | 2 +- .../service-cellular/ServiceCellular.cpp | 2 +- module-services/service-eink/ServiceEink.cpp | 8 +- module-sys/SystemManager/CpuGovernor.cpp | 39 +++ module-sys/SystemManager/CpuSentinel.cpp | 24 +- module-sys/SystemManager/PowerManager.cpp | 54 +++- .../SystemManager/SystemManagerCommon.cpp | 14 +- .../include/SystemManager/CpuGovernor.hpp | 5 + .../include/SystemManager/CpuSentinel.hpp | 5 + .../include/SystemManager/PowerManager.hpp | 18 +- .../include/system/messages/BlockWfiMode.hpp | 39 +++ products/BellHybrid/BellHybridMain.cpp | 9 - .../MeditationTimer.cpp | 12 +- .../MeditationTimer.hpp | 1 + .../ApplicationBellOnBoarding.cpp | 2 +- .../ApplicationBellPowerNap.cpp | 13 +- .../ApplicationBellPowerNap.hpp | 1 + .../ApplicationBellRelaxation.cpp | 23 +- .../ApplicationBellRelaxation.hpp | 1 + .../HomeScreenLayoutClassicWithDate.cpp | 3 +- .../common/src/layouts/HomeScreenLayouts.cpp | 3 +- .../migration/settings_bell/0/up.sql | 2 +- third-party/freeRTOS-kernel/freeRTOS-kernel | 2 +- 53 files changed, 825 insertions(+), 256 deletions(-) create mode 100644 module-bsp/board/rt1051/bellpx/bsp/lpm/EnterSleepMode.c create mode 100644 module-bsp/board/rt1051/bellpx/bsp/lpm/EnterSleepMode.h create mode 100644 module-bsp/board/rt1051/bellpx/bsp/lpm/WfiController.cpp create mode 100644 module-bsp/board/rt1051/bellpx/bsp/lpm/WfiController.hpp create mode 100644 module-bsp/board/rt1051/os/include/fsl_runtimestat_gpt.h create mode 100644 module-sys/common/include/system/messages/BlockWfiMode.hpp diff --git a/board/rt1051/ldscripts/sections.ld b/board/rt1051/ldscripts/sections.ld index d8eb843a4aa282ca04f1f056777d23c8b5d14030..4dd52ebecb50841d1015873d1efc589243443786 100644 --- a/board/rt1051/ldscripts/sections.ld +++ b/board/rt1051/ldscripts/sections.ld @@ -17,6 +17,8 @@ __ocram_noncached_end = ORIGIN(SRAM_OC) + LENGTH(SRAM_OC); __dtcm_ram_start = ORIGIN(SRAM_DTC); __dtcm_ram_end = ORIGIN(SRAM_DTC) + LENGTH(SRAM_DTC); +__sdram_start = ORIGIN(BOARD_SDRAM_TEXT); + __sdram_cached_start = ORIGIN(BOARD_SDRAM_HEAP); __sdram_cached_end = ORIGIN(BOARD_SDRAM_HEAP) + LENGTH(BOARD_SDRAM_HEAP); @@ -49,7 +51,7 @@ SECTIONS .text : ALIGN(4) { FILL(0x00) - __vectors_start__ = ABSOLUTE(.) ; + __vectors_start__ = ABSOLUTE(.); KEEP(*(.isr_vector)) /* Global Section Table */ . = ALIGN(4) ; @@ -64,6 +66,11 @@ SECTIONS LONG( ADDR(.data)); LONG( SIZEOF(.data)); __data_section_table_end = .; + __ocramtext_section_table = .; + LONG(LOADADDR(.ocramtext)); + LONG(ADDR(.ocramtext)); + LONG(SIZEOF(.ocramtext)); + __ocramtext_section_table_end = .; __bss_section_table = .; /* System bss */ LONG( ADDR(.sysbss)); @@ -105,10 +112,18 @@ SECTIONS *libusb_stack.a:*(.data*) } > SRAM_DTC AT > BOARD_SDRAM_TEXT + /* Place WFI and SDRAM driver code in OCRAM to enable switching SDRAM to self-refresh before executing WFI */ + .ocramtext : ALIGN(4) + { + *(.wficode*) + *fsl_semc.c.obj(.text*) + } > SRAM_OC AT > BOARD_SDRAM_TEXT + /* MAIN TEXT SECTION */ .text : ALIGN(4) { - *(.text*) + /* Place here all .text* sections except for the ones in fsl_semc.c.obj file */ + *(EXCLUDE_FILE (*fsl_semc.c.obj) .text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); @@ -191,13 +206,6 @@ SECTIONS *(.sdram.*) } >BOARD_SDRAM_HEAP - /* DMA buffers */ - .intramnoncacheable (NOLOAD) : ALIGN(4) - { - *(.intramnoncacheable) - *(.intramnoncacheable.*) - } > SRAM_OC - /* Place system stack at the very end of DTCM */ _StackSize = 0x1000; .stack ORIGIN(SRAM_DTC) + LENGTH(SRAM_DTC) - _StackSize - 0 : ALIGN(4) diff --git a/harmony_changelog.md b/harmony_changelog.md index 688c6fe8ab9f48804b59554bf230ba375611311e..e7a51da6a98b473db66fc1f3e29cd7ce71053a04 100644 --- a/harmony_changelog.md +++ b/harmony_changelog.md @@ -9,6 +9,8 @@ * Added setting onboarding year to build date year * Added low battery notification on the home screen * Added low battery notification before using the application +* Added entering WFI when CPU is idle to reduce power consumption +* Added switching SDRAM to self-refresh before entering WFI for further power consumption reduction ### Changed / Improved @@ -17,7 +19,6 @@ ### Added * Added gradual alarm volume increase * Added progress bar for all volume control windows -* Improved factory reset procedure to remove user files ### Changed / Improved * Increased clock font in Relaxation, Meditation, Power nap mode @@ -26,6 +27,7 @@ * Extended volume scale from 10 to 15 point scale * Modified volume control characteristic for better user experience * Reduced power consumption for Meditation and Power Nap applications +* Improved factory reset procedure to remove user files ## [2.3.0 2023-12-20] diff --git a/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp b/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp index 15e9bc22b91c0f3c60b9da46a639e9b7aa8153d8..2a4150a803f4936d39da56003514190da1f87f9d 100644 --- a/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp +++ b/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp @@ -37,7 +37,7 @@ namespace gui }); auto sentinelRegistrationMsg = std::make_shared(cpuModeTester); - application->bus.sendUnicastSync(sentinelRegistrationMsg, service::name::system_manager, 30); + application->bus.sendUnicastSync(std::move(sentinelRegistrationMsg), service::name::system_manager, 30); AppWindow::buildInterface(); diff --git a/module-bsp/board/linux/lpm/LinuxLPM.cpp b/module-bsp/board/linux/lpm/LinuxLPM.cpp index 046cec64ae62c3a3cef9bc34f445e82a34fde612..d1f2dd7ee0a4e7001869748e5aab288ef71d4c7b 100644 --- a/module-bsp/board/linux/lpm/LinuxLPM.cpp +++ b/module-bsp/board/linux/lpm/LinuxLPM.cpp @@ -33,4 +33,27 @@ namespace bsp void LinuxLPM::DisableDcdcPowerSaveMode() {} + + void LinuxLPM::AllowEnteringWfiMode() + {} + + void LinuxLPM::BlockEnteringWfiMode() + {} + + std::uint32_t LinuxLPM::EnterWfiModeIfAllowed() + { + return 0; + } + + std::uint32_t LinuxLPM::GetLastTimeSpentInWfi() + { + return 0; + } + + void LinuxLPM::DisableSysTick() + {} + + void LinuxLPM::EnableSysTick() + {} + } // namespace bsp diff --git a/module-bsp/board/linux/lpm/LinuxLPM.h b/module-bsp/board/linux/lpm/LinuxLPM.h index 57238788b5a830fb086d01aee348e5b9e8a5fff4..08b3e6b0d8bea1a60bccba14782403399901cee4 100644 --- a/module-bsp/board/linux/lpm/LinuxLPM.h +++ b/module-bsp/board/linux/lpm/LinuxLPM.h @@ -18,5 +18,13 @@ namespace bsp void EnableDcdcPowerSaveMode() final; void DisableDcdcPowerSaveMode() final; + + void AllowEnteringWfiMode() final; + void BlockEnteringWfiMode() final; + std::uint32_t EnterWfiModeIfAllowed() final; + std::uint32_t GetLastTimeSpentInWfi() final; + + void DisableSysTick() final; + void EnableSysTick() final; }; } // namespace bsp diff --git a/module-bsp/board/rt1051/bellpx/CMakeLists.txt b/module-bsp/board/rt1051/bellpx/CMakeLists.txt index ad9c623469e662c3a43bff7ffba67f86bbd6f66c..86b3aee773e37dffb1f9af407f9ee81e96264e25 100644 --- a/module-bsp/board/rt1051/bellpx/CMakeLists.txt +++ b/module-bsp/board/rt1051/bellpx/CMakeLists.txt @@ -20,6 +20,8 @@ target_sources( bsp/eink/eink_gpio.cpp bsp/lpm/PowerProfile.cpp bsp/lpm/RT1051LPM.cpp + bsp/lpm/WfiController.cpp + bsp/lpm/EnterSleepMode.c bsp/rotary_encoder/rotary_encoder.cpp bsp/rtc/rtc_configuration.cpp bsp/switches/switches.cpp diff --git a/module-bsp/board/rt1051/bellpx/board.cpp b/module-bsp/board/rt1051/bellpx/board.cpp index 788f5f67b866329c4637075d94a9e40542f9aaa9..0deb776c2b7b9340bc076fe223130652d092b5c1 100644 --- a/module-bsp/board/rt1051/bellpx/board.cpp +++ b/module-bsp/board/rt1051/bellpx/board.cpp @@ -51,18 +51,30 @@ namespace namespace bsp { - void board_exit(rebootState state) + void board_configure() + { + /* See * + * https://patchwork.kernel.org/project/linux-arm-kernel/patch/1471885400-9140-1-git-send-email-Anson.Huang@nxp.com/ + */ + CCM->CGPR |= CCM_CGPR_INT_MEM_CLK_LPM_MASK; + + /* ERR050143 */ + IOMUXC_GPR->GPR1 |= IOMUXC_GPR_GPR1_GINT_MASK; + } + + void board_exit(RebootState state) { switch (state) { - case rebootState::none: + case RebootState::None: break; - case rebootState::poweroff: + case RebootState::Poweroff: power_off(); break; - case rebootState::reboot: + case RebootState::Reboot: reset(); break; } + while (true) {} } } // namespace bsp diff --git a/module-bsp/board/rt1051/bellpx/brownout.cpp b/module-bsp/board/rt1051/bellpx/brownout.cpp index ca74cca8ce8bcab88c48b2c2de86b8c0717b9713..9503cd080d541fb6dd8ad1ef48a8b7b8045ef0cb 100644 --- a/module-bsp/board/rt1051/bellpx/brownout.cpp +++ b/module-bsp/board/rt1051/bellpx/brownout.cpp @@ -1,7 +1,6 @@ -// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -#include #include #include @@ -9,25 +8,15 @@ namespace bsp { namespace { - constexpr std::uint32_t OutputVoltage1P1 = 0x19; // 1.275V - constexpr std::uint32_t OutputVoltage2P5 = 0x1F; // 2.875V - - constexpr std::uint32_t OffsetVoltage1P1 = 0x05; // 5*25mv - constexpr std::uint32_t OffsetVoltage2P5 = 0x03; // 3*25mv - } // namespace + constexpr auto outputVoltage2P5 = 0x1BU; // 2.775V + constexpr auto offsetVoltage2P5 = 0x03U; // 3*25mV + } // namespace void Brownout_init() { - // Config LDO Regulatorsand config Brownout voltage offsets - PMU_1P1EnableBrownout(PMU, true); - PMU_1P1SetRegulatorOutputVoltage(PMU, OutputVoltage1P1); - PMU_1P1SetBrownoutOffsetVoltage(PMU, OffsetVoltage1P1); - PMU_1P1EnableOutput(PMU, true); - PMU_2P5nableBrownout(PMU, true); - PMU_2P5SetRegulatorOutputVoltage(PMU, OutputVoltage2P5); - PMU_2P5SetBrownoutOffsetVoltage(PMU, OffsetVoltage2P5); + PMU_2P5SetRegulatorOutputVoltage(PMU, outputVoltage2P5); + PMU_2P5SetBrownoutOffsetVoltage(PMU, offsetVoltage2P5); PMU_2P5EnableOutput(PMU, true); } - } // namespace bsp diff --git a/module-bsp/board/rt1051/bellpx/bsp/lpm/EnterSleepMode.c b/module-bsp/board/rt1051/bellpx/bsp/lpm/EnterSleepMode.c new file mode 100644 index 0000000000000000000000000000000000000000..0bb25e71f80e9d5b486a2be07a17c8578b762ec7 --- /dev/null +++ b/module-bsp/board/rt1051/bellpx/bsp/lpm/EnterSleepMode.c @@ -0,0 +1,29 @@ +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "EnterSleepMode.h" +#include +#include + +extern char __sdram_start; // Defined in linker script + +/* This function needs to be compiled either as a C code, or as a C++ code with + * exception handling disabled (-fno-exceptions), otherwise it is not possible to relocate + * its code into OCRAM. Rationale: + * https://stackoverflow.com/questions/52637962/arm-cortex-m7-long-branch-get-error-relocation-truncated-to-fit-r-arm-prel31 + * + * As compiling single C++ file with exception handling disabled seems to be impossible + * using CMake and selectively disabling exceptions using #pragmas looks ugly, I've decided + * to just put it in a separate .c file. */ +WFI_CODE_SECTION(void enterSleepMode(void)) +{ + /* Wait until SDRAM operations done and switch to self-refresh mode */ + __DSB(); + while ((SEMC->STS0 & SEMC_STS0_IDLE_MASK) == 0) {} // Wait until SEMC idle + __ISB(); + SEMC_SendIPCommand(SEMC, kSEMC_MemType_SDRAM, (uint32_t)&__sdram_start, kSEMC_SDRAMCM_SelfRefresh, 0, NULL); + + /* Go to sleep */ + __WFI(); + __ISB(); +} diff --git a/module-bsp/board/rt1051/bellpx/bsp/lpm/EnterSleepMode.h b/module-bsp/board/rt1051/bellpx/bsp/lpm/EnterSleepMode.h new file mode 100644 index 0000000000000000000000000000000000000000..36a259ca09a7589af9edb10e6a200422c628737d --- /dev/null +++ b/module-bsp/board/rt1051/bellpx/bsp/lpm/EnterSleepMode.h @@ -0,0 +1,13 @@ +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + void enterSleepMode(void); +#ifdef __cplusplus +} +#endif diff --git a/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp b/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp index 912b7a531366269fd764f2a8b54e33221abff17b..bae6bb078c84b060ac760f86fe56b092df4c40d4 100644 --- a/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp +++ b/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp @@ -2,6 +2,7 @@ // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "RT1051LPM.hpp" +#include "WfiController.hpp" namespace bsp { @@ -10,4 +11,24 @@ namespace bsp void RT1051LPM::DisableDcdcPowerSaveMode() {} + + void RT1051LPM::AllowEnteringWfiMode() + { + allowEnteringWfiMode(); + } + + void RT1051LPM::BlockEnteringWfiMode() + { + blockEnteringWfiMode(); + } + + std::uint32_t RT1051LPM::EnterWfiModeIfAllowed() + { + return enterWfiModeIfAllowed(); + } + + std::uint32_t RT1051LPM::GetLastTimeSpentInWfi() + { + return getLastTimeSpentInWfi(); + } } // namespace bsp diff --git a/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.hpp b/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.hpp index c565f42be6fc8db9a46772108e68ed6fcfc9e55f..af06bd3b92eef6fb83d2376ccb9b7e4aa364fc2f 100644 --- a/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.hpp +++ b/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.hpp @@ -12,5 +12,10 @@ namespace bsp public: void EnableDcdcPowerSaveMode() final; void DisableDcdcPowerSaveMode() final; + + void AllowEnteringWfiMode() final; + void BlockEnteringWfiMode() final; + std::uint32_t EnterWfiModeIfAllowed() final; + std::uint32_t GetLastTimeSpentInWfi() final; }; } // namespace bsp diff --git a/module-bsp/board/rt1051/bellpx/bsp/lpm/WfiController.cpp b/module-bsp/board/rt1051/bellpx/bsp/lpm/WfiController.cpp new file mode 100644 index 0000000000000000000000000000000000000000..22ca190f216ef15e3f183cf6b297c413786ede13 --- /dev/null +++ b/module-bsp/board/rt1051/bellpx/bsp/lpm/WfiController.cpp @@ -0,0 +1,175 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "WfiController.hpp" +#include "EnterSleepMode.h" +#include +#include +#include +#include +#include