~aleteoryx/muditaos

e1d3862febaf5467aabfe237fd53fecff11128c2 — Lefucjusz 2 years ago ff18f17
[BH-1673] Fixes for Harmony random resets

Next part of Harmony random resets fixes:
* added RC OSC startup delay as in newest lpm.c;
* changed order of clock source, oscillator and
LDO switching;
* removed connecting internal DCDC load resistor,
as it is only required to speed up converter
startup after it was turned off completely;
* changed DCDC operation mode to continuous
conduction;
* set low VDD_SOC_IN voltage back to 950mV as
suggested in RM.
* added switching DCDC converter mode to
discontinuous conduction for two lowest CPU
clock frequencies, as using CCM mode resulted
in very high current consumption that would
shorten Harmony's life on battery
significantly.
M module-bsp/board/linux/lpm/LinuxLPM.cpp => module-bsp/board/linux/lpm/LinuxLPM.cpp +1 -10
@@ 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

//


@@ 25,9 25,6 @@ namespace bsp
        currentFrequency = freq;
    }

    void LinuxLPM::SetHighestCoreVoltage()
    {}

    uint32_t LinuxLPM::GetCpuFrequency() const noexcept
    {
        return 0;


@@ 42,12 39,6 @@ namespace bsp
    void LinuxLPM::DisableDcdcPowerSaveMode()
    {}

    void LinuxLPM::DisconnectInternalLoadResistor()
    {}

    void LinuxLPM::ConnectInternalLoadResistor()
    {}

    void LinuxLPM::SwitchToRegularModeLDO()
    {}


M module-bsp/board/linux/lpm/LinuxLPM.h => module-bsp/board/linux/lpm/LinuxLPM.h +1 -5
@@ 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

#ifndef PUREPHONE_LINUXLPM_H


@@ 15,16 15,12 @@ namespace bsp
        int32_t PowerOff() override final;
        int32_t Reboot(RebootType reason) override final;
        void SetCpuFrequency(CpuFrequencyMHz freq) final;
        void SetHighestCoreVoltage() final;
        [[nodiscard]] uint32_t GetCpuFrequency() const noexcept final;
        void SwitchOscillatorSource(OscillatorSource source) final;

        void EnableDcdcPowerSaveMode() final;
        void DisableDcdcPowerSaveMode() final;

        void DisconnectInternalLoadResistor() final;
        void ConnectInternalLoadResistor() final;

        void SwitchToRegularModeLDO() final;
        void SwitchToLowPowerModeLDO() final;
    };

M module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.cpp => module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.cpp +3 -8
@@ 13,16 13,16 @@ namespace bsp
    {
        switch (freq) {
        case CpuClock::CpuClock_Osc_4_Mhz:
            CLOCK_SetDiv(kCLOCK_AhbDiv, AhbDiv6);
            CLOCK_SetMux(kCLOCK_PeriphMux, PeriphMuxSourceOsc_24MHz);
            CLOCK_SetDiv(kCLOCK_AhbDiv, AhbDiv6);
            break;
        case CpuClock::CpuClock_Osc_12_Mhz:
            CLOCK_SetDiv(kCLOCK_AhbDiv, AhbDiv2);
            CLOCK_SetMux(kCLOCK_PeriphMux, PeriphMuxSourceOsc_24MHz);
            CLOCK_SetDiv(kCLOCK_AhbDiv, AhbDiv2);
            break;
        case CpuClock::CpuClock_Osc_24_Mhz:
            CLOCK_SetDiv(kCLOCK_AhbDiv, AhbDiv1);
            CLOCK_SetMux(kCLOCK_PeriphMux, PeriphMuxSourceOsc_24MHz);
            CLOCK_SetDiv(kCLOCK_AhbDiv, AhbDiv1);
            break;
        case CpuClock::CpuClock_Pll2_66_Mhz:
            CLOCK_SetDiv(kCLOCK_AhbDiv, AhbDiv8);


@@ 45,9 45,4 @@ namespace bsp
        /* Set SystemCoreClock variable. */
        SystemCoreClockUpdate();
    }

    void CpuFreqLPM::SetHighestCoreVoltage()
    {
        DCDC_AdjustTargetVoltage(DCDC, VDDRun_1150_mV, VDDStandby_925_mV);
    }
} // namespace bsp

