Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Comparator and DAC #74

Merged
merged 17 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions examples/comp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//! ## Origin
//!
//! This code has been taken from the stm32g0xx-hal project and modified slightly to support
//! STM32G4xx MCUs.

//#![deny(warnings)]
#![deny(unsafe_code)]
#![no_main]
#![no_std]

mod utils;
extern crate cortex_m_rt as rt;

use rt::entry;

#[cfg(not(feature = "stm32g474"))]
#[entry]
fn main() -> ! {
loop {} // TODO: add support for more devices
}

#[cfg(feature = "stm32g474")]
#[entry]
fn main() -> ! {
use hal::comparator::{ComparatorExt, ComparatorSplit, Config, Hysteresis, RefintInput};
use hal::gpio::GpioExt;
use hal::prelude::OutputPin;
use hal::rcc::RccExt;
use hal::stm32;
use stm32g4xx_hal as hal;

let dp = stm32::Peripherals::take().expect("cannot take peripherals");
let mut rcc = dp.RCC.constrain();

let gpioa = dp.GPIOA.split(&mut rcc);

let (comp1, comp2, ..) = dp.COMP.split(&mut rcc);

let pa1 = gpioa.pa1.into_analog();
let pa0 = gpioa.pa0.into_analog();
let comp1 = comp1.comparator(&pa1, pa0, Config::default(), &rcc.clocks);
let comp1 = comp1.enable();

// led1 pa1 will be updated manually when to match comp1 value
let mut led1 = gpioa.pa5.into_push_pull_output();

let pa7 = gpioa.pa7.into_analog();
let comp2 = comp2.comparator(
&pa7,
RefintInput::VRefintM12,
Config::default()
.hysteresis(Hysteresis::None)
.output_inverted(),
&rcc.clocks,
);
let led2 = gpioa.pa12.into_push_pull_output();
// Configure PA12 to the comparator's alternate function so it gets
// changed directly by the comparator.
comp2.output_pin(led2);
let _comp2 = comp2.enable().lock();

loop {
// Read comp1 output and update led1 accordingly
match comp1.output() {
true => led1.set_high().unwrap(),
false => led1.set_low().unwrap(),
}
}
}
81 changes: 81 additions & 0 deletions examples/comp_w_dac.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// #![deny(warnings)]
#![deny(unsafe_code)]
#![no_main]
#![no_std]

mod utils;
extern crate cortex_m_rt as rt;

use rt::entry;

#[cfg(not(feature = "stm32g474"))]
#[entry]
fn main() -> ! {
loop {} // TODO: add support for more devices
}

#[cfg(feature = "stm32g474")]
#[entry]
fn main() -> ! {
use embedded_hal::Direction;
use hal::comparator::{self, ComparatorExt, ComparatorSplit};
use hal::dac::{Dac1IntSig1, DacExt, DacOut};
use hal::delay::SYSTDelayExt;
use hal::gpio::GpioExt;
use hal::rcc::RccExt;
use hal::stm32;
use stm32g4xx_hal as hal;

let dp = stm32::Peripherals::take().expect("cannot take peripherals");
let cp = cortex_m::Peripherals::take().expect("cannot take core peripherals");

let mut rcc = dp.RCC.constrain();
let mut delay = cp.SYST.delay(&rcc.clocks);

let gpioa = dp.GPIOA.split(&mut rcc);

// Set up DAC to output to pa4 and to internal signal Dac1IntSig1
// which just so happens is compatible with comp1
let dac1ch1 = dp.DAC1.constrain((gpioa.pa4, Dac1IntSig1), &mut rcc);
let mut dac = dac1ch1.calibrate_buffer(&mut delay).enable();

let (comp1, _comp2, ..) = dp.COMP.split(&mut rcc);
let pa1 = gpioa.pa1.into_analog();

// Set up comparator with pa1 as positive, and the DAC as negative input
let comp = comp1.comparator(
&pa1,
&dac,
comparator::Config::default().hysteresis(comparator::Hysteresis::None),
&rcc.clocks,
);

let led2 = gpioa.pa0.into_push_pull_output();
// Configure PA12 to the comparator's alternate function so it gets
// changed directly by the comparator.
comp.output_pin(led2);
let _comp1 = comp.enable().lock();

let mut dir = Direction::Upcounting;
let mut val = 0;

// Manually step the DAC's value to produce a triangle wave
//
// This will produce a pwm-like signal at pa0 with the duty controlled by pa1
// where
// * 0V at p1 => 0% duty
// * VDDA at p1 => 100% duty
loop {
dac.set_value(val);
match val {
0 => dir = Direction::Upcounting,
4095 => dir = Direction::Downcounting,
_ => (),
};

match dir {
Direction::Upcounting => val += 1,
Direction::Downcounting => val -= 1,
}
}
}
61 changes: 61 additions & 0 deletions examples/dac.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//! ## Origin
//!
//! This code has been taken from the stm32g0xx-hal project and modified to support
//! STM32G4xx MCUs.

// #![deny(warnings)]
#![deny(unsafe_code)]
#![no_main]
#![no_std]

use embedded_hal::Direction;
use hal::dac::{DacExt, DacOut, GeneratorConfig};
use hal::delay::SYSTDelayExt;
use hal::gpio::GpioExt;
use hal::rcc::RccExt;
use stm32g4xx_hal as hal;
mod utils;
extern crate cortex_m_rt as rt;

use hal::stm32;
use rt::entry;

#[entry]
fn main() -> ! {
let dp = stm32::Peripherals::take().expect("cannot take peripherals");
let cp = cortex_m::Peripherals::take().expect("cannot take core peripherals");

let mut rcc = dp.RCC.constrain();
let mut delay = cp.SYST.delay(&rcc.clocks);

let gpioa = dp.GPIOA.split(&mut rcc);
let (dac1ch1, dac1ch2) = dp.DAC1.constrain((gpioa.pa4, gpioa.pa5), &mut rcc);

// dac_manual will have its value set manually
let mut dac_manual = dac1ch1.calibrate_buffer(&mut delay).enable();

// dac_generator will have its value set automatically from its internal noise generator
let mut dac_generator = dac1ch2.enable_generator(GeneratorConfig::noise(11));

let mut dir = Direction::Upcounting;
let mut val = 0;

loop {
// This will pull out a new value from the noise generator and apply it to the DAC
dac_generator.trigger();

// This will manually set the DAC's value
dac_manual.set_value(val);
match val {
0 => dir = Direction::Upcounting,
4095 => dir = Direction::Downcounting,
_ => (),
};

// Step manually set value as a triangle wave
match dir {
Direction::Upcounting => val += 1,
Direction::Downcounting => val -= 1,
}
}
}
Loading