diff options
| author | kalkyl <[email protected]> | 2024-06-05 09:42:08 +0200 |
|---|---|---|
| committer | kalkyl <[email protected]> | 2024-06-05 09:42:08 +0200 |
| commit | bf36bec9bb85caea613687ab9e0c1652f414b95c (patch) | |
| tree | 80a8f818648742dabff97fd2c27053e7211e1077 /embassy-rp | |
| parent | 5f9bc6def7ea8698a6ce45d8e12e1d1bd8cce876 (diff) | |
rp: Add multichannel ADC
Diffstat (limited to 'embassy-rp')
| -rw-r--r-- | embassy-rp/src/adc.rs | 71 |
1 files changed, 66 insertions, 5 deletions
diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs index 101c5b71f..be453d08e 100644 --- a/embassy-rp/src/adc.rs +++ b/embassy-rp/src/adc.rs | |||
| @@ -221,16 +221,26 @@ impl<'d> Adc<'d, Async> { | |||
| 221 | 221 | ||
| 222 | async fn read_many_inner<W: dma::Word>( | 222 | async fn read_many_inner<W: dma::Word>( |
| 223 | &mut self, | 223 | &mut self, |
| 224 | ch: &mut Channel<'_>, | 224 | channels: impl Iterator<Item = u8>, |
| 225 | buf: &mut [W], | 225 | buf: &mut [W], |
| 226 | fcs_err: bool, | 226 | fcs_err: bool, |
| 227 | div: u16, | 227 | div: u16, |
| 228 | dma: impl Peripheral<P = impl dma::Channel>, | 228 | dma: impl Peripheral<P = impl dma::Channel>, |
| 229 | ) -> Result<(), Error> { | 229 | ) -> Result<(), Error> { |
| 230 | let mut rrobin = 0_u8; | ||
| 231 | for c in channels { | ||
| 232 | rrobin |= 1 << c; | ||
| 233 | } | ||
| 234 | let first_ch = rrobin.trailing_zeros() as u8; | ||
| 235 | if rrobin.count_ones() == 1 { | ||
| 236 | rrobin = 0; | ||
| 237 | } | ||
| 238 | |||
| 230 | let r = Self::regs(); | 239 | let r = Self::regs(); |
| 231 | // clear previous errors and set channel | 240 | // clear previous errors and set channel |
| 232 | r.cs().modify(|w| { | 241 | r.cs().modify(|w| { |
| 233 | w.set_ainsel(ch.channel()); | 242 | w.set_ainsel(first_ch); |
| 243 | w.set_rrobin(rrobin); | ||
| 234 | w.set_err_sticky(true); // clear previous errors | 244 | w.set_err_sticky(true); // clear previous errors |
| 235 | w.set_start_many(false); | 245 | w.set_start_many(false); |
| 236 | }); | 246 | }); |
| @@ -283,7 +293,49 @@ impl<'d> Adc<'d, Async> { | |||
| 283 | } | 293 | } |
| 284 | } | 294 | } |
| 285 | 295 | ||
| 296 | /// Sample multiple values from multiple channels using DMA. | ||
| 297 | /// Samples are stored in an interleaved fashion inside the buffer. | ||
| 298 | /// `div` is the integer part of the clock divider and can be calculated with `floor(48MHz / sample_rate * num_channels - 1)` | ||
| 299 | /// Any `div` value of less than 96 will have the same effect as setting it to 0 | ||
| 300 | #[inline] | ||
| 301 | pub async fn read_many_multichannel<S: AdcSample>( | ||
| 302 | &mut self, | ||
| 303 | ch: &mut [Channel<'_>], | ||
| 304 | buf: &mut [S], | ||
| 305 | div: u16, | ||
| 306 | dma: impl Peripheral<P = impl dma::Channel>, | ||
| 307 | ) -> Result<(), Error> { | ||
| 308 | self.read_many_inner(ch.iter().map(|c| c.channel()), buf, false, div, dma) | ||
| 309 | .await | ||
| 310 | } | ||
| 311 | |||
| 312 | /// Sample multiple values from multiple channels using DMA, with errors inlined in samples. | ||
| 313 | /// Samples are stored in an interleaved fashion inside the buffer. | ||
| 314 | /// `div` is the integer part of the clock divider and can be calculated with `floor(48MHz / sample_rate * num_channels - 1)` | ||
| 315 | /// Any `div` value of less than 96 will have the same effect as setting it to 0 | ||
| 316 | #[inline] | ||
| 317 | pub async fn read_many_multichannel_raw( | ||
| 318 | &mut self, | ||
| 319 | ch: &mut [Channel<'_>], | ||
| 320 | buf: &mut [Sample], | ||
| 321 | div: u16, | ||
| 322 | dma: impl Peripheral<P = impl dma::Channel>, | ||
| 323 | ) { | ||
| 324 | // errors are reported in individual samples | ||
| 325 | let _ = self | ||
| 326 | .read_many_inner( | ||
| 327 | ch.iter().map(|c| c.channel()), | ||
| 328 | unsafe { mem::transmute::<_, &mut [u16]>(buf) }, | ||
| 329 | true, | ||
| 330 | div, | ||
| 331 | dma, | ||
| 332 | ) | ||
| 333 | .await; | ||
| 334 | } | ||
| 335 | |||
| 286 | /// Sample multiple values from a channel using DMA. | 336 | /// Sample multiple values from a channel using DMA. |
| 337 | /// `div` is the integer part of the clock divider and can be calculated with `floor(48MHz / sample_rate - 1)` | ||
| 338 | /// Any `div` value of less than 96 will have the same effect as setting it to 0 | ||
| 287 | #[inline] | 339 | #[inline] |
| 288 | pub async fn read_many<S: AdcSample>( | 340 | pub async fn read_many<S: AdcSample>( |
| 289 | &mut self, | 341 | &mut self, |
| @@ -292,10 +344,13 @@ impl<'d> Adc<'d, Async> { | |||
| 292 | div: u16, | 344 | div: u16, |
| 293 | dma: impl Peripheral<P = impl dma::Channel>, | 345 | dma: impl Peripheral<P = impl dma::Channel>, |
| 294 | ) -> Result<(), Error> { | 346 | ) -> Result<(), Error> { |
| 295 | self.read_many_inner(ch, buf, false, div, dma).await | 347 | self.read_many_inner([ch.channel()].into_iter(), buf, false, div, dma) |
| 348 | .await | ||
| 296 | } | 349 | } |
| 297 | 350 | ||
| 298 | /// Sample multiple values from a channel using DMA with errors inlined in samples. | 351 | /// Sample multiple values from a channel using DMA, with errors inlined in samples. |
| 352 | /// `div` is the integer part of the clock divider and can be calculated with `floor(48MHz / sample_rate - 1)` | ||
| 353 | /// Any `div` value of less than 96 will have the same effect as setting it to 0 | ||
| 299 | #[inline] | 354 | #[inline] |
| 300 | pub async fn read_many_raw( | 355 | pub async fn read_many_raw( |
| 301 | &mut self, | 356 | &mut self, |
| @@ -306,7 +361,13 @@ impl<'d> Adc<'d, Async> { | |||
| 306 | ) { | 361 | ) { |
| 307 | // errors are reported in individual samples | 362 | // errors are reported in individual samples |
| 308 | let _ = self | 363 | let _ = self |
| 309 | .read_many_inner(ch, unsafe { mem::transmute::<_, &mut [u16]>(buf) }, true, div, dma) | 364 | .read_many_inner( |
| 365 | [ch.channel()].into_iter(), | ||
| 366 | unsafe { mem::transmute::<_, &mut [u16]>(buf) }, | ||
| 367 | true, | ||
| 368 | div, | ||
| 369 | dma, | ||
| 370 | ) | ||
| 310 | .await; | 371 | .await; |
| 311 | } | 372 | } |
| 312 | } | 373 | } |
