diff options
| author | Fabian Wolter <[email protected]> | 2025-07-21 07:57:49 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-05 21:15:46 +0200 |
| commit | a6562c4f033432e40970aafe82f33c5138adf84e (patch) | |
| tree | b0f9e6e624af1708ffe1b865a3db205979fe5200 /embassy-stm32/build.rs | |
| parent | 0407f7ebe8fabeb81b8a77811ec5dda0fee0b44b (diff) | |
Add STM32F1 AFIO remap
Diffstat (limited to 'embassy-stm32/build.rs')
| -rw-r--r-- | embassy-stm32/build.rs | 125 |
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 | |||
| 2387 | fn 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 | } | ||
