Skip to content

Commit bd2e78e

Browse files
committed
adc: multichannel continuous conversion
1 parent 3fd22e9 commit bd2e78e

File tree

2 files changed

+62
-19
lines changed

2 files changed

+62
-19
lines changed

examples/adc-dma-rx.rs

+57-14
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,23 @@
55

66
use panic_halt as _;
77

8-
use cortex_m::{asm, singleton};
8+
use cortex_m::singleton;
9+
use cortex_m_semihosting::hprintln;
910

1011
use cortex_m_rt::entry;
11-
use stm32f1xx_hal::{adc, pac, prelude::*};
12+
use stm32f1xx_hal::gpio::gpioa::{PA0, PA2};
13+
use stm32f1xx_hal::{adc, gpio::Analog, pac, prelude::*};
14+
15+
pub struct AdcPins(PA0<Analog>, PA2<Analog>);
16+
impl adc::SetChannels<AdcPins> for adc::Adc<pac::ADC1> {
17+
fn set_samples(&mut self) {
18+
self.set_channel_sample_time(0, adc::SampleTime::T_28);
19+
self.set_channel_sample_time(2, adc::SampleTime::T_28);
20+
}
21+
fn set_sequence(&mut self) {
22+
self.set_regular_sequence(&[0, 2, 0, 2]);
23+
}
24+
}
1225

1326
#[entry]
1427
fn main() -> ! {
@@ -34,21 +47,51 @@ fn main() -> ! {
3447

3548
// Configure pa0 as an analog input
3649
let adc_ch0 = gpioa.pa0.into_analog(&mut gpioa.crl);
50+
let adc_ch2 = gpioa.pa2.into_analog(&mut gpioa.crl);
51+
52+
// single-channel continuous conversion
53+
let (adc1, adc_ch0, dma_ch1) = {
54+
let adc_dma = adc1.with_dma(adc_ch0, dma_ch1);
55+
let buf = singleton!(: [u16; 8] = [0; 8]).unwrap();
56+
57+
// The read method consumes the buf and self, starts the adc and dma transfer and returns a
58+
// RxDma struct. The wait method consumes the RxDma struct, waits for the whole transfer to
59+
// be completed and then returns the updated buf and underlying adc_dma struct. For non
60+
// blocking, one can call the is_done method of RxDma and only call wait after that method
61+
// returns true.
62+
let (_buf, adc_dma) = adc_dma.read(buf).wait();
63+
hprintln!("single-channel continuous conversion={:?}", _buf).ok();
64+
65+
// Consumes the AdcDma struct, restores adc configuration to previous state and returns the
66+
// Adc struct in normal mode.
67+
adc_dma.split()
68+
};
69+
70+
// multi-channel single-shot conversion
71+
let (adc1, AdcPins(adc_ch0, adc_ch2), dma_ch1) = {
72+
let pins = AdcPins(adc_ch0, adc_ch2);
73+
let adc_dma = adc1.with_scan_dma::<_, adc::Single>(pins, dma_ch1);
74+
75+
// TODO: should match with # of conversions specified by AdcPins
76+
let buf = singleton!(: [u16; 4] = [0; 4]).unwrap();
77+
78+
let (_buf, adc_dma) = adc_dma.read(buf).wait();
79+
hprintln!("multi-channel single-shot conversion={:?}", _buf).ok();
80+
81+
adc_dma.split()
82+
};
3783

38-
let adc_dma = adc1.with_dma(adc_ch0, dma_ch1);
39-
let buf = singleton!(: [u16; 8] = [0; 8]).unwrap();
84+
// multi-channel continuous conversion
85+
let (_adc1, AdcPins(_adc_ch0, _adc_ch2), _dma_ch1) = {
86+
let pins = AdcPins(adc_ch0, adc_ch2);
87+
let adc_dma = adc1.with_scan_dma::<_, adc::Continuous>(pins, dma_ch1);
88+
let buf = singleton!(: [u16; 8] = [0; 8]).unwrap();
4089

41-
// The read method consumes the buf and self, starts the adc and dma transfer and returns a
42-
// RxDma struct. The wait method consumes the RxDma struct, waits for the whole transfer to be
43-
// completed and then returns the updated buf and underlying adc_dma struct. For non blocking,
44-
// one can call the is_done method of RxDma and only call wait after that method returns true.
45-
let (_buf, adc_dma) = adc_dma.read(buf).wait();
46-
asm::bkpt();
90+
let (_buf, adc_dma) = adc_dma.read(buf).wait();
91+
hprintln!("multi-channel continuous conversion={:?}", _buf).ok();
4792

48-
// Consumes the AdcDma struct, restores adc configuration to previous state and returns the
49-
// Adc struct in normal mode.
50-
let (_adc1, _adc_ch0, _dma_ch1) = adc_dma.split();
51-
asm::bkpt();
93+
adc_dma.split()
94+
};
5295

5396
loop {}
5497
}

src/adc.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use crate::pac::ADC3;
1818

1919
/// Continuous mode
2020
pub struct Continuous;
21-
/// Scan mode
22-
pub struct Scan;
21+
/// Single conversion mode
22+
pub struct Single;
2323

2424
/// ADC configuration
2525
pub struct Adc<ADC> {
@@ -567,7 +567,7 @@ impl<PINS> TransferPayload for AdcDma<PINS, Continuous> {
567567
}
568568
}
569569

570-
impl<PINS> TransferPayload for AdcDma<PINS, Scan> {
570+
impl<PINS> TransferPayload for AdcDma<PINS, Single> {
571571
fn start(&mut self) {
572572
self.channel.start();
573573
self.payload.adc.rb.cr2.modify(|_, w| w.adon().set_bit());
@@ -601,7 +601,7 @@ impl Adc<ADC1> {
601601
}
602602
}
603603

604-
pub fn with_scan_dma<PINS>(mut self, pins: PINS, dma_ch: C1) -> AdcDma<PINS, Scan>
604+
pub fn with_scan_dma<PINS, T>(mut self, pins: PINS, dma_ch: C1) -> AdcDma<PINS, T>
605605
where
606606
Self: SetChannels<PINS>,
607607
{
@@ -651,7 +651,7 @@ where
651651
}
652652
}
653653

654-
impl<PINS> AdcDma<PINS, Scan>
654+
impl<PINS> AdcDma<PINS, Single>
655655
where
656656
Self: TransferPayload,
657657
{

0 commit comments

Comments
 (0)