Browse Source

Add dac (#70)

* Added dac.rs from stm32g4xx-hal crate and modified it a bit.

* Removed IDE files.

* Fix feature gating for DAC module.

* Remove unused calibrate function from DacPin trait.

* Add feature gates for all devices that support DAC.

* Added docs and example.

* Some cleanup, fixed feature gate.
trying.tmp
Mike Panetta 3 years ago committed by Daniel Egger
parent
commit
4c3504c8e1
  1. 1
      CHANGELOG.md
  2. 4
      Cargo.toml
  3. 62
      examples/dac.rs
  4. 195
      src/dac.rs
  5. 9
      src/lib.rs

1
CHANGELOG.md

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Fixed a few deprecation warning and lints
- Enabled commented out and now available GPIOE support for 07x and 09x families
- Extract register block address only once
- Add DAC driver
## [v0.15.1] - 2019-08-11

4
Cargo.toml

@ -74,3 +74,7 @@ opt-level = "s"
[[example]]
name = "led_hal_button_irq"
required-features = ["stm32f042", "rt"]
[[example]]
name = "dac"
required-features = ["stm32f072"]

62
examples/dac.rs

@ -0,0 +1,62 @@
#![deny(unused_imports)]
#![no_main]
#![no_std]
use cortex_m;
use cortex_m_rt as rt;
#[allow(unused_imports)]
use panic_halt;
use stm32f0xx_hal as hal;
use crate::hal::stm32;
use crate::hal::prelude::*;
use crate::hal::dac::*;
use rt::entry;
enum Direction {
Upcounting,
Downcounting,
}
#[entry]
fn main() -> ! {
if let (Some(mut dp), Some(_cp)) = (stm32::Peripherals::take(), cortex_m::Peripherals::take()) {
cortex_m::interrupt::free(move |cs| {
let mut rcc = dp.RCC.configure().sysclk(8.mhz()).freeze(&mut dp.FLASH);
let gpioa = dp.GPIOA.split(&mut rcc);
let mut dac = dac(dp.DAC, gpioa.pa4.into_analog(cs), &mut rcc);
dac.enable();
let mut dir = Direction::Upcounting;
let mut val = 0;
dac.set_value(2058);
cortex_m::asm::bkpt();
dac.set_value(4095);
cortex_m::asm::bkpt();
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,
}
}
});
}
loop {
continue;
}
}

195
src/dac.rs

@ -0,0 +1,195 @@
//! # API for the Digital to Analog converter
//!
//! Currently only supports writing to the DR of the DAC,
//! just a basic one-shot conversion.
//!
//! ## Example
//! ``` no_run
//!#![deny(unused_imports)]
//!#![no_main]
//!#![no_std]
//!
//!use cortex_m;
//!use cortex_m_rt as rt;
//!use panic_halt;
//!
//!use stm32f0xx_hal as hal;
//!
//!use crate::hal::stm32;
//!use crate::hal::prelude::*;
//!use crate::hal::dac::*;
//!
//!use rt::entry;
//!
//!enum Direction {
//! Upcounting,
//! Downcounting,
//!}
//!
//!#[entry]
//!fn main() -> ! {
//! if let (Some(mut dp), Some(_cp)) = (stm32::Peripherals::take(), cortex_m::Peripherals::take()) {
//! cortex_m::interrupt::free(move |cs| {
//! let mut rcc = dp.RCC.configure().sysclk(8.mhz()).freeze(&mut dp.FLASH);
//!
//! let gpioa = dp.GPIOA.split(&mut rcc);
//! let mut dac = dac(dp.DAC, gpioa.pa4.into_analog(cs), &mut rcc);
//!
//! dac.enable();
//!
//! let mut dir = Direction::Upcounting;
//! let mut val = 0;
//!
//! dac.set_value(2058);
//! cortex_m::asm::bkpt();
//!
//! dac.set_value(4095);
//! cortex_m::asm::bkpt();
//!
//! 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,
//! }
//! }
//! });
//! }
//!
//! loop {
//! continue;
//! }
//!}
//! ```
#![deny(unused_imports)]
use core::mem;
use crate::gpio::gpioa::{PA4, PA5};
use crate::rcc::Rcc;
use crate::stm32::DAC;
use crate::gpio::Analog;
pub struct C1;
pub struct C2;
pub trait DacOut<V> {
fn set_value(&mut self, val: V);
fn get_value(&mut self) -> V;
}
pub trait DacPin {
fn enable(&mut self);
}
pub trait Pins<DAC> {
type Output;
}
impl Pins<DAC> for PA4<Analog> {
type Output = C1;
}
impl Pins<DAC> for PA5<Analog> {
type Output = C2;
}
impl Pins<DAC> for (PA4<Analog>, PA5<Analog>) {
type Output = (C1, C2);
}
pub fn dac<PINS>(_dac: DAC, _pins: PINS, rcc: &mut Rcc) -> PINS::Output
where
PINS: Pins<DAC>,
{
// Enable DAC clocks
rcc.regs.apb1enr.modify(|_, w| w.dacen().set_bit());
// Reset DAC
rcc.regs.apb1rstr.modify(|_, w| w.dacrst().set_bit());
rcc.regs.apb1rstr.modify(|_, w| w.dacrst().clear_bit());
unsafe { mem::uninitialized() }
}
macro_rules! dac {
($CX:ident, $en:ident, $cen:ident, $cal_flag:ident, $trim:ident, $mode:ident, $dhrx:ident, $dac_dor:ident, $daccxdhr:ident) => {
impl DacPin for $CX {
fn enable(&mut self) {
let dac = unsafe { &(*DAC::ptr()) };
dac.cr.modify(|_, w| w.$en().set_bit());
}
}
impl DacOut<u16> for $CX {
fn set_value(&mut self, val: u16) {
let dac = unsafe { &(*DAC::ptr()) };
dac.$dhrx.write(|w| unsafe { w.bits(val as u32) });
}
fn get_value(&mut self) -> u16 {
let dac = unsafe { &(*DAC::ptr()) };
dac.$dac_dor.read().bits() as u16
}
}
};
}
pub trait DacExt {
fn constrain<PINS>(self, pins: PINS, rcc: &mut Rcc) -> PINS::Output
where
PINS: Pins<DAC>;
}
impl DacExt for DAC {
fn constrain<PINS>(self, pins: PINS, rcc: &mut Rcc) -> PINS::Output
where
PINS: Pins<DAC>,
{
dac(self, pins, rcc)
}
}
#[cfg(any(
feature = "stm32f051",
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f091",
feature = "stm32f098",
))]
dac!(
C1,
en1,
cen1,
cal_flag1,
otrim1,
mode1,
dhr12r1,
dor1,
dacc1dhr
);
#[cfg(any(
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f091",
feature = "stm32f098",
))]
dac!(
C2,
en2,
cen2,
cal_flag2,
otrim2,
mode2,
dhr12r2,
dor2,
dacc2dhr
);

9
src/lib.rs

@ -28,6 +28,15 @@ pub use stm32f0::stm32f0x8 as stm32;
#[cfg(feature = "device-selected")]
pub mod adc;
#[cfg(any(
feature = "stm32f051",
feature = "stm32f071",
feature = "stm32f072",
feature = "stm32f078",
feature = "stm32f091",
feature = "stm32f098",
))]
pub mod dac;
#[cfg(feature = "device-selected")]
pub mod delay;
#[cfg(feature = "device-selected")]

Loading…
Cancel
Save