Skip to content

Commit b224f83

Browse files
dac copied from stm32f0xx-hal
1 parent 76a26de commit b224f83

File tree

3 files changed

+100
-0
lines changed

3 files changed

+100
-0
lines changed

src/dac.rs

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//! # API for the Digital to Analog converter
2+
//!
3+
//! Currently only supports writing to the DR of the DAC,
4+
//! just a basic one-shot conversion.
5+
#![deny(unused_imports)]
6+
use core::mem;
7+
8+
use crate::gpio::gpioa::{PA4, PA5};
9+
use crate::gpio::Analog;
10+
use crate::pac::DAC;
11+
use crate::stm32::RCC;
12+
13+
pub struct C1;
14+
pub struct C2;
15+
16+
pub trait DacOut<V> {
17+
fn set_value(&mut self, val: V);
18+
fn get_value(&mut self) -> V;
19+
}
20+
21+
pub trait DacPin {
22+
fn enable(&mut self);
23+
}
24+
25+
pub trait Pins<DAC> {
26+
type Output;
27+
}
28+
29+
impl Pins<DAC> for PA4<Analog> {
30+
type Output = C1;
31+
}
32+
33+
impl Pins<DAC> for PA5<Analog> {
34+
type Output = C2;
35+
}
36+
37+
impl Pins<DAC> for (PA4<Analog>, PA5<Analog>) {
38+
type Output = (C1, C2);
39+
}
40+
41+
pub fn dac<PINS>(_dac: DAC, _pins: PINS) -> PINS::Output
42+
where
43+
PINS: Pins<DAC>,
44+
{
45+
// NOTE(unsafe) This executes only during initialisation
46+
let rcc = unsafe { &(*RCC::ptr()) };
47+
48+
// Enable DAC clocks
49+
rcc.apb1enr.modify(|_, w| w.dacen().set_bit());
50+
51+
// Reset DAC
52+
rcc.apb1rstr.modify(|_, w| w.dacrst().set_bit());
53+
rcc.apb1rstr.modify(|_, w| w.dacrst().clear_bit());
54+
55+
unsafe { mem::MaybeUninit::uninit().assume_init() }
56+
}
57+
58+
macro_rules! dac {
59+
($CX:ident, $en:ident, $cen:ident, $cal_flag:ident, $trim:ident, $mode:ident, $dhrx:ident, $dac_dor:ident, $daccxdhr:ident) => {
60+
impl DacPin for $CX {
61+
fn enable(&mut self) {
62+
let dac = unsafe { &(*DAC::ptr()) };
63+
dac.cr.modify(|_, w| w.$en().set_bit());
64+
}
65+
}
66+
67+
impl DacOut<u16> for $CX {
68+
fn set_value(&mut self, val: u16) {
69+
let dac = unsafe { &(*DAC::ptr()) };
70+
dac.$dhrx.write(|w| unsafe { w.bits(val as u32) });
71+
}
72+
73+
fn get_value(&mut self) -> u16 {
74+
let dac = unsafe { &(*DAC::ptr()) };
75+
dac.$dac_dor.read().bits() as u16
76+
}
77+
}
78+
};
79+
}
80+
81+
pub trait DacExt {
82+
fn constrain<PINS>(self, pins: PINS) -> PINS::Output
83+
where
84+
PINS: Pins<DAC>;
85+
}
86+
87+
impl DacExt for DAC {
88+
fn constrain<PINS>(self, pins: PINS) -> PINS::Output
89+
where
90+
PINS: Pins<DAC>,
91+
{
92+
dac(self, pins)
93+
}
94+
}
95+
96+
dac!(C1, en1, cen1, cal_flag1, otrim1, mode1, dhr12r1, dor1, dacc1dhr);
97+
dac!(C2, en2, cen2, cal_flag2, otrim2, mode2, dhr12r2, dor2, dacc2dhr);

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ pub mod adc;
8888
#[cfg(feature = "device-selected")]
8989
pub mod bb;
9090
#[cfg(feature = "device-selected")]
91+
pub mod dac;
92+
#[cfg(feature = "device-selected")]
9193
pub mod delay;
9294
#[cfg(feature = "device-selected")]
9395
pub mod gpio;

src/prelude.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ pub use crate::rcc::RccExt as _stm32f4xx_hal_rcc_RccExt;
1818
))]
1919
pub use crate::rng::RngExt as _stm32f4xx_hal_rng_RngExt;
2020
pub use crate::time::U32Ext as _stm32f4xx_hal_time_U32Ext;
21+
pub use crate::dac::DacExt as _stm32f4xx_hal_dac_DacExt;

0 commit comments

Comments
 (0)