cortex_m/peripheral/
mod.rs1use core::marker::PhantomData;
61use core::ops;
62
63use crate::interrupt;
64
65#[cfg(cm7)]
66pub mod ac;
67#[cfg(not(armv6m))]
68pub mod cbp;
69pub mod cpuid;
70pub mod dcb;
71pub mod dwt;
72#[cfg(not(armv6m))]
73pub mod fpb;
74#[cfg(any(has_fpu, native))]
76pub mod fpu;
77pub mod icb;
78#[cfg(all(not(armv6m), not(armv8m_base)))]
79pub mod itm;
80pub mod mpu;
81pub mod nvic;
82#[cfg(armv8m)]
83pub mod sau;
84pub mod scb;
85pub mod syst;
86#[cfg(not(armv6m))]
87pub mod tpiu;
88
89#[cfg(test)]
90mod test;
91
92#[allow(non_snake_case)]
96#[allow(clippy::manual_non_exhaustive)]
97pub struct Peripherals {
98    #[cfg(cm7)]
100    pub AC: AC,
101
102    pub CBP: CBP,
105
106    pub CPUID: CPUID,
108
109    pub DCB: DCB,
111
112    pub DWT: DWT,
114
115    pub FPB: FPB,
118
119    pub FPU: FPU,
121
122    pub ICB: ICB,
127
128    pub ITM: ITM,
131
132    pub MPU: MPU,
134
135    pub NVIC: NVIC,
137
138    pub SAU: SAU,
140
141    pub SCB: SCB,
143
144    pub SYST: SYST,
146
147    pub TPIU: TPIU,
150
151    _priv: (),
154}
155
156#[no_mangle]
159static CORE_PERIPHERALS: () = ();
160
161static mut TAKEN: bool = false;
163
164impl Peripherals {
165    #[inline]
167    pub fn take() -> Option<Self> {
168        interrupt::free(|_| {
169            if unsafe { TAKEN } {
170                None
171            } else {
172                Some(unsafe { Peripherals::steal() })
173            }
174        })
175    }
176
177    #[inline]
179    pub unsafe fn steal() -> Self {
180        TAKEN = true;
181
182        Peripherals {
183            #[cfg(cm7)]
184            AC: AC {
185                _marker: PhantomData,
186            },
187            CBP: CBP {
188                _marker: PhantomData,
189            },
190            CPUID: CPUID {
191                _marker: PhantomData,
192            },
193            DCB: DCB {
194                _marker: PhantomData,
195            },
196            DWT: DWT {
197                _marker: PhantomData,
198            },
199            FPB: FPB {
200                _marker: PhantomData,
201            },
202            FPU: FPU {
203                _marker: PhantomData,
204            },
205            ICB: ICB {
206                _marker: PhantomData,
207            },
208            ITM: ITM {
209                _marker: PhantomData,
210            },
211            MPU: MPU {
212                _marker: PhantomData,
213            },
214            NVIC: NVIC {
215                _marker: PhantomData,
216            },
217            SAU: SAU {
218                _marker: PhantomData,
219            },
220            SCB: SCB {
221                _marker: PhantomData,
222            },
223            SYST: SYST {
224                _marker: PhantomData,
225            },
226            TPIU: TPIU {
227                _marker: PhantomData,
228            },
229            _priv: (),
230        }
231    }
232}
233
234#[cfg(cm7)]
236pub struct AC {
237    _marker: PhantomData<*const ()>,
238}
239
240#[cfg(cm7)]
241unsafe impl Send for AC {}
242
243#[cfg(cm7)]
244impl AC {
245    pub const PTR: *const self::ac::RegisterBlock = 0xE000_EF90 as *const _;
247
248    #[inline(always)]
250    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
251    pub const fn ptr() -> *const self::ac::RegisterBlock {
252        Self::PTR
253    }
254}
255
256pub struct CBP {
258    _marker: PhantomData<*const ()>,
259}
260
261unsafe impl Send for CBP {}
262
263#[cfg(not(armv6m))]
264impl CBP {
265    #[inline(always)]
266    pub(crate) const unsafe fn new() -> Self {
267        CBP {
268            _marker: PhantomData,
269        }
270    }
271
272    pub const PTR: *const self::cbp::RegisterBlock = 0xE000_EF50 as *const _;
274
275    #[inline(always)]
277    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
278    pub const fn ptr() -> *const self::cbp::RegisterBlock {
279        Self::PTR
280    }
281}
282
283#[cfg(not(armv6m))]
284impl ops::Deref for CBP {
285    type Target = self::cbp::RegisterBlock;
286
287    #[inline(always)]
288    fn deref(&self) -> &Self::Target {
289        unsafe { &*Self::PTR }
290    }
291}
292
293pub struct CPUID {
295    _marker: PhantomData<*const ()>,
296}
297
298unsafe impl Send for CPUID {}
299
300impl CPUID {
301    pub const PTR: *const self::cpuid::RegisterBlock = 0xE000_ED00 as *const _;
303
304    #[inline(always)]
306    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
307    pub const fn ptr() -> *const self::cpuid::RegisterBlock {
308        Self::PTR
309    }
310}
311
312impl ops::Deref for CPUID {
313    type Target = self::cpuid::RegisterBlock;
314
315    #[inline(always)]
316    fn deref(&self) -> &Self::Target {
317        unsafe { &*Self::PTR }
318    }
319}
320
321pub struct DCB {
323    _marker: PhantomData<*const ()>,
324}
325
326unsafe impl Send for DCB {}
327
328impl DCB {
329    pub const PTR: *const dcb::RegisterBlock = 0xE000_EDF0 as *const _;
331
332    #[inline(always)]
334    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
335    pub const fn ptr() -> *const dcb::RegisterBlock {
336        Self::PTR
337    }
338}
339
340impl ops::Deref for DCB {
341    type Target = self::dcb::RegisterBlock;
342
343    #[inline(always)]
344    fn deref(&self) -> &Self::Target {
345        unsafe { &*DCB::PTR }
346    }
347}
348
349pub struct DWT {
351    _marker: PhantomData<*const ()>,
352}
353
354unsafe impl Send for DWT {}
355
356impl DWT {
357    pub const PTR: *const dwt::RegisterBlock = 0xE000_1000 as *const _;
359
360    #[inline(always)]
362    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
363    pub const fn ptr() -> *const dwt::RegisterBlock {
364        Self::PTR
365    }
366}
367
368impl ops::Deref for DWT {
369    type Target = self::dwt::RegisterBlock;
370
371    #[inline(always)]
372    fn deref(&self) -> &Self::Target {
373        unsafe { &*Self::PTR }
374    }
375}
376
377pub struct FPB {
379    _marker: PhantomData<*const ()>,
380}
381
382unsafe impl Send for FPB {}
383
384#[cfg(not(armv6m))]
385impl FPB {
386    pub const PTR: *const fpb::RegisterBlock = 0xE000_2000 as *const _;
388
389    #[inline(always)]
391    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
392    pub const fn ptr() -> *const fpb::RegisterBlock {
393        Self::PTR
394    }
395}
396
397#[cfg(not(armv6m))]
398impl ops::Deref for FPB {
399    type Target = self::fpb::RegisterBlock;
400
401    #[inline(always)]
402    fn deref(&self) -> &Self::Target {
403        unsafe { &*Self::PTR }
404    }
405}
406
407pub struct FPU {
409    _marker: PhantomData<*const ()>,
410}
411
412unsafe impl Send for FPU {}
413
414#[cfg(any(has_fpu, native))]
415impl FPU {
416    pub const PTR: *const fpu::RegisterBlock = 0xE000_EF30 as *const _;
418
419    #[inline(always)]
421    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
422    pub const fn ptr() -> *const fpu::RegisterBlock {
423        Self::PTR
424    }
425}
426
427#[cfg(any(has_fpu, native))]
428impl ops::Deref for FPU {
429    type Target = self::fpu::RegisterBlock;
430
431    #[inline(always)]
432    fn deref(&self) -> &Self::Target {
433        unsafe { &*Self::PTR }
434    }
435}
436
437pub struct ICB {
444    _marker: PhantomData<*const ()>,
445}
446
447unsafe impl Send for ICB {}
448
449impl ICB {
450    pub const PTR: *mut icb::RegisterBlock = 0xE000_E004 as *mut _;
452
453    #[inline(always)]
455    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
456    pub const fn ptr() -> *mut icb::RegisterBlock {
457        Self::PTR
458    }
459}
460
461impl ops::Deref for ICB {
462    type Target = self::icb::RegisterBlock;
463
464    #[inline(always)]
465    fn deref(&self) -> &Self::Target {
466        unsafe { &*Self::PTR }
467    }
468}
469
470impl ops::DerefMut for ICB {
471    #[inline(always)]
472    fn deref_mut(&mut self) -> &mut Self::Target {
473        unsafe { &mut *Self::PTR }
474    }
475}
476
477pub struct ITM {
479    _marker: PhantomData<*const ()>,
480}
481
482unsafe impl Send for ITM {}
483
484#[cfg(all(not(armv6m), not(armv8m_base)))]
485impl ITM {
486    pub const PTR: *mut itm::RegisterBlock = 0xE000_0000 as *mut _;
488
489    #[inline(always)]
491    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
492    pub const fn ptr() -> *mut itm::RegisterBlock {
493        Self::PTR
494    }
495}
496
497#[cfg(all(not(armv6m), not(armv8m_base)))]
498impl ops::Deref for ITM {
499    type Target = self::itm::RegisterBlock;
500
501    #[inline(always)]
502    fn deref(&self) -> &Self::Target {
503        unsafe { &*Self::PTR }
504    }
505}
506
507#[cfg(all(not(armv6m), not(armv8m_base)))]
508impl ops::DerefMut for ITM {
509    #[inline(always)]
510    fn deref_mut(&mut self) -> &mut Self::Target {
511        unsafe { &mut *Self::PTR }
512    }
513}
514
515pub struct MPU {
517    _marker: PhantomData<*const ()>,
518}
519
520unsafe impl Send for MPU {}
521
522impl MPU {
523    pub const PTR: *const mpu::RegisterBlock = 0xE000_ED90 as *const _;
525
526    #[inline(always)]
528    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
529    pub const fn ptr() -> *const mpu::RegisterBlock {
530        Self::PTR
531    }
532}
533
534impl ops::Deref for MPU {
535    type Target = self::mpu::RegisterBlock;
536
537    #[inline(always)]
538    fn deref(&self) -> &Self::Target {
539        unsafe { &*Self::PTR }
540    }
541}
542
543pub struct NVIC {
545    _marker: PhantomData<*const ()>,
546}
547
548unsafe impl Send for NVIC {}
549
550impl NVIC {
551    pub const PTR: *const nvic::RegisterBlock = 0xE000_E100 as *const _;
553
554    #[inline(always)]
556    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
557    pub const fn ptr() -> *const nvic::RegisterBlock {
558        Self::PTR
559    }
560}
561
562impl ops::Deref for NVIC {
563    type Target = self::nvic::RegisterBlock;
564
565    #[inline(always)]
566    fn deref(&self) -> &Self::Target {
567        unsafe { &*Self::PTR }
568    }
569}
570
571pub struct SAU {
573    _marker: PhantomData<*const ()>,
574}
575
576unsafe impl Send for SAU {}
577
578#[cfg(armv8m)]
579impl SAU {
580    pub const PTR: *const sau::RegisterBlock = 0xE000_EDD0 as *const _;
582
583    #[inline(always)]
585    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
586    pub const fn ptr() -> *const sau::RegisterBlock {
587        Self::PTR
588    }
589}
590
591#[cfg(armv8m)]
592impl ops::Deref for SAU {
593    type Target = self::sau::RegisterBlock;
594
595    #[inline(always)]
596    fn deref(&self) -> &Self::Target {
597        unsafe { &*Self::PTR }
598    }
599}
600
601pub struct SCB {
603    _marker: PhantomData<*const ()>,
604}
605
606unsafe impl Send for SCB {}
607
608impl SCB {
609    pub const PTR: *const scb::RegisterBlock = 0xE000_ED04 as *const _;
611
612    #[inline(always)]
614    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
615    pub const fn ptr() -> *const scb::RegisterBlock {
616        Self::PTR
617    }
618}
619
620impl ops::Deref for SCB {
621    type Target = self::scb::RegisterBlock;
622
623    #[inline(always)]
624    fn deref(&self) -> &Self::Target {
625        unsafe { &*Self::PTR }
626    }
627}
628
629pub struct SYST {
631    _marker: PhantomData<*const ()>,
632}
633
634unsafe impl Send for SYST {}
635
636impl SYST {
637    pub const PTR: *const syst::RegisterBlock = 0xE000_E010 as *const _;
639
640    #[inline(always)]
642    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
643    pub const fn ptr() -> *const syst::RegisterBlock {
644        Self::PTR
645    }
646}
647
648impl ops::Deref for SYST {
649    type Target = self::syst::RegisterBlock;
650
651    #[inline(always)]
652    fn deref(&self) -> &Self::Target {
653        unsafe { &*Self::PTR }
654    }
655}
656
657pub struct TPIU {
659    _marker: PhantomData<*const ()>,
660}
661
662unsafe impl Send for TPIU {}
663
664#[cfg(not(armv6m))]
665impl TPIU {
666    pub const PTR: *const tpiu::RegisterBlock = 0xE004_0000 as *const _;
668
669    #[inline(always)]
671    #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")]
672    pub const fn ptr() -> *const tpiu::RegisterBlock {
673        Self::PTR
674    }
675}
676
677#[cfg(not(armv6m))]
678impl ops::Deref for TPIU {
679    type Target = self::tpiu::RegisterBlock;
680
681    #[inline(always)]
682    fn deref(&self) -> &Self::Target {
683        unsafe { &*Self::PTR }
684    }
685}