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 }
119
120 adc.sqr1.modify(|_, w| w.l().bits(0));
122
123 adc.sqr3
125 .modify(|_, w| unsafe { w.sq1().bits(channel & 0x1F) });
126
127 adc.cr2.modify(|_, w| w.swstart().set_bit());
129
130 while adc.sr.read().eoc().bit_is_clear() {}
132
133 adc.dr.read().data().bits() as u16
134}
135
136impl Adc<pac::ADC1> {
137 #[inline]
139 pub fn read(&self, channel: u8) -> u16 {
140 read_channel(&self.adc, channel)
141 }
142}
143
144impl Adc<pac::ADC2> {
145 #[inline]
147 pub fn read(&self, channel: u8) -> u16 {
148 read_channel(&self.adc, channel)
149 }
150}
151
152impl Adc<pac::ADC3> {
153 #[inline]
155 pub fn read(&self, channel: u8) -> u16 {
156 read_channel(&self.adc, channel)
157 }
158}
159
160impl AdcRead for Adc<pac::ADC1> {
161 fn read_channel(&mut self, ch: u8) -> u16 {
162 self.read(ch)
163 }
164}
165
166impl AdcRead for Adc<pac::ADC2> {
167 fn read_channel(&mut self, ch: u8) -> u16 {
168 self.read(ch)
169 }
170}
171
172impl AdcRead for Adc<pac::ADC3> {
173 fn read_channel(&mut self, ch: u8) -> u16 {
174 self.read(ch)
175 }
176}
177
178impl<ADC> Adc<ADC>
179where
180 Adc<ADC>: AdcRead,
181{
182 pub fn make_reader<'a>(adc_ref: &'a RefCell<Self>, channel: u8) -> impl FnMut() -> u16 + 'a {
184 move || adc_ref.borrow_mut().read_channel(channel)
185 }
186}
187
188pub fn volts_from_adc(adc_value: u16, v_ref: f32) -> f32 {
190 let max_adc = (1 << 12) - 1;
191 (adc_value as f32 / max_adc as f32) * v_ref
192}