aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Kröger <[email protected]>2021-08-04 12:29:20 +0200
committerTimo Kröger <[email protected]>2021-08-04 12:42:35 +0200
commitb36337b3d23e99a23968deb7e8d5c65119e9bf0d (patch)
treec99204bcca7fd8193939fe4774e57817776b1043
parent37536695e1790ff6aea7d97464251f1099d9fc85 (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.rs138
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}