msp432/pcm.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//! Power Control Manager (PCM)
6
7use kernel::utilities::registers::interfaces::{Readable, Writeable};
8use kernel::utilities::registers::{
9 register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly,
10};
11use kernel::utilities::StaticRef;
12
13const PCM_BASE: StaticRef<PcmRegisters> =
14 unsafe { StaticRef::new(0x4001_0000 as *const PcmRegisters) };
15
16const PCMKEY: u32 = 0x695A; // for unlocking PCMCTL0 and PCMCTL1
17
18register_structs! {
19 /// PCM
20 PcmRegisters {
21 /// Control 0 Register
22 (0x000 => ctl0: ReadWrite<u32, PCMCTL0::Register>),
23 /// Control 1 Register
24 (0x004 => ctl1: ReadWrite<u32, PCMCTL1::Register>),
25 /// Interrupt Enable Register
26 (0x008 => ie: ReadWrite<u32, PCMIE::Register>),
27 /// Interrupt Flag Register
28 (0x00C => ifg: ReadOnly<u32, PCMIFG::Register>),
29 /// Clear Interrupt Flag Register
30 (0x010 => clrifg: WriteOnly<u32, PCMCLRIFG::Register>),
31 (0x014 => @END),
32 }
33}
34
35register_bitfields![u32,
36 PCMCTL0 [
37 /// Active Mode Request
38 AMR OFFSET(0) NUMBITS(4) [
39 /// LDO based Active Mode at Core voltage setting 0.
40 LDOBasedActiveModeAtCoreVoltageSetting0 = 0,
41 /// LDO based Active Mode at Core voltage setting 1.
42 LDOBasedActiveModeAtCoreVoltageSetting1 = 1,
43 /// DC-DC based Active Mode at Core voltage setting 0.
44 DCDCBasedActiveModeAtCoreVoltageSetting0 = 4,
45 /// DC-DC based Active Mode at Core voltage setting 1.
46 DCDCBasedActiveModeAtCoreVoltageSetting1 = 5,
47 /// Low-Frequency Active Mode at Core voltage setting 0.
48 LowFrequencyActiveModeAtCoreVoltageSetting0 = 8,
49 /// Low-Frequency Active Mode at Core voltage setting 1.
50 LowFrequencyActiveModeAtCoreVoltageSetting1 = 9
51 ],
52 /// Low Power Mode Request
53 LPMR OFFSET(4) NUMBITS(4) [
54 /// LPM3. Core voltage setting is similar to the mode from which LPM3 is entered.
55 LPM3CoreVoltageSettingIsSimilarToTheModeFromWhichLPM3IsEntered = 0,
56 /// LPM3.5. Core voltage setting 0.
57 LPM35CoreVoltageSetting0 = 10,
58 /// LPM4.5
59 LPM45 = 12
60 ],
61 /// Current Power Mode
62 CPM OFFSET(8) NUMBITS(6) [
63 /// LDO based Active Mode at Core voltage setting 0.
64 LDOBasedActiveModeAtCoreVoltageSetting0 = 0,
65 /// LDO based Active Mode at Core voltage setting 1.
66 LDOBasedActiveModeAtCoreVoltageSetting1 = 1,
67 /// DC-DC based Active Mode at Core voltage setting 0.
68 DCDCBasedActiveModeAtCoreVoltageSetting0 = 4,
69 /// DC-DC based Active Mode at Core voltage setting 1.
70 DCDCBasedActiveModeAtCoreVoltageSetting1 = 5,
71 /// Low-Frequency Active Mode at Core voltage setting 0.
72 LowFrequencyActiveModeAtCoreVoltageSetting0 = 8,
73 /// Low-Frequency Active Mode at Core voltage setting 1.
74 LowFrequencyActiveModeAtCoreVoltageSetting1 = 9,
75 /// LDO based LPM0 at Core voltage setting 0.
76 LDOBasedLPM0AtCoreVoltageSetting0 = 16,
77 /// LDO based LPM0 at Core voltage setting 1.
78 LDOBasedLPM0AtCoreVoltageSetting1 = 17,
79 /// DC-DC based LPM0 at Core voltage setting 0.
80 DCDCBasedLPM0AtCoreVoltageSetting0 = 20,
81 /// DC-DC based LPM0 at Core voltage setting 1.
82 DCDCBasedLPM0AtCoreVoltageSetting1 = 21,
83 /// Low-Frequency LPM0 at Core voltage setting 0.
84 LowFrequencyLPM0AtCoreVoltageSetting0 = 24,
85 /// Low-Frequency LPM0 at Core voltage setting 1.
86 LowFrequencyLPM0AtCoreVoltageSetting1 = 25,
87 /// LPM3
88 LPM3 = 32
89 ],
90 /// PCM key
91 PCMKEY OFFSET(16) NUMBITS(16) []
92 ],
93 PCMCTL1 [
94 /// Lock LPM5
95 LOCKLPM5 OFFSET(0) NUMBITS(1) [
96 /// LPMx.5 configuration defaults to reset condition
97 LPMx5ConfigurationDefaultsToResetCondition = 0,
98 /// LPMx.5 configuration remains locked during LPMx.5 entry and exit
99 LPMx5ConfigurationRemainsLockedDuringLPMx5EntryAndExit = 1
100 ],
101 /// Lock Backup
102 LOCKBKUP OFFSET(1) NUMBITS(1) [
103 /// Backup domain configuration defaults to reset condition
104 BackupDomainConfigurationDefaultsToResetCondition = 0,
105 /// Backup domain configuration remains locked during LPM3.5 entry and exit
106 BackupDomainConfigurationRemainsLockedDuringLPM35EntryAndExit = 1
107 ],
108 /// Force LPM entry
109 FORCE_LPM_ENTRY OFFSET(2) NUMBITS(1) [
110 /// PCM aborts LPM3/LPMx.5 transition if the active clock configuration does not mee
111 FORCE_LPM_ENTRY_0 = 0,
112 /// PCM enters LPM3/LPMx.5 after shuting off the clocks forcefully. Application need
113 FORCE_LPM_ENTRY_1 = 1
114 ],
115 /// Power mode request busy flag
116 PMR_BUSY OFFSET(8) NUMBITS(1) [],
117 /// PCM key
118 PCMKEY OFFSET(16) NUMBITS(16) []
119 ],
120 PCMIE [
121 /// LPM invalid transition interrupt enable
122 LPM_INVALID_TR_IE OFFSET(0) NUMBITS(1) [
123 /// Disabled
124 Disabled = 0,
125 /// Enabled
126 Enabled = 1
127 ],
128 /// LPM invalid clock interrupt enable
129 LPM_INVALID_CLK_IE OFFSET(1) NUMBITS(1) [
130 /// Disabled
131 Disabled = 0,
132 /// Enabled
133 Enabled = 1
134 ],
135 /// Active mode invalid transition interrupt enable
136 AM_INVALID_TR_IE OFFSET(2) NUMBITS(1) [
137 /// Disabled
138 Disabled = 0,
139 /// Enabled
140 Enabled = 1
141 ],
142 /// DC-DC error interrupt enable
143 DCDC_ERROR_IE OFFSET(6) NUMBITS(1) [
144 /// Disabled
145 Disabled = 0,
146 /// Enabled
147 Enabled = 1
148 ]
149 ],
150 PCMIFG [
151 /// LPM invalid transition flag
152 LPM_INVALID_TR_IFG OFFSET(0) NUMBITS(1) [],
153 /// LPM invalid clock flag
154 LPM_INVALID_CLK_IFG OFFSET(1) NUMBITS(1) [],
155 /// Active mode invalid transition flag
156 AM_INVALID_TR_IFG OFFSET(2) NUMBITS(1) [],
157 /// DC-DC error flag
158 DCDC_ERROR_IFG OFFSET(6) NUMBITS(1) []
159 ],
160 PCMCLRIFG [
161 /// Clear LPM invalid transition flag
162 CLR_LPM_INVALID_TR_IFG OFFSET(0) NUMBITS(1) [],
163 /// Clear LPM invalid clock flag
164 CLR_LPM_INVALID_CLK_IFG OFFSET(1) NUMBITS(1) [],
165 /// Clear active mode invalid transition flag
166 CLR_AM_INVALID_TR_IFG OFFSET(2) NUMBITS(1) [],
167 /// Clear DC-DC error flag
168 CLR_DCDC_ERROR_IFG OFFSET(6) NUMBITS(1) []
169 ]
170];
171
172pub struct Pcm {
173 registers: StaticRef<PcmRegisters>,
174}
175
176impl Pcm {
177 pub const fn new() -> Pcm {
178 Pcm {
179 registers: PCM_BASE,
180 }
181 }
182 // currently not sure about the interface, so just implement a simple
183 // method for activating AM_LDO_VCORE1 to provide enough power for 48MHz
184 pub fn set_high_power(&self) {
185 while self.registers.ctl1.is_set(PCMCTL1::PMR_BUSY) {}
186 self.registers.ctl0.write(
187 PCMCTL0::PCMKEY.val(PCMKEY) + PCMCTL0::AMR::DCDCBasedActiveModeAtCoreVoltageSetting1,
188 );
189 while self.registers.ctl1.is_set(PCMCTL1::PMR_BUSY) {}
190 }
191}