diff options
| -rw-r--r-- | embassy-stm32/build.rs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 6c364f7bb..2b66e7dad 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -308,6 +308,9 @@ fn main() { | |||
| 308 | // ======== | 308 | // ======== |
| 309 | // Generate RccPeripheral impls | 309 | // Generate RccPeripheral impls |
| 310 | 310 | ||
| 311 | let refcounted_peripherals = HashSet::from(["ADC", "USART", "SPI", "I2C"]); | ||
| 312 | let mut refcount_statics = HashSet::new(); | ||
| 313 | |||
| 311 | for p in METADATA.peripherals { | 314 | for p in METADATA.peripherals { |
| 312 | // generating RccPeripheral impl for H7 ADC3 would result in bad frequency | 315 | // generating RccPeripheral impl for H7 ADC3 would result in bad frequency |
| 313 | if !singletons.contains(&p.name.to_string()) | 316 | if !singletons.contains(&p.name.to_string()) |
| @@ -344,11 +347,40 @@ fn main() { | |||
| 344 | TokenStream::new() | 347 | TokenStream::new() |
| 345 | }; | 348 | }; |
| 346 | 349 | ||
| 350 | let ptype = p | ||
| 351 | .name | ||
| 352 | .replace(&['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'][..], ""); | ||
| 347 | let pname = format_ident!("{}", p.name); | 353 | let pname = format_ident!("{}", p.name); |
| 348 | let clk = format_ident!("{}", rcc.clock.to_ascii_lowercase()); | 354 | let clk = format_ident!("{}", rcc.clock.to_ascii_lowercase()); |
| 349 | let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); | 355 | let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); |
| 350 | let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase()); | 356 | let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase()); |
| 351 | 357 | ||
| 358 | let (before_enable, before_disable) = if refcounted_peripherals.contains(ptype.trim_start_matches("LP")) { | ||
| 359 | let refcount_static = | ||
| 360 | format_ident!("{}_{}", en.register.to_ascii_uppercase(), en.field.to_ascii_uppercase()); | ||
| 361 | |||
| 362 | refcount_statics.insert(refcount_static.clone()); | ||
| 363 | |||
| 364 | ( | ||
| 365 | quote! { | ||
| 366 | use atomic_polyfill::Ordering; | ||
| 367 | |||
| 368 | if refcount_statics::#refcount_static.fetch_add(1, Ordering::SeqCst) > 0 { | ||
| 369 | return; | ||
| 370 | } | ||
| 371 | }, | ||
| 372 | quote! { | ||
| 373 | use atomic_polyfill::Ordering; | ||
| 374 | |||
| 375 | if refcount_statics::#refcount_static.fetch_sub(1, Ordering::SeqCst) > 1 { | ||
| 376 | return; | ||
| 377 | } | ||
| 378 | }, | ||
| 379 | ) | ||
| 380 | } else { | ||
| 381 | (TokenStream::new(), TokenStream::new()) | ||
| 382 | }; | ||
| 383 | |||
| 352 | g.extend(quote! { | 384 | g.extend(quote! { |
| 353 | impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { | 385 | impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { |
| 354 | fn frequency() -> crate::time::Hertz { | 386 | fn frequency() -> crate::time::Hertz { |
| @@ -356,6 +388,7 @@ fn main() { | |||
| 356 | } | 388 | } |
| 357 | fn enable() { | 389 | fn enable() { |
| 358 | critical_section::with(|_| { | 390 | critical_section::with(|_| { |
| 391 | #before_enable | ||
| 359 | #[cfg(feature = "low-power")] | 392 | #[cfg(feature = "low-power")] |
| 360 | crate::rcc::clock_refcount_add(); | 393 | crate::rcc::clock_refcount_add(); |
| 361 | crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); | 394 | crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); |
| @@ -364,6 +397,7 @@ fn main() { | |||
| 364 | } | 397 | } |
| 365 | fn disable() { | 398 | fn disable() { |
| 366 | critical_section::with(|_| { | 399 | critical_section::with(|_| { |
| 400 | #before_disable | ||
| 367 | crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); | 401 | crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); |
| 368 | #[cfg(feature = "low-power")] | 402 | #[cfg(feature = "low-power")] |
| 369 | crate::rcc::clock_refcount_sub(); | 403 | crate::rcc::clock_refcount_sub(); |
| @@ -379,6 +413,21 @@ fn main() { | |||
| 379 | } | 413 | } |
| 380 | } | 414 | } |
| 381 | 415 | ||
| 416 | let mut refcount_mod = TokenStream::new(); | ||
| 417 | for refcount_static in refcount_statics { | ||
| 418 | refcount_mod.extend(quote! { | ||
| 419 | pub(crate) static #refcount_static: AtomicU8 = AtomicU8::new(0); | ||
| 420 | }); | ||
| 421 | } | ||
| 422 | |||
| 423 | g.extend(quote! { | ||
| 424 | mod refcount_statics { | ||
| 425 | use atomic_polyfill::AtomicU8; | ||
| 426 | |||
| 427 | #refcount_mod | ||
| 428 | } | ||
| 429 | }); | ||
| 430 | |||
| 382 | // ======== | 431 | // ======== |
| 383 | // Generate fns to enable GPIO, DMA in RCC | 432 | // Generate fns to enable GPIO, DMA in RCC |
| 384 | 433 | ||
