@@ -38,6 +38,7 @@ pub fn device(d: &Device, target: &Target, items: &mut Vec<Tokens>) -> Result<()
38
38
39
39
items. push ( quote ! {
40
40
#![ doc = #doc]
41
+ #![ allow( private_no_mangle_statics) ]
41
42
#![ deny( missing_docs) ]
42
43
#![ deny( warnings) ]
43
44
#![ allow( non_camel_case_types) ]
@@ -69,8 +70,7 @@ pub fn device(d: &Device, target: &Target, items: &mut Vec<Tokens>) -> Result<()
69
70
extern crate vcell;
70
71
71
72
use core:: ops:: Deref ;
72
-
73
- use bare_metal:: Peripheral ;
73
+ use core:: marker:: PhantomData ;
74
74
} ) ;
75
75
76
76
if let Some ( cpu) = d. cpu . as_ref ( ) {
@@ -101,18 +101,16 @@ pub fn device(d: &Device, target: &Target, items: &mut Vec<Tokens>) -> Result<()
101
101
let mut fields = vec ! [ ] ;
102
102
let mut exprs = vec ! [ ] ;
103
103
if * target == Target :: CortexM {
104
+ items. push ( quote ! {
105
+ pub use cortex_m:: peripheral:: Peripherals as CorePeripherals ;
106
+ } ) ;
107
+
104
108
for p in CORE_PERIPHERALS {
105
109
let id = Ident :: new ( * p) ;
106
110
107
111
items. push ( quote ! {
108
112
pub use cortex_m:: peripheral:: #id;
109
113
} ) ;
110
-
111
- fields. push ( quote ! {
112
- #[ doc = #p]
113
- pub #id: & ' a #id
114
- } ) ;
115
- exprs. push ( quote ! ( #id: & * #id. get( ) ) ) ;
116
114
}
117
115
}
118
116
@@ -139,21 +137,39 @@ pub fn device(d: &Device, target: &Target, items: &mut Vec<Tokens>) -> Result<()
139
137
let id = Ident :: new ( & * p) ;
140
138
fields. push ( quote ! {
141
139
#[ doc = #p]
142
- pub #id: & ' a #id
140
+ pub #id: #id
143
141
} ) ;
144
- exprs. push ( quote ! ( #id: & * #id. get ( ) ) ) ;
142
+ exprs. push ( quote ! ( #id: #id { _marker : PhantomData } ) ) ;
145
143
}
146
144
147
145
items. push ( quote ! {
146
+ #[ no_mangle]
147
+ static mut PERIPHERALS : bool = false ;
148
+
148
149
/// All the peripherals
149
150
#[ allow( non_snake_case) ]
150
- pub struct Peripherals < ' a> {
151
+ pub struct Peripherals {
151
152
#( #fields, ) *
152
153
}
153
154
154
- impl <' a> Peripherals <' a> {
155
- /// Grants access to all the peripherals
156
- pub unsafe fn all( ) -> Self {
155
+ impl Peripherals {
156
+ /// Returns all the peripherals *once*
157
+ pub fn all( ) -> Option <Self > {
158
+ cortex_m:: interrupt:: free( |_| {
159
+ if unsafe { PERIPHERALS } {
160
+ None
161
+ } else {
162
+ Some ( unsafe { Peripherals :: _all( ) } )
163
+ }
164
+ } )
165
+ }
166
+
167
+ #[ doc( hidden) ]
168
+ pub unsafe fn _all( ) -> Self {
169
+ debug_assert!( !PERIPHERALS ) ;
170
+
171
+ PERIPHERALS = true ;
172
+
157
173
Peripherals {
158
174
#( #exprs, ) *
159
175
}
@@ -421,36 +437,44 @@ pub fn peripheral(
421
437
items : & mut Vec < Tokens > ,
422
438
defaults : & Defaults ,
423
439
) -> Result < ( ) > {
424
- let name = Ident :: new ( & * p. name . to_uppercase ( ) ) ;
425
440
let name_pc = Ident :: new ( & * p. name . to_sanitized_upper_case ( ) ) ;
426
441
let address = util:: hex ( p. base_address ) ;
427
442
let description = util:: respace ( p. description . as_ref ( ) . unwrap_or ( & p. name ) ) ;
428
443
444
+ let name_sc = Ident :: new ( & * p. name . to_sanitized_snake_case ( ) ) ;
445
+ let ( base, derived) = if let Some ( base) = p. derived_from . as_ref ( ) {
446
+ // TODO Verify that base exists
447
+ // TODO We don't handle inheritance style `derivedFrom`, we should raise
448
+ // an error in that case
449
+ ( Ident :: new ( & * base. to_sanitized_snake_case ( ) ) , true )
450
+ } else {
451
+ ( name_sc. clone ( ) , false )
452
+ } ;
453
+
429
454
items. push ( quote ! {
430
455
#[ doc = #description]
431
- pub const #name: Peripheral <#name_pc> =
432
- unsafe { Peripheral :: new( #address) } ;
433
- } ) ;
456
+ pub struct #name_pc { _marker: PhantomData <* const ( ) > }
434
457
435
- if let Some ( base) = p. derived_from . as_ref ( ) {
436
- // TODO Verify that base exists
437
- let base_sc = Ident :: new ( & * base. to_sanitized_snake_case ( ) ) ;
438
- items. push ( quote ! {
439
- /// Register block
440
- pub struct #name_pc { register_block: #base_sc:: RegisterBlock }
458
+ unsafe impl Send for #name_pc { }
441
459
442
- impl Deref for #name_pc {
443
- type Target = #base_sc:: RegisterBlock ;
460
+ impl #name_pc {
461
+ /// Returns a pointer to the register block
462
+ pub fn ptr( ) -> * const #base:: RegisterBlock {
463
+ #address as * const _
464
+ }
465
+ }
444
466
445
- fn deref( & self ) -> & #base_sc:: RegisterBlock {
446
- & self . register_block
447
- }
467
+ impl Deref for #name_pc {
468
+ type Target = #base:: RegisterBlock ;
469
+
470
+ fn deref( & self ) -> & #base:: RegisterBlock {
471
+ unsafe { & * #name_pc:: ptr( ) }
448
472
}
449
- } ) ;
473
+ }
474
+ } ) ;
450
475
451
- // TODO We don't handle inheritance style `derivedFrom`, we should raise
452
- // an error in that case
453
- return Ok ( ( ) ) ;
476
+ if derived {
477
+ return Ok ( ( ) )
454
478
}
455
479
456
480
let registers = p. registers . as_ref ( ) . map ( |x| x. as_ref ( ) ) . unwrap_or ( & [ ] [ ..] ) ;
@@ -476,7 +500,6 @@ pub fn peripheral(
476
500
) ?;
477
501
}
478
502
479
- let name_sc = Ident :: new ( & * p. name . to_sanitized_snake_case ( ) ) ;
480
503
let description = util:: respace ( p. description . as_ref ( ) . unwrap_or ( & p. name ) ) ;
481
504
items. push ( quote ! {
482
505
#[ doc = #description]
@@ -485,17 +508,6 @@ pub fn peripheral(
485
508
486
509
#( #mod_items) *
487
510
}
488
-
489
- #[ doc = #description]
490
- pub struct #name_pc { register_block: #name_sc:: RegisterBlock }
491
-
492
- impl Deref for #name_pc {
493
- type Target = #name_sc:: RegisterBlock ;
494
-
495
- fn deref( & self ) -> & #name_sc:: RegisterBlock {
496
- & self . register_block
497
- }
498
- }
499
511
} ) ;
500
512
501
513
Ok ( ( ) )
0 commit comments