Skip to content

Commit 6e4ac90

Browse files
committed
Examples fixed, tested and seems to work
* Add support for comparator to take signal from dac as input * Added example for using dac as input to comparator
1 parent 3c68d70 commit 6e4ac90

File tree

5 files changed

+144
-42
lines changed

5 files changed

+144
-42
lines changed

examples/comp.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
#![no_main]
44
#![no_std]
55

6-
use hal::adc::config::SampleTime;
7-
use hal::adc::{AdcClaim, ClockSource};
86
use hal::comparator::{ComparatorExt, ComparatorSplit, Config, Hysteresis, RefintInput};
9-
use hal::delay::SYSTDelayExt;
107
use hal::gpio::GpioExt;
118
use hal::prelude::OutputPin;
129
use hal::rcc::RccExt;

examples/comp_w_dac.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// #![deny(warnings)]
2+
#![deny(unsafe_code)]
3+
#![no_main]
4+
#![no_std]
5+
6+
use embedded_hal::Direction;
7+
use hal::comparator::{self, ComparatorExt, ComparatorSplit};
8+
use hal::dac::{Dac1IntSig1, DacExt, DacOut};
9+
use hal::delay::SYSTDelayExt;
10+
use hal::gpio::GpioExt;
11+
use hal::rcc::RccExt;
12+
use stm32g4xx_hal as hal;
13+
mod utils;
14+
extern crate cortex_m_rt as rt;
15+
16+
use hal::stm32;
17+
use rt::entry;
18+
19+
#[entry]
20+
fn main() -> ! {
21+
let dp = stm32::Peripherals::take().expect("cannot take peripherals");
22+
let cp = cortex_m::Peripherals::take().expect("cannot take core peripherals");
23+
24+
let mut rcc = dp.RCC.constrain();
25+
let mut delay = cp.SYST.delay(&rcc.clocks);
26+
27+
let gpioa = dp.GPIOA.split(&mut rcc);
28+
let dac1ch1 = dp.DAC1.constrain((gpioa.pa4, Dac1IntSig1), &mut rcc);
29+
30+
let mut dac = dac1ch1.calibrate_buffer(&mut delay).enable();
31+
32+
let (comp1, _comp2, ..) = dp.COMP.split(&mut rcc);
33+
let pa1 = gpioa.pa1.into_analog();
34+
let comp = comp1.comparator(
35+
pa1,
36+
&dac,
37+
comparator::Config::default().hysteresis(comparator::Hysteresis::None),
38+
&rcc.clocks,
39+
);
40+
41+
let led2 = gpioa.pa0.into_push_pull_output();
42+
// Configure PA12 to the comparator's alternate function so it gets
43+
// changed directly by the comparator.
44+
comp.output_pin(led2);
45+
let _comp1 = comp.enable().lock();
46+
47+
let mut dir = Direction::Upcounting;
48+
let mut val = 0;
49+
50+
loop {
51+
dac.set_value(val);
52+
match val {
53+
0 => dir = Direction::Upcounting,
54+
4095 => dir = Direction::Downcounting,
55+
_ => (),
56+
};
57+
58+
match dir {
59+
Direction::Upcounting => val += 1,
60+
Direction::Downcounting => val -= 1,
61+
}
62+
}
63+
}

