imxrt10xx/
dcdc.rs

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.

//! DCDC Converter

use kernel::platform::chip::ClockInterface;
use kernel::utilities::registers::interfaces::{ReadWriteable, Readable};
use kernel::utilities::registers::{self, ReadWrite};
use kernel::utilities::StaticRef;

use crate::ccm;

registers::register_structs! {
    /// DCDC
    DcdcRegisters {
        /// DCDC Register 0
        (0x000 => reg0: ReadWrite<u32, REG0::Register>),
        /// DCDC Register 1
        (0x004 => reg1: ReadWrite<u32, REG1::Register>),
        /// DCDC Register 2
        (0x008 => reg2: ReadWrite<u32, REG2::Register>),
        /// DCDC Register 3
        (0x00C => reg3: ReadWrite<u32, REG3::Register>),
        (0x010 => @END),
    }
}

registers::register_bitfields![u32,
REG0 [
    /// power down the zero cross detection function for discontinuous conductor mode
    PWD_ZCD OFFSET(0) NUMBITS(1) [],
    /// Disable automatic clock switch from internal osc to xtal clock.
    DISABLE_AUTO_CLK_SWITCH OFFSET(1) NUMBITS(1) [],
    /// select 24 MHz Crystal clock for DCDC, when dcdc_disable_auto_clk_switch is set.
    SEL_CLK OFFSET(2) NUMBITS(1) [],
    /// Power down internal osc. Only set this bit, when 24 MHz crystal osc is available
    PWD_OSC_INT OFFSET(3) NUMBITS(1) [],
    /// The power down signal of the current detector.
    PWD_CUR_SNS_CMP OFFSET(4) NUMBITS(1) [],
    /// Set the threshold of current detector, if the peak current of the inductor excee
    CUR_SNS_THRSH OFFSET(5) NUMBITS(3) [],
    /// power down overcurrent detection comparator
    PWD_OVERCUR_DET OFFSET(8) NUMBITS(1) [],
    /// The threshold of over current detection in run mode and power save mode: run mod
    OVERCUR_TRIG_ADJ OFFSET(9) NUMBITS(2) [],
    /// set to "1" to power down the low voltage detection comparator
    PWD_CMP_BATT_DET OFFSET(11) NUMBITS(1) [],
    /// adjust value to poslimit_buck register
    ADJ_POSLIMIT_BUCK OFFSET(12) NUMBITS(4) [],
    /// enable the overload detection in power save mode, if current is larger than the
    EN_LP_OVERLOAD_SNS OFFSET(16) NUMBITS(1) [],
    /// power down overvoltage detection comparator
    PWD_HIGH_VOLT_DET OFFSET(17) NUMBITS(1) [],
    /// the threshold of the counting number of charging times during the period that lp
    LP_OVERLOAD_THRSH OFFSET(18) NUMBITS(2) [],
    /// the period of counting the charging times in power save mode 0: eight 32k cycle
    LP_OVERLOAD_FREQ_SEL OFFSET(20) NUMBITS(1) [],
    /// Adjust hysteretic value in low power from 12.5mV to 25mV
    LP_HIGH_HYS OFFSET(21) NUMBITS(1) [],
    /// power down output range comparator
    PWD_CMP_OFFSET OFFSET(26) NUMBITS(1) [],
    /// 1'b1: Disable xtalok detection circuit 1'b0: Enable xtalok detection circuit
    XTALOK_DISABLE OFFSET(27) NUMBITS(1) [],
    /// reset current alert signal
    CURRENT_ALERT_RESET OFFSET(28) NUMBITS(1) [],
    /// set to 1 to switch internal ring osc to xtal 24M
    XTAL_24M_OK OFFSET(29) NUMBITS(1) [],
    /// Status register to indicate DCDC status. 1'b1: DCDC already settled 1'b0: DCDC i
    STS_DC_OK OFFSET(31) NUMBITS(1) []
],
REG1 [
    /// select the feedback point of the internal regulator
    REG_FBK_SEL OFFSET(7) NUMBITS(2) [],
    /// control the load resistor of the internal regulator of DCDC, the load resistor i
    REG_RLOAD_SW OFFSET(9) NUMBITS(1) [],
    /// set the current bias of low power comparator 0x0: 50 nA 0x1: 100 nA 0x2: 200 nA
    LP_CMP_ISRC_SEL OFFSET(12) NUMBITS(2) [],
    /// increase the threshold detection for common mode analog comparator
    LOOPCTRL_HST_THRESH OFFSET(21) NUMBITS(1) [],
    /// Enable hysteresis in switching converter common mode analog comparators
    LOOPCTRL_EN_HYST OFFSET(23) NUMBITS(1) [],
    /// trim bandgap voltage
    VBG_TRIM OFFSET(24) NUMBITS(5) []
],
REG2 [
    /// Ratio of integral control parameter to proportional control parameter in the swi
    LOOPCTRL_DC_C OFFSET(0) NUMBITS(2) [],
    /// Magnitude of proportional control parameter in the switching DC-DC converter con
    LOOPCTRL_DC_R OFFSET(2) NUMBITS(4) [],
    /// Two's complement feed forward step in duty cycle in the switching DC-DC converte
    LOOPCTRL_DC_FF OFFSET(6) NUMBITS(3) [],
    /// Enable analog circuit of DC-DC converter to respond faster under transient load
    LOOPCTRL_EN_RCSCALE OFFSET(9) NUMBITS(3) [],
    /// Increase the threshold detection for RC scale circuit.
    LOOPCTRL_RCSCALE_THRSH OFFSET(12) NUMBITS(1) [],
    /// Invert the sign of the hysteresis in DC-DC analog comparators.
    LOOPCTRL_HYST_SIGN OFFSET(13) NUMBITS(1) [],
    /// Set to "0" : stop charging if the duty cycle is lower than what set by dcdc_negl
    DISABLE_PULSE_SKIP OFFSET(27) NUMBITS(1) [],
    /// Set high to improve the transition from heavy load to light load
    DCM_SET_CTRL OFFSET(28) NUMBITS(1) []
],
REG3 [
    /// Target value of VDD_SOC, 25 mV each step 0x0: 0.8V 0xE: 1.15V 0x1F:1.575V
    TRG OFFSET(0) NUMBITS(5) [],
    /// Target value of standby (low power) mode 0x0: 0
    TARGET_LP OFFSET(8) NUMBITS(3) [],
    /// Set DCDC clock to half freqeuncy for continuous mode
    MINPWR_DC_HALFCLK OFFSET(24) NUMBITS(1) [],
    /// Ajust delay to reduce ground noise
    MISC_DELAY_TIMING OFFSET(27) NUMBITS(1) [],
    /// Reserved
    MISC_DISABLEFET_LOGIC OFFSET(28) NUMBITS(1) [],
    /// Disable stepping for the output VDD_SOC of DCDC
    DISABLE_STEP OFFSET(30) NUMBITS(1) []
]
];
const DCDC_BASE: StaticRef<DcdcRegisters> =
    unsafe { StaticRef::new(0x40080000 as *const DcdcRegisters) };

/// DCDC converter
pub struct Dcdc<'a> {
    registers: StaticRef<DcdcRegisters>,
    clock_gate: ccm::PeripheralClock<'a>,
}

impl<'a> Dcdc<'a> {
    /// Construct a new DCDC peripheral that can control its own clock
    pub const fn new(ccm: &'a ccm::Ccm) -> Self {
        Self {
            registers: DCDC_BASE,
            clock_gate: ccm::PeripheralClock::ccgr6(ccm, ccm::HCLK6::DCDC),
        }
    }
    /// Returns the interface that controls the DCDC clock
    pub fn clock(&self) -> &(impl ClockInterface + '_) {
        &self.clock_gate
    }
    /// Set the target value of `VDD_SOC`, in milliamps
    ///
    /// Values are clamped between 800mV and 1575mV, with 25mV step
    /// sizes.
    pub fn set_target_vdd_soc(&self, millivolts: u32) {
        let millivolts = millivolts.min(1575).max(800);
        let trg = (millivolts - 800) / 25;
        self.registers.reg3.modify(REG3::TRG.val(trg));
        while !self.registers.reg0.is_set(REG0::STS_DC_OK) {}
    }
}