Skip to content

Commit a92f938

Browse files
authored
Merge pull request #74 from usbalbin/comp_and_dac
Add Comparator and DAC
2 parents 035f767 + 78d4075 commit a92f938

File tree

6 files changed

+1212
-1
lines changed

6 files changed

+1212
-1
lines changed

examples/comp.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! ## Origin
2+
//!
3+
//! This code has been taken from the stm32g0xx-hal project and modified slightly to support
4+
//! STM32G4xx MCUs.
5+
6+
//#![deny(warnings)]
7+
#![deny(unsafe_code)]
8+
#![no_main]
9+
#![no_std]
10+
11+
mod utils;
12+
extern crate cortex_m_rt as rt;
13+
14+
use rt::entry;
15+
16+
#[cfg(not(feature = "stm32g474"))]
17+
#[entry]
18+
fn main() -> ! {
19+
loop {} // TODO: add support for more devices
20+
}
21+
22+
#[cfg(feature = "stm32g474")]
23+
#[entry]
24+
fn main() -> ! {
25+
use hal::comparator::{ComparatorExt, ComparatorSplit, Config, Hysteresis, RefintInput};
26+
use hal::gpio::GpioExt;
27+
use hal::prelude::OutputPin;
28+
use hal::rcc::RccExt;
29+
use hal::stm32;
30+
use stm32g4xx_hal as hal;
31+
32+
let dp = stm32::Peripherals::take().expect("cannot take peripherals");
33+
let mut rcc = dp.RCC.constrain();
34+
35+
let gpioa = dp.GPIOA.split(&mut rcc);
36+
37+
let (comp1, comp2, ..) = dp.COMP.split(&mut rcc);
38+
39+
let pa1 = gpioa.pa1.into_analog();
40+
let pa0 = gpioa.pa0.into_analog();
41+
let comp1 = comp1.comparator(&pa1, pa0, Config::default(), &rcc.clocks);
42+
let comp1 = comp1.enable();
43+
44+
// led1 pa1 will be updated manually when to match comp1 value
45+
let mut led1 = gpioa.pa5.into_push_pull_output();
46+
47+
let pa7 = gpioa.pa7.into_analog();
48+
let comp2 = comp2.comparator(
49+
&pa7,
50+
RefintInput::VRefintM12,
51+
Config::default()
52+
.hysteresis(Hysteresis::None)
53+
.output_inverted(),
54+
&rcc.clocks,
55+
);
56+
let led2 = gpioa.pa12.into_push_pull_output();
57+
// Configure PA12 to the comparator's alternate function so it gets
58+
// changed directly by the comparator.
59+
comp2.output_pin(led2);
60+
let _comp2 = comp2.enable().lock();
61+
62+
loop {
63+
// Read comp1 output and update led1 accordingly
64+
match comp1.output() {
65+
true => led1.set_high().unwrap(),
66+
false => led1.set_low().unwrap(),
67+
}
68+
}
69+
}

