aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-09-15 23:49:41 +0000
committerGitHub <[email protected]>2023-09-15 23:49:41 +0000
commitf27620cc0b7a50c0ba5e93c96a6a88be252af286 (patch)
tree0548e5ff21f5d20f9ba02cef18d6edbc5cbcd350
parent2911774849897234ad84d5658e4401edead0e936 (diff)
parentaa2fa29b89c120ec23d64252d3f1b036c1369b00 (diff)
Merge pull request #1909 from xoviat/adc
stm32: generate adc_common and misc.
-rw-r--r--embassy-stm32/build.rs29
-rw-r--r--embassy-stm32/src/adc/f3.rs2
-rw-r--r--embassy-stm32/src/adc/mod.rs116
-rw-r--r--embassy-stm32/src/rcc/f3.rs14
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:
56pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {} 56pub trait AdcPin<T: Instance>: sealed::AdcPin<T> {}
57pub trait InternalChannel<T>: sealed::InternalChannel<T> {} 57pub trait InternalChannel<T>: sealed::InternalChannel<T> {}
58 58
59#[cfg(not(any(stm32h7, adc_f3, adc_v4)))] 59foreach_adc!(
60foreach_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))]
81foreach_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 });