~aleteoryx/muditaos

ref: 321f56e7744bc9f2cb487f1612cf77eb1ca6e3c7 muditaos/module-bsp/board/rt1051/bsp/lpm/Oscillator.cpp -rw-r--r-- 3.5 KiB
321f56e7 — Lefucjusz [MOS-1032] Fix misleading 'Save' button behavior when setting time 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "Oscillator.hpp"
#include "ClockState.hpp"
#include <fsl_dcdc.h>
#include <fsl_common.h>
#include <cstdint>

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()
    {
        if (!IsExternalOscillatorEnabled()) {
            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.
            CLOCK_SwitchOsc(kCLOCK_XtalOsc);
            /// Wait CCM operation finishes
            while (CCM->CDHIPR != 0) {}
            /// Set Oscillator ready counter value.
            CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(bsp::OscillatorReadyCounterValue);
        }
    }

    void DisableExternalOscillator()
    {
        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;
            }

            /// 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
            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_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);

            /// 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) {}
        }
    }

    [[nodiscard]] bool IsExternalOscillatorEnabled()
    {
        return !(XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_OSC_SEL_MASK);
    }
}; // namespace bsp