diff options
Diffstat (limited to 'embassy-stm32/src/adc/f1.rs')
| -rw-r--r-- | embassy-stm32/src/adc/f1.rs | 45 |
1 files changed, 15 insertions, 30 deletions
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs index 3cdc9d8fb..d6c6f480b 100644 --- a/embassy-stm32/src/adc/f1.rs +++ b/embassy-stm32/src/adc/f1.rs | |||
| @@ -3,11 +3,11 @@ use core::marker::PhantomData; | |||
| 3 | use core::task::Poll; | 3 | use core::task::Poll; |
| 4 | 4 | ||
| 5 | use super::blocking_delay_us; | 5 | use super::blocking_delay_us; |
| 6 | use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; | 6 | use crate::adc::{Adc, AdcChannel, Instance, SampleTime, VrefInt}; |
| 7 | use crate::interrupt::typelevel::Interrupt; | 7 | use crate::interrupt::typelevel::Interrupt; |
| 8 | use crate::interrupt::{self}; | 8 | use crate::interrupt::{self}; |
| 9 | use crate::time::Hertz; | 9 | use crate::time::Hertz; |
| 10 | use crate::{rcc, Peri}; | 10 | use crate::{Peri, rcc}; |
| 11 | 11 | ||
| 12 | pub const VDDA_CALIB_MV: u32 = 3300; | 12 | pub const VDDA_CALIB_MV: u32 = 3300; |
| 13 | pub const ADC_MAX: u32 = (1 << 12) - 1; | 13 | pub const ADC_MAX: u32 = (1 << 12) - 1; |
| @@ -28,20 +28,12 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | pub struct Vref; | 31 | impl<T: Instance> super::SealedSpecialConverter<VrefInt> for T { |
| 32 | impl<T: Instance> AdcChannel<T> for Vref {} | 32 | const CHANNEL: u8 = 17; |
| 33 | impl<T: Instance> super::SealedAdcChannel<T> for Vref { | ||
| 34 | fn channel(&self) -> u8 { | ||
| 35 | 17 | ||
| 36 | } | ||
| 37 | } | 33 | } |
| 38 | 34 | ||
| 39 | pub struct Temperature; | 35 | impl<T: Instance> super::SealedSpecialConverter<super::Temperature> for T { |
| 40 | impl<T: Instance> AdcChannel<T> for Temperature {} | 36 | const CHANNEL: u8 = 16; |
| 41 | impl<T: Instance> super::SealedAdcChannel<T> for Temperature { | ||
| 42 | fn channel(&self) -> u8 { | ||
| 43 | 16 | ||
| 44 | } | ||
| 45 | } | 37 | } |
| 46 | 38 | ||
| 47 | impl<'d, T: Instance> Adc<'d, T> { | 39 | impl<'d, T: Instance> Adc<'d, T> { |
| @@ -51,7 +43,7 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 51 | 43 | ||
| 52 | // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’) | 44 | // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’) |
| 53 | // for at least two ADC clock cycles. | 45 | // for at least two ADC clock cycles. |
| 54 | blocking_delay_us((1_000_000 * 2) / Self::freq().0 + 1); | 46 | blocking_delay_us((1_000_000 * 2) / Self::freq().0 as u64 + 1); |
| 55 | 47 | ||
| 56 | // Reset calibration | 48 | // Reset calibration |
| 57 | T::regs().cr2().modify(|reg| reg.set_rstcal(true)); | 49 | T::regs().cr2().modify(|reg| reg.set_rstcal(true)); |
| @@ -66,15 +58,12 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 66 | } | 58 | } |
| 67 | 59 | ||
| 68 | // One cycle after calibration | 60 | // One cycle after calibration |
| 69 | blocking_delay_us((1_000_000 * 1) / Self::freq().0 + 1); | 61 | blocking_delay_us((1_000_000 * 1) / Self::freq().0 as u64 + 1); |
| 70 | 62 | ||
| 71 | T::Interrupt::unpend(); | 63 | T::Interrupt::unpend(); |
| 72 | unsafe { T::Interrupt::enable() }; | 64 | unsafe { T::Interrupt::enable() }; |
| 73 | 65 | ||
| 74 | Self { | 66 | Self { adc } |
| 75 | adc, | ||
| 76 | sample_time: SampleTime::from_bits(0), | ||
| 77 | } | ||
| 78 | } | 67 | } |
| 79 | 68 | ||
| 80 | fn freq() -> Hertz { | 69 | fn freq() -> Hertz { |
| @@ -94,22 +83,18 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 94 | } | 83 | } |
| 95 | } | 84 | } |
| 96 | 85 | ||
| 97 | pub fn enable_vref(&self) -> Vref { | 86 | pub fn enable_vref(&self) -> super::VrefInt { |
| 98 | T::regs().cr2().modify(|reg| { | 87 | T::regs().cr2().modify(|reg| { |
| 99 | reg.set_tsvrefe(true); | 88 | reg.set_tsvrefe(true); |
| 100 | }); | 89 | }); |
| 101 | Vref {} | 90 | super::VrefInt {} |
| 102 | } | 91 | } |
| 103 | 92 | ||
| 104 | pub fn enable_temperature(&self) -> Temperature { | 93 | pub fn enable_temperature(&self) -> super::Temperature { |
| 105 | T::regs().cr2().modify(|reg| { | 94 | T::regs().cr2().modify(|reg| { |
| 106 | reg.set_tsvrefe(true); | 95 | reg.set_tsvrefe(true); |
| 107 | }); | 96 | }); |
| 108 | Temperature {} | 97 | super::Temperature {} |
| 109 | } | ||
| 110 | |||
| 111 | pub fn set_sample_time(&mut self, sample_time: SampleTime) { | ||
| 112 | self.sample_time = sample_time; | ||
| 113 | } | 98 | } |
| 114 | 99 | ||
| 115 | /// Perform a single conversion. | 100 | /// Perform a single conversion. |
| @@ -134,8 +119,8 @@ impl<'d, T: Instance> Adc<'d, T> { | |||
| 134 | T::regs().dr().read().0 as u16 | 119 | T::regs().dr().read().0 as u16 |
| 135 | } | 120 | } |
| 136 | 121 | ||
| 137 | pub async fn read(&mut self, channel: &mut impl AdcChannel<T>) -> u16 { | 122 | pub async fn read(&mut self, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) -> u16 { |
| 138 | Self::set_channel_sample_time(channel.channel(), self.sample_time); | 123 | Self::set_channel_sample_time(channel.channel(), sample_time); |
| 139 | T::regs().cr1().modify(|reg| { | 124 | T::regs().cr1().modify(|reg| { |
| 140 | reg.set_scan(false); | 125 | reg.set_scan(false); |
| 141 | reg.set_discen(false); | 126 | reg.set_discen(false); |
