aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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}