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}