Skip to content

Commit 3cbbeff

Browse files
committed
[MOS-1011] Fix frequency switching stability
Multiple fixes of clock switching related stability issues: * added RC oscillator hysteresis as in NXP example; * changed DCDC converter config; * configure PLL2 to be able to run on any CPU frequency level; * added switching to 1.275V (overdrive) voltage when applying any clock change above 12MHz as well as LDO or bandgap switching, as done in Mbed OS' lpm.c for RT1050; * changed BMCR AXI queues weighs for SDRAM in JLink scripts to disable operations reordering, as it is known to cause data integrity issues; * extracted some code to separate files; * smaller or bigger code cleanups.
1 parent 321f56e commit 3cbbeff

36 files changed

+399
-317
lines changed

evkbimxrt1050_sdram_init.jlinkscript

+2-2
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ void SDRAM_Init() {
187187

188188
// Config SDR Controller Registers/
189189
MEM_WriteU32(0x402F0000,0x10000004); // MCR
190-
MEM_WriteU32(0x402F0008,0x20200E44); // BMCR0
191-
MEM_WriteU32(0x402F000C,0x20200E40); // BMCR1
190+
MEM_WriteU32(0x402F0008,0x00000081); // BMCR0
191+
MEM_WriteU32(0x402F000C,0x00000081); // BMCR1
192192
MEM_WriteU32(0x402F0010,0x8000001D); // BR0, 64MB OK
193193
MEM_WriteU32(0x402F0040,0x00000E31); // SDRAMCR0 OK
194194
MEM_WriteU32(0x402F0044,0x00774D22); // SDRAMCR1

evkbimxrt1050_sdram_init_T6.jlinkscript

+12-12
Original file line numberDiff line numberDiff line change
@@ -239,21 +239,21 @@ void SDRAM_SEMC_Init(void)
239239
reg_val |= 0x00000002;
240240
MEM_WriteU32(SEMC_MCR, reg_val);
241241

242-
/* Configure queues for AXI bus:
242+
/* 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:
243243
* Queue A:
244-
* WQOS = 4;
245-
* WAGE = 2;
246-
* WSH = 3;
247-
* WRWS = 5 */
248-
MEM_WriteU32(SEMC_BMCR0, 0x00030524);
244+
* WQOS = 1;
245+
* WAGE = 8;
246+
* WSH = 0;
247+
* WRWS = 0 */
248+
MEM_WriteU32(SEMC_BMCR0, 0x00000081);
249249

250250
/* Queue B:
251-
* WQOS = 4;
252-
* WAGE = 2;
253-
* WPH = 3;
254-
* WRWS = 5;
255-
* WBR = 6 */
256-
MEM_WriteU32(SEMC_BMCR1, 0x06050324);
251+
* WQOS = 1;
252+
* WAGE = 8;
253+
* WPH = 0;
254+
* WRWS = 0;
255+
* WBR = 0 */
256+
MEM_WriteU32(SEMC_BMCR1, 0x00000081);
257257

258258
/* Configure MCR:
259259
* set bus timeout cycles to 0x10;

harmony_changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
* General improvement in Eink display and error handling
5353
* Changed the "Turn off Harmony" popup display time to 10 seconds
5454
* The default year has been updated to 2023
55+
* Improved device stability related to frequency scaling
5556

5657
## [2.0.0 2023-06-29]
5758

module-apps/application-settings/windows/advanced/CPUModeTestWindow.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
1+
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
22
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
33

44
#include "CPUModeTestWindow.hpp"
@@ -134,9 +134,9 @@ namespace gui
134134
permanentFreqSpinner = new gui::TextSpinnerBox(permanentFreqBody, {"OFF", "ON"}, Boundaries::Continuous);
135135
permanentFreqSpinner->setMinimumSize(100, 30);
136136
auto ret =
137-
application->async_call<sys::IsCpuPernament, sys::IsCpuPernamentResponse>(service::name::system_manager);
137+
application->async_call<sys::IsCpuPermanent, sys::IsCpuPermanentResponse>(service::name::system_manager);
138138
application->sync(ret);
139-
permanentFreqSpinner->setCurrentValue(ret.getResult().pernament ? "ON" : "OFF");
139+
permanentFreqSpinner->setCurrentValue(ret.getResult().permanent ? "ON" : "OFF");
140140

141141
permanentFreqBody->inputCallback = [&](Item &item, const InputEvent &event) {
142142
auto ret = permanentFreqSpinner->onInput(event);
@@ -193,10 +193,10 @@ namespace gui
193193
newFreqBody->inputCallback = [&](Item &item, const InputEvent &event) {
194194
auto ret = currentFreqSpinner->onInput(event);
195195

196-
auto async = application->async_call<sys::IsCpuPernament, sys::IsCpuPernamentResponse>(
196+
auto async = application->async_call<sys::IsCpuPermanent, sys::IsCpuPermanentResponse>(
197197
service::name::system_manager);
198198
application->sync(async);
199-
if (async.getResult().pernament) {
199+
if (async.getResult().permanent) {
200200
application->bus.sendUnicastSync(
201201
std::make_shared<sys::HoldCpuFrequencyPermanentlyMessage>(
202202
magic_enum::enum_cast<bsp::CpuFrequencyMHz>(std::stoi(currentFreqSpinner->getCurrentValue()))
+5-17
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,36 @@
11
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
22
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
33

4-
//
5-
// Created by mati on 09.09.2019.
6-
//
7-
84
#include "LinuxLPM.h"
95

106
namespace bsp
117
{
12-
13-
int32_t LinuxLPM::PowerOff()
8+
std::int32_t LinuxLPM::PowerOff()
149
{
1510
return 0;
1611
}
1712

18-
int32_t LinuxLPM::Reboot(RebootType)
13+
std::int32_t LinuxLPM::Reboot([[maybe_unused]] RebootType reason)
1914
{
2015
return 0;
2116
}
2217

23-
void LinuxLPM::SetCpuFrequency(bsp::CpuFrequencyMHz freq)
18+
void LinuxLPM::SetCpuFrequency(CpuFrequencyMHz freq)
2419
{
2520
currentFrequency = freq;
2621
}
2722

28-
uint32_t LinuxLPM::GetCpuFrequency() const noexcept
23+
std::uint32_t LinuxLPM::GetCpuFrequency() const noexcept
2924
{
3025
return 0;
3126
}
3227

33-
void LinuxLPM::SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource source)
28+
void LinuxLPM::SwitchOscillatorSource(LowPowerMode::OscillatorSource source)
3429
{}
3530

3631
void LinuxLPM::EnableDcdcPowerSaveMode()
3732
{}
3833

3934
void LinuxLPM::DisableDcdcPowerSaveMode()
4035
{}
41-
42-
void LinuxLPM::SwitchToRegularModeLDO()
43-
{}
44-
45-
void LinuxLPM::SwitchToLowPowerModeLDO()
46-
{}
47-
4836
} // namespace bsp

module-bsp/board/linux/lpm/LinuxLPM.h

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
11
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
22
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
33

4-
#ifndef PUREPHONE_LINUXLPM_H
5-
#define PUREPHONE_LINUXLPM_H
4+
#pragma once
65

76
#include "bsp/lpm/bsp_lpm.hpp"
87

98
namespace bsp
109
{
11-
1210
class LinuxLPM : public LowPowerMode
1311
{
1412
public:
15-
int32_t PowerOff() override final;
16-
int32_t Reboot(RebootType reason) override final;
13+
std::int32_t PowerOff() override final;
14+
std::int32_t Reboot(RebootType reason) override final;
1715
void SetCpuFrequency(CpuFrequencyMHz freq) final;
18-
[[nodiscard]] uint32_t GetCpuFrequency() const noexcept final;
16+
[[nodiscard]] std::uint32_t GetCpuFrequency() const noexcept final;
1917
void SwitchOscillatorSource(OscillatorSource source) final;
2018

2119
void EnableDcdcPowerSaveMode() final;
2220
void DisableDcdcPowerSaveMode() final;
23-
24-
void SwitchToRegularModeLDO() final;
25-
void SwitchToLowPowerModeLDO() final;
2621
};
27-
2822
} // namespace bsp
29-
30-
#endif // PUREPHONE_LINUXLPM_H

module-bsp/board/rt1051/CMakeLists.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
22
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
33

4-
54
target_sources(module-bsp
65
PRIVATE
76
bluetooth/BlueKitchen.cpp
@@ -28,6 +27,8 @@ target_sources(module-bsp
2827
bsp/lpm/Oscillator.cpp
2928
bsp/lpm/RT1051LPMCommon.cpp
3029
bsp/lpm/Bandgap.cpp
30+
bsp/lpm/LDO.cpp
31+
bsp/lpm/DCDC.cpp
3132
bsp/magnetometer/ALS31300.cpp
3233
bsp/pit/pit.cpp
3334
bsp/trng/trng.cpp
@@ -74,6 +75,8 @@ set_source_files_properties(
7475

7576
target_compile_definitions(module-bsp PUBLIC USB_STACK_FREERTOS)
7677

78+
target_compile_definitions(module-bsp PRIVATE BOARD_${PRODUCT}=1)
79+
7780
add_subdirectory(common/fsl_drivers)
7881
add_subdirectory(os)
7982
add_subdirectory(${BOARD})

module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.cpp

-15
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
33

44
#include "RT1051LPM.hpp"
5-
#include <board.h>
6-
#include <board/BoardDefinitions.hpp>
75

86
namespace bsp
97
{
@@ -12,17 +10,4 @@ namespace bsp
1210

1311
void RT1051LPM::DisableDcdcPowerSaveMode()
1412
{}
15-
16-
void RT1051LPM::SwitchToRegularModeLDO()
17-
{
18-
RT1051LPMCommon::RegularLDOMode();
19-
NVIC_ClearPendingIRQ(ANATOP_EVENT0_IRQn);
20-
EnableIRQ(ANATOP_EVENT0_IRQn);
21-
}
22-
23-
void RT1051LPM::SwitchToLowPowerModeLDO()
24-
{
25-
DisableIRQ(ANATOP_EVENT0_IRQn);
26-
RT1051LPMCommon::LowPowerLDOMode();
27-
}
2813
} // namespace bsp

module-bsp/board/rt1051/bellpx/bsp/lpm/RT1051LPM.hpp

+1-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
33

44
#pragma once
5+
56
#include <bsp/lpm/RT1051LPMCommon.hpp>
67

78
namespace bsp
@@ -11,9 +12,5 @@ namespace bsp
1112
public:
1213
void EnableDcdcPowerSaveMode() final;
1314
void DisableDcdcPowerSaveMode() final;
14-
15-
void SwitchToRegularModeLDO() final;
16-
void SwitchToLowPowerModeLDO() final;
1715
};
18-
1916
} // namespace bsp

module-bsp/board/rt1051/bsp/lpm/Bandgap.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "Bandgap.hpp"
55
#include <cstdint>
66
#include <fsl_common.h>
7+
#include <critical.hpp>
78

89
namespace
910
{
@@ -14,22 +15,30 @@ namespace bsp::bandgap
1415
{
1516
void SwitchToRegularMode()
1617
{
18+
cpp_freertos::CriticalSection::Enter();
19+
1720
/* Enable regular bandgap and wait for it to stabilize */
1821
CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_REFTOP_PWD_MASK;
1922
while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_REFTOP_VBGUP_MASK) == 0) {}
2023

