1use core::marker::PhantomData;
61use core::ops;
62
63#[cfg(feature = "cm7")]
64pub mod ac;
65#[cfg(not(armv6m))]
66pub mod cbp;
67pub mod cpuid;
68pub mod dcb;
69pub mod dwt;
70#[cfg(not(armv6m))]
71pub mod fpb;
72#[cfg(any(has_fpu, native))]
74pub mod fpu;
75pub mod icb;
76#[cfg(all(not(armv6m), not(armv8m_base)))]
77pub mod itm;
78pub mod mpu;
79pub mod nvic;
80#[cfg(armv8m)]
81pub mod sau;
82pub mod scb;
83pub mod syst;
84#[cfg(not(armv6m))]
85pub mod tpiu;
86
87#[cfg(test)]
88mod test;
89
90#[allow(non_snake_case)]
94#[non_exhaustive]
95pub struct Peripherals {
96 #[cfg(feature = "cm7")]
98 pub AC: AC,
99
100 pub CBP: CBP,
103
104 pub CPUID: CPUID,
106
107 pub DCB: DCB,
109
110 pub DWT: DWT,
112
113 pub FPB: FPB,
116
117 pub FPU: FPU,
119
120 pub ICB: ICB,
125
126 pub ITM: ITM,
129
130 pub MPU: MPU,
132
133 pub NVIC: NVIC,
135
136 pub SAU: SAU,
138
139 pub SCB: SCB,
141
142 #[cfg(feature = "secure-mode")]
147 pub SCBNS: SCBNS,
148
149 pub SYST: SYST,
151
152 pub TPIU: TPIU,
155}
156
157#[unsafe(no_mangle)]
160static CORE_PERIPHERALS: () = ();
161
162static mut TAKEN: bool = false;
164
165impl Peripherals {
166 #[inline]
168 pub fn take() -> Option<Self> {
169 crate::interrupt::free(|_| {
170 if unsafe { TAKEN } {
171 None
172 } else {
173 Some(unsafe { Peripherals::steal() })
174 }
175 })
176 }
177
178 #[inline]
180 pub unsafe fn steal() -> Self {
181 unsafe {
182 TAKEN = true;
183
184 Peripherals {
185 #[cfg(feature = "cm7")]
186 AC: AC {
187 _marker: PhantomData,
188 },
189 CBP: CBP {
190 _marker: PhantomData,
191 },
192 CPUID: CPUID {
193 _marker: PhantomData,
194 },
195 DCB: DCB {
196 _marker: PhantomData,
197 },
198 DWT: DWT {
199 _marker: PhantomData,
200 },
201 FPB: FPB {
202 _marker: PhantomData,
203 },
204 FPU: FPU {
205 _marker: PhantomData,
206 },
207 ICB: ICB {
208 _marker: PhantomData,
209 },
210 ITM: ITM {
211 _marker: PhantomData,
212 },
213 MPU: MPU {
214 _marker: PhantomData,
215 },
216 NVIC: NVIC {
217 _marker: PhantomData,
218 },
219 SAU: SAU {
220 _marker: PhantomData,
221 },
222 SCB: SCB {
223 _marker: PhantomData,
224 },
225 #[cfg(feature = "secure-mode")]
226 SCBNS: SCBNS {
227 _marker: PhantomData,
228 },
229 SYST: SYST {
230 _marker: PhantomData,
231 },
232 TPIU: TPIU {
233 _marker: PhantomData,
234 },
235 }
236 }
237 }
238}
239
240#[cfg(feature = "cm7")]
242pub struct AC {
243 _marker: PhantomData<*const ()>,
244}
245
246#[cfg(feature = "cm7")]
247unsafe impl Send for AC {}
248
249#[cfg(feature = "cm7")]
250impl AC {
251 pub const PTR: *const self::ac::RegisterBlock = 0xE000_EF90 as *const _;
253
254 #[inline(always)]
256 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
257 pub const fn ptr() -> *const self::ac::RegisterBlock {
258 Self::PTR
259 }
260}
261
262pub struct CBP {
264 _marker: PhantomData<*const ()>,
265}
266
267unsafe impl Send for CBP {}
268
269#[cfg(not(armv6m))]
270impl CBP {
271 #[inline(always)]
272 pub(crate) const unsafe fn new() -> Self {
273 CBP {
274 _marker: PhantomData,
275 }
276 }
277
278 pub const PTR: *const self::cbp::RegisterBlock = 0xE000_EF50 as *const _;
280
281 #[inline(always)]
283 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
284 pub const fn ptr() -> *const self::cbp::RegisterBlock {
285 Self::PTR
286 }
287}
288
289#[cfg(not(armv6m))]
290impl ops::Deref for CBP {
291 type Target = self::cbp::RegisterBlock;
292
293 #[inline(always)]
294 fn deref(&self) -> &Self::Target {
295 unsafe { &*Self::PTR }
296 }
297}
298
299pub struct CPUID {
301 _marker: PhantomData<*const ()>,
302}
303
304unsafe impl Send for CPUID {}
305
306impl CPUID {
307 pub const PTR: *const self::cpuid::RegisterBlock = 0xE000_ED00 as *const _;
309
310 #[inline(always)]
312 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
313 pub const fn ptr() -> *const self::cpuid::RegisterBlock {
314 Self::PTR
315 }
316}
317
318impl ops::Deref for CPUID {
319 type Target = self::cpuid::RegisterBlock;
320
321 #[inline(always)]
322 fn deref(&self) -> &Self::Target {
323 unsafe { &*Self::PTR }
324 }
325}
326
327pub struct DCB {
329 _marker: PhantomData<*const ()>,
330}
331
332unsafe impl Send for DCB {}
333
334impl DCB {
335 pub const PTR: *const dcb::RegisterBlock = 0xE000_EDF0 as *const _;
337
338 #[inline(always)]
340 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
341 pub const fn ptr() -> *const dcb::RegisterBlock {
342 Self::PTR
343 }
344}
345
346impl ops::Deref for DCB {
347 type Target = self::dcb::RegisterBlock;
348
349 #[inline(always)]
350 fn deref(&self) -> &Self::Target {
351 unsafe { &*DCB::PTR }
352 }
353}
354
355pub struct DWT {
357 _marker: PhantomData<*const ()>,
358}
359
360unsafe impl Send for DWT {}
361
362impl DWT {
363 pub const PTR: *const dwt::RegisterBlock = 0xE000_1000 as *const _;
365
366 #[inline(always)]
368 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
369 pub const fn ptr() -> *const dwt::RegisterBlock {
370 Self::PTR
371 }
372}
373
374impl ops::Deref for DWT {
375 type Target = self::dwt::RegisterBlock;
376
377 #[inline(always)]
378 fn deref(&self) -> &Self::Target {
379 unsafe { &*Self::PTR }
380 }
381}
382
383pub struct FPB {
385 _marker: PhantomData<*const ()>,
386}
387
388unsafe impl Send for FPB {}
389
390#[cfg(not(armv6m))]
391impl FPB {
392 pub const PTR: *const fpb::RegisterBlock = 0xE000_2000 as *const _;
394
395 #[inline(always)]
397 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
398 pub const fn ptr() -> *const fpb::RegisterBlock {
399 Self::PTR
400 }
401}
402
403#[cfg(not(armv6m))]
404impl ops::Deref for FPB {
405 type Target = self::fpb::RegisterBlock;
406
407 #[inline(always)]
408 fn deref(&self) -> &Self::Target {
409 unsafe { &*Self::PTR }
410 }
411}
412
413pub struct FPU {
415 _marker: PhantomData<*const ()>,
416}
417
418unsafe impl Send for FPU {}
419
420#[cfg(any(has_fpu, native))]
421impl FPU {
422 pub const PTR: *const fpu::RegisterBlock = 0xE000_EF30 as *const _;
424
425 #[inline(always)]
427 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
428 pub const fn ptr() -> *const fpu::RegisterBlock {
429 Self::PTR
430 }
431}
432
433#[cfg(any(has_fpu, native))]
434impl ops::Deref for FPU {
435 type Target = self::fpu::RegisterBlock;
436
437 #[inline(always)]
438 fn deref(&self) -> &Self::Target {
439 unsafe { &*Self::PTR }
440 }
441}
442
443pub struct ICB {
450 _marker: PhantomData<*const ()>,
451}
452
453unsafe impl Send for ICB {}
454
455impl ICB {
456 pub const PTR: *mut icb::RegisterBlock = 0xE000_E004 as *mut _;
458
459 #[inline(always)]
461 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
462 pub const fn ptr() -> *mut icb::RegisterBlock {
463 Self::PTR
464 }
465}
466
467impl ops::Deref for ICB {
468 type Target = self::icb::RegisterBlock;
469
470 #[inline(always)]
471 fn deref(&self) -> &Self::Target {
472 unsafe { &*Self::PTR }
473 }
474}
475
476impl ops::DerefMut for ICB {
477 #[inline(always)]
478 fn deref_mut(&mut self) -> &mut Self::Target {
479 unsafe { &mut *Self::PTR }
480 }
481}
482
483pub struct ITM {
485 _marker: PhantomData<*const ()>,
486}
487
488unsafe impl Send for ITM {}
489
490#[cfg(all(not(armv6m), not(armv8m_base)))]
491impl ITM {
492 pub const PTR: *mut itm::RegisterBlock = 0xE000_0000 as *mut _;
494
495 #[inline(always)]
497 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
498 pub const fn ptr() -> *mut itm::RegisterBlock {
499 Self::PTR
500 }
501}
502
503#[cfg(all(not(armv6m), not(armv8m_base)))]
504impl ops::Deref for ITM {
505 type Target = self::itm::RegisterBlock;
506
507 #[inline(always)]
508 fn deref(&self) -> &Self::Target {
509 unsafe { &*Self::PTR }
510 }
511}
512
513#[cfg(all(not(armv6m), not(armv8m_base)))]
514impl ops::DerefMut for ITM {
515 #[inline(always)]
516 fn deref_mut(&mut self) -> &mut Self::Target {
517 unsafe { &mut *Self::PTR }
518 }
519}
520
521pub struct MPU {
523 _marker: PhantomData<*const ()>,
524}
525
526unsafe impl Send for MPU {}
527
528impl MPU {
529 pub const PTR: *const mpu::RegisterBlock = 0xE000_ED90 as *const _;
531
532 #[inline(always)]
534 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
535 pub const fn ptr() -> *const mpu::RegisterBlock {
536 Self::PTR
537 }
538}
539
540impl ops::Deref for MPU {
541 type Target = self::mpu::RegisterBlock;
542
543 #[inline(always)]
544 fn deref(&self) -> &Self::Target {
545 unsafe { &*Self::PTR }
546 }
547}
548
549pub struct NVIC {
551 _marker: PhantomData<*const ()>,
552}
553
554unsafe impl Send for NVIC {}
555
556impl NVIC {
557 pub const PTR: *const nvic::RegisterBlock = 0xE000_E100 as *const _;
559
560 #[inline(always)]
562 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
563 pub const fn ptr() -> *const nvic::RegisterBlock {
564 Self::PTR
565 }
566}
567
568impl ops::Deref for NVIC {
569 type Target = self::nvic::RegisterBlock;
570
571 #[inline(always)]
572 fn deref(&self) -> &Self::Target {
573 unsafe { &*Self::PTR }
574 }
575}
576
577pub struct SAU {
579 _marker: PhantomData<*const ()>,
580}
581
582unsafe impl Send for SAU {}
583
584#[cfg(armv8m)]
585impl SAU {
586 pub const PTR: *const sau::RegisterBlock = 0xE000_EDD0 as *const _;
588
589 #[inline(always)]
591 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
592 pub const fn ptr() -> *const sau::RegisterBlock {
593 Self::PTR
594 }
595}
596
597#[cfg(armv8m)]
598impl ops::Deref for SAU {
599 type Target = self::sau::RegisterBlock;
600
601 #[inline(always)]
602 fn deref(&self) -> &Self::Target {
603 unsafe { &*Self::PTR }
604 }
605}
606
607pub struct SCB {
609 _marker: PhantomData<*const ()>,
610}
611
612unsafe impl Send for SCB {}
613
614impl SCB {
615 pub const PTR: *const scb::RegisterBlock = 0xE000_ED04 as *const _;
617
618 #[inline(always)]
620 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
621 pub const fn ptr() -> *const scb::RegisterBlock {
622 Self::PTR
623 }
624}
625
626impl ops::Deref for SCB {
627 type Target = self::scb::RegisterBlock;
628
629 #[inline(always)]
630 fn deref(&self) -> &Self::Target {
631 unsafe { &*Self::PTR }
632 }
633}
634
635#[cfg(feature = "secure-mode")]
640pub struct SCBNS {
641 _marker: core::marker::PhantomData<*const ()>,
642}
643
644#[cfg(feature = "secure-mode")]
645unsafe impl Send for SCBNS {}
646
647#[cfg(feature = "secure-mode")]
648impl SCBNS {
649 pub const PTR: *const scb::RegisterBlock = 0xE002_ED04 as *const _;
651}
652
653#[cfg(feature = "secure-mode")]
654impl ops::Deref for SCBNS {
655 type Target = scb::RegisterBlock;
656
657 #[inline(always)]
658 fn deref(&self) -> &Self::Target {
659 unsafe { &*Self::PTR }
660 }
661}
662
663pub struct SYST {
665 _marker: PhantomData<*const ()>,
666}
667
668unsafe impl Send for SYST {}
669
670impl SYST {
671 pub const PTR: *const syst::RegisterBlock = 0xE000_E010 as *const _;
673
674 #[inline(always)]
676 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
677 pub const fn ptr() -> *const syst::RegisterBlock {
678 Self::PTR
679 }
680}
681
682impl ops::Deref for SYST {
683 type Target = self::syst::RegisterBlock;
684
685 #[inline(always)]
686 fn deref(&self) -> &Self::Target {
687 unsafe { &*Self::PTR }
688 }
689}
690
691pub struct TPIU {
693 _marker: PhantomData<*const ()>,
694}
695
696unsafe impl Send for TPIU {}
697
698#[cfg(not(armv6m))]
699impl TPIU {
700 pub const PTR: *const tpiu::RegisterBlock = 0xE004_0000 as *const _;
702
703 #[inline(always)]
705 #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
706 pub const fn ptr() -> *const tpiu::RegisterBlock {
707 Self::PTR
708 }
709}
710
711#[cfg(not(armv6m))]
712impl ops::Deref for TPIU {
713 type Target = self::tpiu::RegisterBlock;
714
715 #[inline(always)]
716 fn deref(&self) -> &Self::Target {
717 unsafe { &*Self::PTR }
718 }
719}