imxrt10xx/
dcdc.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! DCDC Converter
6
7use kernel::platform::chip::ClockInterface;
8use kernel::utilities::registers::interfaces::{ReadWriteable, Readable};
9use kernel::utilities::registers::{self, ReadWrite};
10use kernel::utilities::StaticRef;
11
12use crate::ccm;
13
14registers::register_structs! {
15    /// DCDC
16    DcdcRegisters {
17        /// DCDC Register 0
18        (0x000 => reg0: ReadWrite<u32, REG0::Register>),
19        /// DCDC Register 1
20        (0x004 => reg1: ReadWrite<u32, REG1::Register>),
21        /// DCDC Register 2
22        (0x008 => reg2: ReadWrite<u32, REG2::Register>),
23        /// DCDC Register 3
24        (0x00C => reg3: ReadWrite<u32, REG3::Register>),
25        (0x010 => @END),
26    }
27}
28
29registers::register_bitfields![u32,
30REG0 [
31    /// power down the zero cross detection function for discontinuous conductor mode
32    PWD_ZCD OFFSET(0) NUMBITS(1) [],
33    /// Disable automatic clock switch from internal osc to xtal clock.
34    DISABLE_AUTO_CLK_SWITCH OFFSET(1) NUMBITS(1) [],
35    /// select 24 MHz Crystal clock for DCDC, when dcdc_disable_auto_clk_switch is set.
36    SEL_CLK OFFSET(2) NUMBITS(1) [],
37    /// Power down internal osc. Only set this bit, when 24 MHz crystal osc is available
38    PWD_OSC_INT OFFSET(3) NUMBITS(1) [],
39    /// The power down signal of the current detector.
40    PWD_CUR_SNS_CMP OFFSET(4) NUMBITS(1) [],
41    /// Set the threshold of current detector, if the peak current of the inductor excee
42    CUR_SNS_THRSH OFFSET(5) NUMBITS(3) [],
43    /// power down overcurrent detection comparator
44    PWD_OVERCUR_DET OFFSET(8) NUMBITS(1) [],
45    /// The threshold of over current detection in run mode and power save mode: run mod
46    OVERCUR_TRIG_ADJ OFFSET(9) NUMBITS(2) [],
47    /// set to "1" to power down the low voltage detection comparator
48    PWD_CMP_BATT_DET OFFSET(11) NUMBITS(1) [],
49    /// adjust value to poslimit_buck register
50    ADJ_POSLIMIT_BUCK OFFSET(12) NUMBITS(4) [],
51    /// enable the overload detection in power save mode, if current is larger than the
52    EN_LP_OVERLOAD_SNS OFFSET(16) NUMBITS(1) [],
53    /// power down overvoltage detection comparator
54    PWD_HIGH_VOLT_DET OFFSET(17) NUMBITS(1) [],
55    /// the threshold of the counting number of charging times during the period that lp
56    LP_OVERLOAD_THRSH OFFSET(18) NUMBITS(2) [],
57    /// the period of counting the charging times in power save mode 0: eight 32k cycle
58    LP_OVERLOAD_FREQ_SEL OFFSET(20) NUMBITS(1) [],
59    /// Adjust hysteretic value in low power from 12.5mV to 25mV
60    LP_HIGH_HYS OFFSET(21) NUMBITS(1) [],
61    /// power down output range comparator
62    PWD_CMP_OFFSET OFFSET(26) NUMBITS(1) [],
63    /// 1'b1: Disable xtalok detection circuit 1'b0: Enable xtalok detection circuit
64    XTALOK_DISABLE OFFSET(27) NUMBITS(1) [],
65    /// reset current alert signal
66    CURRENT_ALERT_RESET OFFSET(28) NUMBITS(1) [],
67    /// set to 1 to switch internal ring osc to xtal 24M
68    XTAL_24M_OK OFFSET(29) NUMBITS(1) [],
69    /// Status register to indicate DCDC status. 1'b1: DCDC already settled 1'b0: DCDC i
70    STS_DC_OK OFFSET(31) NUMBITS(1) []
71],
72REG1 [
73    /// select the feedback point of the internal regulator
74    REG_FBK_SEL OFFSET(7) NUMBITS(2) [],
75    /// control the load resistor of the internal regulator of DCDC, the load resistor i
76    REG_RLOAD_SW OFFSET(9) NUMBITS(1) [],
77    /// set the current bias of low power comparator 0x0: 50 nA 0x1: 100 nA 0x2: 200 nA
78    LP_CMP_ISRC_SEL OFFSET(12) NUMBITS(2) [],
79    /// increase the threshold detection for common mode analog comparator
80    LOOPCTRL_HST_THRESH OFFSET(21) NUMBITS(1) [],
81    /// Enable hysteresis in switching converter common mode analog comparators
82    LOOPCTRL_EN_HYST OFFSET(23) NUMBITS(1) [],
83    /// trim bandgap voltage
84    VBG_TRIM OFFSET(24) NUMBITS(5) []
85],
86REG2 [
87    /// Ratio of integral control parameter to proportional control parameter in the swi
88    LOOPCTRL_DC_C OFFSET(0) NUMBITS(2) [],
89    /// Magnitude of proportional control parameter in the switching DC-DC converter con
90    LOOPCTRL_DC_R OFFSET(2) NUMBITS(4) [],
91    /// Two's complement feed forward step in duty cycle in the switching DC-DC converte
92    LOOPCTRL_DC_FF OFFSET(6) NUMBITS(3) [],
93    /// Enable analog circuit of DC-DC converter to respond faster under transient load
94    LOOPCTRL_EN_RCSCALE OFFSET(9) NUMBITS(3) [],
95    /// Increase the threshold detection for RC scale circuit.
96    LOOPCTRL_RCSCALE_THRSH OFFSET(12) NUMBITS(1) [],
97    /// Invert the sign of the hysteresis in DC-DC analog comparators.
98    LOOPCTRL_HYST_SIGN OFFSET(13) NUMBITS(1) [],
99    /// Set to "0" : stop charging if the duty cycle is lower than what set by dcdc_negl
100    DISABLE_PULSE_SKIP OFFSET(27) NUMBITS(1) [],
101    /// Set high to improve the transition from heavy load to light load
102    DCM_SET_CTRL OFFSET(28) NUMBITS(1) []
103],
104REG3 [
105    /// Target value of VDD_SOC, 25 mV each step 0x0: 0.8V 0xE: 1.15V 0x1F:1.575V
106    TRG OFFSET(0) NUMBITS(5) [],
107    /// Target value of standby (low power) mode 0x0: 0
108    TARGET_LP OFFSET(8) NUMBITS(3) [],
109    /// Set DCDC clock to half freqeuncy for continuous mode
110    MINPWR_DC_HALFCLK OFFSET(24) NUMBITS(1) [],
111    /// Ajust delay to reduce ground noise
112    MISC_DELAY_TIMING OFFSET(27) NUMBITS(1) [],
113    /// Reserved
114    MISC_DISABLEFET_LOGIC OFFSET(28) NUMBITS(1) [],
115    /// Disable stepping for the output VDD_SOC of DCDC
116    DISABLE_STEP OFFSET(30) NUMBITS(1) []
117]
118];
119const DCDC_BASE: StaticRef<DcdcRegisters> =
120    unsafe { StaticRef::new(0x40080000 as *const DcdcRegisters) };
121
122/// DCDC converter
123pub struct Dcdc<'a> {
124    registers: StaticRef<DcdcRegisters>,
125    clock_gate: ccm::PeripheralClock<'a>,
126}
127
128impl<'a> Dcdc<'a> {
129    /// Construct a new DCDC peripheral that can control its own clock
130    pub const fn new(ccm: &'a ccm::Ccm) -> Self {
131        Self {
132            registers: DCDC_BASE,
133            clock_gate: ccm::PeripheralClock::ccgr6(ccm, ccm::HCLK6::DCDC),
134        }
135    }
136    /// Returns the interface that controls the DCDC clock
137    pub fn clock(&self) -> &(impl ClockInterface + '_) {
138        &self.clock_gate
139    }
140    /// Set the target value of `VDD_SOC`, in milliamps
141    ///
142    /// Values are clamped between 800mV and 1575mV, with 25mV step
143    /// sizes.
144    pub fn set_target_vdd_soc(&self, millivolts: u32) {
145        let millivolts = millivolts.min(1575).max(800);
146        let trg = (millivolts - 800) / 25;
147        self.registers.reg3.modify(REG3::TRG.val(trg));
148        while !self.registers.reg0.is_set(REG0::STS_DC_OK) {}
149    }
150}