2124
/* Disable low power bandgap */
2225
XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK;
2326
PMU->MISC0_CLR = REFTOP_LOWPOWER_MASK;
27+
28+
cpp_freertos::CriticalSection::Exit();
2429
}
2530

2631
void SwitchToLowPowerMode()
2732
{
33+
cpp_freertos::CriticalSection::Enter();
34+
2835
/* Enable low power bandgap */
2936
PMU->MISC0_SET = REFTOP_LOWPOWER_MASK;
37+
XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK;
3038

3139
/* Disable regular bandgap */
32-
XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK;
3340
PMU->MISC0_SET = CCM_ANALOG_MISC0_REFTOP_PWD_MASK;
41+
42+
cpp_freertos::CriticalSection::Exit();
3443
}
3544
} // namespace bsp::bandgap

module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
33

44
#include "CpuFreqLPM.hpp"
5-
#include "fsl_dcdc.h"
5+
#include <fsl_dcdc.h>
66

77
namespace bsp
88
{

module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace bsp
99
{
1010
inline constexpr std::uint32_t VDDRun_950_mV = 0x06;
1111
inline constexpr std::uint32_t VDDRun_1150_mV = 0x0E;
12+
inline constexpr std::uint32_t VDDRun_1275_mV = 0x13;
1213

1314
inline constexpr std::uint32_t VDDStandby_925_mV = 0x01;
1415

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
2+
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
3+
4+
#include "DCDC.hpp"
5+
#include "CpuFreqLPM.hpp"
6+
#include <fsl_dcdc.h>
7+
8+
namespace bsp::dcdc
9+
{
10+
void SwitchToOverdriveConfig()
11+
{
12+
/* Switch to CCM mode for improved stability */
13+
DCDC_BootIntoCCM(DCDC);
14+
15+
/* Connect internal DCDC load resistor */
16+
DCDC->REG1 |= DCDC_REG1_REG_RLOAD_SW_MASK;
17+
18+
/* Adjust target voltage to 1.275V */
19+
DCDC_AdjustTargetVoltage(DCDC, VDDRun_1275_mV, VDDStandby_925_mV);
20+
21+
/* Disable FET ODRIVE */
22+
PMU->REG_CORE_CLR = PMU_REG_CORE_FET_ODRIVE_MASK;
23+
}
24+
25+
void SwitchToRegularConfig()
26+
{
27+
/* Adjust target voltage to 1.15V */
28+
DCDC_AdjustTargetVoltage(DCDC, VDDRun_1150_mV, VDDStandby_925_mV);
29+
}
30+
31+
void SwitchToLowPowerConfig()
32+
{
33+
/* Adjust target voltage to nominal 0.95V */
34+
DCDC_AdjustTargetVoltage(DCDC, VDDRun_950_mV, VDDStandby_925_mV);
35+
36+
/* Switch to DCM mode to reduce current consumption */
37+
DCDC_BootIntoDCM(DCDC);
38+
39+
/* Disconnect internal DCDC load resistor */
40+
DCDC->REG1 &= ~DCDC_REG1_REG_RLOAD_SW_MASK;
41+
42+
/* Power down output range comparator */
43+
DCDC->REG0 |= DCDC_REG0_PWD_CMP_OFFSET_MASK;
44+
45+
/* Enable FET ODRIVE */
46+
PMU->REG_CORE_SET = PMU_REG_CORE_FET_ODRIVE_MASK;
47+
}
48+
} // namespace bsp::dcdc
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
2+
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
3+
4+
#pragma once
5+
6+
namespace bsp::dcdc
7+
{
8+
void SwitchToOverdriveConfig();
9+
void SwitchToRegularConfig();
10+
void SwitchToLowPowerConfig();
11+
} // namespace bsp::dcdc

0 commit comments

Comments
 (0)