examples/comp_w_dac.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// #![deny(warnings)]
2+
#![deny(unsafe_code)]
3+
#![no_main]
4+
#![no_std]
5+
6+
mod utils;
7+
extern crate cortex_m_rt as rt;
8+
9+
use rt::entry;
10+
11+
#[cfg(not(feature = "stm32g474"))]
12+
#[entry]
13+
fn main() -> ! {
14+
loop {} // TODO: add support for more devices
15+
}
16+
17+
#[cfg(feature = "stm32g474")]
18+
#[entry]
19+
fn main() -> ! {
20+
use embedded_hal::Direction;
21+
use hal::comparator::{self, ComparatorExt, ComparatorSplit};
22+
use hal::dac::{Dac1IntSig1, DacExt, DacOut};
23+
use hal::delay::SYSTDelayExt;
24+
use hal::gpio::GpioExt;
25+
use hal::rcc::RccExt;
26+
use hal::stm32;
27+
use stm32g4xx_hal as hal;
28+
29+
let dp = stm32::Peripherals::take().expect("cannot take peripherals");
30+
let cp = cortex_m::Peripherals::take().expect("cannot take core peripherals");
31+
32+
let mut rcc = dp.RCC.constrain();
33+
let mut delay = cp.SYST.delay(&rcc.clocks);
34+
35+
let gpioa = dp.GPIOA.split(&mut rcc);
36+
37+
// Set up DAC to output to pa4 and to internal signal Dac1IntSig1
38+
// which just so happens is compatible with comp1
39+
let dac1ch1 = dp.DAC1.constrain((gpioa.pa4, Dac1IntSig1), &mut rcc);
40+
let mut dac = dac1ch1.calibrate_buffer(&mut delay).enable();
41+
42+
let (comp1, _comp2, ..) = dp.COMP.split(&mut rcc);
43+
let pa1 = gpioa.pa1.into_analog();
44+
45+
// Set up comparator with pa1 as positive, and the DAC as negative input
46+
let comp = comp1.comparator(
47+
&pa1,
48+
&dac,
49+
comparator::Config::default().hysteresis(comparator::Hysteresis::None),
50+
&rcc.clocks,
51+
);
52+
53+
let led2 = gpioa.pa0.into_push_pull_output();
54+
// Configure PA12 to the comparator's alternate function so it gets
55+
// changed directly by the comparator.
56+
comp.output_pin(led2);
57+
let _comp1 = comp.enable().lock();
58+
59+
let mut dir = Direction::Upcounting;
60+
let mut val = 0;
61+
62+
// Manually step the DAC's value to produce a triangle wave
63+
//
64+
// This will produce a pwm-like signal at pa0 with the duty controlled by pa1
65+
// where
66+
// * 0V at p1 => 0% duty
67+
// * VDDA at p1 => 100% duty
68+
loop {
69+
dac.set_value(val);
70+
match val {
71+
0 => dir = Direction::Upcounting,
72+
4095 => dir = Direction::Downcounting,
73+
_ => (),
74+
};
75+
76+
match dir {
77+
Direction::Upcounting => val += 1,
78+
Direction::Downcounting => val -= 1,
79+
}
80+
}
81+
}

examples/dac.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//! ## Origin
2+
//!
3+
//! This code has been taken from the stm32g0xx-hal project and modified to support
4+
//! STM32G4xx MCUs.
5+
6+
// #![deny(warnings)]
7+
#![deny(unsafe_code)]
8+
#![no_main]
9+
#![no_std]
10+
11+
use embedded_hal::Direction;
12+
use hal::dac::{DacExt, DacOut, GeneratorConfig};
13+
use hal::delay::SYSTDelayExt;
14+
use hal::gpio::GpioExt;
15+
use hal::rcc::RccExt;
16+
use stm32g4xx_hal as hal;
17+
mod utils;
18+
extern crate cortex_m_rt as rt;
19+
20+
use hal::stm32;
21+
use rt::entry;
22+
23+
#[entry]
24+
fn main() -> ! {
25+
let dp = stm32::Peripherals::take().expect("cannot take peripherals");
26+
let cp = cortex_m::Peripherals::take().expect("cannot take core peripherals");
27+
28+
let mut rcc = dp.RCC.constrain();
29+
let mut delay = cp.SYST.delay(&rcc.clocks);
30+
31+
let gpioa = dp.GPIOA.split(&mut rcc);
32+
let (dac1ch1, dac1ch2) = dp.DAC1.constrain((gpioa.pa4, gpioa.pa5), &mut rcc);
33+
34+
// dac_manual will have its value set manually
35+
let mut dac_manual = dac1ch1.calibrate_buffer(&mut delay).enable();
36+
37+
// dac_generator will have its value set automatically from its internal noise generator
38+
let mut dac_generator = dac1ch2.enable_generator(GeneratorConfig::noise(11));
39+
40+
let mut dir = Direction::Upcounting;
41+
let mut val = 0;
42+
43+
loop {
44+
// This will pull out a new value from the noise generator and apply it to the DAC
45+
dac_generator.trigger();
46+
47+
// This will manually set the DAC's value
48+
dac_manual.set_value(val);
49+
match val {
50+
0 => dir = Direction::Upcounting,
51+
4095 => dir = Direction::Downcounting,
52+
_ => (),
53+
};
54+
55+
// Step manually set value as a triangle wave
56+
match dir {
57+
Direction::Upcounting => val += 1,
58+
Direction::Downcounting => val -= 1,
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)