aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/build.rs')
-rw-r--r--embassy-stm32/build.rs575
1 files changed, 397 insertions, 178 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index b5f1261fe..a3b863340 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -9,8 +9,8 @@ use proc_macro2::{Ident, TokenStream};
9use quote::{format_ident, quote}; 9use quote::{format_ident, quote};
10use stm32_metapac::metadata::ir::BitOffset; 10use stm32_metapac::metadata::ir::BitOffset;
11use stm32_metapac::metadata::{ 11use stm32_metapac::metadata::{
12 MemoryRegion, MemoryRegionKind, PeripheralRccKernelClock, PeripheralRccRegister, PeripheralRegisters, StopMode, 12 ALL_CHIPS, ALL_PERIPHERAL_VERSIONS, METADATA, MemoryRegion, MemoryRegionKind, Peripheral, PeripheralRccKernelClock,
13 ALL_CHIPS, ALL_PERIPHERAL_VERSIONS, METADATA, 13 PeripheralRccRegister, PeripheralRegisters, StopMode,
14}; 14};
15 15
16#[path = "./build_common.rs"] 16#[path = "./build_common.rs"]
@@ -105,13 +105,17 @@ fn main() {
105 } 105 }
106 (false, false) => { 106 (false, false) => {
107 if METADATA.memory.len() != 1 { 107 if METADATA.memory.len() != 1 {
108 panic!("Chip supports single and dual bank configuration. No Cargo feature to select one is enabled. Use the 'single-bank' or 'dual-bank' feature to make your selection") 108 panic!(
109 "Chip supports single and dual bank configuration. No Cargo feature to select one is enabled. Use the 'single-bank' or 'dual-bank' feature to make your selection"
110 )
109 } 111 }
110 METADATA.memory[0] 112 METADATA.memory[0]
111 } 113 }
112 } 114 }
113 }; 115 };
114 116
117 let has_bkpsram = memory.iter().any(|m| m.name == "BKPSRAM");
118
115 // ======== 119 // ========
116 // Generate singletons 120 // Generate singletons
117 121
@@ -122,6 +126,16 @@ fn main() {
122 singletons.push(p.name.to_string()); 126 singletons.push(p.name.to_string());
123 } 127 }
124 128
129 cfgs.declare("backup_sram");
130
131 if has_bkpsram {
132 singletons.push("BKPSRAM".to_string());
133 cfgs.enable("backup_sram")
134 }
135
136 // compile a map of peripherals
137 let peripheral_map: BTreeMap<&str, &Peripheral> = METADATA.peripherals.iter().map(|p| (p.name, p)).collect();
138
125 // generate one singleton per peripheral (with many exceptions...) 139 // generate one singleton per peripheral (with many exceptions...)
126 for p in METADATA.peripherals { 140 for p in METADATA.peripherals {
127 if let Some(r) = &p.registers { 141 if let Some(r) = &p.registers {
@@ -159,6 +173,11 @@ fn main() {
159 } 173 }
160 singletons.push(p.name.to_string()); 174 singletons.push(p.name.to_string());
161 } 175 }
176
177 "eth" => {
178 singletons.push(p.name.to_string());
179 singletons.push("ETH_SMA".to_string());
180 }
162 //"dbgmcu" => {} 181 //"dbgmcu" => {}
163 //"syscfg" => {} 182 //"syscfg" => {}
164 //"dma" => {} 183 //"dma" => {}
@@ -303,9 +322,33 @@ fn main() {
303 _ => panic!("unknown time_driver {:?}", time_driver), 322 _ => panic!("unknown time_driver {:?}", time_driver),
304 }; 323 };
305 324
306 if !time_driver_singleton.is_empty() { 325 let time_driver_irq_decl = if !time_driver_singleton.is_empty() {
307 cfgs.enable(format!("time_driver_{}", time_driver_singleton.to_lowercase())); 326 cfgs.enable(format!("time_driver_{}", time_driver_singleton.to_lowercase()));
308 } 327
328 let p = peripheral_map.get(time_driver_singleton).unwrap();
329 let irqs: BTreeSet<_> = p
330 .interrupts
331 .iter()
332 .filter(|i| i.signal == "CC" || i.signal == "UP")
333 .map(|i| i.interrupt.to_ascii_uppercase())
334 .collect();
335
336 irqs.iter()
337 .map(|i| {
338 let irq = format_ident!("{}", i);
339 quote! {
340 #[cfg(feature = "rt")]
341 #[interrupt]
342 fn #irq() {
343 crate::time_driver::get_driver().on_interrupt();
344 }
345 }
346 })
347 .collect()
348 } else {
349 TokenStream::new()
350 };
351
309 for tim in [ 352 for tim in [
310 "tim1", "tim2", "tim3", "tim4", "tim5", "tim8", "tim9", "tim12", "tim15", "tim20", "tim21", "tim22", "tim23", 353 "tim1", "tim2", "tim3", "tim4", "tim5", "tim8", "tim9", "tim12", "tim15", "tim20", "tim21", "tim22", "tim23",
311 "tim24", 354 "tim24",
@@ -337,8 +380,13 @@ fn main() {
337 // ======== 380 // ========
338 // Generate interrupt declarations 381 // Generate interrupt declarations
339 382
383 let mut exti2_tsc_shared_int_present: Option<stm32_metapac::metadata::Interrupt> = None;
340 let mut irqs = Vec::new(); 384 let mut irqs = Vec::new();
341 for irq in METADATA.interrupts { 385 for irq in METADATA.interrupts {
386 // The PAC doesn't ensure this is listed as the IRQ of EXTI2, so we must do so
387 if irq.name == "EXTI2_TSC" {
388 exti2_tsc_shared_int_present = Some(irq.clone())
389 }
342 irqs.push(format_ident!("{}", irq.name)); 390 irqs.push(format_ident!("{}", irq.name));
343 } 391 }
344 392
@@ -350,103 +398,112 @@ fn main() {
350 ); 398 );
351 }); 399 });
352 400
401 g.extend(time_driver_irq_decl);
402
353 // ======== 403 // ========
354 // Generate FLASH regions 404 // Generate FLASH regions
355 let mut flash_regions = TokenStream::new(); 405 cfgs.declare("flash");
356 let flash_memory_regions: Vec<_> = memory 406 let mut has_flash = false;
357 .iter() 407 if !chip_name.starts_with("stm32n6") {
358 .filter(|x| x.kind == MemoryRegionKind::Flash && x.settings.is_some()) 408 cfgs.enable("flash");
359 .collect(); 409 has_flash = true;
360 for region in flash_memory_regions.iter() { 410
361 let region_name = format_ident!("{}", get_flash_region_name(region.name)); 411 let mut flash_regions = TokenStream::new();
362 let bank_variant = format_ident!( 412 let flash_memory_regions: Vec<_> = memory
363 "{}", 413 .iter()
364 if region.name.starts_with("BANK_1") { 414 .filter(|x| x.kind == MemoryRegionKind::Flash && x.settings.is_some())
365 "Bank1" 415 .collect();
366 } else if region.name.starts_with("BANK_2") { 416 for region in flash_memory_regions.iter() {
367 "Bank2" 417 let region_name = format_ident!("{}", get_flash_region_name(region.name));
368 } else if region.name == "OTP" { 418 let bank_variant = format_ident!(
369 "Otp" 419 "{}",
370 } else { 420 if region.name.starts_with("BANK_1") {
371 continue; 421 "Bank1"
372 } 422 } else if region.name.starts_with("BANK_2") {
373 ); 423 "Bank2"
374 let base = region.address; 424 } else if region.name == "OTP" {
375 let size = region.size; 425 "Otp"
376 let settings = region.settings.as_ref().unwrap(); 426 } else {
377 let erase_size = settings.erase_size; 427 continue;
378 let write_size = settings.write_size; 428 }
379 let erase_value = settings.erase_value; 429 );
380 430 let base = region.address;
381 flash_regions.extend(quote! { 431 let size = region.size;
382 pub const #region_name: crate::flash::FlashRegion = crate::flash::FlashRegion { 432 let settings = region.settings.as_ref().unwrap();
383 bank: crate::flash::FlashBank::#bank_variant, 433 let erase_size = settings.erase_size;
384 base: #base, 434 let write_size = settings.write_size;
385 size: #size, 435 let erase_value = settings.erase_value;
386 erase_size: #erase_size, 436
387 write_size: #write_size, 437 flash_regions.extend(quote! {
388 erase_value: #erase_value, 438 pub const #region_name: crate::flash::FlashRegion = crate::flash::FlashRegion {
389 _ensure_internal: (), 439 bank: crate::flash::FlashBank::#bank_variant,
390 }; 440 base: #base,
391 }); 441 size: #size,
442 erase_size: #erase_size,
443 write_size: #write_size,
444 erase_value: #erase_value,
445 _ensure_internal: (),
446 };
447 });
392 448
393 let region_type = format_ident!("{}", get_flash_region_type_name(region.name)); 449 let region_type = format_ident!("{}", get_flash_region_type_name(region.name));
394 flash_regions.extend(quote! { 450 flash_regions.extend(quote! {
395 #[cfg(flash)] 451 #[cfg(flash)]
396 pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>); 452 pub struct #region_type<'d, MODE = crate::flash::Async>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>, pub(crate) core::marker::PhantomData<MODE>);
397 }); 453 });
398 } 454 }
399 455
400 let (fields, (inits, region_names)): (Vec<TokenStream>, (Vec<TokenStream>, Vec<Ident>)) = flash_memory_regions 456 let (fields, (inits, region_names)): (Vec<TokenStream>, (Vec<TokenStream>, Vec<Ident>)) = flash_memory_regions
401 .iter() 457 .iter()
402 .map(|f| { 458 .map(|f| {
403 let region_name = get_flash_region_name(f.name); 459 let region_name = get_flash_region_name(f.name);
404 let field_name = format_ident!("{}", region_name.to_lowercase()); 460 let field_name = format_ident!("{}", region_name.to_lowercase());
405 let field_type = format_ident!("{}", get_flash_region_type_name(f.name)); 461 let field_type = format_ident!("{}", get_flash_region_type_name(f.name));
406 let field = quote! { 462 let field = quote! {
407 pub #field_name: #field_type<'d, MODE> 463 pub #field_name: #field_type<'d, MODE>
408 }; 464 };
409 let region_name = format_ident!("{}", region_name); 465 let region_name = format_ident!("{}", region_name);
410 let init = quote! { 466 let init = quote! {
411 #field_name: #field_type(&#region_name, unsafe { p.clone_unchecked()}, core::marker::PhantomData) 467 #field_name: #field_type(&#region_name, unsafe { p.clone_unchecked()}, core::marker::PhantomData)
412 }; 468 };
413 469
414 (field, (init, region_name)) 470 (field, (init, region_name))
415 }) 471 })
416 .unzip(); 472 .unzip();
417
418 let regions_len = flash_memory_regions.len();
419 flash_regions.extend(quote! {
420 #[cfg(flash)]
421 pub struct FlashLayout<'d, MODE = crate::flash::Async> {
422 #(#fields),*,
423 _mode: core::marker::PhantomData<MODE>,
424 }
425 473
426 #[cfg(flash)] 474 let regions_len = flash_memory_regions.len();
427 impl<'d, MODE> FlashLayout<'d, MODE> { 475 flash_regions.extend(quote! {
428 pub(crate) fn new(p: embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>) -> Self { 476 #[cfg(flash)]
429 Self { 477 pub struct FlashLayout<'d, MODE = crate::flash::Async> {
430 #(#inits),*, 478 #(#fields),*,
431 _mode: core::marker::PhantomData, 479 _mode: core::marker::PhantomData<MODE>,
480 }
481
482 #[cfg(flash)]
483 impl<'d, MODE> FlashLayout<'d, MODE> {
484 pub(crate) fn new(p: embassy_hal_internal::Peri<'d, crate::peripherals::FLASH>) -> Self {
485 Self {
486 #(#inits),*,
487 _mode: core::marker::PhantomData,
488 }
432 } 489 }
433 } 490 }
434 }
435 491
436 pub const FLASH_REGIONS: [&crate::flash::FlashRegion; #regions_len] = [ 492 pub const FLASH_REGIONS: [&crate::flash::FlashRegion; #regions_len] = [
437 #(&#region_names),* 493 #(&#region_names),*
438 ]; 494 ];
439 }); 495 });
440 496
441 let max_erase_size = flash_memory_regions 497 let max_erase_size = flash_memory_regions
442 .iter() 498 .iter()
443 .map(|region| region.settings.as_ref().unwrap().erase_size) 499 .map(|region| region.settings.as_ref().unwrap().erase_size)
444 .max() 500 .max()
445 .unwrap(); 501 .unwrap();
446 502
447 g.extend(quote! { pub const MAX_ERASE_SIZE: usize = #max_erase_size as usize; }); 503 g.extend(quote! { pub const MAX_ERASE_SIZE: usize = #max_erase_size as usize; });
448 504
449 g.extend(quote! { pub mod flash_regions { #flash_regions } }); 505 g.extend(quote! { pub mod flash_regions { #flash_regions } });
506 }
450 507
451 // ======== 508 // ========
452 // Extract the rcc registers 509 // Extract the rcc registers
@@ -893,6 +950,60 @@ fn main() {
893 } 950 }
894 } 951 }
895 952
953 if kind == "gpio" {
954 for p in METADATA.peripherals {
955 // set all GPIOs to analog mode except for PA13 and PA14 which are SWDIO and SWDCLK
956 if p.registers.is_some()
957 && p.registers.as_ref().unwrap().kind == "gpio"
958 && p.registers.as_ref().unwrap().version != "v1"
959 {
960 let port = format_ident!("{}", p.name);
961 if p.name == "GPIOA" {
962 gg.extend(quote! {
963 // leave PA13 and PA14 as unchanged
964 crate::pac::#port.moder().modify(|w| {
965 w.set_moder(0, crate::pac::gpio::vals::Moder::ANALOG);
966 w.set_moder(1, crate::pac::gpio::vals::Moder::ANALOG);
967 w.set_moder(2, crate::pac::gpio::vals::Moder::ANALOG);
968 w.set_moder(3, crate::pac::gpio::vals::Moder::ANALOG);
969 w.set_moder(4, crate::pac::gpio::vals::Moder::ANALOG);
970 w.set_moder(5, crate::pac::gpio::vals::Moder::ANALOG);
971 w.set_moder(6, crate::pac::gpio::vals::Moder::ANALOG);
972 w.set_moder(7, crate::pac::gpio::vals::Moder::ANALOG);
973 w.set_moder(8, crate::pac::gpio::vals::Moder::ANALOG);
974 w.set_moder(9, crate::pac::gpio::vals::Moder::ANALOG);
975 w.set_moder(10, crate::pac::gpio::vals::Moder::ANALOG);
976 w.set_moder(11, crate::pac::gpio::vals::Moder::ANALOG);
977 w.set_moder(12, crate::pac::gpio::vals::Moder::ANALOG);
978 w.set_moder(15, crate::pac::gpio::vals::Moder::ANALOG);
979 });
980 });
981 } else {
982 gg.extend(quote! {
983 crate::pac::#port.moder().modify(|w| {
984 w.set_moder(0, crate::pac::gpio::vals::Moder::ANALOG);
985 w.set_moder(1, crate::pac::gpio::vals::Moder::ANALOG);
986 w.set_moder(2, crate::pac::gpio::vals::Moder::ANALOG);
987 w.set_moder(3, crate::pac::gpio::vals::Moder::ANALOG);
988 w.set_moder(4, crate::pac::gpio::vals::Moder::ANALOG);
989 w.set_moder(5, crate::pac::gpio::vals::Moder::ANALOG);
990 w.set_moder(6, crate::pac::gpio::vals::Moder::ANALOG);
991 w.set_moder(7, crate::pac::gpio::vals::Moder::ANALOG);
992 w.set_moder(8, crate::pac::gpio::vals::Moder::ANALOG);
993 w.set_moder(9, crate::pac::gpio::vals::Moder::ANALOG);
994 w.set_moder(10, crate::pac::gpio::vals::Moder::ANALOG);
995 w.set_moder(11, crate::pac::gpio::vals::Moder::ANALOG);
996 w.set_moder(12, crate::pac::gpio::vals::Moder::ANALOG);
997 w.set_moder(13, crate::pac::gpio::vals::Moder::ANALOG);
998 w.set_moder(14, crate::pac::gpio::vals::Moder::ANALOG);
999 w.set_moder(15, crate::pac::gpio::vals::Moder::ANALOG);
1000 });
1001 });
1002 }
1003 }
1004 }
1005 }
1006
896 let fname = format_ident!("init_{}", kind); 1007 let fname = format_ident!("init_{}", kind);
897 g.extend(quote! { 1008 g.extend(quote! {
898 pub unsafe fn #fname(){ 1009 pub unsafe fn #fname(){
@@ -1329,14 +1440,32 @@ fn main() {
1329 (("tsc", "G8_IO2"), quote!(crate::tsc::G8IO2Pin)), 1440 (("tsc", "G8_IO2"), quote!(crate::tsc::G8IO2Pin)),
1330 (("tsc", "G8_IO3"), quote!(crate::tsc::G8IO3Pin)), 1441 (("tsc", "G8_IO3"), quote!(crate::tsc::G8IO3Pin)),
1331 (("tsc", "G8_IO4"), quote!(crate::tsc::G8IO4Pin)), 1442 (("tsc", "G8_IO4"), quote!(crate::tsc::G8IO4Pin)),
1443 (("lcd", "SEG"), quote!(crate::lcd::SegPin)),
1444 (("lcd", "COM"), quote!(crate::lcd::ComPin)),
1445 (("lcd", "VLCD"), quote!(crate::lcd::VlcdPin)),
1332 (("dac", "OUT1"), quote!(crate::dac::DacPin<Ch1>)), 1446 (("dac", "OUT1"), quote!(crate::dac::DacPin<Ch1>)),
1333 (("dac", "OUT2"), quote!(crate::dac::DacPin<Ch2>)), 1447 (("dac", "OUT2"), quote!(crate::dac::DacPin<Ch2>)),
1334 ].into(); 1448 ].into();
1335 1449
1336 for p in METADATA.peripherals { 1450 for p in METADATA.peripherals {
1337 if let Some(regs) = &p.registers { 1451 if let Some(regs) = &p.registers {
1452 let mut adc_pairs: BTreeMap<u8, (Option<Ident>, Option<Ident>)> = BTreeMap::new();
1453 let mut seen_lcd_seg_pins = HashSet::new();
1454
1338 for pin in p.pins { 1455 for pin in p.pins {
1339 let key = (regs.kind, pin.signal); 1456 let mut key = (regs.kind, pin.signal);
1457
1458 // LCD is special. There are so many pins!
1459 if regs.kind == "lcd" {
1460 key.1 = pin.signal.trim_end_matches(char::is_numeric);
1461
1462 if key.1 == "SEG" && !seen_lcd_seg_pins.insert(pin.pin) {
1463 // LCD has SEG pins multiplexed in the peripheral
1464 // This means we can see them twice. We need to skip those so we're not impl'ing the trait twice
1465 continue;
1466 }
1467 }
1468
1340 if let Some(tr) = signals.get(&key) { 1469 if let Some(tr) = signals.get(&key) {
1341 let mut peri = format_ident!("{}", p.name); 1470 let mut peri = format_ident!("{}", p.name);
1342 1471
@@ -1379,6 +1508,11 @@ fn main() {
1379 } 1508 }
1380 } 1509 }
1381 1510
1511 // MDIO and MDC are special
1512 if pin.signal == "MDIO" || pin.signal == "MDC" {
1513 peri = format_ident!("{}", "ETH_SMA");
1514 }
1515
1382 // XSPI NCS pin to CSSEL mapping 1516 // XSPI NCS pin to CSSEL mapping
1383 if pin.signal.ends_with("NCS1") { 1517 if pin.signal.ends_with("NCS1") {
1384 g.extend(quote! { 1518 g.extend(quote! {
@@ -1456,25 +1590,29 @@ fn main() {
1456 }; 1590 };
1457 1591
1458 // H7 has differential voltage measurements 1592 // H7 has differential voltage measurements
1459 let ch: Option<u8> = if pin.signal.starts_with("INP") { 1593 let ch: Option<(u8, bool)> = if pin.signal.starts_with("INP") {
1460 Some(pin.signal.strip_prefix("INP").unwrap().parse().unwrap()) 1594 Some((pin.signal.strip_prefix("INP").unwrap().parse().unwrap(), false))
1461 } else if pin.signal.starts_with("INN") { 1595 } else if pin.signal.starts_with("INN") {
1462 // TODO handle in the future when embassy supports differential measurements 1596 Some((pin.signal.strip_prefix("INN").unwrap().parse().unwrap(), true))
1463 None
1464 } else if pin.signal.starts_with("IN") && pin.signal.ends_with('b') { 1597 } else if pin.signal.starts_with("IN") && pin.signal.ends_with('b') {
1465 // we number STM32L1 ADC bank 1 as 0..=31, bank 2 as 32..=63 1598 // we number STM32L1 ADC bank 1 as 0..=31, bank 2 as 32..=63
1466 let signal = pin.signal.strip_prefix("IN").unwrap().strip_suffix('b').unwrap(); 1599 let signal = pin.signal.strip_prefix("IN").unwrap().strip_suffix('b').unwrap();
1467 Some(32u8 + signal.parse::<u8>().unwrap()) 1600 Some((32u8 + signal.parse::<u8>().unwrap(), false))
1468 } else if pin.signal.starts_with("IN") { 1601 } else if pin.signal.starts_with("IN") {
1469 Some(pin.signal.strip_prefix("IN").unwrap().parse().unwrap()) 1602 Some((pin.signal.strip_prefix("IN").unwrap().parse().unwrap(), false))
1470 } else { 1603 } else {
1471 None 1604 None
1472 }; 1605 };
1473 if let Some(ch) = ch { 1606 if let Some((ch, false)) = ch {
1607 adc_pairs.entry(ch).or_insert((None, None)).0.replace(pin_name.clone());
1608
1474 g.extend(quote! { 1609 g.extend(quote! {
1475 impl_adc_pin!( #peri, #pin_name, #ch); 1610 impl_adc_pin!( #peri, #pin_name, #ch);
1476 }) 1611 })
1477 } 1612 }
1613 if let Some((ch, true)) = ch {
1614 adc_pairs.entry(ch).or_insert((None, None)).1.replace(pin_name.clone());
1615 }
1478 } 1616 }
1479 1617
1480 if regs.kind == "opamp" { 1618 if regs.kind == "opamp" {
@@ -1513,6 +1651,23 @@ fn main() {
1513 }) 1651 })
1514 } 1652 }
1515 } 1653 }
1654
1655 {
1656 let peri = format_ident!("{}", p.name);
1657
1658 for (ch, (pin, npin)) in adc_pairs {
1659 let (pin_name, npin_name) = match (pin, npin) {
1660 (Some(pin), Some(npin)) => (pin, npin),
1661 _ => {
1662 continue;
1663 }
1664 };
1665
1666 g.extend(quote! {
1667 impl_adc_pair!( #peri, #pin_name, #npin_name, #ch);
1668 })
1669 }
1670 }
1516 } 1671 }
1517 } 1672 }
1518 1673
@@ -1561,13 +1716,13 @@ fn main() {
1561 .into(); 1716 .into();
1562 1717
1563 if chip_name.starts_with("stm32u5") { 1718 if chip_name.starts_with("stm32u5") {
1564 signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma4)); 1719 signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma));
1565 } else { 1720 } else {
1566 signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma)); 1721 signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma));
1567 } 1722 }
1568 1723
1569 if chip_name.starts_with("stm32wba") { 1724 if chip_name.starts_with("stm32wba") {
1570 signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma4)); 1725 signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma));
1571 } 1726 }
1572 1727
1573 if chip_name.starts_with("stm32g4") { 1728 if chip_name.starts_with("stm32g4") {
@@ -1654,70 +1809,88 @@ fn main() {
1654 } 1809 }
1655 1810
1656 // ======== 1811 // ========
1657 // Generate Div/Mul impls for RCC prescalers/dividers/multipliers. 1812 // Generate Div/Mul impls for RCC and ADC prescalers/dividers/multipliers.
1658 for e in rcc_registers.ir.enums { 1813 for (kind, psc_enums) in ["rcc", "adc", "adccommon"].iter().filter_map(|kind| {
1659 fn is_rcc_name(e: &str) -> bool { 1814 METADATA
1660 match e { 1815 .peripherals
1661 "Pllp" | "Pllq" | "Pllr" | "Plldivst" | "Pllm" | "Plln" | "Prediv1" | "Prediv2" | "Hpre5" => true, 1816 .iter()
1662 "Timpre" | "Pllrclkpre" => false, 1817 .filter_map(|p| p.registers.as_ref())
1663 e if e.ends_with("pre") || e.ends_with("pres") || e.ends_with("div") || e.ends_with("mul") => true, 1818 .find(|r| r.kind == *kind)
1664 _ => false, 1819 .map(|r| (*kind, r.ir.enums))
1820 }) {
1821 for e in psc_enums.iter() {
1822 fn is_adc_name(e: &str) -> bool {
1823 match e {
1824 "Presc" | "Adc4Presc" | "Adcpre" => true,
1825 _ => false,
1826 }
1665 } 1827 }
1666 }
1667 1828
1668 fn parse_num(n: &str) -> Result<Frac, ()> { 1829 fn is_rcc_name(e: &str) -> bool {
1669 for prefix in ["DIV", "MUL"] { 1830 match e {
1670 if let Some(n) = n.strip_prefix(prefix) { 1831 "Pllp" | "Pllq" | "Pllr" | "Plldivst" | "Pllm" | "Plln" | "Prediv1" | "Prediv2" | "Hpre5" => true,
1671 let exponent = n.find('_').map(|e| n.len() - 1 - e).unwrap_or(0) as u32; 1832 "Timpre" | "Pllrclkpre" => false,
1672 let mantissa = n.replace('_', "").parse().map_err(|_| ())?; 1833 e if e.ends_with("pre") || e.ends_with("pres") || e.ends_with("div") || e.ends_with("mul") => true,
1673 let f = Frac { 1834 _ => false,
1674 num: mantissa,
1675 denom: 10u32.pow(exponent),
1676 };
1677 return Ok(f.simplify());
1678 } 1835 }
1679 } 1836 }
1680 Err(())
1681 }
1682 1837
1683 if is_rcc_name(e.name) { 1838 fn parse_num(n: &str) -> Result<Frac, ()> {
1684 let enum_name = format_ident!("{}", e.name); 1839 for prefix in ["DIV", "MUL"] {
1685 let mut muls = Vec::new(); 1840 if let Some(n) = n.strip_prefix(prefix) {
1686 let mut divs = Vec::new(); 1841 let exponent = n.find('_').map(|e| n.len() - 1 - e).unwrap_or(0) as u32;
1687 for v in e.variants { 1842 let mantissa = n.replace('_', "").parse().map_err(|_| ())?;
1688 let Ok(val) = parse_num(v.name) else { 1843 let f = Frac {
1689 panic!("could not parse mul/div. enum={} variant={}", e.name, v.name) 1844 num: mantissa,
1690 }; 1845 denom: 10u32.pow(exponent),
1691 let variant_name = format_ident!("{}", v.name); 1846 };
1692 let variant = quote!(crate::pac::rcc::vals::#enum_name::#variant_name); 1847 return Ok(f.simplify());
1693 let num = val.num; 1848 }
1694 let denom = val.denom; 1849 }
1695 muls.push(quote!(#variant => self * #num / #denom,)); 1850 Err(())
1696 divs.push(quote!(#variant => self * #denom / #num,));
1697 } 1851 }
1698 1852
1699 g.extend(quote! { 1853 if (kind == "rcc" && is_rcc_name(e.name)) || ((kind == "adccommon" || kind == "adc") && is_adc_name(e.name))
1700 impl core::ops::Div<crate::pac::rcc::vals::#enum_name> for crate::time::Hertz { 1854 {
1701 type Output = crate::time::Hertz; 1855 let kind = format_ident!("{}", kind);
1702 fn div(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output { 1856 let enum_name = format_ident!("{}", e.name);
1703 match rhs { 1857 let mut muls = Vec::new();
1704 #(#divs)* 1858 let mut divs = Vec::new();
1705 #[allow(unreachable_patterns)] 1859 for v in e.variants {
1706 _ => unreachable!(), 1860 let Ok(val) = parse_num(v.name) else {
1861 panic!("could not parse mul/div. enum={} variant={}", e.name, v.name)
1862 };
1863 let variant_name = format_ident!("{}", v.name);
1864 let variant = quote!(crate::pac::#kind::vals::#enum_name::#variant_name);
1865 let num = val.num;
1866 let denom = val.denom;
1867 muls.push(quote!(#variant => self * #num / #denom,));
1868 divs.push(quote!(#variant => self * #denom / #num,));
1869 }
1870
1871 g.extend(quote! {
1872 impl core::ops::Div<crate::pac::#kind::vals::#enum_name> for crate::time::Hertz {
1873 type Output = crate::time::Hertz;
1874 fn div(self, rhs: crate::pac::#kind::vals::#enum_name) -> Self::Output {
1875 match rhs {
1876 #(#divs)*
1877 #[allow(unreachable_patterns)]
1878 _ => unreachable!(),
1879 }
1707 } 1880 }
1708 } 1881 }
1709 } 1882 impl core::ops::Mul<crate::pac::#kind::vals::#enum_name> for crate::time::Hertz {
1710 impl core::ops::Mul<crate::pac::rcc::vals::#enum_name> for crate::time::Hertz { 1883 type Output = crate::time::Hertz;
1711 type Output = crate::time::Hertz; 1884 fn mul(self, rhs: crate::pac::#kind::vals::#enum_name) -> Self::Output {
1712 fn mul(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output { 1885 match rhs {
1713 match rhs { 1886 #(#muls)*
1714 #(#muls)* 1887 #[allow(unreachable_patterns)]
1715 #[allow(unreachable_patterns)] 1888 _ => unreachable!(),
1716 _ => unreachable!(), 1889 }
1717 } 1890 }
1718 } 1891 }
1719 } 1892 });
1720 }); 1893 }
1721 } 1894 }
1722 } 1895 }
1723 1896
@@ -1727,7 +1900,19 @@ fn main() {
1727 for p in METADATA.peripherals { 1900 for p in METADATA.peripherals {
1728 let mut pt = TokenStream::new(); 1901 let mut pt = TokenStream::new();
1729 1902
1903 let mut exti2_tsc_injected = false;
1904 if let Some(ref irq) = exti2_tsc_shared_int_present
1905 && p.name == "EXTI"
1906 {
1907 exti2_tsc_injected = true;
1908 let iname = format_ident!("{}", irq.name);
1909 let sname = format_ident!("{}", "EXTI2");
1910 pt.extend(quote!(pub type #sname = crate::interrupt::typelevel::#iname;));
1911 }
1730 for irq in p.interrupts { 1912 for irq in p.interrupts {
1913 if exti2_tsc_injected && irq.signal == "EXTI2" {
1914 continue;
1915 }
1731 let iname = format_ident!("{}", irq.interrupt); 1916 let iname = format_ident!("{}", irq.interrupt);
1732 let sname = format_ident!("{}", irq.signal); 1917 let sname = format_ident!("{}", irq.signal);
1733 pt.extend(quote!(pub type #sname = crate::interrupt::typelevel::#iname;)); 1918 pt.extend(quote!(pub type #sname = crate::interrupt::typelevel::#iname;));
@@ -1760,7 +1945,7 @@ fn main() {
1760 flash_regions_table.push(row); 1945 flash_regions_table.push(row);
1761 } 1946 }
1762 1947
1763 let gpio_base = METADATA.peripherals.iter().find(|p| p.name == "GPIOA").unwrap().address as u32; 1948 let gpio_base = peripheral_map.get("GPIOA").unwrap().address as u32;
1764 let gpio_stride = 0x400; 1949 let gpio_stride = 0x400;
1765 1950
1766 for pin in METADATA.pins { 1951 for pin in METADATA.pins {
@@ -1844,7 +2029,12 @@ fn main() {
1844 if r.kind == "dma" || r.kind == "bdma" || r.kind == "gpdma" || r.kind == "lpdma" { 2029 if r.kind == "dma" || r.kind == "bdma" || r.kind == "gpdma" || r.kind == "lpdma" {
1845 for irq in p.interrupts { 2030 for irq in p.interrupts {
1846 let ch_name = format!("{}_{}", p.name, irq.signal); 2031 let ch_name = format!("{}_{}", p.name, irq.signal);
1847 let ch = METADATA.dma_channels.iter().find(|c| c.name == ch_name).unwrap(); 2032 let ch = METADATA.dma_channels.iter().find(|c| c.name == ch_name);
2033
2034 if ch.is_none() {
2035 continue;
2036 }
2037 let ch = ch.unwrap();
1848 2038
1849 // Some H7 chips have BDMA1 hardcoded for DFSDM, ie no DMAMUX. It's unsupported, skip it. 2039 // Some H7 chips have BDMA1 hardcoded for DFSDM, ie no DMAMUX. It's unsupported, skip it.
1850 if has_dmamux && ch.dmamux.is_none() { 2040 if has_dmamux && ch.dmamux.is_none() {
@@ -1873,6 +2063,19 @@ fn main() {
1873 continue; 2063 continue;
1874 } 2064 }
1875 2065
2066 let dma_peri = peripheral_map.get(ch.dma).unwrap();
2067 let stop_mode = dma_peri
2068 .rcc
2069 .as_ref()
2070 .map(|rcc| rcc.stop_mode.clone())
2071 .unwrap_or_default();
2072
2073 let stop_mode = match stop_mode {
2074 StopMode::Standby => quote! { Standby },
2075 StopMode::Stop2 => quote! { Stop2 },
2076 StopMode::Stop1 => quote! { Stop1 },
2077 };
2078
1876 let name = format_ident!("{}", ch.name); 2079 let name = format_ident!("{}", ch.name);
1877 let idx = ch_idx as u8; 2080 let idx = ch_idx as u8;
1878 #[cfg(feature = "_dual-core")] 2081 #[cfg(feature = "_dual-core")]
@@ -1885,12 +2088,10 @@ fn main() {
1885 quote!(crate::pac::Interrupt::#irq_name) 2088 quote!(crate::pac::Interrupt::#irq_name)
1886 }; 2089 };
1887 2090
1888 g.extend(quote!(dma_channel_impl!(#name, #idx);)); 2091 g.extend(quote!(dma_channel_impl!(#name, #idx, #stop_mode);));
1889 2092
1890 let dma = format_ident!("{}", ch.dma); 2093 let dma = format_ident!("{}", ch.dma);
1891 let ch_num = ch.channel as usize; 2094 let ch_num = ch.channel as usize;
1892
1893 let dma_peri = METADATA.peripherals.iter().find(|p| p.name == ch.dma).unwrap();
1894 let bi = dma_peri.registers.as_ref().unwrap(); 2095 let bi = dma_peri.registers.as_ref().unwrap();
1895 2096
1896 let dma_info = match bi.kind { 2097 let dma_info = match bi.kind {
@@ -1983,33 +2184,47 @@ fn main() {
1983 )); 2184 ));
1984 2185
1985 // ======== 2186 // ========
2187 // Generate backup sram constants
2188 if let Some(m) = memory.iter().find(|m| m.name == "BKPSRAM") {
2189 let bkpsram_base = m.address as usize;
2190 let bkpsram_size = m.size as usize;
2191
2192 g.extend(quote!(
2193 pub const BKPSRAM_BASE: usize = #bkpsram_base;
2194 pub const BKPSRAM_SIZE: usize = #bkpsram_size;
2195 ));
2196 }
2197
2198 // ========
1986 // Generate flash constants 2199 // Generate flash constants
1987 2200
1988 let flash_regions: Vec<&MemoryRegion> = memory 2201 if has_flash {
1989 .iter() 2202 let flash_regions: Vec<&MemoryRegion> = memory
1990 .filter(|x| x.kind == MemoryRegionKind::Flash && x.name.starts_with("BANK_")) 2203 .iter()
1991 .collect(); 2204 .filter(|x| x.kind == MemoryRegionKind::Flash && x.name.starts_with("BANK_"))
1992 let first_flash = flash_regions.first().unwrap(); 2205 .collect();
1993 let total_flash_size = flash_regions 2206 let first_flash = flash_regions.first().unwrap();
1994 .iter() 2207 let total_flash_size = flash_regions
1995 .map(|x| x.size) 2208 .iter()
1996 .reduce(|acc, item| acc + item) 2209 .map(|x| x.size)
1997 .unwrap(); 2210 .reduce(|acc, item| acc + item)
1998 let write_sizes: HashSet<_> = flash_regions 2211 .unwrap();
1999 .iter() 2212 let write_sizes: HashSet<_> = flash_regions
2000 .map(|r| r.settings.as_ref().unwrap().write_size) 2213 .iter()
2001 .collect(); 2214 .map(|r| r.settings.as_ref().unwrap().write_size)
2002 assert_eq!(1, write_sizes.len()); 2215 .collect();
2216 assert_eq!(1, write_sizes.len());
2003 2217
2004 let flash_base = first_flash.address as usize; 2218 let flash_base = first_flash.address as usize;
2005 let total_flash_size = total_flash_size as usize; 2219 let total_flash_size = total_flash_size as usize;
2006 let write_size = (*write_sizes.iter().next().unwrap()) as usize; 2220 let write_size = (*write_sizes.iter().next().unwrap()) as usize;
2007 2221
2008 g.extend(quote!( 2222 g.extend(quote!(
2009 pub const FLASH_BASE: usize = #flash_base; 2223 pub const FLASH_BASE: usize = #flash_base;
2010 pub const FLASH_SIZE: usize = #total_flash_size; 2224 pub const FLASH_SIZE: usize = #total_flash_size;
2011 pub const WRITE_SIZE: usize = #write_size; 2225 pub const WRITE_SIZE: usize = #write_size;
2012 )); 2226 ));
2227 }
2013 2228
2014 // ======== 2229 // ========
2015 // Generate EEPROM constants 2230 // Generate EEPROM constants
@@ -2309,6 +2524,10 @@ fn mem_filter(chip: &str, region: &str) -> bool {
2309 return false; 2524 return false;
2310 } 2525 }
2311 2526
2527 if region.starts_with("SDRAM_") || region.starts_with("FMC_") || region.starts_with("OCTOSPI_") {
2528 return false;
2529 }
2530
2312 true 2531 true
2313} 2532}
2314 2533