aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/adc/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/adc/mod.rs')
-rw-r--r--embassy-stm32/src/adc/mod.rs223
1 files changed, 133 insertions, 90 deletions
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 9040eefe5..a6af1175a 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -32,6 +32,11 @@ use embassy_sync::waitqueue::AtomicWaker;
32#[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))] 32#[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))]
33pub use ringbuffered::RingBufferedAdc; 33pub use ringbuffered::RingBufferedAdc;
34 34
35#[cfg(adc_u5)]
36use crate::pac::adc::vals::Adc4SampleTime;
37#[cfg(adc_wba)]
38use crate::pac::adc::vals::SampleTime as Adc4SampleTime;
39
35#[cfg(any(adc_u5, adc_wba))] 40#[cfg(any(adc_u5, adc_wba))]
36#[path = "adc4.rs"] 41#[path = "adc4.rs"]
37pub mod adc4; 42pub mod adc4;
@@ -44,10 +49,10 @@ pub use crate::pac::adc::vals::Res as Resolution;
44pub use crate::pac::adc::vals::SampleTime; 49pub use crate::pac::adc::vals::SampleTime;
45use crate::peripherals; 50use crate::peripherals;
46 51
47dma_trait!(RxDma, AnyInstance); 52dma_trait!(RxDma, Instance);
48 53
49/// Analog to Digital driver. 54/// Analog to Digital driver.
50pub struct Adc<'d, T: AnyInstance> { 55pub struct Adc<'d, T: Instance> {
51 #[allow(unused)] 56 #[allow(unused)]
52 adc: crate::Peri<'d, T>, 57 adc: crate::Peri<'d, T>,
53} 58}
@@ -66,10 +71,53 @@ impl State {
66 } 71 }
67} 72}
68 73
69trait SealedInstance { 74#[cfg(any(adc_f1, adc_f3v1, adc_f3v2, adc_v1, adc_l0))]
70 #[cfg(not(adc_wba))] 75trait_set::trait_set! {
71 #[allow(unused)] 76 pub trait DefaultInstance = Instance;
77}
78
79#[cfg(any(adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_g4, adc_c0))]
80trait_set::trait_set! {
81 pub trait DefaultInstance = Instance<Regs = crate::pac::adc::Adc>;
82}
83
84#[cfg(adc_wba)]
85trait_set::trait_set! {
86 pub trait DefaultInstance = Instance<Regs = crate::pac::adc::Adc4>;
87}
88
89pub trait BasicAdcRegs {
90 type SampleTime;
91}
92
93#[cfg(any(
94 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
95))]
96trait AdcRegs: BasicAdcRegs {
97 fn enable(&self);
98 fn start(&self);
99 fn stop(&self);
100 fn convert(&self);
101 fn configure_dma(&self, conversion_mode: ConversionMode);
102 fn configure_sequence(&self, sequence: impl ExactSizeIterator<Item = ((u8, bool), Self::SampleTime)>);
103 fn data(&self) -> *mut u16;
104}
105
106#[allow(private_bounds)]
107pub trait BasicInstance {
108 #[cfg(any(
109 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
110 ))]
111 type Regs: AdcRegs;
112}
113
114trait SealedInstance: BasicInstance {
115 #[cfg(any(adc_f1, adc_f3v1, adc_f3v2, adc_v1, adc_l0))]
72 fn regs() -> crate::pac::adc::Adc; 116 fn regs() -> crate::pac::adc::Adc;
117 #[cfg(any(
118 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
119 ))]
120 fn regs() -> Self::Regs;
73 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3v3, adc_f3v2, adc_g0)))] 121 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_f3v3, adc_f3v2, adc_g0)))]
74 #[allow(unused)] 122 #[allow(unused)]
75 fn common_regs() -> crate::pac::adccommon::AdcCommon; 123 fn common_regs() -> crate::pac::adccommon::AdcCommon;
@@ -90,56 +138,6 @@ pub(crate) trait SealedAdcChannel<T> {
90 } 138 }
91} 139}
92 140
93// Temporary patch for ADCs that have not implemented the standard iface yet
94#[cfg(any(adc_v1, adc_l0, adc_f1, adc_f3v1, adc_f3v2, adc_f3v3, adc_v1))]
95trait_set::trait_set! {
96 pub trait AnyInstance = Instance;
97}
98
99#[cfg(any(
100 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
101))]
102pub trait BasicAnyInstance {
103 type SampleTime;
104}
105
106#[cfg(any(
107 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
108))]
109pub(self) trait SealedAnyInstance: BasicAnyInstance {
110 fn enable();
111 fn start();
112 fn stop();
113 fn convert() -> u16;
114 fn configure_dma(conversion_mode: ConversionMode);
115 fn configure_sequence(sequence: impl ExactSizeIterator<Item = ((u8, bool), Self::SampleTime)>);
116 #[allow(dead_code)]
117 fn dr() -> *mut u16;
118}
119
120// On chips without ADC4, AnyInstance is an Instance
121#[cfg(any(adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_g4, adc_c0))]
122#[allow(private_bounds)]
123pub trait AnyInstance: SealedAnyInstance + Instance {}
124
125// On chips with ADC4, AnyInstance is an Instance or adc4::Instance
126#[cfg(any(adc_v4, adc_u5, adc_wba))]
127#[allow(private_bounds)]
128pub trait AnyInstance: SealedAnyInstance + crate::PeripheralType + crate::rcc::RccPeripheral {}
129
130// Implement AnyInstance automatically for SealedAnyInstance
131#[cfg(any(
132 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
133))]
134impl<T: SealedAnyInstance + Instance> BasicAnyInstance for T {
135 type SampleTime = SampleTime;
136}
137
138#[cfg(any(
139 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
140))]
141impl<T: SealedAnyInstance + Instance> AnyInstance for T {}
142
143#[cfg(any(adc_c0, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5))] 141#[cfg(any(adc_c0, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5))]
144/// Number of samples used for averaging. 142/// Number of samples used for averaging.
145#[derive(Copy, Clone, Debug)] 143#[derive(Copy, Clone, Debug)]
@@ -184,28 +182,33 @@ pub enum RegularConversionMode {
184 Triggered(ConversionTrigger), 182 Triggered(ConversionTrigger),
185} 183}
186 184
187impl<'d, T: AnyInstance> Adc<'d, T> { 185impl<'d, T: Instance> Adc<'d, T> {
188 #[cfg(any( 186 #[cfg(any(
189 adc_v2, adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_u5, adc_v3, adc_v4, adc_wba, adc_c0 187 adc_v2, adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_u5, adc_v3, adc_v4, adc_wba, adc_c0
190 ))] 188 ))]
191 /// Read an ADC pin. 189 /// Read an ADC pin.
192 pub fn blocking_read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: T::SampleTime) -> u16 { 190 pub fn blocking_read(
191 &mut self,
192 channel: &mut impl AdcChannel<T>,
193 sample_time: <T::Regs as BasicAdcRegs>::SampleTime,
194 ) -> u16 {
193 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v3, adc_v4, adc_u5, adc_wba))] 195 #[cfg(any(adc_v1, adc_c0, adc_l0, adc_v2, adc_g4, adc_v3, adc_v4, adc_u5, adc_wba))]
194 channel.setup(); 196 channel.setup();
195 197
196 // Ensure no conversions are ongoing 198 // Ensure no conversions are ongoing
197 T::stop(); 199 T::regs().stop();
198 #[cfg(any(adc_v2, adc_v3, adc_g0, adc_h7rs, adc_u0, adc_u5, adc_wba, adc_c0))] 200 #[cfg(any(adc_v2, adc_v3, adc_g0, adc_h7rs, adc_u0, adc_u5, adc_wba, adc_c0))]
199 T::enable(); 201 T::regs().enable();
200 T::configure_sequence([((channel.channel(), channel.is_differential()), sample_time)].into_iter()); 202 T::regs().configure_sequence([((channel.channel(), channel.is_differential()), sample_time)].into_iter());
201 203
202 // On chips with differential channels, enable after configure_sequence to allow setting differential channels 204 // On chips with differential channels, enable after configure_sequence to allow setting differential channels
203 // 205 //
204 // TODO: If hardware allows, enable after configure_sequence on all chips 206 // TODO: If hardware allows, enable after configure_sequence on all chips
205 #[cfg(any(adc_g4, adc_h5))] 207 #[cfg(any(adc_g4, adc_h5))]
206 T::enable(); 208 T::regs().enable();
209 T::regs().convert();
207 210
208 T::convert() 211 unsafe { *T::regs().data() }
209 } 212 }
210 213
211 #[cfg(any(adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))] 214 #[cfg(any(adc_g4, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))]
@@ -245,7 +248,7 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
245 pub async fn read<'a, 'b: 'a>( 248 pub async fn read<'a, 'b: 'a>(
246 &mut self, 249 &mut self,
247 rx_dma: embassy_hal_internal::Peri<'_, impl RxDma<T>>, 250 rx_dma: embassy_hal_internal::Peri<'_, impl RxDma<T>>,
248 sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<'b, T>, T::SampleTime)>, 251 sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<'b, T>, <T::Regs as BasicAdcRegs>::SampleTime)>,
249 readings: &mut [u16], 252 readings: &mut [u16],
250 ) { 253 ) {
251 assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty"); 254 assert!(sequence.len() != 0, "Asynchronous read sequence cannot be empty");
@@ -259,11 +262,11 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
259 ); 262 );
260 263
261 // Ensure no conversions are ongoing 264 // Ensure no conversions are ongoing
262 T::stop(); 265 T::regs().stop();
263 #[cfg(any(adc_g0, adc_v3, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))] 266 #[cfg(any(adc_g0, adc_v3, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))]
264 T::enable(); 267 T::regs().enable();
265 268
266 T::configure_sequence( 269 T::regs().configure_sequence(
267 sequence.map(|(channel, sample_time)| ((channel.channel, channel.is_differential), sample_time)), 270 sequence.map(|(channel, sample_time)| ((channel.channel, channel.is_differential), sample_time)),
268 ); 271 );
269 272
@@ -271,20 +274,20 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
271 // 274 //
272 // TODO: If hardware allows, enable after configure_sequence on all chips 275 // TODO: If hardware allows, enable after configure_sequence on all chips
273 #[cfg(any(adc_g4, adc_h5))] 276 #[cfg(any(adc_g4, adc_h5))]
274 T::enable(); 277 T::regs().enable();
275 T::configure_dma(ConversionMode::Singular); 278 T::regs().configure_dma(ConversionMode::Singular);
276 279
277 let request = rx_dma.request(); 280 let request = rx_dma.request();
278 let transfer = 281 let transfer =
279 unsafe { crate::dma::Transfer::new_read(rx_dma, request, T::dr(), readings, Default::default()) }; 282 unsafe { crate::dma::Transfer::new_read(rx_dma, request, T::regs().data(), readings, Default::default()) };
280 283
281 T::start(); 284 T::regs().start();
282 285
283 // Wait for conversion sequence to finish. 286 // Wait for conversion sequence to finish.
284 transfer.await; 287 transfer.await;
285 288
286 // Ensure conversions are finished. 289 // Ensure conversions are finished.
287 T::stop(); 290 T::regs().stop();
288 } 291 }
289 292
290 #[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))] 293 #[cfg(any(adc_v2, adc_g4, adc_v3, adc_g0, adc_u0))]
@@ -318,7 +321,7 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
318 self, 321 self,
319 dma: embassy_hal_internal::Peri<'a, impl RxDma<T>>, 322 dma: embassy_hal_internal::Peri<'a, impl RxDma<T>>,
320 dma_buf: &'a mut [u16], 323 dma_buf: &'a mut [u16],
321 sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<'b, T>, T::SampleTime)>, 324 sequence: impl ExactSizeIterator<Item = (AnyAdcChannel<'b, T>, <T::Regs as BasicAdcRegs>::SampleTime)>,
322 mode: RegularConversionMode, 325 mode: RegularConversionMode,
323 ) -> RingBufferedAdc<'a, T> { 326 ) -> RingBufferedAdc<'a, T> {
324 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); 327 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
@@ -328,11 +331,11 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
328 "Asynchronous read sequence cannot be more than 16 in length" 331 "Asynchronous read sequence cannot be more than 16 in length"
329 ); 332 );
330 // Ensure no conversions are ongoing 333 // Ensure no conversions are ongoing
331 T::stop(); 334 T::regs().stop();
332 #[cfg(any(adc_g0, adc_v3, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))] 335 #[cfg(any(adc_g0, adc_v3, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_c0))]
333 T::enable(); 336 T::regs().enable();
334 337
335 T::configure_sequence( 338 T::regs().configure_sequence(
336 sequence.map(|(channel, sample_time)| ((channel.channel, channel.is_differential), sample_time)), 339 sequence.map(|(channel, sample_time)| ((channel.channel, channel.is_differential), sample_time)),
337 ); 340 );
338 341
@@ -340,8 +343,8 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
340 // 343 //
341 // TODO: If hardware allows, enable after configure_sequence on all chips 344 // TODO: If hardware allows, enable after configure_sequence on all chips
342 #[cfg(any(adc_g4, adc_h5))] 345 #[cfg(any(adc_g4, adc_h5))]
343 T::enable(); 346 T::regs().enable();
344 T::configure_dma(ConversionMode::Repeated(mode)); 347 T::regs().configure_dma(ConversionMode::Repeated(mode));
345 348
346 core::mem::forget(self); 349 core::mem::forget(self);
347 350
@@ -442,8 +445,8 @@ pub struct AnyAdcChannel<'a, T> {
442 is_differential: bool, 445 is_differential: bool,
443 _phantom: PhantomData<&'a mut T>, 446 _phantom: PhantomData<&'a mut T>,
444} 447}
445impl<T: AnyInstance> AdcChannel<T> for AnyAdcChannel<'_, T> {} 448impl<T: Instance> AdcChannel<T> for AnyAdcChannel<'_, T> {}
446impl<T: AnyInstance> SealedAdcChannel<T> for AnyAdcChannel<'_, T> { 449impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<'_, T> {
447 fn channel(&self) -> u8 { 450 fn channel(&self) -> u8 {
448 self.channel 451 self.channel
449 } 452 }
@@ -459,16 +462,35 @@ impl<T> AnyAdcChannel<'_, T> {
459 self.channel 462 self.channel
460 } 463 }
461} 464}
465
466#[cfg(not(adc_wba))]
467impl BasicAdcRegs for crate::pac::adc::Adc {
468 type SampleTime = SampleTime;
469}
470
471#[cfg(any(adc_wba, adc_u5))]
472impl BasicAdcRegs for crate::pac::adc::Adc4 {
473 type SampleTime = Adc4SampleTime;
474}
475
462#[cfg(adc_wba)] 476#[cfg(adc_wba)]
463foreach_adc!( 477foreach_adc!(
464 (ADC4, $common_inst:ident, $clock:ident) => { 478 (ADC4, $common_inst:ident, $clock:ident) => {
465 impl crate::adc::adc4::SealedInstance for peripherals::ADC4 { 479 impl crate::adc::BasicInstance for peripherals::ADC4 {
466 fn regs() -> crate::pac::adc::Adc4 { 480 type Regs = crate::pac::adc::Adc4;
481 }
482
483 impl crate::adc::SealedInstance for peripherals::ADC4 {
484 fn regs() -> Self::Regs {
467 crate::pac::ADC4 485 crate::pac::ADC4
468 } 486 }
487
488 fn common_regs() -> crate::pac::adccommon::AdcCommon {
489 return crate::pac::$common_inst
490 }
469 } 491 }
470 492
471 impl crate::adc::adc4::Instance for peripherals::ADC4 { 493 impl crate::adc::Instance for peripherals::ADC4 {
472 type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL; 494 type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL;
473 } 495 }
474 }; 496 };
@@ -493,20 +515,32 @@ foreach_adc!(
493#[cfg(adc_u5)] 515#[cfg(adc_u5)]
494foreach_adc!( 516foreach_adc!(
495 (ADC4, $common_inst:ident, $clock:ident) => { 517 (ADC4, $common_inst:ident, $clock:ident) => {
496 impl crate::adc::adc4::SealedInstance for peripherals::ADC4 { 518 impl crate::adc::BasicInstance for peripherals::ADC4 {
497 fn regs() -> crate::pac::adc::Adc4 { 519 type Regs = crate::pac::adc::Adc4;
520 }
521
522 impl crate::adc::SealedInstance for peripherals::ADC4 {
523 fn regs() -> Self::Regs {
498 crate::pac::ADC4 524 crate::pac::ADC4
499 } 525 }
526
527 fn common_regs() -> crate::pac::adccommon::AdcCommon {
528 return crate::pac::$common_inst
529 }
500 } 530 }
501 531
502 impl crate::adc::adc4::Instance for peripherals::ADC4 { 532 impl crate::adc::Instance for peripherals::ADC4 {
503 type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL; 533 type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL;
504 } 534 }
505 }; 535 };
506 536
507 ($inst:ident, $common_inst:ident, $clock:ident) => { 537 ($inst:ident, $common_inst:ident, $clock:ident) => {
538 impl crate::adc::BasicInstance for peripherals::$inst {
539 type Regs = crate::pac::adc::Adc;
540 }
541
508 impl crate::adc::SealedInstance for peripherals::$inst { 542 impl crate::adc::SealedInstance for peripherals::$inst {
509 fn regs() -> crate::pac::adc::Adc { 543 fn regs() -> Self::Regs {
510 crate::pac::$inst 544 crate::pac::$inst
511 } 545 }
512 546
@@ -524,14 +558,23 @@ foreach_adc!(
524#[cfg(not(any(adc_u5, adc_wba)))] 558#[cfg(not(any(adc_u5, adc_wba)))]
525foreach_adc!( 559foreach_adc!(
526 ($inst:ident, $common_inst:ident, $clock:ident) => { 560 ($inst:ident, $common_inst:ident, $clock:ident) => {
561 impl crate::adc::BasicInstance for peripherals::$inst {
562 #[cfg(any(
563 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
564 ))]
565 type Regs = crate::pac::adc::Adc;
566 }
567
527 impl crate::adc::SealedInstance for peripherals::$inst { 568 impl crate::adc::SealedInstance for peripherals::$inst {
528 #[cfg(not(adc_wba))] 569 #[cfg(any(
529 fn regs() -> crate::pac::adc::Adc { 570 adc_v2, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5, adc_wba, adc_g4, adc_c0
571 ))]
572 fn regs() -> Self::Regs {
530 crate::pac::$inst 573 crate::pac::$inst
531 } 574 }
532 575
533 #[cfg(adc_wba)] 576 #[cfg(any(adc_f1, adc_f3v1, adc_f3v2, adc_v1, adc_l0))]
534 fn regs() -> crate::pac::adc::Adc4 { 577 fn regs() -> crate::pac::adc::Adc {
535 crate::pac::$inst 578 crate::pac::$inst
536 } 579 }
537 580