1#[cfg(gpt)]
4use crate::pac::gpt;
5#[cfg(iic)]
6use crate::pac::iic;
7use crate::pac::{
8 common::{RW, Reg},
9 pfs::regs::Pin,
10 system::vals::{Prc0, Prc1},
11};
12
13pub trait ProtectedPeripheral {
15 fn is_protected(&self) -> bool;
18
19 fn protected_write<F>(&self, func: F)
21 where
22 F: Fn();
23}
24
25pub trait ProtectedModify<T: Copy> {
27 fn protected_modify(&self, f: impl FnOnce(&mut T));
29
30 fn is_protected(&self) -> bool {
33 true
34 }
35}
36
37pub trait ProtectedWrite<T: Copy> {
39 fn protected_write(&self, f: impl FnOnce(&mut T));
41}
42
43#[cfg(iic)]
44impl ProtectedModify<iic::regs::Icmr3> for Reg<iic::regs::Icmr3, RW> {
45 #[inline]
46 fn is_protected(&self) -> bool {
47 !self.read().ackwp()
48 }
49
50 #[inline]
51 fn protected_modify(&self, func: impl FnOnce(&mut iic::regs::Icmr3)) {
52 let protected = self.is_protected();
53
54 if protected {
55 self.modify(|w| w.set_ackwp(true));
56 }
57
58 self.modify(func);
59
60 if protected {
61 self.modify(|w| w.set_ackwp(false));
62 }
63 }
64}
65
66impl ProtectedModify<Pin> for Reg<Pin, RW> {
67 #[inline]
68 fn is_protected(&self) -> bool {
69 let pfs = crate::pac::PFS;
70 let pwpr = cfg_select! {
71 all(trust_zone_v2, secure) => pfs.pwpr_s(),
72 _ => pfs.pwpr()
73 };
74
75 !pwpr.read().pfswe()
76 }
77
78 fn protected_modify(&self, func: impl FnOnce(&mut Pin)) {
79 let pfs = crate::pac::PFS;
82 let protected = self.is_protected();
83
84 let pwpr = cfg_select! {
85 all(trust_zone_v2, secure) => pfs.pwpr_s(),
86 _ => pfs.pwpr()
87 };
88
89 if protected {
90 trace!("PFS WriteProt: {}", pfs.pwpr().read());
91
92 pwpr.modify(|w| w.set_b0wi(false));
93 pwpr.modify(|w| w.set_pfswe(true));
94
95 #[cfg(feature = "strict-assert")]
96 assert!(pwpr.read().pfswe());
97 }
98
99 self.modify(func);
100
101 if protected {
102 pwpr.modify(|w| w.set_b0wi(false));
103 pwpr.modify(|w| w.set_pfswe(false));
104
105 #[cfg(feature = "strict-assert")]
106 assert!(!pwpr.read().pfswe());
107 trace!("PFS WriteProt: {}", pwpr.read());
108 }
109 }
110}
111
112impl ProtectedPeripheral for crate::pac::system::System {
113 fn protected_write<F>(&self, func: F)
114 where
115 F: Fn(),
116 {
117 use crate::pac::system::vals::Prc0;
118
119 let prcr = cfg_select! {
120 all(trust_zone_v2, secure) => self.prcr_s(),
121 _ => self.prcr()
122 };
123
124 let protected = self.is_protected();
125
126 if protected {
127 trace!("SYSTEM WriteProt: {}", prcr.read());
128 prcr.write(|w| {
129 w.set_prkey(crate::pac::system::vals::Prkey::ProtectKey);
130 w.set_prc0(Prc0::NotProtected);
131 w.set_prc1(Prc1::NotProtected);
132 });
133 }
134
135 func();
136
137 if protected {
138 prcr.write(|w| {
139 w.set_prkey(crate::pac::system::vals::Prkey::ProtectKey);
140 w.set_prc0(Prc0::Protected);
141 w.set_prc1(Prc1::Protected);
142 });
143 trace!("SYSTEM WriteProt: {}", prcr.read());
144 }
145 }
146
147 #[inline]
148 fn is_protected(&self) -> bool {
149 let prcr = cfg_select! {
150 all(trust_zone_v2, secure) => self.prcr_s(),
151 _ => self.prcr()
152 };
153
154 let status = prcr.read();
155 status.prc0() == Prc0::Protected || status.prc1() == Prc1::Protected
156 }
157}
158
159#[cfg(gpt)]
161impl ProtectedPeripheral for gpt::Gpt {
162 fn protected_write<F>(&self, func: F)
163 where
164 F: Fn(),
165 {
166 use gpt::vals::Prkey;
167
168 let protected = self.is_protected();
169
170 if protected {
171 self.gtwp().write(|w| {
172 w.set_wp(false);
173 w.set_prkey(Prkey::ProtectKey);
174 });
175 trace!("WP: {}", self.gtwp().read());
176 }
177
178 func();
179
180 if protected {
181 self.gtwp().write(|w| {
182 w.set_wp(true);
183 w.set_prkey(Prkey::ProtectKey);
184 });
185 trace!("WP: {}", self.gtwp().read());
186 }
187 }
188
189 #[inline]
190 fn is_protected(&self) -> bool {
191 self.gtwp().read().wp()
192 }
193}