aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/build.rs
diff options
context:
space:
mode:
authorFabian Wolter <[email protected]>2025-07-21 07:57:49 +0200
committerDario Nieuwenhuis <[email protected]>2025-09-05 21:15:46 +0200
commita6562c4f033432e40970aafe82f33c5138adf84e (patch)
treeb0f9e6e624af1708ffe1b865a3db205979fe5200 /embassy-stm32/build.rs
parent0407f7ebe8fabeb81b8a77811ec5dda0fee0b44b (diff)
Add STM32F1 AFIO remap
Diffstat (limited to 'embassy-stm32/build.rs')
-rw-r--r--embassy-stm32/build.rs125
1 files changed, 111 insertions, 14 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index b731012c6..f55e1e0c9 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1391,9 +1391,60 @@ fn main() {
1391 }) 1391 })
1392 } 1392 }
1393 1393
1394 g.extend(quote! { 1394 let pin_trait_impl = p
1395 pin_trait_impl!(#tr, #peri, #pin_name, #af); 1395 .afio
1396 }) 1396 .as_ref()
1397 .and_then(|afio| {
1398 if p.name.starts_with("TIM") {
1399 // timers are handled by timer_afio_impl!()
1400 return None;
1401 }
1402
1403 let values = afio
1404 .values
1405 .iter()
1406 .filter(|v| v.pins.contains(&pin.pin))
1407 .map(|v| v.value)
1408 .collect::<Vec<_>>();
1409
1410 if values.is_empty() {
1411 None
1412 } else {
1413 let setter = format_ident!("set_{}", afio.field.to_lowercase());
1414 let type_and_values = if is_bool_field("AFIO", afio.register, afio.field) {
1415 let values = values.iter().map(|&v| v > 0);
1416 quote!(AfioRemapBool, [#(#values),*])
1417 } else {
1418 quote!(AfioRemap, [#(#values),*])
1419 };
1420
1421 Some(quote! {
1422 pin_trait_afio_impl!(#tr, #peri, #pin_name, {#setter, #type_and_values});
1423 })
1424 }
1425 })
1426 .unwrap_or_else(|| {
1427 let peripherals_with_afio = [
1428 "CAN",
1429 "CEC",
1430 "ETH",
1431 "I2C",
1432 "SPI",
1433 "SUBGHZSPI",
1434 "USART",
1435 "UART",
1436 "LPUART",
1437 ];
1438 let af_or_not_applicable = if peripherals_with_afio.iter().any(|&x| p.name.starts_with(x)) {
1439 quote!(0, crate::gpio::AfioRemapNotApplicable)
1440 } else {
1441 quote!(#af)
1442 };
1443
1444 quote!(pin_trait_impl!(#tr, #peri, #pin_name, #af_or_not_applicable);)
1445 });
1446
1447 g.extend(pin_trait_impl);
1397 } 1448 }
1398 1449
1399 // ADC is special 1450 // ADC is special
@@ -1588,17 +1639,7 @@ fn main() {
1588 let register = format_ident!("{}", remap_info.register.to_lowercase()); 1639 let register = format_ident!("{}", remap_info.register.to_lowercase());
1589 let setter = format_ident!("set_{}", remap_info.field.to_lowercase()); 1640 let setter = format_ident!("set_{}", remap_info.field.to_lowercase());
1590 1641
1591 let field_metadata = METADATA 1642 let value = if is_bool_field("SYSCFG", &remap_info.register, &remap_info.field) {
1592 .peripherals
1593 .iter()
1594 .filter(|p| p.name == "SYSCFG")
1595 .flat_map(|p| p.registers.as_ref().unwrap().ir.fieldsets.iter())
1596 .filter(|f| f.name.eq_ignore_ascii_case(remap_info.register))
1597 .flat_map(|f| f.fields.iter())
1598 .find(|f| f.name.eq_ignore_ascii_case(remap_info.field))
1599 .unwrap();
1600
1601 let value = if field_metadata.bit_size == 1 {
1602 let bool_value = format_ident!("{}", remap_info.value > 0); 1643 let bool_value = format_ident!("{}", remap_info.value > 0);
1603 quote!(#bool_value) 1644 quote!(#bool_value)
1604 } else { 1645 } else {
@@ -1929,6 +1970,48 @@ fn main() {
1929 }); 1970 });
1930 1971
1931 // ======== 1972 // ========
1973 // Generate timer AFIO impls
1974
1975 for p in METADATA.peripherals {
1976 if p.name.starts_with("TIM") {
1977 let pname = format_ident!("{}", p.name);
1978 let afio = if let Some(afio) = &p.afio {
1979 let register = format_ident!("{}", afio.register.to_lowercase());
1980 let setter = format_ident!("set_{}", afio.field.to_lowercase());
1981
1982 let swj_cfg = if afio.register == "MAPR" {
1983 quote!(w.set_swj_cfg(crate::pac::afio::vals::SwjCfg::NO_OP);)
1984 } else {
1985 quote!()
1986 };
1987 let bool_eval = if is_bool_field("AFIO", &afio.register, &afio.field) {
1988 quote!(> 0)
1989 } else {
1990 quote!()
1991 };
1992
1993 let values = afio.values.iter().map(|v| {
1994 let mapr_value = v.value;
1995 let pin = v.pins.iter().map(|p| {
1996 let port_num = p.chars().nth(1).unwrap() as u8 - b'A';
1997 let pin_num = p[2..].parse::<u8>().unwrap();
1998 port_num * 16 + pin_num
1999 });
2000 quote!(#mapr_value, [#(#pin),*])
2001 });
2002
2003 quote! {
2004 , |v| crate::pac::AFIO.#register().modify(|w| { #swj_cfg w.#setter(v #bool_eval); }), #({#values}),*
2005 }
2006 } else {
2007 quote!()
2008 };
2009
2010 g.extend(quote!(timer_afio_impl!(#pname #afio);));
2011 }
2012 }
2013
2014 // ========
1932 // Generate gpio_block() function 2015 // Generate gpio_block() function
1933 2016
1934 let gpio_base = METADATA.peripherals.iter().find(|p| p.name == "GPIOA").unwrap().address as usize; 2017 let gpio_base = METADATA.peripherals.iter().find(|p| p.name == "GPIOA").unwrap().address as usize;
@@ -2300,3 +2383,17 @@ fn gcd(a: u32, b: u32) -> u32 {
2300 } 2383 }
2301 gcd(b, a % b) 2384 gcd(b, a % b)
2302} 2385}
2386
2387fn is_bool_field(peripheral: &str, register: &str, field: &str) -> bool {
2388 let field_metadata = METADATA
2389 .peripherals
2390 .iter()
2391 .filter(|p| p.name == peripheral)
2392 .flat_map(|p| p.registers.as_ref().unwrap().ir.fieldsets.iter())
2393 .filter(|f| f.name.eq_ignore_ascii_case(register))
2394 .flat_map(|f| f.fields.iter())
2395 .find(|f| f.name.eq_ignore_ascii_case(field))
2396 .unwrap();
2397
2398 field_metadata.bit_size == 1
2399}