1#![allow(non_camel_case_types)]
2use crate::port;
29pub use avr_hal_generic::adc::{AdcChannel, AdcOps, ClockDivider};
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36#[repr(u8)]
37pub enum ReferenceVoltage {
38 #[cfg(any(feature = "attiny85", feature = "attiny167",))]
40 Aref,
41 AVcc,
43 Internal1_1,
45 #[cfg(any(feature = "attiny85", feature = "attiny167",))]
47 Internal2_56,
48}
49
50impl Default for ReferenceVoltage {
51 fn default() -> Self {
52 Self::AVcc
53 }
54}
55
56#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
58pub struct AdcSettings {
59 pub clock_divider: ClockDivider,
60 pub ref_voltage: ReferenceVoltage,
61}
62
63pub type Adc<CLOCK> = avr_hal_generic::adc::Adc<crate::Attiny, crate::pac::ADC, CLOCK>;
65
66pub type Channel = avr_hal_generic::adc::Channel<crate::Attiny, crate::pac::ADC>;
68
69pub mod channel {
82 #[cfg(feature = "attiny167")]
83 pub struct AVcc_4;
84 pub struct Vbg;
85 pub struct Gnd;
86 pub struct Temperature;
87}
88
89fn apply_clock(peripheral: &crate::pac::ADC, settings: AdcSettings) {
90 peripheral.adcsra.write(|w| {
91 w.aden().set_bit();
92 match settings.clock_divider {
93 ClockDivider::Factor2 => w.adps().prescaler_2(),
94 ClockDivider::Factor4 => w.adps().prescaler_4(),
95 ClockDivider::Factor8 => w.adps().prescaler_8(),
96 ClockDivider::Factor16 => w.adps().prescaler_16(),
97 ClockDivider::Factor32 => w.adps().prescaler_32(),
98 ClockDivider::Factor64 => w.adps().prescaler_64(),
99 ClockDivider::Factor128 => w.adps().prescaler_128(),
100 }
101 });
102}
103
104#[cfg(feature = "attiny85")]
105avr_hal_generic::impl_adc! {
106 hal: crate::Attiny,
107 peripheral: crate::pac::ADC,
108 settings: AdcSettings,
109 apply_settings: |peripheral, settings| {
110 apply_clock(peripheral, settings);
111 peripheral.admux.write(|w| match settings.ref_voltage {
112 ReferenceVoltage::Aref => w.refs().aref(),
113 ReferenceVoltage::AVcc => w.refs().vcc(),
114 ReferenceVoltage::Internal1_1 => w.refs().internal().refs2().clear_bit(),
115 ReferenceVoltage::Internal2_56 => w.refs().internal().refs2().set_bit(),
116 });
117 },
118 channel_id: crate::pac::adc::admux::MUX_A,
119 set_channel: |peripheral, id| {
120 peripheral.admux.modify(|_, w| w.mux().variant(id));
121 },
122 pins: {
123 port::PB5: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d),
124 port::PB2: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d),
125 port::PB4: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d),
126 port::PB3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d),
127 },
128 channels: {
129 channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG,
130 channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND,
131 channel::Temperature: crate::pac::adc::admux::MUX_A::TEMPSENS,
132 },
133}
134
135#[cfg(feature = "attiny88")]
136avr_hal_generic::impl_adc! {
137 hal: crate::Attiny,
138 peripheral: crate::pac::ADC,
139 settings: AdcSettings,
140 apply_settings: |peripheral, settings| {
141 apply_clock(peripheral, settings);
142 peripheral.admux.write(|w| match settings.ref_voltage {
143 ReferenceVoltage::AVcc => w.refs0().avcc(),
144 ReferenceVoltage::Internal1_1 => w.refs0().internal(),
145 });
146 },
147 channel_id: crate::pac::adc::admux::MUX_A,
148 set_channel: |peripheral, id| {
149 peripheral.admux.modify(|_, w| w.mux().variant(id));
150 },
151 pins: {
152 port::PC0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d),
153 port::PC1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d),
154 port::PC2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d),
155 port::PC3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d),
156 port::PC4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d),
157 port::PC5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d),
158 port::PA0: (crate::pac::adc::admux::MUX_A::ADC6, didr0::adc6d),
159 port::PA1: (crate::pac::adc::admux::MUX_A::ADC7, didr0::adc7d),
160 },
161 channels: {
162 channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG,
163 channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND,
164 channel::Temperature: crate::pac::adc::admux::MUX_A::TEMPSENS,
165 },
166}
167
168#[cfg(feature = "attiny167")]
169avr_hal_generic::impl_adc! {
170 hal: crate::Attiny,
171 peripheral: crate::pac::ADC,
172 settings: AdcSettings,
173 apply_settings: |peripheral, settings| {
174 apply_clock(peripheral, settings);
175 peripheral.amiscr.write(|w| match settings.ref_voltage {
176 ReferenceVoltage::Aref => w.arefen().set_bit(),
177 _ => w.arefen().clear_bit(),
178 });
179 peripheral.admux.write(|w| match settings.ref_voltage {
180 ReferenceVoltage::Aref => w.refs().avcc(),
181 ReferenceVoltage::AVcc => w.refs().avcc(),
182 ReferenceVoltage::Internal1_1 => w.refs().internal_11(),
183 ReferenceVoltage::Internal2_56 => w.refs().internal_256(),
184 });
185 },
186 channel_id: crate::pac::adc::admux::MUX_A,
187 set_channel: |peripheral, id| {
188 peripheral.admux.modify(|_, w| w.mux().variant(id));
189 },
190 pins: {
191 port::PA0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d),
192 port::PA1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d),
193 port::PA2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d),
194 port::PA3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d),
195 port::PA4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d),
196 port::PA5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d),
197 port::PA6: (crate::pac::adc::admux::MUX_A::ADC6, didr0::adc6d),
198 port::PA7: (crate::pac::adc::admux::MUX_A::ADC7, didr0::adc7d),
199 port::PB5: (crate::pac::adc::admux::MUX_A::ADC8, didr1::adc8d),
200 port::PB6: (crate::pac::adc::admux::MUX_A::ADC9, didr1::adc9d),
201 port::PB7: (crate::pac::adc::admux::MUX_A::ADC10, didr1::adc10d),
202 },
203 channels: {
204 channel::AVcc_4: crate::pac::adc::admux::MUX_A::ADC_AVCC_4,
205 channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG,
206 channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND,
207 channel::Temperature: crate::pac::adc::admux::MUX_A::TEMPSENS,
208 },
209}