Merge pull request #1909 from xoviat/adc

stm32: generate adc_common and misc.
This commit is contained in:
xoviat 2023-09-15 23:49:41 +00:00 committed by GitHub
commit f27620cc0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 116 deletions

View File

@ -817,6 +817,17 @@ fn main() {
let mut peripherals_table: Vec<Vec<String>> = Vec::new(); let mut peripherals_table: Vec<Vec<String>> = Vec::new();
let mut pins_table: Vec<Vec<String>> = Vec::new(); let mut pins_table: Vec<Vec<String>> = Vec::new();
let mut dma_channels_table: Vec<Vec<String>> = Vec::new(); let mut dma_channels_table: Vec<Vec<String>> = Vec::new();
let mut adc_common_table: Vec<Vec<String>> = Vec::new();
/*
If ADC3_COMMON exists, ADC3 and higher are assigned to it
All other ADCs are assigned to ADC_COMMON
ADC3 and higher are assigned to the adc34 clock in the table
The adc3_common cfg directive is added if ADC3_COMMON exists
*/
let has_adc3 = METADATA.peripherals.iter().find(|p| p.name == "ADC3_COMMON").is_some();
let set_adc345 = HashSet::from(["ADC3", "ADC4", "ADC5"]);
for m in METADATA for m in METADATA
.memory .memory
@ -854,6 +865,17 @@ fn main() {
} }
} }
if regs.kind == "adc" {
let (adc_common, adc_clock) = if set_adc345.contains(p.name) && has_adc3 {
("ADC3_COMMON", "adc34")
} else {
("ADC_COMMON", "adc")
};
let row = vec![p.name.to_string(), adc_common.to_string(), adc_clock.to_string()];
adc_common_table.push(row);
}
for irq in p.interrupts { for irq in p.interrupts {
let row = vec![ let row = vec![
p.name.to_string(), p.name.to_string(),
@ -932,6 +954,7 @@ fn main() {
make_table(&mut m, "foreach_peripheral", &peripherals_table); make_table(&mut m, "foreach_peripheral", &peripherals_table);
make_table(&mut m, "foreach_pin", &pins_table); make_table(&mut m, "foreach_pin", &pins_table);
make_table(&mut m, "foreach_dma_channel", &dma_channels_table); make_table(&mut m, "foreach_dma_channel", &dma_channels_table);
make_table(&mut m, "foreach_adc", &adc_common_table);
let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string(); let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string();
@ -973,6 +996,12 @@ fn main() {
println!("cargo:rustc-cfg={}x{}", &chip_name[..9], &chip_name[10..11]); println!("cargo:rustc-cfg={}x{}", &chip_name[..9], &chip_name[10..11]);
} }
// =======
// ADC3_COMMON is present
if has_adc3 {
println!("cargo:rustc-cfg={}", "adc3_common");
}
// ======= // =======
// Features for targeting groups of chips // Features for targeting groups of chips

View File

@ -50,7 +50,7 @@ impl<'d, T: Instance> Adc<'d, T> {
while T::regs().cr().read().adcal() {} while T::regs().cr().read().adcal() {}
// Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223) // Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223)
delay.delay_us(6 * 1_000_000 / Self::freq().0); delay.delay_us(1 + (6 * 1_000_000 / Self::freq().0));
// Enable the adc // Enable the adc
T::regs().cr().modify(|w| w.set_aden(true)); T::regs().cr().modify(|w| w.set_aden(true));

View File

@ -56,127 +56,21 @@ pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc:
pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
pub trait InternalChannel<T>: sealed::InternalChannel<T> {} pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
#[cfg(not(any(stm32h7, adc_f3, adc_v4)))] foreach_adc!(
foreach_peripheral!( ($inst:ident, $common_inst:ident, $clock:ident) => {
(adc, $inst:ident) => {
impl crate::adc::sealed::Instance for peripherals::$inst { impl crate::adc::sealed::Instance for peripherals::$inst {
fn regs() -> crate::pac::adc::Adc { fn regs() -> crate::pac::adc::Adc {
crate::pac::$inst crate::pac::$inst
} }
#[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_g0)))] #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_g0)))]
fn common_regs() -> crate::pac::adccommon::AdcCommon { fn common_regs() -> crate::pac::adccommon::AdcCommon {
foreach_peripheral!{
(adccommon, $common_inst:ident) => {
return crate::pac::$common_inst return crate::pac::$common_inst
};
}
}
}
impl crate::adc::Instance for peripherals::$inst {}
};
);
#[cfg(any(stm32h7, adc_f3, adc_v4))]
foreach_peripheral!(
(adc, ADC3) => {
impl crate::adc::sealed::Instance for peripherals::ADC3 {
fn regs() -> crate::pac::adc::Adc {
crate::pac::ADC3
}
#[cfg(all(not(adc_f1), not(adc_v1)))]
#[allow(unreachable_code)]
fn common_regs() -> crate::pac::adccommon::AdcCommon {
foreach_peripheral!{
(adccommon, ADC3_COMMON) => {
return crate::pac::ADC3_COMMON
};
// Fall back to ADC_COMMON if ADC3_COMMON does not exist
(adccommon, ADC_COMMON) => {
return crate::pac::ADC_COMMON
};
}
} }
#[cfg(adc_f3)] #[cfg(adc_f3)]
fn frequency() -> crate::time::Hertz { fn frequency() -> crate::time::Hertz {
unsafe { crate::rcc::get_freqs() }.adc34.unwrap() unsafe { crate::rcc::get_freqs() }.$clock.unwrap()
}
}
impl crate::adc::Instance for peripherals::ADC3 {}
};
(adc, ADC4) => {
impl crate::adc::sealed::Instance for peripherals::ADC4 {
fn regs() -> crate::pac::adc::Adc {
crate::pac::ADC4
}
#[cfg(not(any(adc_f1, adc_v1)))]
#[allow(unreachable_code)]
fn common_regs() -> crate::pac::adccommon::AdcCommon {
foreach_peripheral!{
(adccommon, ADC3_COMMON) => {
return crate::pac::ADC3_COMMON
};
// Fall back to ADC_COMMON if ADC3_COMMON does not exist
(adccommon, ADC_COMMON) => {
return crate::pac::ADC_COMMON
};
}
}
#[cfg(adc_f3)]
fn frequency() -> crate::time::Hertz {
unsafe { crate::rcc::get_freqs() }.adc34.unwrap()
}
}
impl crate::adc::Instance for peripherals::ADC4 {}
};
(adc, ADC5) => {
impl crate::adc::sealed::Instance for peripherals::ADC5 {
fn regs() -> crate::pac::adc::Adc {
crate::pac::ADC5
}
#[cfg(not(any(adc_f1, adc_v1)))]
#[allow(unreachable_code)]
fn common_regs() -> crate::pac::adccommon::AdcCommon {
foreach_peripheral!{
(adccommon, ADC3_COMMON) => {
return crate::pac::ADC3_COMMON
};
// Fall back to ADC_COMMON if ADC3_COMMON does not exist
(adccommon, ADC_COMMON) => {
return crate::pac::ADC_COMMON
};
}
}
#[cfg(adc_f3)]
fn frequency() -> crate::time::Hertz {
unsafe { crate::rcc::get_freqs() }.adc34.unwrap()
}
}
impl crate::adc::Instance for peripherals::ADC5 {}
};
(adc, $inst:ident) => {
impl crate::adc::sealed::Instance for peripherals::$inst {
fn regs() -> crate::pac::adc::Adc {
crate::pac::$inst
}
#[cfg(not(any(adc_f1, adc_v1)))]
fn common_regs() -> crate::pac::adccommon::AdcCommon {
foreach_peripheral!{
(adccommon, ADC_COMMON) => {
return crate::pac::ADC_COMMON
};
}
}
#[cfg(adc_f3)]
fn frequency() -> crate::time::Hertz {
unsafe { crate::rcc::get_freqs() }.adc.unwrap()
} }
} }

View File

@ -280,7 +280,7 @@ pub(crate) unsafe fn init(config: Config) {
} }
}); });
#[cfg(rcc_f3)] #[cfg(all(rcc_f3, adc3_common))]
let adc34 = config.adc.map(|adc| { let adc34 = config.adc.map(|adc| {
if !adc.is_bus() { if !adc.is_bus() {
RCC.cfgr2().modify(|w| { RCC.cfgr2().modify(|w| {
@ -291,9 +291,13 @@ pub(crate) unsafe fn init(config: Config) {
Hertz(sysclk / adc as u32) Hertz(sysclk / adc as u32)
}) })
} else { } else {
// TODO: need to use only if adc32_common is present crate::pac::ADC3_COMMON.ccr().modify(|w| {
assert!(!(adc.bus_div() == 1 && hpre_bits != Hpre::DIV1));
todo!() w.set_ckmode(adc.into());
Hertz(sysclk / adc.bus_div() as u32)
})
} }
}); });
@ -323,8 +327,10 @@ pub(crate) unsafe fn init(config: Config) {
ahb1: Hertz(hclk), ahb1: Hertz(hclk),
#[cfg(rcc_f3)] #[cfg(rcc_f3)]
adc: adc, adc: adc,
#[cfg(rcc_f3)] #[cfg(all(rcc_f3, adc3_common))]
adc34: adc34, adc34: adc34,
#[cfg(all(rcc_f3, not(adc3_common)))]
adc34: None,
#[cfg(stm32f334)] #[cfg(stm32f334)]
hrtim: hrtim, hrtim: hrtim,
}); });