1use cortex_m::interrupt::InterruptNumber;
10
11use crate::{
12 module_stop::ModuleStop as _,
13 pac::{self, icu::regs::Ielsr},
14 peripherals::ELC,
15};
16
17#[cfg(trust_zone)]
18use pac::{
19 cpscu::vals::SecurityAttribution,
20 system::vals::{Prc4, Prkey},
21};
22
23pub unsafe trait IcuInterrupt: InterruptNumber + Copy {
34 #[inline(always)]
36 fn icu_disable(&self) {
37 let icu = pac::ICU;
38
39 icu.ielsr(self.number() as _).modify(|w| w.set_iels(0));
40 trace!("IEL{}: disable", self.number());
41 }
42
43 #[inline(always)]
54 unsafe fn icu_enable(&self, mask: InterruptEvent) {
55 let icu = pac::ICU;
56
57 trace!("IEL{}: enable={}", self.number(), mask);
58
59 icu.ielsr(self.number() as _).modify(|w| {
60 w.set_iels(mask as _);
61 });
62 }
63
64 #[inline(always)]
66 fn icu_enabled(&self) -> bool {
67 self.icu_event() != InterruptEvent::None
68 }
69
70 #[inline(always)]
72 fn icu_event(&self) -> InterruptEvent {
73 let icu = pac::ICU;
74
75 let event = icu.ielsr(self.number() as _).read().iels();
76
77 let event: InterruptEvent = unsafe { core::mem::transmute(event) };
80 trace!("IEL{}: event={}", self.number(), event);
81
82 event
83 }
84
85 #[inline(always)]
89 fn dtc_disable(&self) {
90 let icu = pac::ICU;
91
92 icu.ielsr(self.number() as _).write_value(Ielsr(0));
93 }
94
95 #[inline(always)]
99 fn dtc_enable(&self, mask: InterruptEvent) {
100 let icu = pac::ICU;
101
102 trace!("IEL{}: enable={}, dtc=true", self.number(), mask);
103
104 icu.ielsr(self.number() as _).write(|r| {
105 r.set_dtce(true);
106 r.set_iels(mask as _);
107 });
108 }
109
110 #[inline(always)]
115 fn is_dtc(&self) -> bool {
116 let icu = pac::ICU;
117
118 icu.ielsr(self.number() as _).read().dtce()
119 }
120
121 #[inline(always)]
127 fn icu_unpend(&self) {
128 let icu = pac::ICU;
129
130 icu.ielsr(self.number() as _).modify(|w| w.set_ir(false));
131 }
132
133 #[inline(always)]
139 fn icu_pend(&self) {
140 let icu = pac::ICU;
141
142 icu.ielsr(self.number() as _).modify(|w| w.set_ir(true));
143 }
144
145 fn icu_is_pending(&self) -> bool {
147 let icu = pac::ICU;
148
149 icu.ielsr(self.number() as _).read().ir()
150 }
151
152 fn icu_status(&self) {
154 let icu = pac::ICU;
155 let number = self.number();
156 let ielsr = icu.ielsr(number as _);
157 let status = ielsr.read();
158 trace!("IEL{}: ir={}, dtce={}", number, status.ir(), status.dtce());
159 }
160
161 #[cfg(trust_zone)]
169 fn set_security_attribution(&self, attribution: SecurityAttribution) {
170 let cpscu = pac::CPSCU;
171 let system = pac::SYSTEM;
172
173 let prcr = cfg_select! {
174 all(trust_zone_v2, secure) => system.prcr_s(),
175 _ => system.prcr()
176 };
177
178 prcr.modify(|r| {
179 r.set_prkey(Prkey::ProtectKey);
180 r.set_prc4(Prc4::NotProtected);
181 });
182
183 cpscu
185 .icusarg()
186 .modify(|r| r.set_saielsr(self.number() as _, attribution));
187
188 info!(
189 "ICUSARG: {}",
190 cpscu.icusarg().read().saielsr(self.number() as _)
191 );
192
193 prcr.modify(|r| {
194 r.set_prkey(Prkey::ProtectKey);
195 r.set_prc4(Prc4::Protected);
196 });
197 }
198}
199
200unsafe impl<T: InterruptNumber + Copy> IcuInterrupt for T {}
201
202#[allow(private_bounds)]
204pub trait SoftwareEventGenerator<const N: u8>: SealedSoftwareEventGenerator<N> {
205 fn event(&self) -> InterruptEvent;
207
208 #[inline(always)]
210 fn fire(&self) {
211 let elc = crate::pac::ELC;
212 elc.elsegr(self.index() as _).write(|r| r.set_wi(false));
213 elc.elsegr(self.index() as _).write(|r| r.set_we(true));
214 elc.elsegr(self.index() as _).write(|r| r.set_seg(true));
215 }
216}
217
218trait SealedSoftwareEventGenerator<const N: u8> {
219 fn index(&self) -> u8;
220}
221
222pub struct SoftwareEvent<const N: u8> {}
226
227impl<const N: u8> SoftwareEvent<N> {
228 pub const fn new() -> Self {
230 Self {}
231 }
232}
233
234impl SoftwareEventGenerator<0> for SoftwareEvent<0> {
235 #[inline(always)]
236 fn event(&self) -> InterruptEvent {
237 InterruptEvent::ElcSoftwareEvent0
238 }
239}
240
241impl SealedSoftwareEventGenerator<0> for SoftwareEvent<0> {
242 #[inline(always)]
243 fn index(&self) -> u8 {
244 0
245 }
246}
247
248impl SoftwareEventGenerator<1> for SoftwareEvent<1> {
249 #[inline(always)]
250 fn event(&self) -> InterruptEvent {
251 InterruptEvent::ElcSoftwareEvent1
252 }
253}
254impl SealedSoftwareEventGenerator<1> for SoftwareEvent<1> {
255 #[inline(always)]
256 fn index(&self) -> u8 {
257 1
258 }
259}
260
261#[allow(unused, missing_docs)]
265#[cfg_attr(feature = "defmt", derive(defmt::Format))]
266#[repr(u8)]
267pub enum EventSignal {
268 PortIrq0 = 0x01,
269 PortIrq1 = 0x02,
270 PortIrq2 = 0x03,
271 PortIrq3 = 0x04,
272 PortIrq4 = 0x05,
273 PortIrq5 = 0x06,
274 PortIrq6 = 0x07,
275 PortIrq7 = 0x08,
276 PortIrq8 = 0x09,
277 PortIrq9 = 0x0a,
278 PortIrq10 = 0x0b,
279 PortIrq11 = 0x0c,
280 PortIrq12 = 0x0d,
281 PortIrq13 = 0x0e,
282 PortIrq14 = 0x0f,
283 PortIrq15 = 0x10,
284
285 Dmac0Int = 0x11,
286 Dmac1Int = 0x12,
287 Dmac2Int = 0x13,
288 Dmac3Int = 0x14,
289
290 DtcEnd = 0x16,
291
292 Lvd1 = 0x19,
293 Lvd2 = 0x1A,
294
295 MoscStop = 0x1C,
296
297 SnoozeRequest = 0x1D,
298
299 Agt0Agti = 0x1E,
300 Agt0AgtCmAi = 0x1F,
301 Agt0AgtCmBi = 0x20,
302
303 Agt1Agti = 0x21,
304 Agt1AgtCmAi = 0x22,
305 Agt1AgtCmBi = 0x23,
306
307 IwdtNmi = 0x24,
308 WdtNmi = 0x25,
309
310 RtcPrd = 0x27,
311
312 AdcAdi = 0x29,
313 AdcWcmpM = 0x2D,
314 AdcWcmpUm = 0x2E,
315
316 AcmpLp0 = 0x2F,
317 AcmpLp1 = 0x30,
318
319 Iic0Rxi = 0x35,
320 Iic0Txi = 0x36,
321 Iic0Tei = 0x37,
322 Iic0Eei = 0x38,
323
324 Iic1Rxi = 0x3A,
325 Iic1Txi = 0x3B,
326 Iic1Tei = 0x3C,
327 Iic1Eei = 0x3D,
328
329 DocDopci = 0x46,
330
331 IoportGroup1 = 0x4F,
332 IoportGroup2 = 0x50,
333 IoportGroup3 = 0x51,
334 IoportGroup4 = 0x52,
335
336 ElcSwEvt0 = 0x53,
337 ElcSwEvt1 = 0x54,
338
339 Gpt0CcmpA = 0x57,
340 Gpt0CcmpB = 0x58,
341 Gpt0CmpC = 0x59,
342 Gpt0CmpD = 0x5A,
343 Gpt0CmpE = 0x5B,
344 Gpt0CmpF = 0x5C,
345 Gpt0Ovf = 0x5D,
346 Gpt0Udf = 0x5E,
347
348 Gpt1CcmpA = 0x5F,
349 Gpt1CcmpB = 0x60,
350 Gpt1CmpC = 0x61,
351 Gpt1CmpD = 0x62,
352 Gpt1CmpE = 0x63,
353 Gpt1CmpF = 0x64,
354 Gpt1Ovf = 0x65,
355 Gpt1Udf = 0x66,
356
357 Gpt2CcmpA = 0x67,
358 Gpt2CcmpB = 0x68,
359 Gpt2CmpC = 0x69,
360 Gpt2CmpD = 0x6A,
361 Gpt2CmpE = 0x6B,
362 Gpt2CmpF = 0x6C,
363 Gpt2Ovf = 0x6D,
364 Gpt2Udf = 0x6E,
365
366 Gpt3CcmpA = 0x6F,
367 Gpt3CcmpB = 0x70,
368 Gpt3CmpC = 0x71,
369 Gpt3CmpD = 0x72,
370 Gpt3CmpE = 0x73,
371 Gpt3CmpF = 0x74,
372 Gpt3Ovf = 0x75,
373 Gpt3Udf = 0x76,
374
375 Gpt4CcmpA = 0x77,
376 Gpt4CcmpB = 0x78,
377 Gpt4CmpC = 0x79,
378 Gpt4CmpD = 0x7A,
379 Gpt4CmpE = 0x7B,
380 Gpt4CmpF = 0x7C,
381 Gpt4Ovf = 0x7D,
382 Gpt4Udf = 0x7E,
383
384 Gpt5CcmpA = 0x7F,
385 Gpt5CcmpB = 0x80,
386 Gpt5CmpC = 0x81,
387 Gpt5CmpD = 0x82,
388 Gpt5CmpE = 0x83,
389 Gpt5CmpF = 0x84,
390 Gpt5Ovf = 0x85,
391 Gpt5Udf = 0x86,
392
393 Gpt6CcmpA = 0x87,
394 Gpt6CcmpB = 0x88,
395 Gpt6CmpC = 0x89,
396 Gpt6CmpD = 0x8A,
397 Gpt6CmpE = 0x8B,
398 Gpt6CmpF = 0x8C,
399 Gpt6Ovf = 0x8D,
400 Gpt6Udf = 0x8E,
401
402 Gpt7CcmpA = 0x8F,
403 Gpt7CcmpB = 0x90,
404 Gpt7CmpC = 0x91,
405 Gpt7CmpD = 0x92,
406 Gpt7CmpE = 0x93,
407 Gpt7CmpF = 0x94,
408 Gpt7Ovf = 0x95,
409 Gpt7Udf = 0x96,
410
411 GptUvwEdge = 0x97,
412
413 Sci0Rxi = 0x98,
414 Sci0Txi = 0x99,
415 Sci0Tei = 0x9A,
416 Sci0Eri = 0x9B,
417 Sci0Am = 0x9C,
418
419 Sci1Rxi = 0x9E,
420 Sci1Txi = 0x9F,
421 Sci1Tei = 0xA0,
422 Sci1Eri = 0xA1,
423 Sci1Am = 0xA2,
424
425 Sci2Rxi = 0xA3,
426 Sci2Txi = 0xA4,
427 Sci2Tei = 0xA5,
428 Sci2Eri = 0xA6,
429 Sci2Am = 0xA7,
430
431 Sci9Rxi = 0xA8,
432 Sci9Txi = 0xA9,
433 Sci9Tei = 0xAA,
434 Sci9Eri = 0xAB,
435 Sci9Am = 0xAC,
436
437 Spi0SpRi = 0xAD,
438 Spi0SpTi = 0xAE,
439 Spi0SpIi = 0xAF,
440 Spi0SpEi = 0xB0,
441 Spi0SpTend = 0xB1,
442
443 Spi1SpRi = 0xB2,
444 Spi1SpTi = 0xB3,
445 Spi1SpIi = 0xB4,
446 Spi1SpEi = 0xB5,
447 Spi1SpTend = 0xB6,
448}
449
450include!(concat!(env!("OUT_DIR"), "/event_link.rs"));
451
452pub(crate) fn init() {
454 ELC::start_module();
455}