@@ -38,6 +38,7 @@ pub fn device(d: &Device, target: &Target, items: &mut Vec<Tokens>) -> Result<()
3838
3939 items. push ( quote ! {
4040 #![ doc = #doc]
41+ #![ allow( private_no_mangle_statics) ]
4142 #![ deny( missing_docs) ]
4243 #![ deny( warnings) ]
4344 #![ allow( non_camel_case_types) ]
@@ -69,8 +70,7 @@ pub fn device(d: &Device, target: &Target, items: &mut Vec<Tokens>) -> Result<()
6970 extern crate vcell;
7071
7172 use core:: ops:: Deref ;
72-
73- use bare_metal:: Peripheral ;
73+ use core:: marker:: PhantomData ;
7474 } ) ;
7575
7676 if let Some ( cpu) = d. cpu . as_ref ( ) {
@@ -101,18 +101,16 @@ pub fn device(d: &Device, target: &Target, items: &mut Vec<Tokens>) -> Result<()
101101 let mut fields = vec ! [ ] ;
102102 let mut exprs = vec ! [ ] ;
103103 if * target == Target :: CortexM {
104+ items. push ( quote ! {
105+ pub use cortex_m:: peripheral:: Peripherals as CorePeripherals ;
106+ } ) ;
107+
104108 for p in CORE_PERIPHERALS {
105109 let id = Ident :: new ( * p) ;
106110
107111 items. push ( quote ! {
108112 pub use cortex_m:: peripheral:: #id;
109113 } ) ;
110-
111- fields. push ( quote ! {
112- #[ doc = #p]
113- pub #id: & ' a #id
114- } ) ;
115- exprs. push ( quote ! ( #id: & * #id. get( ) ) ) ;
116114 }
117115 }
118116
@@ -139,21 +137,39 @@ pub fn device(d: &Device, target: &Target, items: &mut Vec<Tokens>) -> Result<()
139137 let id = Ident :: new ( & * p) ;
140138 fields. push ( quote ! {
141139 #[ doc = #p]
142- pub #id: & ' a #id
140+ pub #id: #id
143141 } ) ;
144- exprs. push ( quote ! ( #id: & * #id. get ( ) ) ) ;
142+ exprs. push ( quote ! ( #id: #id { _marker : PhantomData } ) ) ;
145143 }
146144
147145 items. push ( quote ! {
146+ #[ no_mangle]
147+ static mut PERIPHERALS : bool = false ;
148+
148149 /// All the peripherals
149150 #[ allow( non_snake_case) ]
150- pub struct Peripherals < ' a> {
151+ pub struct Peripherals {
151152 #( #fields, ) *
152153 }
153154
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+
157173 Peripherals {
158174 #( #exprs, ) *
159175 }
@@ -421,36 +437,44 @@ pub fn peripheral(
421437 items : & mut Vec < Tokens > ,
422438 defaults : & Defaults ,
423439) -> Result < ( ) > {
424- let name = Ident :: new ( & * p. name . to_uppercase ( ) ) ;
425440 let name_pc = Ident :: new ( & * p. name . to_sanitized_upper_case ( ) ) ;
426441 let address = util:: hex ( p. base_address ) ;
427442 let description = util:: respace ( p. description . as_ref ( ) . unwrap_or ( & p. name ) ) ;
428443
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+
429454 items. push ( quote ! {
430455 #[ doc = #description]
431- pub const #name: Peripheral <#name_pc> =
432- unsafe { Peripheral :: new( #address) } ;
433- } ) ;
456+ pub struct #name_pc { _marker: PhantomData <* const ( ) > }
434457
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 { }
441459
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+ }
444466
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( ) }
448472 }
449- } ) ;
473+ }
474+ } ) ;
450475
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 ( ( ) )
454478 }
455479
456480 let registers = p. registers . as_ref ( ) . map ( |x| x. as_ref ( ) ) . unwrap_or ( & [ ] [ ..] ) ;
@@ -476,7 +500,6 @@ pub fn peripheral(
476500 ) ?;
477501 }
478502
479- let name_sc = Ident :: new ( & * p. name . to_sanitized_snake_case ( ) ) ;
480503 let description = util:: respace ( p. description . as_ref ( ) . unwrap_or ( & p. name ) ) ;
481504 items. push ( quote ! {
482505 #[ doc = #description]
@@ -485,17 +508,6 @@ pub fn peripheral(
485508
486509 #( #mod_items) *
487510 }
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- }
499511 } ) ;
500512
501513 Ok ( ( ) )
0 commit comments