1use core::{
2 marker::PhantomData,
3 sync::atomic::{AtomicBool, Ordering},
4};
5
6use super::{AdcCalScheme, AdcConfig, Attenuation, Error};
7use crate::{
8 peripherals::{ADC1, ADC2, SENS},
9 private,
10};
11
12pub(super) const NUM_ATTENS: usize = 10;
13
14mod calibration;
15pub use self::calibration::*;
16
17static ADC2_IN_USE: AtomicBool = AtomicBool::new(false);
20
21#[doc(hidden)]
22pub fn try_claim_adc2(_: private::Internal) -> Result<(), Error> {
24 if ADC2_IN_USE.fetch_or(true, Ordering::Relaxed) {
25 Err(Error::Adc2InUse)
26 } else {
27 Ok(())
28 }
29}
30
31#[doc(hidden)]
32pub fn release_adc2(_: private::Internal) {
34 ADC2_IN_USE.store(false, Ordering::Relaxed);
35}
36
37#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
39#[cfg_attr(feature = "defmt", derive(defmt::Format))]
40#[allow(clippy::enum_variant_names, reason = "unit of measurement")]
41pub enum Resolution {
42 _9Bit,
44 _10Bit,
46 _11Bit,
48 #[default]
50 _12Bit,
51}
52
53#[doc(hidden)]
54pub trait RegisterAccess {
55 fn set_resolution(resolution: u8);
56
57 fn set_attenuation(channel: usize, attenuation: u8);
58
59 fn clear_dig_force();
60
61 fn set_start_force();
62
63 fn set_en_pad_force();
64
65 fn set_en_pad(channel: u8);
66
67 fn clear_start_sar();
68
69 fn set_start_sar();
70
71 fn read_done_sar() -> bool;
72
73 fn read_data_sar() -> u16;
74
75 fn instance_number() -> u8;
76}
77
78impl RegisterAccess for ADC1<'_> {
79 fn set_resolution(resolution: u8) {
80 SENS::regs()
81 .sar_start_force()
82 .modify(|_, w| unsafe { w.sar1_bit_width().bits(resolution) });
83 SENS::regs()
84 .sar_read_ctrl()
85 .modify(|_, w| unsafe { w.sar1_sample_bit().bits(resolution) });
86 }
87
88 fn set_attenuation(channel: usize, attenuation: u8) {
89 SENS::regs().sar_atten1().modify(|r, w| {
90 let new_value = (r.bits() & !(0b11 << (channel * 2)))
91 | (((attenuation & 0b11) as u32) << (channel * 2));
92
93 unsafe { w.sar1_atten().bits(new_value) }
94 });
95 }
96
97 fn clear_dig_force() {
98 SENS::regs()
99 .sar_read_ctrl()
100 .modify(|_, w| w.sar1_dig_force().clear_bit());
101 }
102
103 fn set_start_force() {
104 SENS::regs()
105 .sar_meas_start1()
106 .modify(|_, w| w.meas1_start_force().set_bit());
107 }
108
109 fn set_en_pad_force() {
110 SENS::regs()
111 .sar_meas_start1()
112 .modify(|_, w| w.sar1_en_pad_force().set_bit());
113 }
114
115 fn set_en_pad(channel: u8) {
116 SENS::regs()
117 .sar_meas_start1()
118 .modify(|_, w| unsafe { w.sar1_en_pad().bits(1 << channel) });
119 }
120
121 fn clear_start_sar() {
122 SENS::regs()
123 .sar_meas_start1()
124 .modify(|_, w| w.meas1_start_sar().clear_bit());
125 }
126
127 fn set_start_sar() {
128 SENS::regs()
129 .sar_meas_start1()
130 .modify(|_, w| w.meas1_start_sar().set_bit());
131 }
132
133 fn read_done_sar() -> bool {
134 SENS::regs()
135 .sar_meas_start1()
136 .read()
137 .meas1_done_sar()
138 .bit_is_set()
139 }
140
141 fn read_data_sar() -> u16 {
142 SENS::regs()
143 .sar_meas_start1()
144 .read()
145 .meas1_data_sar()
146 .bits()
147 }
148
149 fn instance_number() -> u8 {
150 1
151 }
152}
153
154impl RegisterAccess for ADC2<'_> {
155 fn set_resolution(resolution: u8) {
156 SENS::regs()
157 .sar_start_force()
158 .modify(|_, w| unsafe { w.sar2_bit_width().bits(resolution) });
159 SENS::regs()
160 .sar_read_ctrl2()
161 .modify(|_, w| unsafe { w.sar2_sample_bit().bits(resolution) });
162 }
163
164 fn set_attenuation(channel: usize, attenuation: u8) {
165 SENS::regs().sar_atten2().modify(|r, w| {
166 let new_value = (r.bits() & !(0b11 << (channel * 2)))
167 | (((attenuation & 0b11) as u32) << (channel * 2));
168
169 unsafe { w.sar2_atten().bits(new_value) }
170 });
171 }
172
173 fn clear_dig_force() {
174 SENS::regs()
175 .sar_read_ctrl2()
176 .modify(|_, w| w.sar2_dig_force().clear_bit());
177 }
178
179 fn set_start_force() {
180 SENS::regs()
181 .sar_meas_start2()
182 .modify(|_, w| w.meas2_start_force().set_bit());
183 }
184
185 fn set_en_pad_force() {
186 SENS::regs()
187 .sar_meas_start2()
188 .modify(|_, w| w.sar2_en_pad_force().set_bit());
189 }
190
191 fn set_en_pad(channel: u8) {
192 SENS::regs()
193 .sar_meas_start2()
194 .modify(|_, w| unsafe { w.sar2_en_pad().bits(1 << channel) });
195 }
196
197 fn clear_start_sar() {
198 SENS::regs()
199 .sar_meas_start2()
200 .modify(|_, w| w.meas2_start_sar().clear_bit());
201 }
202
203 fn set_start_sar() {
204 SENS::regs()
205 .sar_meas_start2()
206 .modify(|_, w| w.meas2_start_sar().set_bit());
207 }
208
209 fn read_done_sar() -> bool {
210 SENS::regs()
211 .sar_meas_start2()
212 .read()
213 .meas2_done_sar()
214 .bit_is_set()
215 }
216
217 fn read_data_sar() -> u16 {
218 SENS::regs()
219 .sar_meas_start2()
220 .read()
221 .meas2_data_sar()
222 .bits()
223 }
224
225 fn instance_number() -> u8 {
226 2
227 }
228}
229
230pub struct Adc<'d, ADC, Dm: crate::DriverMode> {
232 _adc: ADC,
233 attenuations: [Option<Attenuation>; NUM_ATTENS],
234 active_channel: Option<u8>,
235 resolution_bits: u8,
236 adc2_claimed: bool,
238 _phantom: PhantomData<(Dm, &'d mut ())>,
239}
240
241impl<'d, ADCX> Adc<'d, ADCX, crate::Blocking>
242where
243 ADCX: RegisterAccess + 'd,
244{
245 pub fn new(adc_instance: ADCX, config: AdcConfig<ADCX>) -> Result<Self, Error> {
254 let adc2_claimed = if ADCX::instance_number() == 2 {
256 if try_claim_adc2(private::Internal).is_err() {
257 return Err(Error::Adc2InUse);
258 }
259 true
260 } else {
261 false
262 };
263
264 let sensors = SENS::regs();
265
266 ADCX::set_resolution(config.resolution as u8);
268
269 let attenuations = config.attenuations;
271
272 for (channel, attenuation) in attenuations.iter().enumerate() {
273 if let Some(attenuation) = attenuation {
274 ADCX::set_attenuation(channel, *attenuation as u8);
275 }
276 }
277
278 ADCX::clear_dig_force();
280 ADCX::set_start_force();
281 ADCX::set_en_pad_force();
282 sensors.sar_touch_ctrl1().modify(|_, w| {
283 w.xpd_hall_force().set_bit();
284 w.hall_phase_force().set_bit()
285 });
286
287 sensors.sar_meas_wait2().modify(|_, w| unsafe {
288 w.force_xpd_sar().bits(0b11);
290 w.force_xpd_amp().bits(0b10)
292 });
293 sensors.sar_meas_ctrl().modify(|_, w| unsafe {
294 w.amp_rst_fb_fsm().bits(0);
295 w.amp_short_ref_fsm().bits(0);
296 w.amp_short_ref_gnd_fsm().bits(0)
297 });
298 sensors.sar_meas_wait1().modify(|_, w| unsafe {
299 w.sar_amp_wait1().bits(1);
300 w.sar_amp_wait2().bits(1)
301 });
302 sensors
303 .sar_meas_wait2()
304 .modify(|_, w| unsafe { w.sar_amp_wait3().bits(1) });
305
306 sensors
309 .sar_read_ctrl()
310 .modify(|_, w| w.sar1_data_inv().set_bit());
311 sensors
312 .sar_read_ctrl2()
313 .modify(|_, w| w.sar2_data_inv().set_bit());
314
315 Ok(Adc {
316 _adc: adc_instance,
317 attenuations: config.attenuations,
318 active_channel: None,
319 resolution_bits: match config.resolution {
320 Resolution::_9Bit => 9,
321 Resolution::_10Bit => 10,
322 Resolution::_11Bit => 11,
323 Resolution::_12Bit => 12,
324 },
325 adc2_claimed,
326 _phantom: PhantomData,
327 })
328 }
329
330 pub fn read_oneshot<PIN, CS>(
341 &mut self,
342 pin: &mut super::AdcPin<PIN, ADCX, CS>,
343 ) -> nb::Result<u16, Error>
344 where
345 PIN: super::AdcChannel,
346 CS: AdcCalScheme<ADCX>,
347 {
348 let channel = pin.pin.adc_channel();
349 if self.attenuations[channel as usize].is_none() {
350 return Err(nb::Error::Other(Error::ChannelNotConfigured(channel)));
351 }
352
353 if let Some(active_channel) = self.active_channel {
354 if active_channel != pin.pin.adc_channel() {
358 return Err(nb::Error::WouldBlock);
359 }
360 } else {
361 self.active_channel = Some(pin.pin.adc_channel());
363
364 ADCX::set_en_pad(pin.pin.adc_channel());
365
366 ADCX::clear_start_sar();
367 ADCX::set_start_sar();
368 }
369
370 let conversion_finished = ADCX::read_done_sar();
372 if !conversion_finished {
373 return Err(nb::Error::WouldBlock);
374 }
375
376 let mut converted_value = ADCX::read_data_sar() as u32;
378 converted_value <<= 12 - self.resolution_bits;
379 if converted_value > 4095 {
380 converted_value = 4095;
381 }
382
383 self.active_channel = None;
385
386 Ok(pin.cal_scheme.adc_val(converted_value as u16))
387 }
388}
389
390impl<ADC, Dm: crate::DriverMode> Drop for Adc<'_, ADC, Dm> {
391 fn drop(&mut self) {
392 if self.adc2_claimed {
393 release_adc2(private::Internal);
394 }
395 }
396}