1use crate::ficr;
11use enum_primitive::cast::FromPrimitive;
12use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
13use kernel::utilities::registers::{register_bitfields, ReadWrite};
14use kernel::utilities::StaticRef;
15
16use crate::gpio::Pin;
17
18const UICR_BASE: StaticRef<UicrRegisters> =
19 unsafe { StaticRef::new(0x10001200 as *const UicrRegisters) };
20
21#[repr(C)]
22struct UicrRegisters {
23 pselreset0: ReadWrite<u32, Pselreset::Register>,
26 pselreset1: ReadWrite<u32, Pselreset::Register>,
29 approtect: ReadWrite<u32, ApProtect::Register>,
32 nfcpins: ReadWrite<u32, NfcPins::Register>,
35 _reserved1: [u32; 60],
36 extsupply: ReadWrite<u32, ExtSupply::Register>,
39 regout0: ReadWrite<u32, RegOut::Register>,
42}
43
44register_bitfields! [u32,
45 Pselreset [
47 PIN OFFSET(0) NUMBITS(5) [],
49 PORT OFFSET(5) NUMBITS(1) [],
51 CONNECTION OFFSET(31) NUMBITS(1) [
53 DISCONNECTED = 1,
54 CONNECTED = 0
55 ]
56 ],
57 ApProtect [
59 PALL OFFSET(0) NUMBITS(8) [
61 ENABLED = 0x00,
63 HWDISABLE = 0x5a,
65 DISABLED = 0xff
67 ]
68 ],
69 NfcPins [
71 PROTECT OFFSET(0) NUMBITS(1) [
73 DISABLED = 0,
75 NFC = 1
78 ]
79 ],
80 ExtSupply [
82 EXTSUPPLY OFFSET(0) NUMBITS(1) [
84 DISABLED = 0,
86 ENABLED = 1
88 ]
89 ],
90 RegOut [
92 VOUT OFFSET(0) NUMBITS(3) [
94 V1_8 = 0,
95 V2_1 = 1,
96 V2_4 = 2,
97 V2_7 = 3,
98 V3_0 = 4,
99 V3_3 = 5,
100 DEFAULT = 7
101 ]
102 ]
103];
104
105pub struct Uicr {
106 registers: StaticRef<UicrRegisters>,
107}
108
109#[derive(Copy, Clone, PartialEq)]
110pub enum Regulator0Output {
117 V1_8 = 0,
118 V2_1 = 1,
119 V2_4 = 2,
120 V2_7 = 3,
121 V3_0 = 4,
122 V3_3 = 5,
123 DEFAULT = 7,
124}
125
126impl From<u32> for Regulator0Output {
127 fn from(val: u32) -> Self {
128 match val & 7 {
129 0 => Regulator0Output::V1_8,
130 1 => Regulator0Output::V2_1,
131 2 => Regulator0Output::V2_4,
132 3 => Regulator0Output::V2_7,
133 4 => Regulator0Output::V3_0,
134 5 => Regulator0Output::V3_3,
135 7 => Regulator0Output::DEFAULT,
136 _ => Regulator0Output::DEFAULT, }
138 }
139}
140
141impl Uicr {
142 pub const fn new() -> Uicr {
143 Uicr {
144 registers: UICR_BASE,
145 }
146 }
147
148 pub fn set_psel0_reset_pin(&self, pin: Pin) {
149 self.registers.pselreset0.set(pin as u32);
150 }
151
152 pub fn get_psel0_reset_pin(&self) -> Option<Pin> {
153 Pin::from_u32(self.registers.pselreset0.get())
154 }
155
156 pub fn set_psel1_reset_pin(&self, pin: Pin) {
157 self.registers.pselreset1.set(pin as u32);
158 }
159
160 pub fn get_psel1_reset_pin(&self) -> Option<Pin> {
161 Pin::from_u32(self.registers.pselreset1.get())
162 }
163
164 pub fn set_vout(&self, vout: Regulator0Output) {
165 self.registers.regout0.modify(RegOut::VOUT.val(vout as u32));
166 }
167
168 pub fn get_vout(&self) -> Regulator0Output {
169 Regulator0Output::from(self.registers.regout0.read(RegOut::VOUT))
170 }
171
172 pub fn set_nfc_pins_protection(&self, protected: bool) {
173 if protected {
174 self.registers.nfcpins.write(NfcPins::PROTECT::NFC);
175 } else {
176 self.registers.nfcpins.write(NfcPins::PROTECT::DISABLED);
177 }
178 }
179
180 pub fn is_nfc_pins_protection_enabled(&self) -> bool {
181 self.registers.nfcpins.matches_all(NfcPins::PROTECT::NFC)
182 }
183
184 pub fn is_ap_protect_enabled(&self) -> bool {
185 let factory_config = ficr::Ficr::new();
189 let disabled_val = if factory_config.has_updated_approtect_logic() {
190 ApProtect::PALL::HWDISABLE
191 } else {
192 ApProtect::PALL::DISABLED
193 };
194
195 !self.registers.approtect.matches_all(disabled_val)
198 }
199
200 pub fn set_ap_protect(&self) {
201 self.registers.approtect.write(ApProtect::PALL::ENABLED);
202 }
203
204 pub fn disable_ap_protect(&self) {
208 let factory_config = ficr::Ficr::new();
211 if factory_config.has_updated_approtect_logic() {
212 self.registers.approtect.write(ApProtect::PALL::HWDISABLE);
215 } else {
216 self.registers.approtect.write(ApProtect::PALL::DISABLED);
218 }
219 }
220}