stm32f1xx_hal/
dac.rs

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
7use crate::{
8    gpio::{Analog, PA4, PA5},
9    pac::{DAC, RCC},
10    rcc::{Enable, Reset},
11};
12
13pub struct C1;
14pub struct C2;
15
16pub trait DacOut<V> {
17    fn set_value(&mut self, val: V);
18    fn get_value(&mut self) -> V;
19}
20
21pub trait DacPin {
22    fn enable(&mut self);
23}
24
25pub trait Pins<DAC> {
26    type Output;
27    #[doc(hidden)]
28    fn init() -> Self::Output;
29}
30
31impl Pins<DAC> for PA4<Analog> {
32    type Output = C1;
33    fn init() -> Self::Output {
34        C1
35    }
36}
37
38impl Pins<DAC> for PA5<Analog> {
39    type Output = C2;
40    fn init() -> Self::Output {
41        C2
42    }
43}
44
45impl Pins<DAC> for (PA4<Analog>, PA5<Analog>) {
46    type Output = (C1, C2);
47    fn init() -> Self::Output {
48        (C1, C2)
49    }
50}
51
52pub fn dac<PINS>(_dac: DAC, _pins: PINS, rcc: &mut RCC) -> PINS::Output
53where
54    PINS: Pins<DAC>,
55{
56    // Enable and reset clock.
57    DAC::enable(rcc);
58    DAC::reset(rcc);
59
60    PINS::init()
61}
62
63macro_rules! dac {
64    ($CX:ident, $en:ident, $cen:ident, $cal_flag:ident, $trim:ident, $mode:ident, $dhrx:ident, $dac_dor:ident, $daccxdhr:ident) => {
65        impl DacPin for $CX {
66            fn enable(&mut self) {
67                let dac = unsafe { &(*DAC::ptr()) };
68                dac.cr().modify(|_, w| w.$en().set_bit());
69            }
70        }
71
72        impl DacOut<u16> for $CX {
73            fn set_value(&mut self, val: u16) {
74                let dac = unsafe { &(*DAC::ptr()) };
75                dac.$dhrx().write(|w| unsafe { w.bits(val as u32) });
76            }
77
78            fn get_value(&mut self) -> u16 {
79                let dac = unsafe { &(*DAC::ptr()) };
80                dac.$dac_dor().read().bits() as u16
81            }
82        }
83    };
84}
85
86pub trait DacExt {
87    fn constrain<PINS>(self, pins: PINS, rcc: &mut RCC) -> PINS::Output
88    where
89        PINS: Pins<DAC>;
90}
91
92impl DacExt for DAC {
93    fn constrain<PINS>(self, pins: PINS, rcc: &mut RCC) -> PINS::Output
94    where
95        PINS: Pins<DAC>,
96    {
97        dac(self, pins, rcc)
98    }
99}
100
101dac!(C1, en1, cen1, cal_flag1, otrim1, mode1, dhr12r1, dor1, dacc1dhr);
102dac!(C2, en2, cen2, cal_flag2, otrim2, mode2, dhr12r2, dor2, dacc2dhr);