atsamd_hal/peripherals/adc/
d11.rs
1use atsamd_hal_macros::hal_cfg;
3
4use crate::clock::GenericClockController;
5use crate::ehal_02::adc::{Channel, OneShot};
6use crate::gpio::*;
7use crate::pac::{self, adc, Pm};
8
9pub use adc::avgctrl::Samplenumselect as SampleRate;
11pub use adc::ctrlb::Prescalerselect as Prescaler;
13pub use adc::ctrlb::Resselselect as Resolution;
18pub use adc::inputctrl::Gainselect as Gain;
20pub use adc::refctrl::Refselselect as Reference;
22
23pub struct Adc<ADC> {
25 adc: ADC,
26}
27
28impl Adc<pac::Adc> {
29 #[allow(clippy::self_named_constructors)]
36 pub fn adc(adc: pac::Adc, pm: &mut Pm, clocks: &mut GenericClockController) -> Self {
37 pm.apbcmask().modify(|_, w| w.adc_().set_bit());
38
39 let gclk0 = clocks.gclk0();
41 clocks.adc(&gclk0).expect("adc clock setup failed");
42 while adc.status().read().syncbusy().bit_is_set() {}
43
44 adc.ctrla().modify(|_, w| w.swrst().set_bit());
45 while adc.status().read().syncbusy().bit_is_set() {}
46
47 adc.ctrlb().modify(|_, w| {
48 w.prescaler().div32();
49 w.ressel()._12bit()
50 });
51 while adc.status().read().syncbusy().bit_is_set() {}
52
53 adc.sampctrl().modify(|_, w| unsafe { w.samplen().bits(5) }); while adc.status().read().syncbusy().bit_is_set() {}
55
56 adc.inputctrl().modify(|_, w| w.muxneg().gnd()); while adc.status().read().syncbusy().bit_is_set() {}
58
59 let mut newadc = Self { adc };
60 newadc.samples(adc::avgctrl::Samplenumselect::_1);
61 newadc.gain(adc::inputctrl::Gainselect::Div2);
62 newadc.reference(adc::refctrl::Refselselect::Intvcc1);
63
64 newadc
65 }
66
67 pub fn samples(&mut self, samples: SampleRate) {
69 use adc::avgctrl::Samplenumselect;
70 self.adc.avgctrl().modify(|_, w| {
71 w.samplenum().variant(samples);
72 unsafe {
73 w.adjres().bits(match samples {
76 Samplenumselect::_1 => 0,
77 Samplenumselect::_2 => 1,
78 Samplenumselect::_4 => 2,
79 Samplenumselect::_8 => 3,
80 _ => 4,
81 })
82 }
83 });
84 while self.adc.status().read().syncbusy().bit_is_set() {}
85 }
86
87 pub fn gain(&mut self, gain: Gain) {
89 self.adc.inputctrl().modify(|_, w| w.gain().variant(gain));
90 while self.adc.status().read().syncbusy().bit_is_set() {}
91 }
92
93 pub fn reference(&mut self, reference: Reference) {
95 self.adc
96 .refctrl()
97 .modify(|_, w| w.refsel().variant(reference));
98 while self.adc.status().read().syncbusy().bit_is_set() {}
99 }
100
101 pub fn prescaler(&mut self, prescaler: Prescaler) {
103 self.adc
104 .ctrlb()
105 .modify(|_, w| w.prescaler().variant(prescaler));
106 while self.adc.status().read().syncbusy().bit_is_set() {}
107 }
108
109 pub fn resolution(&mut self, resolution: Resolution) {
111 self.adc
112 .ctrlb()
113 .modify(|_, w| w.ressel().variant(resolution));
114 while self.adc.status().read().syncbusy().bit_is_set() {}
115 }
116
117 fn power_up(&mut self) {
118 while self.adc.status().read().syncbusy().bit_is_set() {}
119 self.adc.ctrla().modify(|_, w| w.enable().set_bit());
120 while self.adc.status().read().syncbusy().bit_is_set() {}
121 }
122
123 fn power_down(&mut self) {
124 while self.adc.status().read().syncbusy().bit_is_set() {}
125 self.adc.ctrla().modify(|_, w| w.enable().clear_bit());
126 while self.adc.status().read().syncbusy().bit_is_set() {}
127 }
128
129 fn convert(&mut self) -> u16 {
130 self.adc.swtrig().modify(|_, w| w.start().set_bit());
131 while self.adc.intflag().read().resrdy().bit_is_clear() {}
132 while self.adc.status().read().syncbusy().bit_is_set() {}
133
134 self.adc.intflag().modify(|_, w| w.resrdy().set_bit());
136
137 self.adc.swtrig().modify(|_, w| w.start().set_bit());
140 while self.adc.intflag().read().resrdy().bit_is_clear() {}
141 while self.adc.status().read().syncbusy().bit_is_set() {}
142
143 self.adc.result().read().result().bits()
144 }
145}
146
147impl<WORD, PIN> OneShot<pac::Adc, WORD, PIN> for Adc<pac::Adc>
148where
149 WORD: From<u16>,
150 PIN: Channel<pac::Adc, ID = u8>,
151{
152 type Error = ();
153
154 fn read(&mut self, _pin: &mut PIN) -> nb::Result<WORD, Self::Error> {
155 let chan = PIN::channel();
156 while self.adc.status().read().syncbusy().bit_is_set() {}
157
158 self.adc
159 .inputctrl()
160 .modify(|_, w| unsafe { w.muxpos().bits(chan) });
161 self.power_up();
162 let result = self.convert();
163 self.power_down();
164
165 Ok(result.into())
166 }
167}
168
169macro_rules! adc_pins {
170 (
171 $(
172 $( #[$cfg:meta] )?
173 $PinId:ident: $CHAN:literal
174 ),+
175 $(,)?
176 ) => {
177 $(
178 $( #[$cfg] )?
179 impl Channel<$crate::pac::Adc> for Pin<$PinId, AlternateB> {
180 type ID = u8;
181 fn channel() -> u8 { $CHAN }
182 }
183 )+
184 }
185}
186
187#[hal_cfg("adc-d11")]
188adc_pins! {
189 #[hal_cfg("pa02")]
190 PA02: 0,
191 #[hal_cfg("pa03")]
192 PA03: 1,
193 #[hal_cfg("pa04")]
194 PA04: 2,
195 #[hal_cfg("pa05")]
196 PA05: 3,
197 #[hal_cfg("pa06")]
198 PA06: 4,
199 #[hal_cfg("pa07")]
200 PA07: 5,
201 #[hal_cfg("pa14")]
202 PA14: 6,
203 #[hal_cfg("pa15")]
204 PA15: 7,
205 #[hal_cfg("pa10")]
206 PA10: 8,
207 #[hal_cfg("pa11")]
208 PA11: 9,
209}
210
211#[hal_cfg("adc-d21")]
212adc_pins! {
213 #[hal_cfg("pa02")]
214 PA02: 0,
215 #[hal_cfg("pa03")]
216 PA03: 1,
217 #[hal_cfg("pb08")]
218 PB08: 2,
219 #[hal_cfg("pb09")]
220 PB09: 3,
221 #[hal_cfg("pa04")]
222 PA04: 4,
223 #[hal_cfg("pa05")]
224 PA05: 5,
225 #[hal_cfg("pa06")]
226 PA06: 6,
227 #[hal_cfg("pa07")]
228 PA07: 7,
229 #[hal_cfg("pb00")]
230 PB00: 8,
231 #[hal_cfg("pb01")]
232 PB01: 9,
233 #[hal_cfg("pb02")]
234 PB02: 10,
235 #[hal_cfg("pb03")]
236 PB03: 11,
237 #[hal_cfg("pb04")]
238 PB04: 12,
239 #[hal_cfg("pb05")]
240 PB05: 13,
241 #[hal_cfg("pb06")]
242 PB06: 14,
243 #[hal_cfg("pb07")]
244 PB07: 15,
245 #[hal_cfg("pa08")]
246 PA08: 16,
247 #[hal_cfg("pa09")]
248 PA09: 17,
249 #[hal_cfg("pa10")]
250 PA10: 18,
251 #[hal_cfg("pa11")]
252 PA11: 19,
253}