diff options
| author | xoviat <[email protected]> | 2023-09-15 23:49:41 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-15 23:49:41 +0000 |
| commit | f27620cc0b7a50c0ba5e93c96a6a88be252af286 (patch) | |
| tree | 0548e5ff21f5d20f9ba02cef18d6edbc5cbcd350 | |
| parent | 2911774849897234ad84d5658e4401edead0e936 (diff) | |
| parent | aa2fa29b89c120ec23d64252d3f1b036c1369b00 (diff) | |
Merge pull request #1909 from xoviat/adc
stm32: generate adc_common and misc.
| -rw-r--r-- | embassy-stm32/build.rs | 29 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/f3.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/mod.rs | 116 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/f3.rs | 14 |
4 files changed, 45 insertions, 116 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index bb81736ba..6d7f788db 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -817,6 +817,17 @@ fn main() { | |||
| 817 | let mut peripherals_table: Vec<Vec<String>> = Vec::new(); | 817 | let mut peripherals_table: Vec<Vec<String>> = Vec::new(); |
| 818 | let mut pins_table: Vec<Vec<String>> = Vec::new(); | 818 | let mut pins_table: Vec<Vec<String>> = Vec::new(); |
| 819 | let mut dma_channels_table: Vec<Vec<String>> = Vec::new(); | 819 | let mut dma_channels_table: Vec<Vec<String>> = Vec::new(); |
| 820 | let mut adc_common_table: Vec<Vec<String>> = Vec::new(); | ||
| 821 | |||
| 822 | /* | ||
| 823 | If ADC3_COMMON exists, ADC3 and higher are assigned to it | ||
| 824 | All other ADCs are assigned to ADC_COMMON | ||
| 825 | |||
| 826 | ADC3 and higher are assigned to the adc34 clock in the table | ||
| 827 | The adc3_common cfg directive is added if ADC3_COMMON exists | ||
| 828 | */ | ||
| 829 | let has_adc3 = METADATA.peripherals.iter().find(|p| p.name == "ADC3_COMMON").is_some(); | ||
| 830 | let set_adc345 = HashSet::from(["ADC3", "ADC4", "ADC5"]); | ||
| 820 | 831 | ||
| 821 | for m in METADATA | 832 | for m in METADATA |
| 822 | .memory | 833 | .memory |
| @@ -854,6 +865,17 @@ fn main() { | |||
| 854 | } | 865 | } |
| 855 | } | 866 | } |
| 856 | 867 | ||
| 868 | if regs.kind == "adc" { | ||
| 869 | let (adc_common, adc_clock) = if set_adc345.contains(p.name) && has_adc3 { | ||
| 870 | ("ADC3_COMMON", "adc34") | ||
| 871 | } else { | ||
| 872 | ("ADC_COMMON", "adc") | ||
| 873 | }; | ||
| 874 | |||
| 875 | let row = vec![p.name.to_string(), adc_common.to_string(), adc_clock.to_string()]; | ||
| 876 | adc_common_table.push(row); | ||
| 877 | } | ||
| 878 | |||
| 857 | for irq in p.interrupts { | 879 | for irq in p.interrupts { |
| 858 | let row = vec![ | 880 | let row = vec![ |
| 859 | p.name.to_string(), | 881 | p.name.to_string(), |
| @@ -932,6 +954,7 @@ fn main() { | |||
| 932 | make_table(&mut m, "foreach_peripheral", &peripherals_table); | 954 | make_table(&mut m, "foreach_peripheral", &peripherals_table); |
| 933 | make_table(&mut m, "foreach_pin", &pins_table); | 955 | make_table(&mut m, "foreach_pin", &pins_table); |
| 934 | make_table(&mut m, "foreach_dma_channel", &dma_channels_table); | 956 | make_table(&mut m, "foreach_dma_channel", &dma_channels_table); |
| 957 | make_table(&mut m, "foreach_adc", &adc_common_table); | ||
| 935 | 958 | ||
| 936 | let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); | 959 | let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); |
| 937 | let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string(); | 960 | let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string(); |
| @@ -974,6 +997,12 @@ fn main() { | |||
| 974 | } | 997 | } |
| 975 | 998 | ||
| 976 | // ======= | 999 | // ======= |
| 1000 | // ADC3_COMMON is present | ||
| 1001 | if has_adc3 { | ||
| 1002 | println!("cargo:rustc-cfg={}", "adc3_common"); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | // ======= | ||
| 977 | // Features for targeting groups of chips | 1006 | // Features for targeting groups of chips |
| 978 | 1007 | ||
| 979 | println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4 | 1008 | println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4 |
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs index 2971ad527..b39d6ac8e 100644 --- a/embassy-stm32/src/adc/f3.rs +++ b/embassy-stm32/src/adc/f3.rs | |||
| @@ -50,7 +50,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 50 | while T::regs().cr().read().adcal() {} | 50 | while T::regs().cr().read().adcal() {} |
| 51 | 51 | ||
| 52 | // Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223) | 52 | // Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223) |
| 53 | delay.delay_us(6 * 1_000_000 / Self::freq().0); | 53 | delay.delay_us(1 + (6 * 1_000_000 / Self::freq().0)); |
| 54 | 54 | ||
| 55 | // Enable the adc | 55 | // Enable the adc |
| 56 | T::regs().cr().modify(|w| w.set_aden(true)); | 56 | T::regs().cr().modify(|w| w.set_aden(true)); |
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs index d1cfd8fbd..9334deac4 100644 --- a/embassy-stm32/src/adc/mod.rs +++ b/embassy-stm32/src/adc/mod.rs | |||
| @@ -56,127 +56,21 @@ pub trait Instance: sealed::Instance + crate::Peripheral<P = Self> + crate::rcc: | |||
| 56 | pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} | 56 | pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} |
| 57 | pub trait InternalChannel<T>: sealed::InternalChannel<T> {} | 57 | pub trait InternalChannel<T>: sealed::InternalChannel<T> {} |
| 58 | 58 | ||
| 59 | #[cfg(not(any(stm32h7, adc_f3, adc_v4)))] | 59 | foreach_adc!( |
| 60 | foreach_peripheral!( | 60 | ($inst:ident, $common_inst:ident, $clock:ident) => { |
| 61 | (adc, $inst:ident) => { | ||
| 62 | impl crate::adc::sealed::Instance for peripherals::$inst { | 61 | impl crate::adc::sealed::Instance for peripherals::$inst { |
| 63 | fn regs() -> crate::pac::adc::Adc { | 62 | fn regs() -> crate::pac::adc::Adc { |
| 64 | crate::pac::$inst | 63 | crate::pac::$inst |
| 65 | } | 64 | } |
| 66 | #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_g0)))] | ||
| 67 | fn common_regs() -> crate::pac::adccommon::AdcCommon { | ||
| 68 | foreach_peripheral!{ | ||
| 69 | (adccommon, $common_inst:ident) => { | ||
| 70 | return crate::pac::$common_inst | ||
| 71 | }; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | impl crate::adc::Instance for peripherals::$inst {} | ||
| 77 | }; | ||
| 78 | ); | ||
| 79 | |||
| 80 | #[cfg(any(stm32h7, adc_f3, adc_v4))] | ||
| 81 | foreach_peripheral!( | ||
| 82 | (adc, ADC3) => { | ||
| 83 | impl crate::adc::sealed::Instance for peripherals::ADC3 { | ||
| 84 | fn regs() -> crate::pac::adc::Adc { | ||
| 85 | crate::pac::ADC3 | ||
| 86 | } | ||
| 87 | #[cfg(all(not(adc_f1), not(adc_v1)))] | ||
| 88 | #[allow(unreachable_code)] | ||
| 89 | fn common_regs() -> crate::pac::adccommon::AdcCommon { | ||
| 90 | foreach_peripheral!{ | ||
| 91 | (adccommon, ADC3_COMMON) => { | ||
| 92 | return crate::pac::ADC3_COMMON | ||
| 93 | }; | ||
| 94 | // Fall back to ADC_COMMON if ADC3_COMMON does not exist | ||
| 95 | (adccommon, ADC_COMMON) => { | ||
| 96 | return crate::pac::ADC_COMMON | ||
| 97 | }; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | #[cfg(adc_f3)] | ||
| 102 | fn frequency() -> crate::time::Hertz { | ||
| 103 | unsafe { crate::rcc::get_freqs() }.adc34.unwrap() | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | impl crate::adc::Instance for peripherals::ADC3 {} | ||
| 108 | }; | ||
| 109 | (adc, ADC4) => { | ||
| 110 | impl crate::adc::sealed::Instance for peripherals::ADC4 { | ||
| 111 | fn regs() -> crate::pac::adc::Adc { | ||
| 112 | crate::pac::ADC4 | ||
| 113 | } | ||
| 114 | #[cfg(not(any(adc_f1, adc_v1)))] | ||
| 115 | #[allow(unreachable_code)] | ||
| 116 | fn common_regs() -> crate::pac::adccommon::AdcCommon { | ||
| 117 | foreach_peripheral!{ | ||
| 118 | (adccommon, ADC3_COMMON) => { | ||
| 119 | return crate::pac::ADC3_COMMON | ||
| 120 | }; | ||
| 121 | // Fall back to ADC_COMMON if ADC3_COMMON does not exist | ||
| 122 | (adccommon, ADC_COMMON) => { | ||
| 123 | return crate::pac::ADC_COMMON | ||
| 124 | }; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | #[cfg(adc_f3)] | ||
| 129 | fn frequency() -> crate::time::Hertz { | ||
| 130 | unsafe { crate::rcc::get_freqs() }.adc34.unwrap() | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | impl crate::adc::Instance for peripherals::ADC4 {} | ||
| 135 | }; | ||
| 136 | (adc, ADC5) => { | ||
| 137 | impl crate::adc::sealed::Instance for peripherals::ADC5 { | ||
| 138 | fn regs() -> crate::pac::adc::Adc { | ||
| 139 | crate::pac::ADC5 | ||
| 140 | } | ||
| 141 | #[cfg(not(any(adc_f1, adc_v1)))] | ||
| 142 | #[allow(unreachable_code)] | ||
| 143 | fn common_regs() -> crate::pac::adccommon::AdcCommon { | ||
| 144 | foreach_peripheral!{ | ||
| 145 | (adccommon, ADC3_COMMON) => { | ||
| 146 | return crate::pac::ADC3_COMMON | ||
| 147 | }; | ||
| 148 | // Fall back to ADC_COMMON if ADC3_COMMON does not exist | ||
| 149 | (adccommon, ADC_COMMON) => { | ||
| 150 | return crate::pac::ADC_COMMON | ||
| 151 | }; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | 65 | ||
| 155 | #[cfg(adc_f3)] | 66 | #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_g0)))] |
| 156 | fn frequency() -> crate::time::Hertz { | ||
| 157 | unsafe { crate::rcc::get_freqs() }.adc34.unwrap() | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | impl crate::adc::Instance for peripherals::ADC5 {} | ||
| 162 | }; | ||
| 163 | (adc, $inst:ident) => { | ||
| 164 | impl crate::adc::sealed::Instance for peripherals::$inst { | ||
| 165 | fn regs() -> crate::pac::adc::Adc { | ||
| 166 | crate::pac::$inst | ||
| 167 | } | ||
| 168 | #[cfg(not(any(adc_f1, adc_v1)))] | ||
| 169 | fn common_regs() -> crate::pac::adccommon::AdcCommon { | 67 | fn common_regs() -> crate::pac::adccommon::AdcCommon { |
| 170 | foreach_peripheral!{ | 68 | return crate::pac::$common_inst |
| 171 | (adccommon, ADC_COMMON) => { | ||
| 172 | return crate::pac::ADC_COMMON | ||
| 173 | }; | ||
| 174 | } | ||
| 175 | } | 69 | } |
| 176 | 70 | ||
| 177 | #[cfg(adc_f3)] | 71 | #[cfg(adc_f3)] |
| 178 | fn frequency() -> crate::time::Hertz { | 72 | fn frequency() -> crate::time::Hertz { |
| 179 | unsafe { crate::rcc::get_freqs() }.adc.unwrap() | 73 | unsafe { crate::rcc::get_freqs() }.$clock.unwrap() |
| 180 | } | 74 | } |
| 181 | } | 75 | } |
| 182 | 76 | ||
diff --git a/embassy-stm32/src/rcc/f3.rs b/embassy-stm32/src/rcc/f3.rs index cbbe4f98b..630dbd4fe 100644 --- a/embassy-stm32/src/rcc/f3.rs +++ b/embassy-stm32/src/rcc/f3.rs | |||
| @@ -280,7 +280,7 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 280 | } | 280 | } |
| 281 | }); | 281 | }); |
| 282 | 282 | ||
| 283 | #[cfg(rcc_f3)] | 283 | #[cfg(all(rcc_f3, adc3_common))] |
| 284 | let adc34 = config.adc.map(|adc| { | 284 | let adc34 = config.adc.map(|adc| { |
| 285 | if !adc.is_bus() { | 285 | if !adc.is_bus() { |
| 286 | RCC.cfgr2().modify(|w| { | 286 | RCC.cfgr2().modify(|w| { |
| @@ -291,9 +291,13 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 291 | Hertz(sysclk / adc as u32) | 291 | Hertz(sysclk / adc as u32) |
| 292 | }) | 292 | }) |
| 293 | } else { | 293 | } else { |
| 294 | // TODO: need to use only if adc32_common is present | 294 | crate::pac::ADC3_COMMON.ccr().modify(|w| { |
| 295 | assert!(!(adc.bus_div() == 1 && hpre_bits != Hpre::DIV1)); | ||
| 296 | |||
| 297 | w.set_ckmode(adc.into()); | ||
| 295 | 298 | ||
| 296 | todo!() | 299 | Hertz(sysclk / adc.bus_div() as u32) |
| 300 | }) | ||
| 297 | } | 301 | } |
| 298 | }); | 302 | }); |
| 299 | 303 | ||
| @@ -323,8 +327,10 @@ pub(crate) unsafe fn init(config: Config) { | |||
| 323 | ahb1: Hertz(hclk), | 327 | ahb1: Hertz(hclk), |
| 324 | #[cfg(rcc_f3)] | 328 | #[cfg(rcc_f3)] |
| 325 | adc: adc, | 329 | adc: adc, |
| 326 | #[cfg(rcc_f3)] | 330 | #[cfg(all(rcc_f3, adc3_common))] |
| 327 | adc34: adc34, | 331 | adc34: adc34, |
| 332 | #[cfg(all(rcc_f3, not(adc3_common)))] | ||
| 333 | adc34: None, | ||
| 328 | #[cfg(stm32f334)] | 334 | #[cfg(stm32f334)] |
| 329 | hrtim: hrtim, | 335 | hrtim: hrtim, |
| 330 | }); | 336 | }); |
