1use crate::port;
28pub use avr_hal_generic::adc::{AdcChannel, AdcOps, ClockDivider};
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35#[repr(u8)]
36pub enum ReferenceVoltage {
37 Aref,
39 AVcc,
41 Internal,
43}
44
45impl Default for ReferenceVoltage {
46 fn default() -> Self {
47 Self::AVcc
48 }
49}
50
51#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
53pub struct AdcSettings {
54 pub clock_divider: ClockDivider,
55 pub ref_voltage: ReferenceVoltage,
56}
57
58fn apply_settings(peripheral: &crate::pac::ADC, settings: AdcSettings) {
59 peripheral.adcsra.write(|w| {
60 w.aden().set_bit();
61 match settings.clock_divider {
62 ClockDivider::Factor2 => w.adps().prescaler_2(),
63 ClockDivider::Factor4 => w.adps().prescaler_4(),
64 ClockDivider::Factor8 => w.adps().prescaler_8(),
65 ClockDivider::Factor16 => w.adps().prescaler_16(),
66 ClockDivider::Factor32 => w.adps().prescaler_32(),
67 ClockDivider::Factor64 => w.adps().prescaler_64(),
68 ClockDivider::Factor128 => w.adps().prescaler_128(),
69 }
70 });
71 peripheral.admux.write(|w| match settings.ref_voltage {
72 ReferenceVoltage::Aref => w.refs().aref(),
73 ReferenceVoltage::AVcc => w.refs().avcc(),
74 ReferenceVoltage::Internal => w.refs().internal(),
75 });
76}
77
78pub type Adc<CLOCK> = avr_hal_generic::adc::Adc<crate::Atmega, crate::pac::ADC, CLOCK>;
80
81pub type Channel = avr_hal_generic::adc::Channel<crate::Atmega, crate::pac::ADC>;
83
84pub mod channel {
97 #[cfg(all(
98 any(
99 feature = "atmega168",
100 feature = "atmega32a",
101 feature = "atmega328p",
102 feature = "atmega328pb",
103 feature = "atmega48p",
104 feature = "atmega128a",
105 feature = "atmega1284p",
106 feature = "atmega8",
107 feature = "atmega88p"
108 ),
109 feature = "enable-extra-adc",
110 ))]
111 pub struct ADC6;
112 #[cfg(all(
113 any(
114 feature = "atmega168",
115 feature = "atmega32a",
116 feature = "atmega328p",
117 feature = "atmega328pb",
118 feature = "atmega48p",
119 feature = "atmega128a",
120 feature = "atmega1284p",
121 feature = "atmega8",
122 feature = "atmega88p"
123 ),
124 feature = "enable-extra-adc",
125 ))]
126 pub struct ADC7;
127 #[cfg(any(
128 feature = "atmega1280",
129 feature = "atmega16",
130 feature = "atmega168",
131 feature = "atmega2560",
132 feature = "atmega32a",
133 feature = "atmega328p",
134 feature = "atmega328pb",
135 feature = "atmega32u4",
136 feature = "atmega48p",
137 feature = "atmega128a",
138 feature = "atmega1284p",
139 feature = "atmega8",
140 feature = "atmega16",
141 feature = "atmega164pa",
142 feature = "atmega88p"
143 ))]
144 pub struct Vbg;
145 #[cfg(any(
146 feature = "atmega1280",
147 feature = "atmega168",
148 feature = "atmega2560",
149 feature = "atmega32a",
150 feature = "atmega328p",
151 feature = "atmega328pb",
152 feature = "atmega32u4",
153 feature = "atmega48p",
154 feature = "atmega128a",
155 feature = "atmega1284p",
156 feature = "atmega8",
157 feature = "atmega16",
158 feature = "atmega164pa",
159 feature = "atmega88p"
160 ))]
161 pub struct Gnd;
162 #[cfg(any(
163 feature = "atmega328p",
164 feature = "atmega328pb",
165 feature = "atmega32u4",
166 feature = "atmega48p",
167 feature = "atmega88p"
168 ))]
169 pub struct Temperature;
170}
171
172#[cfg(any(
173 feature = "atmega168",
174 feature = "atmega328p",
175 feature = "atmega328pb",
176 feature = "atmega48p",
177 feature = "atmega88p"
178))]
179avr_hal_generic::impl_adc! {
180 hal: crate::Atmega,
181 peripheral: crate::pac::ADC,
182 settings: AdcSettings,
183 apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) },
184 channel_id: crate::pac::adc::admux::MUX_A,
185 set_channel: |peripheral, id| {
186 peripheral.admux.modify(|_, w| w.mux().variant(id));
187 },
188 pins: {
189 port::PC0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d),
190 port::PC1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d),
191 port::PC2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d),
192 port::PC3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d),
193 port::PC4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d),
194 port::PC5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d),
195 },
196 channels: {
197 #[cfg(feature = "enable-extra-adc")]
198 channel::ADC6: crate::pac::adc::admux::MUX_A::ADC6,
199 #[cfg(feature = "enable-extra-adc")]
200 channel::ADC7: crate::pac::adc::admux::MUX_A::ADC7,
201 channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG,
202 channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND,
203 #[cfg(any(feature = "atmega328p", feature = "atmega328pb", feature = "atmega48p"))]
204 channel::Temperature: crate::pac::adc::admux::MUX_A::TEMPSENS,
205 },
206}
207
208#[cfg(any(feature = "atmega16", feature = "atmega32a"))]
209avr_hal_generic::impl_adc! {
210 hal: crate::Atmega,
211 peripheral: crate::pac::ADC,
212 settings: AdcSettings,
213 apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) },
214 channel_id: crate::pac::adc::admux::MUX_A,
215 set_channel: |peripheral, id| {
216 peripheral.admux.modify(|_, w| w.mux().variant(id));
217 },
218 pins: {
219 port::PA0: (crate::pac::adc::admux::MUX_A::ADC0),
220 port::PA1: (crate::pac::adc::admux::MUX_A::ADC1),
221 port::PA2: (crate::pac::adc::admux::MUX_A::ADC2),
222 port::PA3: (crate::pac::adc::admux::MUX_A::ADC3),
223 port::PA4: (crate::pac::adc::admux::MUX_A::ADC4),
224 port::PA5: (crate::pac::adc::admux::MUX_A::ADC5),
225 port::PA6: (crate::pac::adc::admux::MUX_A::ADC6),
226 port::PA7: (crate::pac::adc::admux::MUX_A::ADC7),
227 },
228 channels: {
229 channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG,
230 channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND,
231 },
232}
233
234#[cfg(feature = "atmega32u4")]
235avr_hal_generic::impl_adc! {
236 hal: crate::Atmega,
237 peripheral: crate::pac::ADC,
238 settings: AdcSettings,
239 apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) },
240 channel_id: u8,
241 set_channel: |peripheral, id| {
242 peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f));
243 peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0));
244 },
245 pins: {
246 port::PF0: (0b000000, didr0::adc0d),
247 port::PF1: (0b000001, didr0::adc1d),
248 port::PF4: (0b000100, didr0::adc4d),
249 port::PF5: (0b000101, didr0::adc5d),
250 port::PF6: (0b000110, didr0::adc6d),
251 port::PF7: (0b000111, didr0::adc7d),
252 port::PD4: (0b100000, didr2::adc8d),
253 port::PD6: (0b100001, didr2::adc9d),
254 port::PD7: (0b100010, didr2::adc10d),
255 port::PB4: (0b100011, didr2::adc11d),
256 port::PB5: (0b100100, didr2::adc12d),
257 port::PB6: (0b100101, didr2::adc13d),
258 },
259 channels: {
260 channel::Vbg: 0b011110,
261 channel::Gnd: 0b011111,
262 channel::Temperature: 0b100111,
263 },
264}
265
266#[cfg(feature = "atmega128a")]
267avr_hal_generic::impl_adc! {
268 hal: crate::Atmega,
269 peripheral: crate::pac::ADC,
270 settings: AdcSettings,
271 apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) },
272 channel_id: crate::pac::adc::admux::MUX_A,
273 set_channel: |peripheral, id| {
274 peripheral.admux.modify(|_, w| w.mux().variant(id));
275 },
276 pins: {
277 port::PF0: (crate::pac::adc::admux::MUX_A::ADC0),
278 port::PF1: (crate::pac::adc::admux::MUX_A::ADC1),
279 port::PF2: (crate::pac::adc::admux::MUX_A::ADC2),
280 port::PF3: (crate::pac::adc::admux::MUX_A::ADC3),
281 port::PF4: (crate::pac::adc::admux::MUX_A::ADC4),
282 port::PF5: (crate::pac::adc::admux::MUX_A::ADC5),
283 port::PF6: (crate::pac::adc::admux::MUX_A::ADC6),
284 port::PF7: (crate::pac::adc::admux::MUX_A::ADC7),
285 },
286 channels: {
287 channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG,
288 channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND,
289 },
290}
291
292#[cfg(any(feature = "atmega2560", feature = "atmega1280"))]
293avr_hal_generic::impl_adc! {
294 hal: crate::Atmega,
295 peripheral: crate::pac::ADC,
296 settings: AdcSettings,
297 apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) },
298 channel_id: u8,
299 set_channel: |peripheral, id| {
300 peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f));
301 peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0));
302 },
303 pins: {
304 port::PF0: (0b000000, didr0::adc0d),
305 port::PF1: (0b000001, didr0::adc1d),
306 port::PF2: (0b000010, didr0::adc2d),
307 port::PF3: (0b000011, didr0::adc3d),
308 port::PF4: (0b000100, didr0::adc4d),
309 port::PF5: (0b000101, didr0::adc5d),
310 port::PF6: (0b000110, didr0::adc6d),
311 port::PF7: (0b000111, didr0::adc7d),
312 port::PK0: (0b100000, didr2::adc8d),
313 port::PK1: (0b100001, didr2::adc9d),
314 port::PK2: (0b100010, didr2::adc10d),
315 port::PK3: (0b100011, didr2::adc11d),
316 port::PK4: (0b100100, didr2::adc12d),
317 port::PK5: (0b100101, didr2::adc13d),
318 port::PK6: (0b100110, didr2::adc14d),
319 port::PK7: (0b100111, didr2::adc15d),
320 },
321 channels: {
322 channel::Vbg: 0b011110,
323 channel::Gnd: 0b011111,
324 },
325}
326
327#[cfg(any(feature = "atmega1284p"))]
328avr_hal_generic::impl_adc! {
329 hal: crate::Atmega,
330 peripheral: crate::pac::ADC,
331 settings: AdcSettings,
332 apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) },
333 channel_id: crate::pac::adc::admux::MUX_A,
334 set_channel: |peripheral, id| {
335 peripheral.admux.modify(|_, w| w.mux().variant(id));
336 },
337 pins: {
338 port::PA0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d),
339 port::PA1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d),
340 port::PA2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d),
341 port::PA3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d),
342 port::PA4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d),
343 port::PA5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d),
344 },
345 channels: {
346 #[cfg(feature = "enable-extra-adc")]
347 channel::ADC6: crate::pac::adc::admux::MUX_A::ADC6,
348 #[cfg(feature = "enable-extra-adc")]
349 channel::ADC7: crate::pac::adc::admux::MUX_A::ADC7,
350 channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG,
351 channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND,
352 },
353}
354
355#[cfg(any(feature = "atmega8"))]
356avr_hal_generic::impl_adc! {
357 hal: crate::Atmega,
358 peripheral: crate::pac::ADC,
359 settings: AdcSettings,
360 apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) },
361 channel_id: crate::pac::adc::admux::MUX_A,
362 set_channel: |peripheral, id| {
363 peripheral.admux.modify(|_, w| w.mux().variant(id));
364 },
365 pins: {
366 port::PC0: (crate::pac::adc::admux::MUX_A::ADC0),
367 port::PC1: (crate::pac::adc::admux::MUX_A::ADC1),
368 port::PC2: (crate::pac::adc::admux::MUX_A::ADC2),
369 port::PC3: (crate::pac::adc::admux::MUX_A::ADC3),
370 port::PC4: (crate::pac::adc::admux::MUX_A::ADC4),
371 port::PC5: (crate::pac::adc::admux::MUX_A::ADC5),
372 },
373 channels: {
374 #[cfg(feature = "enable-extra-adc")]
375 channel::ADC6: crate::pac::adc::admux::MUX_A::ADC6,
376 #[cfg(feature = "enable-extra-adc")]
377 channel::ADC7: crate::pac::adc::admux::MUX_A::ADC7,
378 channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG,
379 channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND,
380 },
381}
382
383#[cfg(any(feature = "atmega164pa"))]
384avr_hal_generic::impl_adc! {
385 hal: crate::Atmega,
386 peripheral: crate::pac::ADC,
387 settings: AdcSettings,
388 apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) },
389 channel_id: crate::pac::adc::admux::MUX_A,
390 set_channel: |peripheral, id| {
391 peripheral.admux.modify(|_, w| w.mux().variant(id));
392 },
393 pins: {
394 port::PA0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d),
395 port::PA1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d),
396 port::PA2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d),
397 port::PA3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d),
398 port::PA4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d),
399 port::PA5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d),
400 port::PA6: (crate::pac::adc::admux::MUX_A::ADC6, didr0::adc6d),
401 port::PA7: (crate::pac::adc::admux::MUX_A::ADC7, didr0::adc7d),
402 },
403 channels: {
404 channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG,
405 channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND,
406 },
407}