diff options
| author | Timo Kröger <[email protected]> | 2021-08-04 12:29:20 +0200 |
|---|---|---|
| committer | Timo Kröger <[email protected]> | 2021-08-04 12:42:35 +0200 |
| commit | b36337b3d23e99a23968deb7e8d5c65119e9bf0d (patch) | |
| tree | c99204bcca7fd8193939fe4774e57817776b1043 | |
| parent | 37536695e1790ff6aea7d97464251f1099d9fc85 (diff) | |
Refactor bit search logic when no clock specified
Always search for a enable bit, even when no clock is specified in the
yaml. Try to derive the clock name from the register name.
This change picked up USART2 for stm32wle which was missing the clock.
| -rw-r--r-- | stm32-metapac-gen/src/lib.rs | 138 |
1 files changed, 60 insertions, 78 deletions
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs index 2398d5a8c..b10f250de 100644 --- a/stm32-metapac-gen/src/lib.rs +++ b/stm32-metapac-gen/src/lib.rs | |||
| @@ -423,88 +423,70 @@ pub fn gen(options: Options) { | |||
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | if let Some(rcc) = &rcc { | 425 | if let Some(rcc) = &rcc { |
| 426 | let clock_prefix: Option<&str> = if let Some(clock) = &p.clock { | 426 | // Workaround for clock registers being split on some chip families. Assume fields are |
| 427 | Some(clock) | 427 | // named after peripheral and look for first field matching and use that register. |
| 428 | } else if name.starts_with("TIM") { | 428 | let mut en = find_reg_for_field(&rcc, "^.+ENR\\d*$", &format!("{}EN", name)); |
| 429 | // Not all peripherals like timers the clock hint due to insufficient information from | 429 | let mut rst = find_reg_for_field(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name)); |
| 430 | // chip definition. If clock is not specified, the first matching register with the | 430 | |
| 431 | // expected field will be used. | 431 | if en.is_none() && name.ends_with("1") { |
| 432 | Some("") | 432 | en = find_reg_for_field( |
| 433 | } else { | 433 | &rcc, |
| 434 | None | 434 | "^.+ENR\\d*$", |
| 435 | }; | 435 | &format!("{}EN", &name[..name.len() - 1]), |
| 436 | 436 | ); | |
| 437 | if let Some(clock_prefix) = clock_prefix { | 437 | rst = find_reg_for_field( |
| 438 | // Workaround for clock registers being split on some chip families. Assume fields are | 438 | &rcc, |
| 439 | // named after peripheral and look for first field matching and use that register. | 439 | "^.+RSTR\\d*$", |
| 440 | let mut en = | 440 | &format!("{}RST", &name[..name.len() - 1]), |
| 441 | find_reg_for_field(&rcc, "^.+ENR\\d*$", &format!("{}EN", name)); | 441 | ); |
| 442 | let mut rst = | 442 | } |
| 443 | find_reg_for_field(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name)); | ||
| 444 | |||
| 445 | if en.is_none() && name.ends_with("1") { | ||
| 446 | en = find_reg_for_field( | ||
| 447 | &rcc, | ||
| 448 | "^.+ENR\\d*$", | ||
| 449 | &format!("{}EN", &name[..name.len() - 1]), | ||
| 450 | ); | ||
| 451 | rst = find_reg_for_field( | ||
| 452 | &rcc, | ||
| 453 | "^.+RSTR\\d*$", | ||
| 454 | &format!("{}RST", &name[..name.len() - 1]), | ||
| 455 | ); | ||
| 456 | } | ||
| 457 | |||
| 458 | match (en, rst) { | ||
| 459 | (Some((enable_reg, enable_field)), reset_reg_field) => { | ||
| 460 | let clock = if clock_prefix.is_empty() { | ||
| 461 | let re = Regex::new("([A-Z]+\\d*).*").unwrap(); | ||
| 462 | if !re.is_match(enable_reg) { | ||
| 463 | panic!( | ||
| 464 | "unable to derive clock name from register name {}", | ||
| 465 | enable_reg | ||
| 466 | ); | ||
| 467 | } else { | ||
| 468 | let caps = re.captures(enable_reg).unwrap(); | ||
| 469 | caps.get(1).unwrap().as_str() | ||
| 470 | } | ||
| 471 | } else { | ||
| 472 | clock_prefix | ||
| 473 | }; | ||
| 474 | |||
| 475 | let clock = if name.starts_with("TIM") { | ||
| 476 | format!("{}_tim", clock.to_ascii_lowercase()) | ||
| 477 | } else { | ||
| 478 | clock.to_ascii_lowercase() | ||
| 479 | }; | ||
| 480 | |||
| 481 | let mut row = Vec::with_capacity(6); | ||
| 482 | row.push(name.clone()); | ||
| 483 | row.push(clock); | ||
| 484 | row.push(enable_reg.to_ascii_lowercase()); | ||
| 485 | |||
| 486 | if let Some((reset_reg, reset_field)) = reset_reg_field { | ||
| 487 | row.push(reset_reg.to_ascii_lowercase()); | ||
| 488 | row.push(format!("set_{}", enable_field.to_ascii_lowercase())); | ||
| 489 | row.push(format!("set_{}", reset_field.to_ascii_lowercase())); | ||
| 490 | } else { | ||
| 491 | row.push(format!("set_{}", enable_field.to_ascii_lowercase())); | ||
| 492 | } | ||
| 493 | 443 | ||
| 494 | if !name.starts_with("GPIO") { | 444 | match (en, rst) { |
| 495 | peripheral_rcc_table.push(row); | 445 | (Some((enable_reg, enable_field)), reset_reg_field) => { |
| 496 | } else { | 446 | let clock = match &p.clock { |
| 497 | gpio_rcc_table.push(row); | 447 | Some(clock) => clock.as_str(), |
| 498 | gpio_regs.insert(enable_reg.to_ascii_lowercase()); | 448 | None => { |
| 449 | // No clock was specified, derive the clock name from the enable register name. | ||
| 450 | let re = Regex::new("([A-Z]+\\d*).*").unwrap(); | ||
| 451 | let caps = re.captures(enable_reg).expect( | ||
| 452 | "unable to derive clock name from register name {}", | ||
| 453 | ); | ||
| 454 | caps.get(1).unwrap().as_str() | ||
| 499 | } | 455 | } |
| 456 | }; | ||
| 457 | |||
| 458 | let clock = if name.starts_with("TIM") { | ||
| 459 | format!("{}_tim", clock.to_ascii_lowercase()) | ||
| 460 | } else { | ||
| 461 | clock.to_ascii_lowercase() | ||
| 462 | }; | ||
| 463 | |||
| 464 | let mut row = Vec::with_capacity(6); | ||
| 465 | row.push(name.clone()); | ||
| 466 | row.push(clock); | ||
| 467 | row.push(enable_reg.to_ascii_lowercase()); | ||
| 468 | |||
| 469 | if let Some((reset_reg, reset_field)) = reset_reg_field { | ||
| 470 | row.push(reset_reg.to_ascii_lowercase()); | ||
| 471 | row.push(format!("set_{}", enable_field.to_ascii_lowercase())); | ||
| 472 | row.push(format!("set_{}", reset_field.to_ascii_lowercase())); | ||
| 473 | } else { | ||
| 474 | row.push(format!("set_{}", enable_field.to_ascii_lowercase())); | ||
| 500 | } | 475 | } |
| 501 | (None, Some(_)) => { | 476 | |
| 502 | println!("Unable to find enable register for {}", name) | 477 | if !name.starts_with("GPIO") { |
| 503 | } | 478 | peripheral_rcc_table.push(row); |
| 504 | (None, None) => { | 479 | } else { |
| 505 | println!("Unable to find enable and reset register for {}", name) | 480 | gpio_rcc_table.push(row); |
| 481 | gpio_regs.insert(enable_reg.to_ascii_lowercase()); | ||
| 506 | } | 482 | } |
| 507 | } | 483 | } |
| 484 | (None, Some(_)) => { | ||
| 485 | println!("Unable to find enable register for {}", name) | ||
| 486 | } | ||
| 487 | (None, None) => { | ||
| 488 | println!("Unable to find enable and reset register for {}", name) | ||
| 489 | } | ||
| 508 | } | 490 | } |
| 509 | } | 491 | } |
| 510 | } | 492 | } |
| @@ -770,6 +752,6 @@ fn gen_memory_x(out_dir: &PathBuf, chip: &Chip) { | |||
| 770 | 752 | ||
| 771 | fs::create_dir_all(out_dir.join("memory_x")).unwrap(); | 753 | fs::create_dir_all(out_dir.join("memory_x")).unwrap(); |
| 772 | let mut file = File::create(out_dir.join("memory_x").join("memory.x")).unwrap(); | 754 | let mut file = File::create(out_dir.join("memory_x").join("memory.x")).unwrap(); |
| 773 | file.write_all( memory_x.as_bytes() ).unwrap(); | 755 | file.write_all(memory_x.as_bytes()).unwrap(); |
| 774 | 756 | ||
| 775 | } | 757 | } |
