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}