@@ -18,23 +18,26 @@ fn main() {
1818 let mut cfgs = CfgSet :: new ( ) ;
1919 build_common:: set_target_cfgs ( & mut cfgs) ;
2020
21- // TODO: Declare all possible driver cfgs. Needs extra info in pac metadata
21+ fn driver_to_cfg_name ( name : & str ) -> String {
22+ match name. split_once ( "::" ) {
23+ Some ( ( path, _block) ) => path,
24+ None => name,
25+ }
26+ . replace ( "/" , "_" )
27+ }
28+
29+ // Declare all drivers in nxp-pac (used or unused)
30+ for peripheral in nxp_pac:: metadata:: META_PERIPHERALS {
31+ cfgs. declare ( & driver_to_cfg_name ( peripheral) ) ;
32+ }
2233
2334 // Enable all drivers for this chip
2435 for peripheral in METADATA . peripherals {
2536 if peripheral. driver_name . is_empty ( ) {
2637 continue ;
2738 }
2839
29- let cfg_name = match peripheral. driver_name . split_once ( "::" ) {
30- Some ( ( path, _block) ) => path,
31- None => peripheral. driver_name ,
32- }
33- . replace ( "/" , "_" ) ;
34-
35- cfgs. enable ( & cfg_name) ;
36- // Temporary until todo above is removed
37- cfgs. declare ( & cfg_name) ;
40+ cfgs. enable ( & driver_to_cfg_name ( peripheral. driver_name ) ) ;
3841 }
3942
4043 let generated = [
@@ -58,11 +61,34 @@ fn main() {
5861}
5962
6063fn generate_peripherals_call ( ) -> TokenStream {
61- let mut singletons: Vec < String > = Vec :: new ( ) ;
64+ struct Singleton {
65+ name : String ,
66+ feature : Option < String > ,
67+ }
68+
69+ impl Singleton {
70+ pub fn just_name ( name : impl ToString ) -> Self {
71+ Self {
72+ name : name. to_string ( ) ,
73+ feature : None ,
74+ }
75+ }
76+ }
77+
78+ let mut singletons: Vec < Singleton > = Vec :: new ( ) ;
6279 // Add pins
63- singletons. extend ( METADATA . pins . iter ( ) . map ( |pin| pin. name . to_owned ( ) ) ) ;
80+ singletons. extend ( METADATA . pins . iter ( ) . map ( |pin| Singleton {
81+ name : pin. name . to_owned ( ) ,
82+ feature : pin. feature . map ( |str| str. to_owned ( ) ) ,
83+ } ) ) ;
84+
6485 // Add peripherals
65- singletons. extend ( METADATA . peripherals . iter ( ) . map ( |peripheral| peripheral. name . to_owned ( ) ) ) ;
86+ singletons. extend (
87+ METADATA
88+ . peripherals
89+ . iter ( )
90+ . map ( |peripheral| Singleton :: just_name ( peripheral. name ) ) ,
91+ ) ;
6692
6793 // Add DMA channels
6894 let dma_regex = Regex :: new ( r"(?i:^DMA)(\d+)" ) . unwrap ( ) ;
@@ -75,7 +101,7 @@ fn generate_peripherals_call() -> TokenStream {
75101 let channels_num = get_regex_num ( dma_peripheral. driver_name , & dma_channels_regex) . unwrap ( ) ;
76102
77103 for channel in 0 ..channels_num {
78- singletons. push ( format ! ( "DMA{dma_num}_CH{channel}" ) ) ;
104+ singletons. push ( Singleton :: just_name ( format ! ( "DMA{dma_num}_CH{channel}" ) ) ) ;
79105 }
80106 }
81107
@@ -87,14 +113,22 @@ fn generate_peripherals_call() -> TokenStream {
87113 . filter_map ( |p| get_regex_num ( p. name , & ctimer_regex) )
88114 {
89115 for num in 0 ..4 {
90- singletons. push ( format ! ( "CTIMER{ctimer_num}_CH{num}" ) ) ;
116+ singletons. push ( Singleton :: just_name ( format ! ( "CTIMER{ctimer_num}_CH{num}" ) ) ) ;
91117 }
92118 }
93119
94- // TODO: Remove singletons for pins with dual-use based on feature flags
95-
96120 // Output the singletons
97- let singleton_tokens: Vec < _ > = singletons. iter ( ) . map ( |s| format_ident ! ( "{}" , s) ) . collect ( ) ;
121+ let singleton_tokens: Vec < _ > = singletons
122+ . iter ( )
123+ . map ( |s| {
124+ let feature = s
125+ . feature
126+ . as_ref ( )
127+ . map_or ( TokenStream :: default ( ) , |feature| quote ! { #[ cfg( feature = #feature) ] } ) ;
128+ let name = format_ident ! ( "{}" , s. name) ;
129+ quote ! { #feature #name }
130+ } )
131+ . collect ( ) ;
98132
99133 quote ! {
100134 embassy_hal_internal:: peripherals!( #( #singleton_tokens) , * ) ;
@@ -116,6 +150,17 @@ fn generate_interrupt_mod_call() -> TokenStream {
116150 }
117151}
118152
153+ fn pin_feature_gate ( pin_name : & str ) -> TokenStream {
154+ let pin = METADATA
155+ . pins
156+ . iter ( )
157+ . find ( |pin| pin. name == pin_name)
158+ . expect ( & format ! ( "Failed to find pin {pin_name}" ) ) ;
159+ pin. feature
160+ . as_ref ( )
161+ . map_or ( TokenStream :: default ( ) , |feature| quote ! { #[ cfg( feature = #feature) ] } )
162+ }
163+
119164fn generate_gpio_pin_impls ( ) -> TokenStream {
120165 let mut generated = TokenStream :: new ( ) ;
121166
@@ -132,8 +177,10 @@ fn generate_gpio_pin_impls() -> TokenStream {
132177 assert_eq ! ( s. pins. len( ) , 1 , "Each gpio signal should only have 1 pin: {s:?}" ) ;
133178 let pin = format_ident ! ( "{}" , s. pins[ 0 ] . pin) ;
134179 let pin_num = proc_macro2:: Literal :: u32_unsuffixed ( s. name . parse ( ) . unwrap ( ) ) ;
180+ let feature_gate = pin_feature_gate ( s. pins [ 0 ] . pin ) ;
135181
136182 generated. extend ( quote ! {
183+ #feature_gate
137184 impl_gpio_pin!( #pin, #gpio_num, #pin_num, #peripheral) ;
138185 } ) ;
139186 }
@@ -156,7 +203,10 @@ fn generate_adc_pin_impls() -> TokenStream {
156203 . unwrap ( ) ;
157204 for pin in signal. pins {
158205 let pin_name = format_ident ! ( "{}" , pin. pin) ;
206+ let feature_gate = pin_feature_gate ( pin. pin ) ;
207+
159208 generated. extend ( quote ! {
209+ #feature_gate
160210 impl_adc_pin!( #pin_name, #adc_name, #channel) ;
161211 } ) ;
162212 }
@@ -178,7 +228,10 @@ fn generate_clkout_impls() -> TokenStream {
178228 for pin in signal. pins {
179229 let pin_name = format_ident ! ( "{}" , pin. pin) ;
180230 let mux = format_ident ! ( "MUX{}" , pin. alt) ;
231+ let feature_gate = pin_feature_gate ( pin. pin ) ;
232+
181233 generated. extend ( quote ! {
234+ #feature_gate
182235 impl_clkout_pin!( #pin_name, #mux) ;
183236 } ) ;
184237 }
@@ -199,7 +252,10 @@ fn generate_lpi2c_pin_impls() -> TokenStream {
199252 for pin in signal. pins {
200253 let pin_name = format_ident ! ( "{}" , pin. pin) ;
201254 let mux = format_ident ! ( "MUX{}" , pin. alt) ;
255+ let feature_gate = pin_feature_gate ( pin. pin ) ;
256+
202257 generated. extend ( quote ! {
258+ #feature_gate
203259 impl_lpi2c_pin!( #pin_name, #lpi2c_name, #mux, #signal_pin) ;
204260 } ) ;
205261 }
@@ -220,7 +276,10 @@ fn generate_i3c_pin_impls() -> TokenStream {
220276 for pin in signal. pins {
221277 let pin_name = format_ident ! ( "{}" , pin. pin) ;
222278 let mux = format_ident ! ( "MUX{}" , pin. alt) ;
279+ let feature_gate = pin_feature_gate ( pin. pin ) ;
280+
223281 generated. extend ( quote ! {
282+ #feature_gate
224283 impl_i3c_pin!( #pin_name, #i3c_name, #mux, #signal_pin) ;
225284 } ) ;
226285 }
@@ -241,7 +300,10 @@ fn generate_spi_pin_impls() -> TokenStream {
241300 for pin in signal. pins {
242301 let pin_name = format_ident ! ( "{}" , pin. pin) ;
243302 let mux = format_ident ! ( "MUX{}" , pin. alt) ;
303+ let feature_gate = pin_feature_gate ( pin. pin ) ;
304+
244305 generated. extend ( quote ! {
306+ #feature_gate
245307 impl_spi_pin!( #pin_name, #spi_name, #mux, #signal_pin) ;
246308 } ) ;
247309 }
@@ -276,10 +338,13 @@ fn generate_ctimer_pin_impls() -> TokenStream {
276338 for pin in signal. pins {
277339 let pin_name = format_ident ! ( "{}" , pin. pin) ;
278340 let mux = format_ident ! ( "MUX{}" , pin. alt) ;
341+ let feature_gate = pin_feature_gate ( pin. pin ) ;
342+
279343 mat_pins. insert ( pin_name. clone ( ) , mux) ;
280344
281345 let ctimer_channel = format_ident ! ( "{}_CH{}" , ctimer_name, match_index) ;
282346 generated. extend ( quote ! {
347+ #feature_gate
283348 impl_ctimer_match!( #ctimer_name, #ctimer_channel, #pin_name) ;
284349 } ) ;
285350 }
@@ -289,12 +354,16 @@ fn generate_ctimer_pin_impls() -> TokenStream {
289354 }
290355
291356 for ( pin_name, mux) in inp_pins {
357+ let feature_gate = pin_feature_gate ( & pin_name. to_string ( ) ) ;
292358 generated. extend ( quote ! {
359+ #feature_gate
293360 impl_ctimer_input_pin!( #pin_name, #ctimer_name, #mux) ;
294361 } ) ;
295362 }
296363 for ( pin_name, mux) in mat_pins {
364+ let feature_gate = pin_feature_gate ( & pin_name. to_string ( ) ) ;
297365 generated. extend ( quote ! {
366+ #feature_gate
298367 impl_ctimer_output_pin!( #pin_name, #ctimer_name, #mux) ;
299368 } ) ;
300369 }
@@ -314,7 +383,10 @@ fn generate_lpuart_pin_impls() -> TokenStream {
314383 for pin in signal. pins {
315384 let pin_name = format_ident ! ( "{}" , pin. pin) ;
316385 let mux = format_ident ! ( "MUX{}" , pin. alt) ;
386+ let feature_gate = pin_feature_gate ( pin. pin ) ;
387+
317388 generated. extend ( quote ! {
389+ #feature_gate
318390 impl_lpuart_pin!( #lpuart_name, #pin_name, #mux, #signal_name) ;
319391 } ) ;
320392 }
0 commit comments