M module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.hpp => module-bsp/board/rt1051/bsp/lpm/CpuFreqLPM.hpp +0 -7
@@ 8,13 8,7 @@
namespace bsp
{
    inline constexpr std::uint32_t VDDRun_950_mV  = 0x06;
    inline constexpr std::uint32_t VDDRun_975_mV  = 0x07;
    inline constexpr std::uint32_t VDDRun_1050_mV = 0x0A;
    inline constexpr std::uint32_t VDDRun_1075_mV = 0x0B;
    inline constexpr std::uint32_t VDDRun_1100_mV = 0x0C;
    inline constexpr std::uint32_t VDDRun_1125_mV = 0x0D;
    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;



@@ 53,6 47,5 @@ namespace bsp

        CpuFreqLPM();
        void SetCpuFrequency(CpuClock freq);
        void SetHighestCoreVoltage();
    };
} // namespace bsp

M module-bsp/board/rt1051/bsp/lpm/Oscillator.cpp => module-bsp/board/rt1051/bsp/lpm/Oscillator.cpp +11 -6
@@ 16,13 16,15 @@ namespace bsp
    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()
    {
        if (!IsExternalOscillatorEnabled()) {
            CLOCK_InitExternalClk(0);
            /// Wait at least 200us for XTAL stable
            const uint32_t cpuFreqency = CLOCK_GetCpuClkFreq();
            SDK_DelayAtLeastUs(200, cpuFreqency);
            CLOCK_InitExternalClk(false);
            /// Wait for XTAL to become stable
            SDK_DelayAtLeastUs(XtalStabilizationTimeUs, CLOCK_GetCpuClkFreq());
            /// Switch DCDC to use DCDC external OSC
            DCDC_SetClockSource(DCDC, kDCDC_ClockExternalOsc);
            /// Switch clock source to external OSC.


@@ 43,9 45,9 @@ namespace bsp
                return;
            }

            // Enable RC OSC. It needs at least 4ms to be stable, so self tuning need to be enabled.
            /// 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;
            // Configure self-tuning for RC OSC
            /// 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) |


@@ 53,10 55,13 @@ namespace bsp
            XTALOSC24M->OSC_CONFIG1 = XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR(bsp::CurrentTuningValueInUseForConfig1) |
                                      XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG(bsp::TargetCountUsedToTune);

            /// Wait for RC OSC to become stable
            SDK_DelayAtLeastUs(RcOscStabilizationTimeUs, CLOCK_GetCpuClkFreq());
            /// 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) {}

M module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.cpp => module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.cpp +14 -36
@@ 5,6 5,7 @@

#include <log/log.hpp>
#include <fsl_clock.h>
#include <fsl_dcdc.h>
#include <bsp/bsp.hpp>
#include "Oscillator.hpp"
#include "critical.hpp"


@@ 13,7 14,6 @@

namespace bsp
{

    using namespace drivers;

    RT1051LPMCommon::RT1051LPMCommon()


@@ 65,22 65,16 @@ namespace bsp
    CpuFrequencyMHz RT1051LPMCommon::onChangeUp(CpuFrequencyMHz freq, bsp::CpuFrequencyMHz newFrequency)
    {
        if ((freq <= CpuFrequencyMHz::Level_1) && (newFrequency > CpuFrequencyMHz::Level_1)) {
            // connect internal load resistor
            ConnectInternalLoadResistor();
            // Switch DCDC to full throttle during oscillator switch
            SetHighestCoreVoltage();
            // Enable regular 2P5 and 1P1 LDO and Turn off weak 2P5 and 1P1 LDO
            SwitchToRegularModeLDO();
            // switch oscillator source
            SwitchOscillatorSource(LowPowerMode::OscillatorSource::External);
            // then switch external RAM clock source
            // Switch DCDC to CCM mode to improve stability
            DCDC_BootIntoCCM(DCDC);
            // Switch external RAM clock source to PLL2
            if (driverSEMC) {
                driverSEMC->SwitchToPLL2ClockSource();
            }
            // Add intermediate step in frequency
            if (newFrequency > CpuFrequencyMHz::Level_4) {
                return CpuFrequencyMHz::Level_4;
            }
            // 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;
    }


@@ 88,17 82,16 @@ namespace bsp
    void RT1051LPMCommon::onChangeDown(CpuFrequencyMHz newFrequency)
    {
        if (newFrequency <= bsp::CpuFrequencyMHz::Level_1) {
            // Enable weak 2P5 and 1P1 LDO and Turn off regular 2P5 and 1P1 LDO
            SwitchToLowPowerModeLDO();
            // then switch osc source
            // Switch to internal RC oscillator
            SwitchOscillatorSource(bsp::LowPowerMode::OscillatorSource::Internal);
            // and switch external RAM clock source
            // Enable weak 2P5 and 1P1 LDO, turn off regular 2P5 and 1P1 LDO
            SwitchToLowPowerModeLDO();
            // Switch external RAM clock source to OSC
            if (driverSEMC) {
                driverSEMC->SwitchToPeripheralClockSource();
            }

            // disconnect internal load resistor
            DisconnectInternalLoadResistor();
            // Switch DCDC to DCM mode to reduce current consumption
            DCDC_BootIntoDCM(DCDC);
        }
    }



@@ 142,11 135,6 @@ namespace bsp
        currentFrequency = freq;
    }

    void RT1051LPMCommon::SetHighestCoreVoltage()
    {
        CpuFreq->SetHighestCoreVoltage();
    }

    uint32_t RT1051LPMCommon::GetCpuFrequency() const noexcept
    {
        return CLOCK_GetCpuClkFreq();


@@ 166,16 154,6 @@ namespace bsp
        }
    }

    void RT1051LPMCommon::DisconnectInternalLoadResistor()
    {
        DCDC->REG1 &= ~DCDC_REG1_REG_RLOAD_SW_MASK;
    }

    void RT1051LPMCommon::ConnectInternalLoadResistor()
    {
        DCDC->REG1 |= DCDC_REG1_REG_RLOAD_SW_MASK;
    }

    void RT1051LPMCommon::RegularLDOMode()
    {
        // Enable regular 2P5 and 1P1 LDO

M module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.hpp => module-bsp/board/rt1051/bsp/lpm/RT1051LPMCommon.hpp +0 -4
@@ 16,13 16,9 @@ namespace bsp
        int32_t PowerOff() final;
        int32_t Reboot(RebootType reason) final;
        void SetCpuFrequency(CpuFrequencyMHz freq) final;
        void SetHighestCoreVoltage() final;
        [[nodiscard]] uint32_t GetCpuFrequency() const noexcept final;
        void SwitchOscillatorSource(OscillatorSource source) final;

        void DisconnectInternalLoadResistor() final;
        void ConnectInternalLoadResistor() final;

        void RegularLDOMode();
        void LowPowerLDOMode();


M module-bsp/board/rt1051/common/board.cpp => module-bsp/board/rt1051/common/board.cpp +5 -2
@@ 179,8 179,11 @@ namespace bsp
        //        SNVS->LPGPR[0] = rebootCode::rebootFailedToBoot;
        // TODO: Here we can implement boot-time fail detection

        // Set internal DCDC to DCM mode. Switching between DCM and CCM mode will be done automatically.
        DCDC_BootIntoDCM(DCDC);
        // 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();

M module-bsp/board/rt1051/drivers/RT1051DriverPLL2.cpp => module-bsp/board/rt1051/drivers/RT1051DriverPLL2.cpp +3 -3
@@ 16,7 16,7 @@ namespace drivers
    RT1051DriverPLL2::RT1051DriverPLL2() noexcept
    {
        if (!IsPLL2Enabled()) {
            // Set VDD_SOC_IN required to safely start PLL2
            // Set VDD_SOC_IN to 1.15V required to safely start PLL2
            DCDC_AdjustTargetVoltage(DCDC, bsp::VDDRun_1150_mV, bsp::VDDStandby_925_mV);
            // Turn on regular band gap and wait for stable
            CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_REFTOP_PWD_MASK;


@@ 44,8 44,8 @@ namespace drivers
            XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK;
            PMU->MISC0_SET              = CCM_ANALOG_MISC0_REFTOP_PWD_MASK;

            // After turning off PLL2 and with CPU @4MHZ VDD_SOC_IN can be set to 950mV, 975mV to be safe
            DCDC_AdjustTargetVoltage(DCDC, bsp::VDDRun_975_mV, bsp::VDDStandby_925_mV);
            // 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);
        }
    }


M module-bsp/bsp/lpm/bsp_lpm.hpp => module-bsp/bsp/lpm/bsp_lpm.hpp +0 -4
@@ 42,7 42,6 @@ namespace bsp
        virtual int32_t Reboot(RebootType reason) = 0;

        virtual void SetCpuFrequency(CpuFrequencyMHz freq) = 0;
        virtual void SetHighestCoreVoltage()               = 0;
        [[nodiscard]] CpuFrequencyMHz GetCurrentFrequencyLevel() const noexcept;
        [[nodiscard]] virtual uint32_t GetCpuFrequency() const noexcept = 0;



@@ 51,9 50,6 @@ namespace bsp
        virtual void EnableDcdcPowerSaveMode()  = 0;
        virtual void DisableDcdcPowerSaveMode() = 0;

        virtual void DisconnectInternalLoadResistor() = 0;
        virtual void ConnectInternalLoadResistor()    = 0;

        virtual void SwitchToRegularModeLDO()  = 0;
        virtual void SwitchToLowPowerModeLDO() = 0;