diff options
| -rw-r--r-- | embassy-stm32/src/adc/ringbuffered_v2.rs | 67 | ||||
| -rw-r--r-- | embassy-stm32/src/adc/v2.rs | 107 |
2 files changed, 14 insertions, 160 deletions
diff --git a/embassy-stm32/src/adc/ringbuffered_v2.rs b/embassy-stm32/src/adc/ringbuffered_v2.rs index ecb8ae3f2..c520daea4 100644 --- a/embassy-stm32/src/adc/ringbuffered_v2.rs +++ b/embassy-stm32/src/adc/ringbuffered_v2.rs | |||
| @@ -16,73 +16,6 @@ fn clear_interrupt_flags(r: crate::pac::adc::Adc) { | |||
| 16 | }); | 16 | }); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | #[derive(PartialOrd, PartialEq, Debug, Clone, Copy)] | ||
| 20 | pub(super) enum Sequence { | ||
| 21 | One, | ||
| 22 | Two, | ||
| 23 | Three, | ||
| 24 | Four, | ||
| 25 | Five, | ||
| 26 | Six, | ||
| 27 | Seven, | ||
| 28 | Eight, | ||
| 29 | Nine, | ||
| 30 | Ten, | ||
| 31 | Eleven, | ||
| 32 | Twelve, | ||
| 33 | Thirteen, | ||
| 34 | Fourteen, | ||
| 35 | Fifteen, | ||
| 36 | Sixteen, | ||
| 37 | } | ||
| 38 | |||
| 39 | impl From<Sequence> for u8 { | ||
| 40 | fn from(s: Sequence) -> u8 { | ||
| 41 | match s { | ||
| 42 | Sequence::One => 0, | ||
| 43 | Sequence::Two => 1, | ||
| 44 | Sequence::Three => 2, | ||
| 45 | Sequence::Four => 3, | ||
| 46 | Sequence::Five => 4, | ||
| 47 | Sequence::Six => 5, | ||
| 48 | Sequence::Seven => 6, | ||
| 49 | Sequence::Eight => 7, | ||
| 50 | Sequence::Nine => 8, | ||
| 51 | Sequence::Ten => 9, | ||
| 52 | Sequence::Eleven => 10, | ||
| 53 | Sequence::Twelve => 11, | ||
| 54 | Sequence::Thirteen => 12, | ||
| 55 | Sequence::Fourteen => 13, | ||
| 56 | Sequence::Fifteen => 14, | ||
| 57 | Sequence::Sixteen => 15, | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | impl From<u8> for Sequence { | ||
| 63 | fn from(val: u8) -> Self { | ||
| 64 | match val { | ||
| 65 | 0 => Sequence::One, | ||
| 66 | 1 => Sequence::Two, | ||
| 67 | 2 => Sequence::Three, | ||
| 68 | 3 => Sequence::Four, | ||
| 69 | 4 => Sequence::Five, | ||
| 70 | 5 => Sequence::Six, | ||
| 71 | 6 => Sequence::Seven, | ||
| 72 | 7 => Sequence::Eight, | ||
| 73 | 8 => Sequence::Nine, | ||
| 74 | 9 => Sequence::Ten, | ||
| 75 | 10 => Sequence::Eleven, | ||
| 76 | 11 => Sequence::Twelve, | ||
| 77 | 12 => Sequence::Thirteen, | ||
| 78 | 13 => Sequence::Fourteen, | ||
| 79 | 14 => Sequence::Fifteen, | ||
| 80 | 15 => Sequence::Sixteen, | ||
| 81 | _ => panic!("Invalid sequence number"), | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | pub struct RingBufferedAdc<'d, T: Instance> { | 19 | pub struct RingBufferedAdc<'d, T: Instance> { |
| 87 | pub(super) _phantom: PhantomData<T>, | 20 | pub(super) _phantom: PhantomData<T>, |
| 88 | pub(super) ring_buf: ReadableRingBuffer<'d, u16>, | 21 | pub(super) ring_buf: ReadableRingBuffer<'d, u16>, |
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs index e81e820e3..44e655b45 100644 --- a/embassy-stm32/src/adc/v2.rs +++ b/embassy-stm32/src/adc/v2.rs | |||
| @@ -2,12 +2,11 @@ use core::marker::PhantomData; | |||
| 2 | use core::mem; | 2 | use core::mem; |
| 3 | 3 | ||
| 4 | use super::blocking_delay_us; | 4 | use super::blocking_delay_us; |
| 5 | use crate::adc::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime}; | 5 | use crate::adc::{Adc, AdcChannel, AnyAdcChannel, Instance, Resolution, RxDma, SampleTime, SealedAdcChannel}; |
| 6 | use crate::dma::{Priority, ReadableRingBuffer, TransferOptions}; | 6 | use crate::dma::{Priority, ReadableRingBuffer, TransferOptions}; |
| 7 | use crate::peripherals::ADC1; | 7 | use crate::peripherals::ADC1; |
| 8 | use crate::time::Hertz; | 8 | use crate::time::Hertz; |
| 9 | use crate::{Peri, rcc}; | 9 | use crate::{Peri, rcc}; |
| 10 | use ringbuffered_v2::Sequence; | ||
| 11 | 10 | ||
| 12 | mod ringbuffered_v2; | 11 | mod ringbuffered_v2; |
| 13 | pub use ringbuffered_v2::RingBufferedAdc; | 12 | pub use ringbuffered_v2::RingBufferedAdc; |
| @@ -128,7 +127,7 @@ where | |||
| 128 | /// | 127 | /// |
| 129 | /// [`read`]: #method.read | 128 | /// [`read`]: #method.read |
| 130 | pub fn into_ring_buffered<'a>( | 129 | pub fn into_ring_buffered<'a>( |
| 131 | mut self, | 130 | self, |
| 132 | dma: Peri<'d, impl RxDma<T>>, | 131 | dma: Peri<'d, impl RxDma<T>>, |
| 133 | dma_buf: &'d mut [u16], | 132 | dma_buf: &'d mut [u16], |
| 134 | sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, | 133 | sequence: impl ExactSizeIterator<Item = (&'a mut AnyAdcChannel<T>, SampleTime)>, |
| @@ -147,109 +146,31 @@ where | |||
| 147 | 146 | ||
| 148 | let ring_buf = unsafe { ReadableRingBuffer::new(dma, request, rx_src, dma_buf, opts) }; | 147 | let ring_buf = unsafe { ReadableRingBuffer::new(dma, request, rx_src, dma_buf, opts) }; |
| 149 | 148 | ||
| 150 | for (i, (channel, sample_time)) in sequence.enumerate() { | ||
| 151 | let sequence = match i { | ||
| 152 | 0 => Sequence::One, | ||
| 153 | 1 => Sequence::Two, | ||
| 154 | 2 => Sequence::Three, | ||
| 155 | 3 => Sequence::Four, | ||
| 156 | 4 => Sequence::Five, | ||
| 157 | 5 => Sequence::Six, | ||
| 158 | 6 => Sequence::Seven, | ||
| 159 | 7 => Sequence::Eight, | ||
| 160 | 8 => Sequence::Nine, | ||
| 161 | 9 => Sequence::Ten, | ||
| 162 | 10 => Sequence::Eleven, | ||
| 163 | 11 => Sequence::Twelve, | ||
| 164 | 12 => Sequence::Thirteen, | ||
| 165 | 13 => Sequence::Fourteen, | ||
| 166 | 14 => Sequence::Fifteen, | ||
| 167 | 15 => Sequence::Sixteen, | ||
| 168 | _ => unreachable!(), | ||
| 169 | }; | ||
| 170 | |||
| 171 | self.set_sample_sequence(sequence, channel, sample_time); | ||
| 172 | } | ||
| 173 | |||
| 174 | // Don't disable the clock | ||
| 175 | mem::forget(self); | ||
| 176 | |||
| 177 | RingBufferedAdc { | ||
| 178 | _phantom: PhantomData, | ||
| 179 | ring_buf, | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | fn is_on() -> bool { | ||
| 184 | T::regs().cr2().read().adon() | ||
| 185 | } | ||
| 186 | |||
| 187 | fn stop_adc() { | ||
| 188 | T::regs().cr2().modify(|reg| { | ||
| 189 | reg.set_adon(false); | ||
| 190 | }); | ||
| 191 | } | ||
| 192 | |||
| 193 | fn start_adc() { | ||
| 194 | T::regs().cr2().modify(|reg| { | 149 | T::regs().cr2().modify(|reg| { |
| 195 | reg.set_adon(true); | 150 | reg.set_adon(true); |
| 196 | }); | 151 | }); |
| 197 | } | ||
| 198 | |||
| 199 | fn set_sample_sequence(&mut self, sequence: Sequence, channel: &mut impl AdcChannel<T>, sample_time: SampleTime) { | ||
| 200 | let was_on = Self::is_on(); | ||
| 201 | if !was_on { | ||
| 202 | Self::start_adc(); | ||
| 203 | } | ||
| 204 | 152 | ||
| 205 | // Check the sequence is long enough | 153 | // Check the sequence is long enough |
| 206 | T::regs().sqr1().modify(|r| { | 154 | T::regs().sqr1().modify(|r| { |
| 207 | let prev: Sequence = r.l().into(); | 155 | r.set_l((sequence.len() - 1).try_into().unwrap()); |
| 208 | if prev < sequence { | ||
| 209 | let new_l: Sequence = sequence; | ||
| 210 | trace!("Setting sequence length from {:?} to {:?}", prev as u8, new_l as u8); | ||
| 211 | r.set_l(sequence.into()) | ||
| 212 | } else { | ||
| 213 | r.set_l(prev.into()) | ||
| 214 | } | ||
| 215 | }); | 156 | }); |
| 216 | 157 | ||
| 217 | // Set this GPIO as an analog input. | 158 | for (i, (channel, sample_time)) in sequence.enumerate() { |
| 218 | channel.setup(); | 159 | // Set this GPIO as an analog input. |
| 160 | channel.setup(); | ||
| 219 | 161 | ||
| 220 | // Set the channel in the right sequence field. | 162 | // Set the channel in the right sequence field. |
| 221 | match sequence { | 163 | T::regs().sqr3().modify(|w| w.set_sq(i, channel.channel())); |
| 222 | Sequence::One => T::regs().sqr3().modify(|w| w.set_sq(0, channel.channel())), | ||
| 223 | Sequence::Two => T::regs().sqr3().modify(|w| w.set_sq(1, channel.channel())), | ||
| 224 | Sequence::Three => T::regs().sqr3().modify(|w| w.set_sq(2, channel.channel())), | ||
| 225 | Sequence::Four => T::regs().sqr3().modify(|w| w.set_sq(3, channel.channel())), | ||
| 226 | Sequence::Five => T::regs().sqr3().modify(|w| w.set_sq(4, channel.channel())), | ||
| 227 | Sequence::Six => T::regs().sqr3().modify(|w| w.set_sq(5, channel.channel())), | ||
| 228 | Sequence::Seven => T::regs().sqr2().modify(|w| w.set_sq(0, channel.channel())), | ||
| 229 | Sequence::Eight => T::regs().sqr2().modify(|w| w.set_sq(1, channel.channel())), | ||
| 230 | Sequence::Nine => T::regs().sqr2().modify(|w| w.set_sq(2, channel.channel())), | ||
| 231 | Sequence::Ten => T::regs().sqr2().modify(|w| w.set_sq(3, channel.channel())), | ||
| 232 | Sequence::Eleven => T::regs().sqr2().modify(|w| w.set_sq(4, channel.channel())), | ||
| 233 | Sequence::Twelve => T::regs().sqr2().modify(|w| w.set_sq(5, channel.channel())), | ||
| 234 | Sequence::Thirteen => T::regs().sqr1().modify(|w| w.set_sq(0, channel.channel())), | ||
| 235 | Sequence::Fourteen => T::regs().sqr1().modify(|w| w.set_sq(1, channel.channel())), | ||
| 236 | Sequence::Fifteen => T::regs().sqr1().modify(|w| w.set_sq(2, channel.channel())), | ||
| 237 | Sequence::Sixteen => T::regs().sqr1().modify(|w| w.set_sq(3, channel.channel())), | ||
| 238 | }; | ||
| 239 | 164 | ||
| 240 | if !was_on { | 165 | Self::set_channel_sample_time(channel.channel(), sample_time); |
| 241 | Self::stop_adc(); | ||
| 242 | } | 166 | } |
| 243 | 167 | ||
| 244 | self.set_channels_sample_time(&[channel.channel()], sample_time); | 168 | // Don't disable the clock |
| 245 | 169 | mem::forget(self); | |
| 246 | Self::start_adc(); | ||
| 247 | } | ||
| 248 | 170 | ||
| 249 | fn set_channels_sample_time(&mut self, ch: &[u8], sample_time: SampleTime) { | 171 | RingBufferedAdc { |
| 250 | let ch_iter = ch.iter(); | 172 | _phantom: PhantomData, |
| 251 | for idx in ch_iter { | 173 | ring_buf, |
| 252 | Self::set_channel_sample_time(*idx, sample_time); | ||
| 253 | } | 174 | } |
| 254 | } | 175 | } |
| 255 | 176 | ||
