1use core::cell::RefCell;
15
16use stm32f7xx_hal::pac;
17
18pub struct Adc<ADC> {
20 adc: ADC,
21}
22
23impl<ADC> Adc<ADC> {
24 #[inline]
25 pub fn free(self) -> ADC {
26 self.adc
27 }
28}
29
30pub trait AdcRead {
32 fn read_channel(&mut self, ch: u8) -> u16;
33}
34
35fn configure_common() {
36 let common = unsafe { &*pac::ADC_COMMON::ptr() };
37
38 common.ccr.modify(|_, w| w.adcpre().div4());
40}
41
42fn init_basic_adc(adc: &pac::adc1::RegisterBlock) {
43 adc.cr2.modify(|_, w| w.adon().clear_bit());
45
46 adc.cr1.modify(|_, w| w.res().bits(0b00));
48 adc.cr2.modify(|_, w| {
49 w.cont().clear_bit();
50 w.align().right();
51 w.exten().disabled();
52 w
53 });
54
55 adc.smpr2.modify(|_, w| unsafe { w.bits(0) });
57
58 adc.cr2.modify(|_, w| w.adon().set_bit());
60}
61
62impl Adc<pac::ADC1> {
63 pub fn adc1(adc1: pac::ADC1) -> Self {
65 let rcc = unsafe { &*pac::RCC::ptr() };
66 rcc.apb2enr.modify(|_, w| w.adc1en().set_bit());
67
68 configure_common();
69 init_basic_adc(&adc1);
70
71 Self { adc: adc1 }
72 }
73}
74
75impl Adc<pac::ADC2> {
76 pub fn adc2(adc2: pac::ADC2) -> Self {
78 let rcc = unsafe { &*pac::RCC::ptr() };
79 rcc.apb2enr.modify(|_, w| w.adc2en().set_bit());
80
81 configure_common();
82 init_basic_adc(&adc2);
83
84 Self { adc: adc2 }
85 }
86}
87
88impl Adc<pac::ADC3> {
89 pub fn adc3(adc3: pac::ADC3) -> Self {
91 let rcc = unsafe { &*pac::RCC::ptr() };
92 rcc.apb2enr.modify(|_, w| w.adc3en().set_bit());
93
94 configure_common();
95 init_basic_adc(&adc3);
96
97 Self { adc: adc3 }
98 }
99}
100
101fn read_channel(adc: &pac::adc1::RegisterBlock, channel: u8) -> u16 {
103 if channel <= 9 {
105 adc.smpr2.modify(|_, w| match channel {
106 0 => w.smp0().bits(0b111),
107 1 => w.smp1().bits(0b111),
108 2 => w.smp2().bits(0b111),
109 3 => w.smp3().bits(0b111),
110 4 => w.smp4().bits(0b111),
111 5 => w.smp5().bits(0b111),
112 6 => w.smp6().bits(0b111),
113 7 => w.smp7().bits(0b111),
114 8 => w.smp8().bits(0b111),
115 9 => w.smp9().bits(0b111),
116 _ => unreachable!(),
117 });
118 } else if channel == 12 {
119 adc.smpr1.modify(|_, w| w.smp12().bits(0b111));
120 }
121
122 adc.sqr1.modify(|_, w| w.l().bits(0));
124
125 adc.sqr3
127 .modify(|_, w| unsafe { w.sq1().bits(channel & 0x1F) });
128
129 let mut sum: u32 = 0;
130 const SAMPLES: u32 = 16;
131
132 for _ in 0..SAMPLES {
133 adc.cr2.modify(|_, w| w.swstart().set_bit());
135
136 while adc.sr.read().eoc().bit_is_clear() {}
138
139 sum += adc.dr.read().data().bits() as u32;
140 }
141
142 (sum / SAMPLES) as u16
143}
144
145impl Adc<pac::ADC1> {
146 #[inline]
148 pub fn read(&self, channel: u8) -> u16 {
149 read_channel(&self.adc, channel)
150 }
151}
152
153impl Adc<pac::ADC2> {
154 #[inline]
156 pub fn read(&self, channel: u8) -> u16 {
157 read_channel(&self.adc, channel)
158 }
159}
160
161impl Adc<pac::ADC3> {
162 #[inline]
164 pub fn read(&self, channel: u8) -> u16 {
165 read_channel(&self.adc, channel)
166 }
167}
168
169impl AdcRead for Adc<pac::ADC1> {
170 fn read_channel(&mut self, ch: u8) -> u16 {
171 self.read(ch)
172 }
173}
174
175impl AdcRead for Adc<pac::ADC2> {
176 fn read_channel(&mut self, ch: u8) -> u16 {
177 self.read(ch)
178 }
179}
180
181impl AdcRead for Adc<pac::ADC3> {
182 fn read_channel(&mut self, ch: u8) -> u16 {
183 self.read(ch)
184 }
185}
186
187impl<ADC> Adc<ADC>
188where
189 Adc<ADC>: AdcRead,
190{
191 pub fn make_reader<'a>(adc_ref: &'a RefCell<Self>, channel: u8) -> impl FnMut() -> u16 + 'a {
193 move || adc_ref.borrow_mut().read_channel(channel)
194 }
195}
196
197pub fn volts_from_adc(adc_value: u16, v_ref: f32) -> f32 {
199 let max_adc = (1 << 12) - 1;
200 (adc_value as f32 / max_adc as f32) * v_ref
201}