examples/dac.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ fn main() -> ! {
2626
let gpioa = dp.GPIOA.split(&mut rcc);
2727
let (dac1ch1, dac1ch2) = dp.DAC1.constrain((gpioa.pa4, gpioa.pa5), &mut rcc);
2828

29-
let mut dac = dac1ch1.calibrate_buffer(&mut delay).enable();
30-
let mut generator = dac1ch2.enable_generator(GeneratorConfig::noise(11));
29+
let mut dac_manual = dac1ch1.calibrate_buffer(&mut delay).enable();
30+
let mut dac_generator = dac1ch2.enable_generator(GeneratorConfig::noise(11));
3131

3232
let mut dir = Direction::Upcounting;
3333
let mut val = 0;
3434

3535
loop {
36-
generator.trigger();
37-
dac.set_value(val);
36+
dac_generator.trigger();
37+
dac_manual.set_value(val);
3838
match val {
3939
0 => dir = Direction::Upcounting,
4040
4095 => dir = Direction::Downcounting,

src/comparator.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ refint_input!(COMP5, COMP6, COMP7,);
347347

348348
macro_rules! dac_input {
349349
($COMP:ident: $channel:ty, $bits:expr) => {
350-
impl<ED> NegativeInput<$COMP> for &$channel {
350+
impl<const MODE: u8, ED> NegativeInput<$COMP> for &$channel {
351351
const USE_VREFINT: bool = false;
352352

353353
fn use_resistor_divider(&self) -> bool {
@@ -361,62 +361,62 @@ macro_rules! dac_input {
361361
};
362362
}
363363

364-
dac_input!(COMP1: dac::Dac3Ch1<ED>, 0b100);
365-
dac_input!(COMP1: dac::Dac1Ch1<ED>, 0b101);
364+
dac_input!(COMP1: dac::Dac3Ch1<MODE, ED>, 0b100);
365+
dac_input!(COMP1: dac::Dac1Ch1<MODE, ED>, 0b101);
366366

367-
dac_input!(COMP2: dac::Dac3Ch2<ED>, 0b100);
368-
dac_input!(COMP2: dac::Dac1Ch2<ED>, 0b101);
367+
dac_input!(COMP2: dac::Dac3Ch2<MODE, ED>, 0b100);
368+
dac_input!(COMP2: dac::Dac1Ch2<MODE, ED>, 0b101);
369369

370-
dac_input!(COMP3: dac::Dac3Ch1<ED>, 0b100);
371-
dac_input!(COMP3: dac::Dac1Ch1<ED>, 0b101);
370+
dac_input!(COMP3: dac::Dac3Ch1<MODE, ED>, 0b100);
371+
dac_input!(COMP3: dac::Dac1Ch1<MODE, ED>, 0b101);
372372

373-
dac_input!(COMP4: dac::Dac3Ch2<ED>, 0b100);
374-
dac_input!(COMP4: dac::Dac1Ch1<ED>, 0b101);
373+
dac_input!(COMP4: dac::Dac3Ch2<MODE, ED>, 0b100);
374+
dac_input!(COMP4: dac::Dac1Ch1<MODE, ED>, 0b101);
375375

376376
#[cfg(any(
377377
feature = "stm32g473",
378378
feature = "stm32g483",
379379
feature = "stm32g474",
380380
feature = "stm32g484"
381381
))]
382-
dac_input!(COMP5: dac::Dac4Ch1<ED>, 0b100);
382+
dac_input!(COMP5: dac::Dac4Ch1<MODE, ED>, 0b100);
383383
#[cfg(any(
384384
feature = "stm32g473",
385385
feature = "stm32g483",
386386
feature = "stm32g474",
387387
feature = "stm32g484"
388388
))]
389-
dac_input!(COMP5: dac::Dac1Ch2<ED>, 0b101);
389+
dac_input!(COMP5: dac::Dac1Ch2<MODE, ED>, 0b101);
390390

391391
#[cfg(any(
392392
feature = "stm32g473",
393393
feature = "stm32g483",
394394
feature = "stm32g474",
395395
feature = "stm32g484"
396396
))]
397-
dac_input!(COMP6: dac::Dac4Ch2<ED>, 0b100);
397+
dac_input!(COMP6: dac::Dac4Ch2<MODE, ED>, 0b100);
398398
#[cfg(any(
399399
feature = "stm32g473",
400400
feature = "stm32g483",
401401
feature = "stm32g474",
402402
feature = "stm32g484"
403403
))]
404-
dac_input!(COMP6: dac::Dac2Ch1<ED>, 0b101);
404+
dac_input!(COMP6: dac::Dac2Ch1<MODE, ED>, 0b101);
405405

406406
#[cfg(any(
407407
feature = "stm32g473",
408408
feature = "stm32g483",
409409
feature = "stm32g474",
410410
feature = "stm32g484"
411411
))]
412-
dac_input!(COMP7: dac::Dac4Ch1<ED>, 0b100);
412+
dac_input!(COMP7: dac::Dac4Ch1<MODE, ED>, 0b100);
413413
#[cfg(any(
414414
feature = "stm32g473",
415415
feature = "stm32g483",
416416
feature = "stm32g474",
417417
feature = "stm32g484"
418418
))]
419-
dac_input!(COMP7: dac::Dac2Ch1<ED>, 0b101);
419+
dac_input!(COMP7: dac::Dac2Ch1<MODE, ED>, 0b101);
420420

