diff --git a/evkbimxrt1050_sdram_init.jlinkscript b/evkbimxrt1050_sdram_init.jlinkscript index ce4dc6cb8..7a4c70812 100644 --- a/evkbimxrt1050_sdram_init.jlinkscript +++ b/evkbimxrt1050_sdram_init.jlinkscript @@ -187,8 +187,8 @@ void SDRAM_Init() { // Config SDR Controller Registers/ MEM_WriteU32(0x402F0000,0x10000004); // MCR - MEM_WriteU32(0x402F0008,0x20200E44); // BMCR0 - MEM_WriteU32(0x402F000C,0x20200E40); // BMCR1 + MEM_WriteU32(0x402F0008,0x00000081); // BMCR0 + MEM_WriteU32(0x402F000C,0x00000081); // BMCR1 MEM_WriteU32(0x402F0010,0x8000001D); // BR0, 64MB OK MEM_WriteU32(0x402F0040,0x00000E31); // SDRAMCR0 OK MEM_WriteU32(0x402F0044,0x00774D22); // SDRAMCR1 diff --git a/evkbimxrt1050_sdram_init_T6.jlinkscript b/evkbimxrt1050_sdram_init_T6.jlinkscript index c9f0aaae9..43cba99c9 100644 --- a/evkbimxrt1050_sdram_init_T6.jlinkscript +++ b/evkbimxrt1050_sdram_init_T6.jlinkscript @@ -239,21 +239,21 @@ void SDRAM_SEMC_Init(void) reg_val |= 0x00000002; MEM_WriteU32(SEMC_MCR, reg_val); - /* Configure queues for AXI bus: + /* Configure queues for AXI bus as suggested in https://community.nxp.com/t5/i-MX-RT/i-MXRT1060-SEMC-SDRAM-Data-Corruption/m-p/11696908: * Queue A: - * WQOS = 4; - * WAGE = 2; - * WSH = 3; - * WRWS = 5 */ - MEM_WriteU32(SEMC_BMCR0, 0x00030524); + * WQOS = 1; + * WAGE = 8; + * WSH = 0; + * WRWS = 0 */ + MEM_WriteU32(SEMC_BMCR0, 0x00000081); /* Queue B: - * WQOS = 4; - * WAGE = 2; - * WPH = 3; - * WRWS = 5; - * WBR = 6 */ - MEM_WriteU32(SEMC_BMCR1, 0x06050324); + * WQOS = 1; + * WAGE = 8; + * WPH = 0; + * WRWS = 0; + * WBR = 0 */ + MEM_WriteU32(SEMC_BMCR1, 0x00000081); /* Configure MCR: * set bus timeout cycles to 0x10; diff --git a/harmony_changelog.md b/harmony_changelog.md index c155e316c..8ec965776 100644 --- a/harmony_changelog.md +++ b/harmony_changelog.md @@ -52,6 +52,7 @@ * General improvement in Eink display and error handling * Changed the "Turn off Harmony" popup display time to 10 seconds * The default year has been updated to 2023 +* Improved device stability related to frequency scaling ## [2.0.0 2023-06-29] diff --git a/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp b/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp index bfd157dd1..15e9bc22b 100644 --- a/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp +++ b/module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "CPUModeTestWindow.hpp" @@ -134,9 +134,9 @@ namespace gui permanentFreqSpinner = new gui::TextSpinnerBox(permanentFreqBody, {"OFF", "ON"}, Boundaries::Continuous); permanentFreqSpinner->setMinimumSize(100, 30); auto ret = - application->async_call(service::name::system_manager); + application->async_call(service::name::system_manager); application->sync(ret); - permanentFreqSpinner->setCurrentValue(ret.getResult().pernament ? "ON" : "OFF"); + permanentFreqSpinner->setCurrentValue(ret.getResult().permanent ? "ON" : "OFF"); permanentFreqBody->inputCallback = [&](Item &item, const InputEvent &event) { auto ret = permanentFreqSpinner->onInput(event); @@ -193,10 +193,10 @@ namespace gui newFreqBody->inputCallback = [&](Item &item, const InputEvent &event) { auto ret = currentFreqSpinner->onInput(event); - auto async = application->async_call( + auto async = application->async_call( service::name::system_manager); application->sync(async); - if (async.getResult().pernament) { + if (async.getResult().permanent) { application->bus.sendUnicastSync( std::make_shared( magic_enum::enum_cast(std::stoi(currentFreqSpinner->getCurrentValue())) diff --git a/module-bsp/board/linux/lpm/LinuxLPM.cpp b/module-bsp/board/linux/lpm/LinuxLPM.cpp index b1bd221d0..046cec64a 100644 --- a/module-bsp/board/linux/lpm/LinuxLPM.cpp +++ b/module-bsp/board/linux/lpm/LinuxLPM.cpp @@ -1,36 +1,31 @@ // Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -// -// Created by mati on 09.09.2019. -// - #include "LinuxLPM.h" namespace bsp { - - int32_t LinuxLPM::PowerOff() + std::int32_t LinuxLPM::PowerOff() { return 0; } - int32_t LinuxLPM::Reboot(RebootType) + std::int32_t LinuxLPM::Reboot([[maybe_unused]] RebootType reason) { return 0; } - void LinuxLPM::SetCpuFrequency(bsp::CpuFrequencyMHz freq) + void LinuxLPM::SetCpuFrequency(CpuFrequencyMHz freq) { currentFrequency = freq; } - uint32_t LinuxLPM::GetCpuFrequency() const noexcept + std::uint32_t LinuxLPM::GetCpuFrequency() const noexcept { return 0; } - void LinuxLPM::SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource source) + void LinuxLPM::SwitchOscillatorSource(LowPowerMode::OscillatorSource source) {} void LinuxLPM::EnableDcdcPowerSaveMode() @@ -38,11 +33,4 @@ namespace bsp void LinuxLPM::DisableDcdcPowerSaveMode() {} - - void LinuxLPM::SwitchToRegularModeLDO() - {} - - void LinuxLPM::SwitchToLowPowerModeLDO() - {} - } // namespace bsp diff --git a/module-bsp/board/linux/lpm/LinuxLPM.h b/module-bsp/board/linux/lpm/LinuxLPM.h index f7864847c..57238788b 100644 --- a/module-bsp/board/linux/lpm/LinuxLPM.h +++ b/module-bsp/board/linux/lpm/LinuxLPM.h @@ -1,30 +1,22 @@ // Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md -#ifndef PUREPHONE_LINUXLPM_H -#define PUREPHONE_LINUXLPM_H +#pragma once #include "bsp/lpm/bsp_lpm.hpp" namespace bsp { - class LinuxLPM : public LowPowerMode { public: - int32_t PowerOff() override final; - int32_t Reboot(RebootType reason) override final; + std::int32_t PowerOff() override final; + std::int32_t Reboot(RebootType reason) override final; void SetCpuFrequency(CpuFrequencyMHz freq) final; - [[nodiscard]] uint32_t GetCpuFrequency() const noexcept final; + [[nodiscard]] std::uint32_t GetCpuFrequency() const noexcept final; void SwitchOscillatorSource(OscillatorSource source) final; void EnableDcdcPowerSaveMode() final; void DisableDcdcPowerSaveMode() final; - - void SwitchToRegularModeLDO() final; - void SwitchToLowPowerModeLDO() final; }; - } // namespace bsp - -#endif // PUREPHONE_LINUXLPM_H diff --git a/module-bsp/board/rt1051/CMakeLists.txt b/module-bsp/board/rt1051/CMakeLists.txt index 2b62c5597..88022f231 100644 --- a/module-bsp/board/rt1051/CMakeLists.txt +++ b/module-bsp/board/rt1051/CMakeLists.txt @@ -1,7 +1,6 @@ # Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. # For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - target_sources(module-bsp PRIVATE bluetooth/BlueKitchen.cpp @@ -28,6 +27,8 @@ target_sources(module-bsp bsp/lpm/Oscillator.cpp bsp/lpm/RT1051LPMCommon.cpp bsp/lpm/Bandgap.cpp + bsp/lpm/LDO.cpp + bsp/lpm/DCDC.cpp bsp/magnetometer/ALS31300.cpp bsp/pit/pit.cpp bsp/trng/trng.cpp @@ -74,6 +75,8 @@ set_source_files_properties( target_compile_definitions(module-bsp PUBLIC USB_STACK_FREERTOS) +target_compile_definitions(module-bsp PRIVATE BOARD_${PRODUCT}=1) + add_subdirectory(common/fsl_drivers) add_subdirectory(os) add_subdirectory(${BOARD}) diff --git a/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp b/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp index 0d474dafa..912b7a531 100644 --- a/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp +++ b/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp @@ -2,8 +2,6 @@ // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "RT1051LPM.hpp" -#include -#include namespace bsp { @@ -12,17 +10,4 @@ namespace bsp void RT1051LPM::DisableDcdcPowerSaveMode() {} - - void RT1051LPM::SwitchToRegularModeLDO() - { - RT1051LPMCommon::RegularLDOMode(); - NVIC_ClearPendingIRQ(ANATOP_EVENT0_IRQn); - EnableIRQ(ANATOP_EVENT0_IRQn); - } - - void RT1051LPM::SwitchToLowPowerModeLDO() - { - DisableIRQ(ANATOP_EVENT0_IRQn); - RT1051LPMCommon::LowPowerLDOMode(); - } } // 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 4aac802b8..c565f42be 100644 --- a/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.hpp +++ b/module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.hpp @@ -2,6 +2,7 @@ // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once + #include namespace bsp @@ -11,9 +12,5 @@ namespace bsp public: void EnableDcdcPowerSaveMode() final; void DisableDcdcPowerSaveMode() final; - - void SwitchToRegularModeLDO() final; - void SwitchToLowPowerModeLDO() final; }; - } // namespace bsp diff --git a/module-bsp/board/rt1051/bsp/lpm/Bandgap.cpp b/module-bsp/board/rt1051/bsp/lpm/Bandgap.cpp index b6c465a2c..136f2e194 100644 --- a/module-bsp/board/rt1051/bsp/lpm/Bandgap.cpp +++ b/module-bsp/board/rt1051/bsp/lpm/Bandgap.cpp @@ -4,6 +4,7 @@ #include "Bandgap.hpp" #include #include +#include namespace { @@ -14,6 +15,8 @@ namespace bsp::bandgap { void SwitchToRegularMode() { + cpp_freertos::CriticalSection::Enter(); + /* Enable regular bandgap and wait for it to stabilize */ CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_REFTOP_PWD_MASK; while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_REFTOP_VBGUP_MASK) == 0) {} @@ -21,15 +24,21 @@ namespace bsp::bandgap /* Disable low power bandgap */ XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK; PMU->MISC0_CLR = REFTOP_LOWPOWER_MASK; + + cpp_freertos::CriticalSection::Exit(); } void SwitchToLowPowerMode() { + cpp_freertos::CriticalSection::Enter(); + /* Enable low power bandgap */ PMU->MISC0_SET = REFTOP_LOWPOWER_MASK; + XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK; /* Disable regular bandgap */ - XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK; PMU->MISC0_SET = CCM_ANALOG_MISC0_REFTOP_PWD_MASK; + + cpp_freertos::CriticalSection::Exit(); } } // namespace bsp::bandgap diff --git a/module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.cpp b/module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.cpp index c7b055eef..25946d9a3 100644 --- a/module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.cpp +++ b/module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.cpp @@ -2,7 +2,7 @@ // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "CpuFreqLPM.hpp" -#include "fsl_dcdc.h" +#include namespace bsp { diff --git a/module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.hpp b/module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.hpp index c6e6c0b47..d1f96d463 100644 --- a/module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.hpp +++ b/module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.hpp @@ -9,6 +9,7 @@ namespace bsp { inline constexpr std::uint32_t VDDRun_950_mV = 0x06; inline constexpr std::uint32_t VDDRun_1150_mV = 0x0E; + inline constexpr std::uint32_t VDDRun_1275_mV = 0x13; inline constexpr std::uint32_t VDDStandby_925_mV = 0x01; diff --git a/module-bsp/board/rt1051/bsp/lpm/DCDC.cpp b/module-bsp/board/rt1051/bsp/lpm/DCDC.cpp new file mode 100644 index 000000000..bf220d5bf --- /dev/null +++ b/module-bsp/board/rt1051/bsp/lpm/DCDC.cpp @@ -0,0 +1,48 @@ +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "DCDC.hpp" +#include "CpuFreqLPM.hpp" +#include + +namespace bsp::dcdc +{ + void SwitchToOverdriveConfig() + { + /* Switch to CCM mode for improved stability */ + DCDC_BootIntoCCM(DCDC); + + /* Connect internal DCDC load resistor */ + DCDC->REG1 |= DCDC_REG1_REG_RLOAD_SW_MASK; + + /* Adjust target voltage to 1.275V */ + DCDC_AdjustTargetVoltage(DCDC, VDDRun_1275_mV, VDDStandby_925_mV); + + /* Disable FET ODRIVE */ + PMU->REG_CORE_CLR = PMU_REG_CORE_FET_ODRIVE_MASK; + } + + void SwitchToRegularConfig() + { + /* Adjust target voltage to 1.15V */ + DCDC_AdjustTargetVoltage(DCDC, VDDRun_1150_mV, VDDStandby_925_mV); + } + + void SwitchToLowPowerConfig() + { + /* Adjust target voltage to nominal 0.95V */ + DCDC_AdjustTargetVoltage(DCDC, VDDRun_950_mV, VDDStandby_925_mV); + + /* Switch to DCM mode to reduce current consumption */ + DCDC_BootIntoDCM(DCDC); + + /* Disconnect internal DCDC load resistor */ + DCDC->REG1 &= ~DCDC_REG1_REG_RLOAD_SW_MASK; + + /* Power down output range comparator */ + DCDC->REG0 |= DCDC_REG0_PWD_CMP_OFFSET_MASK; + + /* Enable FET ODRIVE */ + PMU->REG_CORE_SET = PMU_REG_CORE_FET_ODRIVE_MASK; + } +} // namespace bsp::dcdc diff --git a/module-bsp/board/rt1051/bsp/lpm/DCDC.hpp b/module-bsp/board/rt1051/bsp/lpm/DCDC.hpp new file mode 100644 index 000000000..bab373bdf --- /dev/null +++ b/module-bsp/board/rt1051/bsp/lpm/DCDC.hpp @@ -0,0 +1,11 @@ +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +namespace bsp::dcdc +{ + void SwitchToOverdriveConfig(); + void SwitchToRegularConfig(); + void SwitchToLowPowerConfig(); +} // namespace bsp::dcdc diff --git a/module-bsp/board/rt1051/bsp/lpm/LDO.cpp b/module-bsp/board/rt1051/bsp/lpm/LDO.cpp new file mode 100644 index 000000000..527e77960 --- /dev/null +++ b/module-bsp/board/rt1051/bsp/lpm/LDO.cpp @@ -0,0 +1,62 @@ +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "LDO.hpp" +#include +#include + +namespace +{ + constexpr auto ldoStabilizationDelayUs{40}; +} + +namespace bsp::ldo +{ + void SwitchToRegularMode() + { + cpp_freertos::CriticalSection::Enter(); + + /* Enable regular 2P5 and disable weak 2P5 LDO */ + PMU->REG_2P5_SET = PMU_REG_2P5_ENABLE_LINREG_MASK; + PMU->REG_2P5_CLR = PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; + + /* Wait for regular 2P5 to become stable (documentation Low Power AN12085) */ + while ((PMU->REG_2P5 & PMU_REG_2P5_OK_VDD2P5_MASK) == 0) {} + + /* Enable regular 1P1 and disable weak 1P1 LDO */ + PMU->REG_1P1_SET = PMU_REG_1P1_ENABLE_LINREG_MASK; + PMU->REG_1P1_CLR = PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; + + /* Wait for regular 1P1 to become stable (documentation Low Power AN12085) */ + while ((PMU->REG_1P1 & PMU_REG_1P1_OK_VDD1P1_MASK) == 0) {} + + cpp_freertos::CriticalSection::Exit(); + +#if BOARD_BellHybrid == 1 + NVIC_ClearPendingIRQ(ANATOP_EVENT0_IRQn); + EnableIRQ(ANATOP_EVENT0_IRQn); +#endif + } + + void SwitchToLowPowerMode() + { +#if BOARD_BellHybrid == 1 + DisableIRQ(ANATOP_EVENT0_IRQn); +#endif + + cpp_freertos::CriticalSection::Enter(); + + /* Enable weak 2P5 and disable regular 2P5 LDO */ + PMU->REG_2P5_SET = PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; + PMU->REG_2P5_CLR = PMU_REG_2P5_ENABLE_LINREG_MASK; + + /* Enable weak 1P1 and disable regular 1P1 LDO */ + PMU->REG_1P1_SET = PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; + PMU->REG_1P1_CLR = PMU_REG_1P1_ENABLE_LINREG_MASK; + + /* Wait for weak LDOs to stabilize */ + SDK_DelayAtLeastUs(ldoStabilizationDelayUs, CLOCK_GetCpuClkFreq()); + + cpp_freertos::CriticalSection::Exit(); + } +} // namespace bsp::ldo diff --git a/module-bsp/board/rt1051/bsp/lpm/LDO.hpp b/module-bsp/board/rt1051/bsp/lpm/LDO.hpp new file mode 100644 index 000000000..9d3bbf175 --- /dev/null +++ b/module-bsp/board/rt1051/bsp/lpm/LDO.hpp @@ -0,0 +1,10 @@ +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +namespace bsp::ldo +{ + void SwitchToRegularMode(); + void SwitchToLowPowerMode(); +} // namespace bsp::ldo diff --git a/module-bsp/board/rt1051/bsp/lpm/Oscillator.cpp b/module-bsp/board/rt1051/bsp/lpm/Oscillator.cpp index 9c19447ab..6815c84d1 100644 --- a/module-bsp/board/rt1051/bsp/lpm/Oscillator.cpp +++ b/module-bsp/board/rt1051/bsp/lpm/Oscillator.cpp @@ -3,73 +3,92 @@ #include "Oscillator.hpp" #include "ClockState.hpp" +#include #include #include #include +namespace +{ + constexpr std::uint8_t oscillatorReadyCounterValue{127}; + constexpr std::uint32_t currentTuningValueInUseForConfig0{0x4}; + constexpr std::uint32_t initialNegativeHysteresisValue{0x2}; + constexpr std::uint32_t negativeHysteresisValue{0x3}; + constexpr std::uint32_t positiveHysteresisValue{0x3}; + constexpr std::uint32_t tuningValue{0xA7}; + constexpr std::uint32_t currentTuningValueInUseForConfig1{0x40}; + constexpr std::uint32_t targetCountUsedToTune{0x2DC}; + + constexpr std::uint32_t xtalStabilizationTimeUs{200}; + constexpr std::uint32_t rcOscStabilizationTimeUs{4000}; +} // namespace + namespace bsp { - inline constexpr std::uint8_t OscillatorReadyCounterValue{127}; - inline constexpr std::uint32_t CurrentTuningValueInUseForConfig0{0x4}; - inline constexpr std::uint32_t NegativeHysteresisValue{0x2}; - inline constexpr std::uint32_t TuningValue{0xA7}; - inline constexpr std::uint32_t CurrentTuningValueInUseForConfig1{0x40}; - inline constexpr std::uint32_t TargetCountUsedToTune{0x2DC}; - - inline constexpr std::uint32_t XtalStabilizationTimeUs{200}; - inline constexpr std::uint32_t RcOscStabilizationTimeUs{4000}; - - void EnableExternalOscillator() + void SwitchToExternalOscillator() { + cpp_freertos::CriticalSection::Enter(); if (!IsExternalOscillatorEnabled()) { + /// Init internal oscillator CLOCK_InitExternalClk(false); /// Wait for XTAL to become stable - SDK_DelayAtLeastUs(XtalStabilizationTimeUs, CLOCK_GetCpuClkFreq()); + SDK_DelayAtLeastUs(xtalStabilizationTimeUs, CLOCK_GetCpuClkFreq()); /// Switch DCDC to use DCDC external OSC DCDC_SetClockSource(DCDC, kDCDC_ClockExternalOsc); /// Switch clock source to external OSC. CLOCK_SwitchOsc(kCLOCK_XtalOsc); - /// Wait CCM operation finishes - while (CCM->CDHIPR != 0) {} + /// Deinit internal oscillator + CLOCK_DeinitRcOsc24M(); /// Set Oscillator ready counter value. - CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(bsp::OscillatorReadyCounterValue); + CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(oscillatorReadyCounterValue); } + cpp_freertos::CriticalSection::Exit(); } - void DisableExternalOscillator() + bool SwitchToInternalOscillator() { + cpp_freertos::CriticalSection::Enter(); if (IsExternalOscillatorEnabled()) { if (IsClockEnabled(kCLOCK_Lpuart1) || IsClockEnabled(kCLOCK_Lpuart2) || IsClockEnabled(kCLOCK_Lpuart3) || IsClockEnabled(kCLOCK_Lpuart4) || IsClockEnabled(kCLOCK_Lpuart5) || IsClockEnabled(kCLOCK_Lpuart6) || IsClockEnabled(kCLOCK_Lpuart7) || IsClockEnabled(kCLOCK_Lpuart8)) { - return; + cpp_freertos::CriticalSection::Exit(); + return false; } /// Enable RC OSC. It needs at least 4ms to be stable, so self tuning need to be enabled. - XTALOSC24M->LOWPWR_CTRL |= XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK; + CLOCK_InitRcOsc24M(); /// Configure self-tuning for RC OSC - XTALOSC24M->OSC_CONFIG0 = XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR(bsp::CurrentTuningValueInUseForConfig0) | - XTALOSC24M_OSC_CONFIG0_SET_HYST_MINUS(bsp::NegativeHysteresisValue) | - XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG(bsp::TuningValue) | + XTALOSC24M->OSC_CONFIG0 = XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG_CUR(currentTuningValueInUseForConfig0) | + XTALOSC24M_OSC_CONFIG0_SET_HYST_MINUS(initialNegativeHysteresisValue) | + XTALOSC24M_OSC_CONFIG0_RC_OSC_PROG(tuningValue) | XTALOSC24M_OSC_CONFIG0_START_MASK | XTALOSC24M_OSC_CONFIG0_ENABLE_MASK; - XTALOSC24M->OSC_CONFIG1 = XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR(bsp::CurrentTuningValueInUseForConfig1) | - XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG(bsp::TargetCountUsedToTune); + + XTALOSC24M->OSC_CONFIG1 = XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR(currentTuningValueInUseForConfig1) | + XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG(targetCountUsedToTune); /// Wait for RC OSC to become stable - SDK_DelayAtLeastUs(RcOscStabilizationTimeUs, CLOCK_GetCpuClkFreq()); + SDK_DelayAtLeastUs(rcOscStabilizationTimeUs, CLOCK_GetCpuClkFreq()); + /// Add hysteresis + std::uint32_t oscConfig0Value = XTALOSC24M->OSC_CONFIG0; + oscConfig0Value &= ~(XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK | XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK); + oscConfig0Value |= XTALOSC24M_OSC_CONFIG0_HYST_PLUS(positiveHysteresisValue) | + XTALOSC24M_OSC_CONFIG0_HYST_MINUS(negativeHysteresisValue); + XTALOSC24M->OSC_CONFIG0 = oscConfig0Value; /// Switch DCDC to use DCDC internal OSC DCDC_SetClockSource(DCDC, kDCDC_ClockInternalOsc); /// Switch clock source to internal RC CLOCK_SwitchOsc(kCLOCK_RcOsc); /// Deinit external oscillator CLOCK_DeinitExternalClk(); - /// Wait CCM operation finishes - while (CCM->CDHIPR != 0) {} } + cpp_freertos::CriticalSection::Exit(); + + return true; } [[nodiscard]] bool IsExternalOscillatorEnabled() { - return !(XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_OSC_SEL_MASK); + return not static_cast(XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_OSC_SEL_MASK); } }; // namespace bsp diff --git a/module-bsp/board/rt1051/bsp/lpm/Oscillator.hpp b/module-bsp/board/rt1051/bsp/lpm/Oscillator.hpp index 69d9e51a8..c506cd9a7 100644 --- a/module-bsp/board/rt1051/bsp/lpm/Oscillator.hpp +++ b/module-bsp/board/rt1051/bsp/lpm/Oscillator.hpp @@ -1,11 +1,11 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once namespace bsp { - void EnableExternalOscillator(); - void DisableExternalOscillator(); + void SwitchToExternalOscillator(); + bool SwitchToInternalOscillator(); [[nodiscard]] bool IsExternalOscillatorEnabled(); } // namespace bsp diff --git a/module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.cpp b/module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.cpp index a6f3c117a..c947a4cca 100644 --- a/module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.cpp +++ b/module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.cpp @@ -2,15 +2,13 @@ // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "RT1051LPMCommon.hpp" - #include #include -#include #include #include "Oscillator.hpp" -#include "critical.hpp" #include "drivers/semc/DriverSEMC.hpp" #include +#include "DCDC.hpp" namespace bsp { @@ -22,13 +20,13 @@ namespace bsp CpuFreq = std::make_unique(); } - int32_t RT1051LPMCommon::PowerOff() + std::int32_t RT1051LPMCommon::PowerOff() { board_power_off(); return 0; } - int32_t RT1051LPMCommon::Reboot(RebootType reason) + std::int32_t RT1051LPMCommon::Reboot(RebootType reason) { switch (reason) { case RebootType::GoToRecoveryUpdate: @@ -62,75 +60,83 @@ namespace bsp Down }; - CpuFrequencyMHz RT1051LPMCommon::onChangeUp(CpuFrequencyMHz freq, bsp::CpuFrequencyMHz newFrequency) + void RT1051LPMCommon::onChangeUp(CpuFrequencyMHz freq, CpuFrequencyMHz newFrequency) { if ((freq <= CpuFrequencyMHz::Level_1) && (newFrequency > CpuFrequencyMHz::Level_1)) { - // Switch DCDC to CCM mode to improve stability - DCDC_BootIntoCCM(DCDC); - // Switch external RAM clock source to PLL2 + /* Switch to external crystal oscillator */ + SwitchOscillatorSource(LowPowerMode::OscillatorSource::External); + + /* Switch external RAM clock source to PLL2 */ if (driverSEMC) { driverSEMC->SwitchToPLL2ClockSource(); } - // Enable regular 2P5 and 1P1 LDO, turn off weak 2P5 and 1P1 LDO - SwitchToRegularModeLDO(); - // Switch to external crystal oscillator - SwitchOscillatorSource(LowPowerMode::OscillatorSource::External); } - return newFrequency; } void RT1051LPMCommon::onChangeDown(CpuFrequencyMHz newFrequency) { - if (newFrequency <= bsp::CpuFrequencyMHz::Level_1) { - // Switch to internal RC oscillator - SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource::Internal); - // Enable weak 2P5 and 1P1 LDO, turn off regular 2P5 and 1P1 LDO - SwitchToLowPowerModeLDO(); - // Switch external RAM clock source to OSC + if (newFrequency <= CpuFrequencyMHz::Level_1) { + /* Switch to internal RC oscillator */ + SwitchOscillatorSource(LowPowerMode::OscillatorSource::Internal); + + /* Switch external RAM clock source to OSC */ if (driverSEMC) { driverSEMC->SwitchToPeripheralClockSource(); } - // Switch DCDC to DCM mode to reduce current consumption - DCDC_BootIntoDCM(DCDC); } } - void RT1051LPMCommon::SetCpuFrequency(bsp::CpuFrequencyMHz freq) + void RT1051LPMCommon::SetCpuFrequency(CpuFrequencyMHz freq) { if (currentFrequency == freq) { return; } - const Change change = (currentFrequency < freq) ? Change::Up : Change::Down; - if (Change::Up == change) { - freq = onChangeUp(currentFrequency, freq); + + /* Switch to overdrive config for any frequency change above 12MHz */ + const auto isChangeAbove12MHz = + (currentFrequency > CpuFrequencyMHz::Level_1) || (freq > CpuFrequencyMHz::Level_1); + if (isChangeAbove12MHz) { + dcdc::SwitchToOverdriveConfig(); } + + const auto changeDirection = (currentFrequency < freq) ? Change::Up : Change::Down; + if (Change::Up == changeDirection) { + onChangeUp(currentFrequency, freq); + } + switch (freq) { - case bsp::CpuFrequencyMHz::Level_0: + case CpuFrequencyMHz::Level_0: CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Osc_4_Mhz); break; - case bsp::CpuFrequencyMHz::Level_1: + case CpuFrequencyMHz::Level_1: CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Osc_12_Mhz); break; - case bsp::CpuFrequencyMHz::Level_2: + case CpuFrequencyMHz::Level_2: CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Osc_24_Mhz); break; - case bsp::CpuFrequencyMHz::Level_3: + case CpuFrequencyMHz::Level_3: CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Pll2_66_Mhz); break; - case bsp::CpuFrequencyMHz::Level_4: + case CpuFrequencyMHz::Level_4: CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Pll2_132_Mhz); break; - case bsp::CpuFrequencyMHz::Level_5: + case CpuFrequencyMHz::Level_5: CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Pll2_264_Mhz); break; - case bsp::CpuFrequencyMHz::Level_6: + case CpuFrequencyMHz::Level_6: CpuFreq->SetCpuFrequency(CpuFreqLPM::CpuClock::CpuClock_Pll2_528_Mhz); break; } - if (Change::Down == change) { + /* Switch back to regular config after clock change is done */ + if (isChangeAbove12MHz) { + dcdc::SwitchToRegularConfig(); + } + + if (Change::Down == changeDirection) { onChangeDown(freq); } + LOG_INFO("CPU frequency changed to %lu", CLOCK_GetFreq(kCLOCK_CpuClk)); currentFrequency = freq; } @@ -140,46 +146,16 @@ namespace bsp return CLOCK_GetCpuClkFreq(); } - void RT1051LPMCommon::SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource source) + void RT1051LPMCommon::SwitchOscillatorSource(LowPowerMode::OscillatorSource source) { - if (source == bsp::LowPowerMode::OscillatorSource::Internal) { - cpp_freertos::CriticalSection::Enter(); - bsp::DisableExternalOscillator(); - cpp_freertos::CriticalSection::Exit(); + switch (source) { + case LowPowerMode::OscillatorSource::Internal: + SwitchToInternalOscillator(); + break; + + case LowPowerMode::OscillatorSource::External: + SwitchToExternalOscillator(); + break; } - else if (source == bsp::LowPowerMode::OscillatorSource::External) { - cpp_freertos::CriticalSection::Enter(); - bsp::EnableExternalOscillator(); - cpp_freertos::CriticalSection::Exit(); - } - } - - void RT1051LPMCommon::RegularLDOMode() - { - // Enable regular 2P5 and 1P1 LDO - PMU->REG_2P5_SET = PMU_REG_2P5_ENABLE_LINREG_MASK; - PMU->REG_1P1_SET = PMU_REG_1P1_ENABLE_LINREG_MASK; - - // Wait for regular LDOs to become stable (documentation Low Power AN12085) - while ((PMU->REG_2P5 & PMU_REG_2P5_OK_VDD2P5_MASK) == 0) {} - while ((PMU->REG_1P1 & PMU_REG_1P1_OK_VDD1P1_MASK) == 0) {} - - // Turn off weak 2P5 and 1P1 LDO - PMU->REG_2P5_CLR = PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; - PMU->REG_1P1_CLR = PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; - } - - void RT1051LPMCommon::LowPowerLDOMode() - { - // Enable weak 2P5 and 1P1 LDO - PMU->REG_2P5_SET = PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; - PMU->REG_1P1_SET = PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; - - // Wait for 40us for weak LDOs to stabilize - SDK_DelayAtLeastUs(40, CLOCK_GetCpuClkFreq()); - - // Disable regular 2P5 and 1P1 LDO - PMU->REG_2P5_CLR = PMU_REG_2P5_ENABLE_LINREG_MASK; - PMU->REG_1P1_CLR = PMU_REG_1P1_ENABLE_LINREG_MASK; } } // namespace bsp diff --git a/module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.hpp b/module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.hpp index c93c7d622..9241bf8ee 100644 --- a/module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.hpp +++ b/module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.hpp @@ -13,21 +13,17 @@ namespace bsp { public: RT1051LPMCommon(); - int32_t PowerOff() final; - int32_t Reboot(RebootType reason) final; + std::int32_t PowerOff() final; + std::int32_t Reboot(RebootType reason) final; void SetCpuFrequency(CpuFrequencyMHz freq) final; - [[nodiscard]] uint32_t GetCpuFrequency() const noexcept final; + [[nodiscard]] std::uint32_t GetCpuFrequency() const noexcept final; void SwitchOscillatorSource(OscillatorSource source) final; - void RegularLDOMode(); - void LowPowerLDOMode(); - private: - CpuFrequencyMHz onChangeUp(CpuFrequencyMHz freq, CpuFrequencyMHz newFrequency); - void onChangeDown(bsp::CpuFrequencyMHz freq); + void onChangeUp(CpuFrequencyMHz freq, CpuFrequencyMHz newFrequency); + void onChangeDown(CpuFrequencyMHz freq); std::unique_ptr CpuFreq; std::shared_ptr driverSEMC; }; - } // namespace bsp diff --git a/module-bsp/board/rt1051/common/board.cpp b/module-bsp/board/rt1051/common/board.cpp index 586eedbd4..7ee24229a 100644 --- a/module-bsp/board/rt1051/common/board.cpp +++ b/module-bsp/board/rt1051/common/board.cpp @@ -179,12 +179,6 @@ namespace bsp // SNVS->LPGPR[0] = rebootCode::rebootFailedToBoot; // TODO: Here we can implement boot-time fail detection - // Set internal DCDC to CCM mode, DCM is allowed ONLY in low power modes (see AN12085, 5.3.9, p.33) - DCDC_BootIntoCCM(DCDC); - - // Disconnect DCDC internal load resistor - DCDC->REG1 &= ~DCDC_REG1_REG_RLOAD_SW_MASK; - PrintSystemClocks(); clearAndPrintBootReason(); diff --git a/module-bsp/board/rt1051/drivers/RT1051DriverOscillator.cpp b/module-bsp/board/rt1051/drivers/RT1051DriverOscillator.cpp index e41a3ca73..2237ccc78 100644 --- a/module-bsp/board/rt1051/drivers/RT1051DriverOscillator.cpp +++ b/module-bsp/board/rt1051/drivers/RT1051DriverOscillator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "RT1051DriverOscillator.hpp" @@ -9,7 +9,7 @@ namespace drivers RT1051DriverOscillator::RT1051DriverOscillator() noexcept { - bsp::EnableExternalOscillator(); + bsp::SwitchToExternalOscillator(); } } // namespace drivers diff --git a/module-bsp/board/rt1051/drivers/RT1051DriverPLL2.cpp b/module-bsp/board/rt1051/drivers/RT1051DriverPLL2.cpp index df6df93d1..a2a3b1e5b 100644 --- a/module-bsp/board/rt1051/drivers/RT1051DriverPLL2.cpp +++ b/module-bsp/board/rt1051/drivers/RT1051DriverPLL2.cpp @@ -3,41 +3,63 @@ #include "RT1051DriverPLL2.hpp" #include "board/rt1051/bsp/lpm/ClockState.hpp" -#include "board/rt1051/bsp/lpm/Bandgap.hpp" #include "board/rt1051/bsp/lpm/CpuFreqLPM.hpp" -#include +#include "board/rt1051/bsp/lpm/Bandgap.hpp" +#include "board/rt1051/bsp/lpm/LDO.hpp" +#include "board/rt1051/bsp/lpm/DCDC.hpp" + +namespace +{ + inline std::uint32_t getCurrentVDDRunVoltage() + { + return (DCDC->REG3 & DCDC_REG3_TRG_MASK); + } +} // namespace namespace drivers { RT1051DriverPLL2::RT1051DriverPLL2() noexcept { if (!IsPLL2Enabled()) { - // Set VDD_SOC_IN to 1.15V required to safely start PLL2 - DCDC_AdjustTargetVoltage(DCDC, bsp::VDDRun_1150_mV, bsp::VDDStandby_925_mV); + /* Check if switching conditions already met */ + const auto isCurrentVoltageOverdrive = (getCurrentVDDRunVoltage() >= bsp::VDDRun_1275_mV); + if (!isCurrentVoltageOverdrive) { + bsp::dcdc::SwitchToOverdriveConfig(); + } - // Switch to regular bandgap + /* Switch to regular bandgap */ bsp::bandgap::SwitchToRegularMode(); - // Enable PLL2 + /* Switch to regular LDO */ + bsp::ldo::SwitchToRegularMode(); + + /* Switch back to regular config */ + if (!isCurrentVoltageOverdrive) { + bsp::dcdc::SwitchToRegularConfig(); + } + + /* Enable PLL2 */ clkPLL2setup(CLK_ENABLE); } } - RT1051DriverPLL2::~RT1051DriverPLL2() + RT1051DriverPLL2::~RT1051DriverPLL2() noexcept { if ((CLOCK_GetMux(kCLOCK_SemcMux) == SemcMuxPeripheralClock) && !bsp::IsClockEnabled(kCLOCK_Lpspi1) && !bsp::IsClockEnabled(kCLOCK_Lpspi2) && !bsp::IsClockEnabled(kCLOCK_Lpspi3) && !bsp::IsClockEnabled(kCLOCK_Lpspi4) && !bsp::IsClockEnabled(kCLOCK_Usdhc1) && !bsp::IsClockEnabled(kCLOCK_Usdhc2)) { - - // Disable PLL2 + /* Disable PLL2 */ clkPLL2setup(CLK_DISABLE); - // Switch to low power bandgap - bsp::bandgap::SwitchToLowPowerMode(); + /* Switch DCDC to low power config */ + bsp::dcdc::SwitchToLowPowerConfig(); - // After turning off PLL2 and with CPU @4MHZ VDD_SOC_IN can be set to 950mV - DCDC_AdjustTargetVoltage(DCDC, bsp::VDDRun_950_mV, bsp::VDDStandby_925_mV); + /* Switch to low power LDO */ + bsp::ldo::SwitchToLowPowerMode(); + + /* Switch to low power bandgap */ + bsp::bandgap::SwitchToLowPowerMode(); } } @@ -45,5 +67,4 @@ namespace drivers { return not static_cast(CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_POWERDOWN_MASK); } - } // namespace drivers diff --git a/module-bsp/board/rt1051/drivers/RT1051DriverPLL2.hpp b/module-bsp/board/rt1051/drivers/RT1051DriverPLL2.hpp index 243338432..e35e4c783 100644 --- a/module-bsp/board/rt1051/drivers/RT1051DriverPLL2.hpp +++ b/module-bsp/board/rt1051/drivers/RT1051DriverPLL2.hpp @@ -1,23 +1,23 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once #include "board/clock_config.h" +#include namespace drivers { - inline constexpr uint32_t SemcMuxPLL2Clock{1}; - inline constexpr uint32_t SemcMuxPeripheralClock{0}; + inline constexpr std::uint32_t SemcMuxPLL2Clock{1}; + inline constexpr std::uint32_t SemcMuxPeripheralClock{0}; class RT1051DriverPLL2 { public: RT1051DriverPLL2() noexcept; - ~RT1051DriverPLL2(); + ~RT1051DriverPLL2() noexcept; private: [[nodiscard]] bool IsPLL2Enabled() const noexcept; }; - } // namespace drivers diff --git a/module-bsp/board/rt1051/drivers/RT1051DriverPWM.cpp b/module-bsp/board/rt1051/drivers/RT1051DriverPWM.cpp index baa869b8f..3bc51a322 100644 --- a/module-bsp/board/rt1051/drivers/RT1051DriverPWM.cpp +++ b/module-bsp/board/rt1051/drivers/RT1051DriverPWM.cpp @@ -1,10 +1,9 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "RT1051DriverPWM.hpp" #include "RT1051DriverPWMhelper.hpp" #include -#include "../board.h" #include namespace drivers @@ -155,7 +154,6 @@ namespace drivers unsigned numOfChannels, std::uint32_t _clockFrequency) { - pwm_mode_t pwmMode = kPWM_SignedCenterAligned; PWM_SetupPwm(base, pwmModule, config, numOfChannels, pwmMode, parameters.frequency, _clockFrequency); } @@ -174,7 +172,7 @@ namespace drivers void RT1051DriverPWM::UpdateClockFrequency(bsp::CpuFrequencyMHz newFrequency) { cpp_freertos::LockGuard lock(frequencyChangeMutex); - std::uint32_t convertedFrequency = static_cast(newFrequency) * bsp::MHz_frequency_multiplier; + const auto convertedFrequency = static_cast(newFrequency) * bsp::HzPerMHz; if (clockFrequency != convertedFrequency) { SetupPWMInstance(pwmSignalsConfig.data(), enabledChannels.size(), convertedFrequency); diff --git a/module-bsp/board/rt1051/puretx/bsp/lpm/RT1051LPM.cpp b/module-bsp/board/rt1051/puretx/bsp/lpm/RT1051LPM.cpp index 511cb956c..635e48f8f 100644 --- a/module-bsp/board/rt1051/puretx/bsp/lpm/RT1051LPM.cpp +++ b/module-bsp/board/rt1051/puretx/bsp/lpm/RT1051LPM.cpp @@ -2,12 +2,10 @@ // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "RT1051LPM.hpp" -#include #include namespace bsp { - using namespace drivers; RT1051LPM::RT1051LPM() @@ -16,17 +14,19 @@ namespace bsp DriverGPIOParams{}); gpio_2 = DriverGPIO::Create(static_cast(BoardDefinitions::DCDC_INVERTER_MODE_GPIO), DriverGPIOParams{}); - gpio_1->ConfPin(DriverGPIOPinParams{.dir = DriverGPIOPinParams::Direction::Output, - .irqMode = DriverGPIOPinParams::InterruptMode::NoIntmode, - .defLogic = 1, - .pin = static_cast(BoardDefinitions::POWER_SWITCH_HOLD_BUTTON)}); + gpio_1->ConfPin( + DriverGPIOPinParams{.dir = DriverGPIOPinParams::Direction::Output, + .irqMode = DriverGPIOPinParams::InterruptMode::NoIntmode, + .defLogic = 1, + .pin = static_cast(BoardDefinitions::POWER_SWITCH_HOLD_BUTTON)}); - gpio_2->ConfPin(DriverGPIOPinParams{.dir = DriverGPIOPinParams::Direction::Output, - .irqMode = DriverGPIOPinParams::InterruptMode::NoIntmode, - .defLogic = 0, - .pin = static_cast(BoardDefinitions::DCDC_INVERTER_MODE_PIN)}); + gpio_2->ConfPin( + DriverGPIOPinParams{.dir = DriverGPIOPinParams::Direction::Output, + .irqMode = DriverGPIOPinParams::InterruptMode::NoIntmode, + .defLogic = 0, + .pin = static_cast(BoardDefinitions::DCDC_INVERTER_MODE_PIN)}); - gpio_1->WritePin(static_cast(BoardDefinitions::POWER_SWITCH_HOLD_BUTTON), 1); + gpio_1->WritePin(static_cast(BoardDefinitions::POWER_SWITCH_HOLD_BUTTON), 1); EnableDcdcPowerSaveMode(); } @@ -34,23 +34,12 @@ namespace bsp // Current threshold for entry to and exit from the PSM mode is set to 100 mA void RT1051LPM::EnableDcdcPowerSaveMode() { - gpio_2->WritePin(static_cast(BoardDefinitions::DCDC_INVERTER_MODE_PIN), 0); + gpio_2->WritePin(static_cast(BoardDefinitions::DCDC_INVERTER_MODE_PIN), 0); } // Forces both bucks to operate in PWM mode void RT1051LPM::DisableDcdcPowerSaveMode() { - gpio_2->WritePin(static_cast(BoardDefinitions::DCDC_INVERTER_MODE_PIN), 1); + gpio_2->WritePin(static_cast(BoardDefinitions::DCDC_INVERTER_MODE_PIN), 1); } - - void RT1051LPM::SwitchToRegularModeLDO() - { - RT1051LPMCommon::RegularLDOMode(); - } - - void RT1051LPM::SwitchToLowPowerModeLDO() - { - RT1051LPMCommon::LowPowerLDOMode(); - } - } // namespace bsp diff --git a/module-bsp/board/rt1051/puretx/bsp/lpm/RT1051LPM.hpp b/module-bsp/board/rt1051/puretx/bsp/lpm/RT1051LPM.hpp index 62890cdf4..7088dc755 100644 --- a/module-bsp/board/rt1051/puretx/bsp/lpm/RT1051LPM.hpp +++ b/module-bsp/board/rt1051/puretx/bsp/lpm/RT1051LPM.hpp @@ -14,12 +14,8 @@ namespace bsp void EnableDcdcPowerSaveMode() final; void DisableDcdcPowerSaveMode() final; - void SwitchToRegularModeLDO() final; - void SwitchToLowPowerModeLDO() final; - private: std::shared_ptr gpio_1; std::shared_ptr gpio_2; }; - } // namespace bsp diff --git a/module-bsp/bsp/common.cpp b/module-bsp/bsp/common.cpp index f4ff516f2..d8bb74ab5 100644 --- a/module-bsp/bsp/common.cpp +++ b/module-bsp/bsp/common.cpp @@ -1,41 +1,37 @@ #include "common.hpp" -namespace bsp{ - const char *c_str(const Board &board) +namespace bsp +{ + std::uint8_t CpuMHZToLevel(enum CpuFrequencyMHz val) { - switch (board) { - case Board::RT1051: - return "RT1051"; - break; - case Board::Linux: - return "Linux"; - break; - case Board::none: - default: - return "none"; - break; + switch (val) { + case CpuFrequencyMHz::Level_0: + return 0; + case CpuFrequencyMHz::Level_1: + return 1; + case CpuFrequencyMHz::Level_2: + return 2; + case CpuFrequencyMHz::Level_3: + return 3; + case CpuFrequencyMHz::Level_4: + return 4; + case CpuFrequencyMHz::Level_5: + return 5; + case CpuFrequencyMHz::Level_6: + return 6; + } + return -1; + } + + const char *c_str(Board board) + { + switch (board) { + case Board::RT1051: + return "RT1051"; + case Board::Linux: + return "Linux"; + default: + return "none"; } } - - uint8_t CpuMHZToLevel(enum CpuFrequencyMHz val) - { - switch (val) { - case CpuFrequencyMHz::Level_0: - return 0; - case CpuFrequencyMHz::Level_1: - return 1; - case CpuFrequencyMHz::Level_2: - return 2; - case CpuFrequencyMHz::Level_3: - return 3; - case CpuFrequencyMHz::Level_4: - return 4; - case CpuFrequencyMHz::Level_5: - return 5; - case CpuFrequencyMHz::Level_6: - return 6; - } - return -1; - } }; - diff --git a/module-bsp/bsp/common.hpp b/module-bsp/bsp/common.hpp index d69116359..226fc2ec3 100644 --- a/module-bsp/bsp/common.hpp +++ b/module-bsp/bsp/common.hpp @@ -4,12 +4,13 @@ #pragma once #include + namespace bsp { - enum class RetCode{ + enum class RetCode + { Success, Failure - }; /// CPU frequency is dependent on the clock settings. @@ -25,16 +26,15 @@ namespace bsp Level_6 = 528 }; - uint8_t CpuMHZToLevel(enum CpuFrequencyMHz val); - - constexpr auto MHz_frequency_multiplier = 1000000U; - - enum class Board{ + enum class Board + { RT1051, - Linux, - none + Linux, + none }; - [[nodiscard]] const char *c_str(const Board &board); + constexpr auto HzPerMHz = 1000000U; + + [[nodiscard]] std::uint8_t CpuMHZToLevel(CpuFrequencyMHz val); + [[nodiscard]] const char *c_str(Board board); } - diff --git a/module-bsp/bsp/lpm/bsp_lpm.hpp b/module-bsp/bsp/lpm/bsp_lpm.hpp index 55702448a..4b97703a7 100644 --- a/module-bsp/bsp/lpm/bsp_lpm.hpp +++ b/module-bsp/bsp/lpm/bsp_lpm.hpp @@ -14,7 +14,6 @@ namespace drivers namespace bsp { - class LowPowerMode { public: @@ -23,6 +22,7 @@ namespace bsp External, Internal }; + enum class RebootType { NormalRestart, @@ -38,21 +38,18 @@ namespace bsp static std::optional> Create(); - virtual int32_t PowerOff() = 0; - virtual int32_t Reboot(RebootType reason) = 0; + virtual std::int32_t PowerOff() = 0; + virtual std::int32_t Reboot(RebootType reason) = 0; virtual void SetCpuFrequency(CpuFrequencyMHz freq) = 0; [[nodiscard]] CpuFrequencyMHz GetCurrentFrequencyLevel() const noexcept; - [[nodiscard]] virtual uint32_t GetCpuFrequency() const noexcept = 0; + [[nodiscard]] virtual std::uint32_t GetCpuFrequency() const noexcept = 0; virtual void SwitchOscillatorSource(OscillatorSource source) = 0; virtual void EnableDcdcPowerSaveMode() = 0; virtual void DisableDcdcPowerSaveMode() = 0; - virtual void SwitchToRegularModeLDO() = 0; - virtual void SwitchToLowPowerModeLDO() = 0; - protected: CpuFrequencyMHz currentFrequency = CpuFrequencyMHz::Level_6; }; diff --git a/module-sys/SystemManager/PowerManager.cpp b/module-sys/SystemManager/PowerManager.cpp index 8fb434ed4..335d1f886 100644 --- a/module-sys/SystemManager/PowerManager.cpp +++ b/module-sys/SystemManager/PowerManager.cpp @@ -21,7 +21,7 @@ namespace sys constexpr auto highestLevelName{"highestCpuFrequency"}; } // namespace - CpuFrequencyMonitor::CpuFrequencyMonitor(const std::string name) : levelName(name) + CpuFrequencyMonitor::CpuFrequencyMonitor(const std::string &name) : levelName(name) {} [[nodiscard]] auto CpuFrequencyMonitor::GetName() const noexcept -> std::string @@ -153,18 +153,18 @@ namespace sys cpuStatistics.TrackChange(ret); } - bool PowerManager::IsCpuPernamentFrequency() + bool PowerManager::IsCpuPermanentFrequency() { return cpuAlgorithms->get(sys::cpu::AlgoID::FrequencyHold) != nullptr; } - void PowerManager::SetPernamentFrequency(bsp::CpuFrequencyMHz freq) + void PowerManager::SetPermanentFrequency(bsp::CpuFrequencyMHz freq) { cpuAlgorithms->emplace(sys::cpu::AlgoID::FrequencyHold, std::make_unique(freq, powerProfile)); } - void PowerManager::ResetPernamentFrequency() + void PowerManager::ResetPermanentFrequency() { cpuAlgorithms->remove(sys::cpu::AlgoID::FrequencyHold); } diff --git a/module-sys/SystemManager/SystemManagerCommon.cpp b/module-sys/SystemManager/SystemManagerCommon.cpp index 6a34e5ef4..e9bb45109 100644 --- a/module-sys/SystemManager/SystemManagerCommon.cpp +++ b/module-sys/SystemManager/SystemManagerCommon.cpp @@ -592,21 +592,18 @@ namespace sys connect(typeid(sys::DeviceRegistrationMessage), [this](sys::Message *message) -> sys::MessagePointer { auto msg = static_cast(message); deviceManager->RegisterNewDevice(msg->getDevice()); - return sys::MessageNone{}; }); connect(typeid(sys::SentinelRegistrationMessage), [this](sys::Message *message) -> sys::MessagePointer { auto msg = static_cast(message); powerManager->RegisterNewSentinel(msg->getSentinel()); - return sys::MessageNone{}; }); connect(typeid(sys::SentinelRemovalMessage), [this](sys::Message *message) -> sys::MessagePointer { auto msg = static_cast(message); powerManager->RemoveSentinel(msg->getSentinelName()); - return std::make_shared(); }); @@ -622,22 +619,21 @@ namespace sys connect(typeid(sys::ReleaseCpuFrequencyMessage), [this](sys::Message *message) -> sys::MessagePointer { auto msg = static_cast(message); powerManager->ResetCpuFrequencyRequest(msg->getName()); - return sys::MessageNone{}; }); - connect(typeid(sys::IsCpuPernament), [this](sys::Message *message) -> sys::MessagePointer { - return std::make_shared(powerManager->IsCpuPernamentFrequency()); + connect(typeid(sys::IsCpuPermanent), [this](sys::Message *message) -> sys::MessagePointer { + return std::make_shared(powerManager->IsCpuPermanentFrequency()); }); connect(typeid(sys::HoldCpuFrequencyPermanentlyMessage), [this](sys::Message *message) -> sys::MessagePointer { auto msg = static_cast(message); - powerManager->SetPernamentFrequency(msg->request); + powerManager->SetPermanentFrequency(msg->request); return std::make_shared(); }); connect(typeid(sys::ReleaseCpuPermanentFrequencyMessage), [this](sys::Message *message) -> sys::MessagePointer { - powerManager->ResetPernamentFrequency(); + powerManager->ResetPermanentFrequency(); return std::make_shared(); }); @@ -754,7 +750,7 @@ namespace sys void SystemManagerCommon::UpdateResourcesAfterCpuFrequencyChange(bsp::CpuFrequencyMHz newFrequency) { - if (newFrequency <= bsp::CpuFrequencyMHz::Level_1) { + if (newFrequency <= bsp::CpuFrequencyMHz::Level_2) { purefs::subsystem::disk_mgr()->pm_control(purefs::blkdev::pm_state::suspend); } else { diff --git a/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.cpp b/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.cpp index ab68d1b82..6f7628cc2 100644 --- a/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.cpp +++ b/module-sys/SystemManager/cpu/algorithm/FrequencyStepping.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "FrequencyStepping.hpp" @@ -23,9 +23,7 @@ namespace sys::cpu case bsp::CpuFrequencyMHz::Level_3: return bsp::CpuFrequencyMHz::Level_2; case bsp::CpuFrequencyMHz::Level_2: - [[fallthrough]]; case bsp::CpuFrequencyMHz::Level_1: - [[fallthrough]]; case bsp::CpuFrequencyMHz::Level_0: return profile.minimalFrequency; } diff --git a/module-sys/SystemManager/include/SystemManager/PowerManager.hpp b/module-sys/SystemManager/include/SystemManager/PowerManager.hpp index f4cd09dc6..454d3ed72 100644 --- a/module-sys/SystemManager/include/SystemManager/PowerManager.hpp +++ b/module-sys/SystemManager/include/SystemManager/PowerManager.hpp @@ -25,7 +25,7 @@ namespace sys class CpuFrequencyMonitor { public: - explicit CpuFrequencyMonitor(const std::string name); + explicit CpuFrequencyMonitor(const std::string &name); [[nodiscard]] auto GetName() const noexcept -> std::string; [[nodiscard]] auto GetPeriodRuntimePercentage(const TickType_t periodTicksIncrease) const noexcept @@ -65,9 +65,9 @@ namespace sys void RemoveSentinel(std::string sentinelName) const; void SetCpuFrequencyRequest(const std::string &sentinelName, bsp::CpuFrequencyMHz request); void ResetCpuFrequencyRequest(const std::string &sentinelName); - bool IsCpuPernamentFrequency(); - void SetPernamentFrequency(bsp::CpuFrequencyMHz freq); - void ResetPernamentFrequency(); + bool IsCpuPermanentFrequency(); + void SetPermanentFrequency(bsp::CpuFrequencyMHz freq); + void ResetPermanentFrequency(); void LogPowerManagerStatistics(); diff --git a/module-sys/common/include/system/messages/RequestCpuFrequencyMessage.hpp b/module-sys/common/include/system/messages/RequestCpuFrequencyMessage.hpp index 4f88b1ef8..cdae249c9 100644 --- a/module-sys/common/include/system/messages/RequestCpuFrequencyMessage.hpp +++ b/module-sys/common/include/system/messages/RequestCpuFrequencyMessage.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -8,20 +8,19 @@ namespace sys { - - struct IsCpuPernament : public sys::DataMessage + struct IsCpuPermanent : public sys::DataMessage { public: - explicit IsCpuPernament() + explicit IsCpuPermanent() {} }; - struct IsCpuPernamentResponse : public sys::ResponseMessage + struct IsCpuPermanentResponse : public sys::ResponseMessage { public: - explicit IsCpuPernamentResponse(bool pernament) : pernament(pernament) + explicit IsCpuPermanentResponse(bool permanent) : permanent(permanent) {} - const bool pernament = false; + const bool permanent = false; }; struct HoldCpuFrequencyPermanentlyMessage : public sys::DataMessage @@ -37,5 +36,4 @@ namespace sys class ReleaseCpuPermanentFrequencyMessage : public sys::DataMessage {}; - } // namespace sys diff --git a/pure_changelog.md b/pure_changelog.md index 88d6a955c..0af5dde4a 100644 --- a/pure_changelog.md +++ b/pure_changelog.md @@ -16,6 +16,7 @@ * Change roaming indicator to show domestic roaming as home network * Optimized ServiceAudio power management * Blocked call execution with empty phone number field +* Improved device stability related to frequency scaling ### Fixed