1use core::marker::PhantomData;
2
3use super::{AdcConfig, Attenuation};
4use crate::peripherals::{ADC1, ADC2, RTC_IO, SENS};
5
6pub(super) const NUM_ATTENS: usize = 10;
7
8#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
11#[allow(clippy::enum_variant_names, reason = "peripheral is unstable")]
12pub enum Resolution {
13 Resolution9Bit = 0b00,
15 Resolution10Bit = 0b01,
17 Resolution11Bit = 0b10,
19 #[default]
21 Resolution12Bit = 0b11,
22}
23
24#[doc(hidden)]
25pub trait RegisterAccess {
26 fn set_bit_width(resolution: u8);
27
28 fn set_sample_bit(resolution: u8);
29
30 fn set_attenuation(channel: usize, attenuation: u8);
31
32 fn clear_dig_force();
33
34 fn set_start_force();
35
36 fn set_en_pad_force();
37
38 fn set_en_pad(channel: u8);
39
40 fn clear_start_sar();
41
42 fn set_start_sar();
43
44 fn read_done_sar() -> bool;
45
46 fn read_data_sar() -> u16;
47}
48
49impl RegisterAccess for ADC1<'_> {
50 fn set_bit_width(resolution: u8) {
51 SENS::regs()
52 .sar_start_force()
53 .modify(|_, w| unsafe { w.sar1_bit_width().bits(resolution) });
54 }
55
56 fn set_sample_bit(resolution: u8) {
57 SENS::regs()
58 .sar_read_ctrl()
59 .modify(|_, w| unsafe { w.sar1_sample_bit().bits(resolution) });
60 }
61
62 fn set_attenuation(channel: usize, attenuation: u8) {
63 SENS::regs().sar_atten1().modify(|r, w| {
64 let new_value = (r.bits() & !(0b11 << (channel * 2)))
65 | (((attenuation & 0b11) as u32) << (channel * 2));
66
67 unsafe { w.sar1_atten().bits(new_value) }
68 });
69 }
70
71 fn clear_dig_force() {
72 SENS::regs()
73 .sar_read_ctrl()
74 .modify(|_, w| w.sar1_dig_force().clear_bit());
75 }
76
77 fn set_start_force() {
78 SENS::regs()
79 .sar_meas_start1()
80 .modify(|_, w| w.meas1_start_force().set_bit());
81 }
82
83 fn set_en_pad_force() {
84 SENS::regs()
85 .sar_meas_start1()
86 .modify(|_, w| w.sar1_en_pad_force().set_bit());
87 }
88
89 fn set_en_pad(channel: u8) {
90 SENS::regs()
91 .sar_meas_start1()
92 .modify(|_, w| unsafe { w.sar1_en_pad().bits(1 << channel) });
93 }
94
95 fn clear_start_sar() {
96 SENS::regs()
97 .sar_meas_start1()
98 .modify(|_, w| w.meas1_start_sar().clear_bit());
99 }
100
101 fn set_start_sar() {
102 SENS::regs()
103 .sar_meas_start1()
104 .modify(|_, w| w.meas1_start_sar().set_bit());
105 }
106
107 fn read_done_sar() -> bool {
108 SENS::regs()
109 .sar_meas_start1()
110 .read()
111 .meas1_done_sar()
112 .bit_is_set()
113 }
114
115 fn read_data_sar() -> u16 {
116 SENS::regs()
117 .sar_meas_start1()
118 .read()
119 .meas1_data_sar()
120 .bits()
121 }
122}
123
124impl RegisterAccess for ADC2<'_> {
125 fn set_bit_width(resolution: u8) {
126 SENS::regs()
127 .sar_start_force()
128 .modify(|_, w| unsafe { w.sar2_bit_width().bits(resolution) });
129 }
130
131 fn set_sample_bit(resolution: u8) {
132 SENS::regs()
133 .sar_read_ctrl2()
134 .modify(|_, w| unsafe { w.sar2_sample_bit().bits(resolution) });
135 }
136
137 fn set_attenuation(channel: usize, attenuation: u8) {
138 SENS::regs().sar_atten2().modify(|r, w| {
139 let new_value = (r.bits() & !(0b11 << (channel * 2)))
140 | (((attenuation & 0b11) as u32) << (channel * 2));
141
142 unsafe { w.sar2_atten().bits(new_value) }
143 });
144 }
145
146 fn clear_dig_force() {
147 SENS::regs()
148 .sar_read_ctrl2()
149 .modify(|_, w| w.sar2_dig_force().clear_bit());
150 }
151
152 fn set_start_force() {
153 SENS::regs()
154 .sar_meas_start2()
155 .modify(|_, w| w.meas2_start_force().set_bit());
156 }
157
158 fn set_en_pad_force() {
159 SENS::regs()
160 .sar_meas_start2()
161 .modify(|_, w| w.sar2_en_pad_force().set_bit());
162 }
163
164 fn set_en_pad(channel: u8) {
165 SENS::regs()
166 .sar_meas_start2()
167 .modify(|_, w| unsafe { w.sar2_en_pad().bits(1 << channel) });
168 }
169
170 fn clear_start_sar() {
171 SENS::regs()
172 .sar_meas_start2()
173 .modify(|_, w| w.meas2_start_sar().clear_bit());
174 }
175
176 fn set_start_sar() {
177 SENS::regs()
178 .sar_meas_start2()
179 .modify(|_, w| w.meas2_start_sar().set_bit());
180 }
181
182 fn read_done_sar() -> bool {
183 SENS::regs()
184 .sar_meas_start2()
185 .read()
186 .meas2_done_sar()
187 .bit_is_set()
188 }
189
190 fn read_data_sar() -> u16 {
191 SENS::regs()
192 .sar_meas_start2()
193 .read()
194 .meas2_data_sar()
195 .bits()
196 }
197}
198
199pub struct Adc<'d, ADC, Dm: crate::DriverMode> {
201 _adc: ADC,
202 attenuations: [Option<Attenuation>; NUM_ATTENS],
203 active_channel: Option<u8>,
204 _phantom: PhantomData<(Dm, &'d mut ())>,
205}
206
207impl<'d, ADCI> Adc<'d, ADCI, crate::Blocking>
208where
209 ADCI: RegisterAccess + 'd,
210{
211 pub fn new(adc_instance: ADCI, config: AdcConfig<ADCI>) -> Self {
214 let sensors = SENS::regs();
215
216 let resolution: u8 = config.resolution as u8;
218
219 ADCI::set_bit_width(resolution);
220 ADCI::set_sample_bit(resolution);
221
222 let attenuations = config.attenuations;
224
225 for (channel, attentuation) in attenuations.iter().enumerate() {
226 if let Some(attenuation) = attentuation {
227 ADC1::set_attenuation(channel, *attenuation as u8);
228 }
229 }
230
231 ADCI::clear_dig_force();
233 ADCI::set_start_force();
234 ADCI::set_en_pad_force();
235 sensors
236 .sar_touch_ctrl1()
237 .modify(|_, w| w.xpd_hall_force().set_bit());
238 sensors
239 .sar_touch_ctrl1()
240 .modify(|_, w| w.hall_phase_force().set_bit());
241
242 sensors
244 .sar_meas_wait2()
245 .modify(|_, w| unsafe { w.force_xpd_sar().bits(0b11) });
246
247 sensors
249 .sar_meas_wait2()
250 .modify(|_, w| unsafe { w.force_xpd_amp().bits(0b10) });
251 sensors
252 .sar_meas_ctrl()
253 .modify(|_, w| unsafe { w.amp_rst_fb_fsm().bits(0) });
254 sensors
255 .sar_meas_ctrl()
256 .modify(|_, w| unsafe { w.amp_short_ref_fsm().bits(0) });
257 sensors
258 .sar_meas_ctrl()
259 .modify(|_, w| unsafe { w.amp_short_ref_gnd_fsm().bits(0) });
260 sensors
261 .sar_meas_wait1()
262 .modify(|_, w| unsafe { w.sar_amp_wait1().bits(1) });
263 sensors
264 .sar_meas_wait1()
265 .modify(|_, w| unsafe { w.sar_amp_wait2().bits(1) });
266 sensors
267 .sar_meas_wait2()
268 .modify(|_, w| unsafe { w.sar_amp_wait3().bits(1) });
269
270 sensors
273 .sar_read_ctrl2()
274 .modify(|_, w| w.sar2_data_inv().set_bit());
275
276 Adc {
277 _adc: adc_instance,
278 attenuations: config.attenuations,
279 active_channel: None,
280 _phantom: PhantomData,
281 }
282 }
283
284 pub fn read_oneshot<PIN>(&mut self, _pin: &mut super::AdcPin<PIN, ADCI>) -> nb::Result<u16, ()>
290 where
291 PIN: super::AdcChannel,
292 {
293 if self.attenuations[PIN::CHANNEL as usize].is_none() {
294 panic!("Channel {} is not configured reading!", PIN::CHANNEL);
295 }
296
297 if let Some(active_channel) = self.active_channel {
298 if active_channel != PIN::CHANNEL {
302 return Err(nb::Error::WouldBlock);
303 }
304 } else {
305 self.active_channel = Some(PIN::CHANNEL);
307
308 ADCI::set_en_pad(PIN::CHANNEL);
309
310 ADCI::clear_start_sar();
311 ADCI::set_start_sar();
312 }
313
314 let conversion_finished = ADCI::read_done_sar();
316 if !conversion_finished {
317 return Err(nb::Error::WouldBlock);
318 }
319
320 let converted_value = ADCI::read_data_sar();
322
323 self.active_channel = None;
325
326 Ok(converted_value)
327 }
328}
329
330impl<ADC1> Adc<'_, ADC1, crate::Blocking> {
331 pub fn enable_hall_sensor() {
333 RTC_IO::regs()
334 .hall_sens()
335 .modify(|_, w| w.xpd_hall().set_bit());
336 }
337
338 pub fn disable_hall_sensor() {
340 RTC_IO::regs()
341 .hall_sens()
342 .modify(|_, w| w.xpd_hall().clear_bit());
343 }
344}
345
346mod adc_implementation {
347 crate::analog::adc::impl_adc_interface! {
348 ADC1 [
349 (GPIO36<'_>, 0), (GPIO37<'_>, 1), (GPIO38<'_>, 2), (GPIO39<'_>, 3), (GPIO33<'_>, 4), (GPIO32<'_>, 5), (GPIO34<'_>, 6), (GPIO35<'_>, 7), ]
358 }
359
360 crate::analog::adc::impl_adc_interface! {
361 ADC2 [
362 (GPIO4<'_>, 0),
363 (GPIO0<'_>, 1),
364 (GPIO2<'_>, 2),
365 (GPIO15<'_>, 3), (GPIO13<'_>, 4), (GPIO12<'_>, 5), (GPIO14<'_>, 6), (GPIO27<'_>, 7),
370 (GPIO25<'_>, 8),
371 (GPIO26<'_>, 9),
372 ]
373 }
374}