421421
pub struct Comparator<C, ED> {
422422
regs: C,

src/dac.rs

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl ED for Disabled {}
6464

6565
macro_rules! impl_dac {
6666
($DACxCHy:ident) => {
67-
pub struct $DACxCHy<ED> {
67+
pub struct $DACxCHy<const MODE_BITS: u8, ED> {
6868
_enabled: PhantomData<ED>,
6969
}
7070
};
@@ -83,21 +83,63 @@ pub trait Pins<DAC> {
8383
type Output;
8484
}
8585

86+
const M_EXT_PIN: u8 = 0b000;
87+
const M_MIX_SIG: u8 = 0b001;
88+
const M_INT_SIG: u8 = 0b011;
89+
90+
pub struct Dac1IntSig1;
91+
pub struct Dac1IntSig2;
92+
pub struct Dac2IntSig1;
93+
pub struct Dac3IntSig1;
94+
pub struct Dac3IntSig2;
95+
pub struct Dac4IntSig1;
96+
pub struct Dac4IntSig2;
97+
8698
macro_rules! impl_pin_for_dac {
8799
($DAC:ident: $pin:ty, $output:ty) => {
100+
#[allow(unused_parens)]
88101
impl Pins<$DAC> for $pin {
102+
#[allow(unused_parens)]
89103
type Output = $output;
90104
}
91105
};
92106
}
93107

94-
impl_pin_for_dac!(DAC1: PA4<DefaultMode>, Dac1Ch1<Disabled>);
95-
impl_pin_for_dac!(DAC1: PA5<DefaultMode>, Dac1Ch2<Disabled>);
96-
impl_pin_for_dac!(
97-
DAC1: (PA4<DefaultMode>, PA5<DefaultMode>),
98-
(Dac1Ch1<Disabled>, Dac1Ch2<Disabled>)
99-
);
100-
impl_pin_for_dac!(DAC2: PA6<DefaultMode>, Dac2Ch1<Disabled>);
108+
// Implement all combinations of ch2 for the specified ch1 on DAC1
109+
macro_rules! impl_dac1_ch2_combos {
110+
($($pin_ch1:ty, $output_ch1:ty)*) => {
111+
$(impl_pin_for_dac!(DAC1: $pin_ch1, // ch2: Not used
112+
$output_ch1
113+
);)*
114+
impl_pin_for_dac!(DAC1: ($($pin_ch1,)* PA5<DefaultMode>), // ch2: Ext pin
115+
($($output_ch1,)* Dac1Ch2<M_EXT_PIN, Disabled>)
116+
);
117+
impl_pin_for_dac!(DAC1: ($($pin_ch1,)* Dac1IntSig2), // ch2: Internal
118+
($($output_ch1,)* Dac1Ch2<M_INT_SIG, Disabled>)
119+
);
120+
impl_pin_for_dac!(DAC1: ($($pin_ch1,)* (PA5<DefaultMode>, Dac1IntSig2)),// ch2: Mixed
121+
($($output_ch1,)* Dac1Ch2<M_MIX_SIG, Disabled>)
122+
);
123+
};
124+
}
125+
126+
impl_dac1_ch2_combos!(); // ch1: Not used
127+
impl_dac1_ch2_combos!(PA4<DefaultMode>, Dac1Ch1<M_EXT_PIN, Disabled>); // ch1: Ext pin
128+
impl_dac1_ch2_combos!(Dac1IntSig1, Dac1Ch1<M_INT_SIG, Disabled>); // ch1: Internal
129+
impl_dac1_ch2_combos!((PA4<DefaultMode>, Dac1IntSig1), Dac1Ch1<M_MIX_SIG, Disabled>); // ch1: Mixed
130+
131+
// DAC2
132+
impl_pin_for_dac!(DAC2: PA6<DefaultMode>, Dac2Ch1<M_EXT_PIN, Disabled>); // ch1: Ext pin
133+
impl_pin_for_dac!(DAC2: Dac2IntSig1, Dac2Ch1<M_INT_SIG, Disabled>); // ch1: Internal
134+
impl_pin_for_dac!(DAC2: (PA6<DefaultMode>, Dac2IntSig1), Dac2Ch1<M_MIX_SIG, Disabled>); // ch1: Mixed
135+
136+
// DAC3 int
137+
impl_pin_for_dac!(DAC3: Dac3IntSig1, Dac3Ch1<M_INT_SIG, Disabled>);
138+
impl_pin_for_dac!(DAC3: Dac3IntSig2, Dac3Ch2<M_INT_SIG, Disabled>);
139+
140+
// DAC4 int
141+
impl_pin_for_dac!(DAC4: Dac4IntSig1, Dac4Ch1<M_INT_SIG, Disabled>);
142+
impl_pin_for_dac!(DAC4: Dac4IntSig2, Dac4Ch2<M_INT_SIG, Disabled>);
101143

102144
pub fn dac<DAC, PINS>(_dac: DAC, _pins: PINS, _rcc: &mut Rcc) -> PINS::Output
103145
where
@@ -132,19 +174,19 @@ macro_rules! dac_helper {
132174
$swtrig:ident
133175
),)+) => {
134176
$(
135-
impl $CX<Disabled> {
136-
pub fn enable(self) -> $CX<Enabled> {
177+
impl<const MODE_BITS: u8> $CX<MODE_BITS, Disabled> {
178+
pub fn enable(self) -> $CX<MODE_BITS, Enabled> {
137179
let dac = unsafe { &(*<$DAC>::ptr()) };
138180

139-
dac.dac_mcr.modify(|_, w| unsafe { w.$mode().bits(1) });
181+
dac.dac_mcr.modify(|_, w| unsafe { w.$mode().bits(MODE_BITS) });
140182
dac.dac_cr.modify(|_, w| w.$en().set_bit());
141183

142184
$CX {
143185
_enabled: PhantomData,
144186
}
145187
}
146188

147-
pub fn enable_unbuffered(self) -> $CX<EnabledUnbuffered> {
189+
/*pub fn enable_unbuffered(self) -> $CX<MODE_BITS, EnabledUnbuffered> {
148190
let dac = unsafe { &(*<$DAC>::ptr()) };
149191
150192
dac.dac_mcr.modify(|_, w| unsafe { w.$mode().bits(2) });
@@ -153,12 +195,12 @@ macro_rules! dac_helper {
153195
$CX {
154196
_enabled: PhantomData,
155197
}
156-
}
198+
}*/
157199

158-
pub fn enable_generator(self, config: GeneratorConfig) -> $CX<WaveGenerator> {
200+
pub fn enable_generator(self, config: GeneratorConfig) -> $CX<MODE_BITS, WaveGenerator> {
159201
let dac = unsafe { &(*<$DAC>::ptr()) };
160202

161-
dac.dac_mcr.modify(|_, w| unsafe { w.$mode().bits(1) });
203+
dac.dac_mcr.modify(|_, w| unsafe { w.$mode().bits(MODE_BITS) });
162204
dac.dac_cr.modify(|_, w| unsafe {
163205
w.$wave().bits(config.mode);
164206
w.$ten().set_bit();
@@ -172,7 +214,7 @@ macro_rules! dac_helper {
172214
}
173215
}
174216

175-
impl<ED> $CX<ED> {
217+
impl<const MODE_BITS: u8, ED> $CX<MODE_BITS, ED> {
176218
/// Calibrate the DAC output buffer by performing a "User
177219
/// trimming" operation. It is useful when the VDDA/VREF+
178220
/// voltage or temperature differ from the factory trimming
@@ -184,7 +226,7 @@ macro_rules! dac_helper {
184226
///
185227
/// After the calibration operation, the DAC channel is
186228
/// disabled.
187-
pub fn calibrate_buffer<T>(self, delay: &mut T) -> $CX<Disabled>
229+
pub fn calibrate_buffer<T>(self, delay: &mut T) -> $CX<MODE_BITS, Disabled>
188230
where
189231
T: DelayUs<u32>,
190232
{
@@ -209,7 +251,7 @@ macro_rules! dac_helper {
209251
}
210252

211253
/// Disable the DAC channel
212-
pub fn disable(self) -> $CX<Disabled> {
254+
pub fn disable(self) -> $CX<MODE_BITS, Disabled> {
213255
let dac = unsafe { &(*<$DAC>::ptr()) };
214256
dac.dac_cr.modify(|_, w| unsafe {
215257
w.$en().clear_bit().$wave().bits(0).$ten().clear_bit()
@@ -223,7 +265,7 @@ macro_rules! dac_helper {
223265

224266
/// DacOut implementation available in any Enabled/Disabled
225267
/// state
226-
impl<ED> DacOut<u16> for $CX<ED> {
268+
impl<const MODE_BITS: u8, ED> DacOut<u16> for $CX<MODE_BITS, ED> {
227269
fn set_value(&mut self, val: u16) {
228270
let dac = unsafe { &(*<$DAC>::ptr()) };
229271
dac.$dhrx.write(|w| unsafe { w.bits(val as u32) });
@@ -236,7 +278,7 @@ macro_rules! dac_helper {
236278
}
237279

238280
/// Wave generator state implementation
239-
impl $CX<WaveGenerator> {
281+
impl<const MODE_BITS: u8> $CX<MODE_BITS, WaveGenerator> {
240282
pub fn trigger(&mut self) {
241283
let dac = unsafe { &(*<$DAC>::ptr()) };
242284
dac.dac_swtrgr.write(|w| { w.$swtrig().set_bit() });

0 commit comments

Comments
 (0)