stm32/rcc: use PLL enums from PAC.
This commit is contained in:
		@@ -893,6 +893,105 @@ fn main() {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ========
 | 
			
		||||
    // Generate Div/Mul impls for RCC prescalers/dividers/multipliers.
 | 
			
		||||
    let rcc_registers = METADATA
 | 
			
		||||
        .peripherals
 | 
			
		||||
        .iter()
 | 
			
		||||
        .filter_map(|p| p.registers.as_ref())
 | 
			
		||||
        .find(|r| r.kind == "rcc")
 | 
			
		||||
        .unwrap()
 | 
			
		||||
        .ir;
 | 
			
		||||
 | 
			
		||||
    for e in rcc_registers.enums {
 | 
			
		||||
        fn is_rcc_name(e: &str) -> bool {
 | 
			
		||||
            match e {
 | 
			
		||||
                "Pllp" | "Pllq" | "Pllr" | "Pllm" | "Plln" => true,
 | 
			
		||||
                "Timpre" | "Pllrclkpre" => false,
 | 
			
		||||
                e if e.ends_with("pre") || e.ends_with("div") || e.ends_with("mul") => true,
 | 
			
		||||
                _ => false,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #[derive(Copy, Clone, Debug)]
 | 
			
		||||
        struct Frac {
 | 
			
		||||
            num: u32,
 | 
			
		||||
            denom: u32,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl Frac {
 | 
			
		||||
            fn simplify(self) -> Self {
 | 
			
		||||
                let d = gcd(self.num, self.denom);
 | 
			
		||||
                Self {
 | 
			
		||||
                    num: self.num / d,
 | 
			
		||||
                    denom: self.denom / d,
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn gcd(a: u32, b: u32) -> u32 {
 | 
			
		||||
            if b == 0 {
 | 
			
		||||
                return a;
 | 
			
		||||
            }
 | 
			
		||||
            gcd(b, a % b)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn parse_num(n: &str) -> Result<Frac, ()> {
 | 
			
		||||
            for prefix in ["DIV", "MUL"] {
 | 
			
		||||
                if let Some(n) = n.strip_prefix(prefix) {
 | 
			
		||||
                    let exponent = n.find('_').map(|e| n.len() - 1 - e).unwrap_or(0) as u32;
 | 
			
		||||
                    let mantissa = n.replace('_', "").parse().map_err(|_| ())?;
 | 
			
		||||
                    let f = Frac {
 | 
			
		||||
                        num: mantissa,
 | 
			
		||||
                        denom: 10u32.pow(exponent),
 | 
			
		||||
                    };
 | 
			
		||||
                    return Ok(f.simplify());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Err(())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if is_rcc_name(e.name) {
 | 
			
		||||
            let enum_name = format_ident!("{}", e.name);
 | 
			
		||||
            let mut muls = Vec::new();
 | 
			
		||||
            let mut divs = Vec::new();
 | 
			
		||||
            for v in e.variants {
 | 
			
		||||
                let Ok(val) = parse_num(v.name) else {
 | 
			
		||||
                    panic!("could not parse mul/div. enum={} variant={}", e.name, v.name)
 | 
			
		||||
                };
 | 
			
		||||
                let variant_name = format_ident!("{}", v.name);
 | 
			
		||||
                let variant = quote!(crate::pac::rcc::vals::#enum_name::#variant_name);
 | 
			
		||||
                let num = val.num;
 | 
			
		||||
                let denom = val.denom;
 | 
			
		||||
                muls.push(quote!(#variant => self * #num / #denom,));
 | 
			
		||||
                divs.push(quote!(#variant => self * #denom / #num,));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            g.extend(quote! {
 | 
			
		||||
                impl core::ops::Div<crate::pac::rcc::vals::#enum_name> for crate::time::Hertz {
 | 
			
		||||
                    type Output = crate::time::Hertz;
 | 
			
		||||
                    fn div(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output {
 | 
			
		||||
                        match rhs {
 | 
			
		||||
                            #(#divs)*
 | 
			
		||||
                            #[allow(unreachable_patterns)]
 | 
			
		||||
                            _ => unreachable!(),
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                impl core::ops::Mul<crate::pac::rcc::vals::#enum_name> for crate::time::Hertz {
 | 
			
		||||
                    type Output = crate::time::Hertz;
 | 
			
		||||
                    fn mul(self, rhs: crate::pac::rcc::vals::#enum_name) -> Self::Output {
 | 
			
		||||
                        match rhs {
 | 
			
		||||
                            #(#muls)*
 | 
			
		||||
                            #[allow(unreachable_patterns)]
 | 
			
		||||
                            _ => unreachable!(),
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ========
 | 
			
		||||
    // Write foreach_foo! macrotables
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user