1use crate::clocks::{phclk, Stm32f4Clocks};
6use core::cell::Cell;
7use kernel::hil;
8use kernel::platform::chip::ClockInterface;
9use kernel::utilities::registers::interfaces::{ReadWriteable, Writeable};
10use kernel::utilities::registers::{register_bitfields, ReadWrite, WriteOnly};
11use kernel::utilities::StaticRef;
12use kernel::ErrorCode;
13
14#[repr(C)]
16pub struct DacRegisters {
17 cr: ReadWrite<u32, CR::Register>,
18 swtrigr: WriteOnly<u32, SWTRIGR::Register>,
19 dhr12r1: ReadWrite<u32, DHR12R1::Register>,
20 dhr8r1: ReadWrite<u32, DHR8R1::Register>,
21 dhr12r2: ReadWrite<u32, DHR12R2::Register>,
22 dhr12l2: ReadWrite<u32, DHR12L2::Register>,
23 dhr8r2: ReadWrite<u32, DHR8R2::Register>,
24 dhr12rd: ReadWrite<u32, DHR12RD::Register>,
25 dhr12ld: ReadWrite<u32, DHR12LD::Register>,
26 dhr8rd: ReadWrite<u32, DHR8RD::Register>,
27 dor1: ReadWrite<u32, DOR1::Register>,
28 dor2: ReadWrite<u32, DOR2::Register>,
29}
30
31register_bitfields![u32,
32 CR [
34 DMAUDRIE2 OFFSET(29) NUMBITS(1) [],
36 DMAEN2 OFFSET(28) NUMBITS(1) [],
38 MAMP2 OFFSET(24) NUMBITS(4) [],
40 WAVE2 OFFSET(22) NUMBITS(2) [],
42 TSEL2 OFFSET(19) NUMBITS(3) [],
44 TEN2 OFFSET(18) NUMBITS(1) [],
46 BOFF2 OFFSET(17) NUMBITS(1) [],
48 EN2 OFFSET(16) NUMBITS(1) [],
50 DMAUDRIE1 OFFSET(13) NUMBITS(1) [],
52 DMAEN1 OFFSET(12) NUMBITS(1) [],
54 MAMP1 OFFSET(8) NUMBITS(4) [],
56 WAVE1 OFFSET(6) NUMBITS(2) [],
58 TSEL1 OFFSET(3) NUMBITS(3) [],
60 TEN1 OFFSET(2) NUMBITS(1) [],
62 BOFF1 OFFSET(1) NUMBITS(1) [],
64 EN1 OFFSET(0) NUMBITS(1) [],
66 ],
67 SWTRIGR [
69 SWTRIG2 OFFSET(1) NUMBITS(1) [],
71 SWTRIG1 OFFSET(0) NUMBITS(1) []
73 ],
74 DHR12R1 [
76 DACC1DHR OFFSET(0) NUMBITS(12) []
78 ],
79 DHR8R1 [
81 DACC1DHR OFFSET(0) NUMBITS(8) []
83 ],
84 DHR12R2 [
86 DACC2DHR OFFSET(0) NUMBITS(12) []
88 ],
89 DHR12L2 [
91 DACC2DHR OFFSET(0) NUMBITS(12) []
93 ],
94 DHR8R2 [
96 DACC2DHR OFFSET(0) NUMBITS(8) []
98 ],
99 DHR12RD [
101 DACC2DHR OFFSET(16) NUMBITS(12) [],
103 DACC1DHR OFFSET(0) NUMBITS(12) []
105 ],
106 DHR12LD [
108 DACC2DHR OFFSET(16) NUMBITS(12) [],
110 DACC1DHR OFFSET(0) NUMBITS(12) []
112 ],
113 DHR8RD [
115 DACC2DHR OFFSET(8) NUMBITS(8) [],
117 DACC1DHR OFFSET(0) NUMBITS(8) []
119 ],
120 DOR1 [
122 DACC1DOR OFFSET(0) NUMBITS(12) []
124 ],
125 DOR2 [
127 DACC2DOR OFFSET(0) NUMBITS(12) []
129 ],
130 SR [
132 DMAUDR2 OFFSET(29) NUMBITS(1) [],
134 DMAUDR1 OFFSET(13) NUMBITS(1) []
136 ]
137];
138
139const DAC_BASE: StaticRef<DacRegisters> =
140 unsafe { StaticRef::new(0x40007400 as *const DacRegisters) };
141
142pub struct Dac<'a> {
143 registers: StaticRef<DacRegisters>,
144 clock: DacClock<'a>,
145 initialized: Cell<bool>,
146 enabled: Cell<bool>,
147}
148
149impl<'a> Dac<'a> {
150 pub const fn new(clocks: &'a dyn Stm32f4Clocks) -> Self {
151 Self {
152 registers: DAC_BASE,
153 clock: DacClock(phclk::PeripheralClock::new(
154 phclk::PeripheralClockType::APB1(phclk::PCLK1::DAC),
155 clocks,
156 )),
157 initialized: Cell::new(false),
158 enabled: Cell::new(false),
159 }
160 }
161
162 fn initialize(&self) -> Result<(), ErrorCode> {
163 if !self.is_enabled_clock() {
164 self.enable_clock();
165 }
166
167 self.registers.cr.modify(CR::BOFF1::CLEAR);
169 self.registers.cr.modify(CR::TEN1::CLEAR);
170 self.registers.cr.modify(CR::TSEL1::CLEAR);
171 self.registers.cr.modify(CR::WAVE1::CLEAR);
172 self.registers.cr.modify(CR::MAMP1::CLEAR);
173
174 self.enable();
175
176 Ok(())
177 }
178
179 fn enable(&self) {
180 self.registers.cr.modify(CR::EN1::SET);
181 }
182
183 pub fn handle_interrupt(&self) {}
185
186 fn is_enabled_clock(&self) -> bool {
187 self.clock.is_enabled()
188 }
189
190 fn enable_clock(&self) {
191 self.clock.enable();
192 }
193}
194
195struct DacClock<'a>(phclk::PeripheralClock<'a>);
196
197impl ClockInterface for DacClock<'_> {
198 fn is_enabled(&self) -> bool {
199 self.0.is_enabled()
200 }
201
202 fn enable(&self) {
203 self.0.enable();
204 }
205
206 fn disable(&self) {
207 self.0.disable();
208 }
209}
210
211impl hil::dac::DacChannel for Dac<'_> {
212 fn set_value(&self, value: usize) -> Result<(), ErrorCode> {
213 if !self.initialized.get() {
214 self.initialize()?;
215 }
216
217 if !self.enabled.get() {
218 self.enable();
219 }
220
221 self.registers
222 .dhr12r1
223 .write(DHR12R1::DACC1DHR.val(value as u32));
224 Ok(())
225 }
226}