1use core::{
4 convert::Infallible,
5 ops::DerefMut,
6 sync::atomic::{self, Ordering},
7};
8
9use crate::{
10 dma::{dma1, Event as DMAEvent, RxDma, Transfer, TransferPayload, W},
11 dmamux::{DmaInput, DmaMux},
12 gpio::{self, Analog},
13 hal::{
14 adc::{Channel as EmbeddedHalChannel, OneShot},
15 blocking::delay::DelayUs,
16 },
17 pac,
18 rcc::{Enable, Reset, AHB2, CCIPR},
19 signature::{VrefCal, VtempCalHigh, VtempCalLow, VDDA_CALIB_MV},
20};
21
22use pac::{ADC1, ADC_COMMON};
23use stable_deref_trait::StableDeref;
24
25pub struct Vref;
27
28pub struct Vbat;
30
31pub struct Temperature;
33
34pub struct ADC {
36 pub(crate) adc: ADC1,
37 common: ADC_COMMON,
38 resolution: Resolution,
39 sample_time: SampleTime,
40 calibrated_vdda: u32,
41}
42
43#[derive(Copy, Clone, PartialEq)]
44pub enum DmaMode {
45 Disabled = 0,
46 Oneshot = 1,
47 }
50
51#[derive(PartialEq, PartialOrd, Clone, Copy)]
52pub enum Sequence {
53 One = 0,
54 Two = 1,
55 Three = 2,
56 Four = 3,
57 Five = 4,
58 Six = 5,
59 Seven = 6,
60 Eight = 7,
61 Nine = 8,
62 Ten = 9,
63 Eleven = 10,
64 Twelve = 11,
65 Thirteen = 12,
66 Fourteen = 13,
67 Fifteen = 14,
68 Sixteen = 15,
69}
70
71impl From<u8> for Sequence {
72 fn from(bits: u8) -> Self {
73 match bits {
74 0 => Sequence::One,
75 1 => Sequence::Two,
76 2 => Sequence::Three,
77 3 => Sequence::Four,
78 4 => Sequence::Five,
79 5 => Sequence::Six,
80 6 => Sequence::Seven,
81 7 => Sequence::Eight,
82 8 => Sequence::Nine,
83 9 => Sequence::Ten,
84 10 => Sequence::Eleven,
85 11 => Sequence::Twelve,
86 12 => Sequence::Thirteen,
87 13 => Sequence::Fourteen,
88 14 => Sequence::Fifteen,
89 15 => Sequence::Sixteen,
90 _ => unimplemented!(),
91 }
92 }
93}
94
95impl Into<u8> for Sequence {
96 fn into(self) -> u8 {
97 match self {
98 Sequence::One => 0,
99 Sequence::Two => 1,
100 Sequence::Three => 2,
101 Sequence::Four => 3,
102 Sequence::Five => 4,
103 Sequence::Six => 5,
104 Sequence::Seven => 6,
105 Sequence::Eight => 7,
106 Sequence::Nine => 8,
107 Sequence::Ten => 9,
108 Sequence::Eleven => 10,
109 Sequence::Twelve => 11,
110 Sequence::Thirteen => 12,
111 Sequence::Fourteen => 13,
112 Sequence::Fifteen => 14,
113 Sequence::Sixteen => 15,
114 }
115 }
116}
117
118#[derive(PartialEq, PartialOrd, Clone, Copy)]
119pub enum Event {
120 EndOfRegularSequence,
121 EndOfRegularConversion,
122}
123
124impl ADC {
125 pub fn new(
127 adc: ADC1,
128 common: ADC_COMMON,
129 ahb: &mut AHB2,
130 ccipr: &mut CCIPR,
131 delay: &mut impl DelayUs<u32>,
132 ) -> Self {
133 ADC1::enable(ahb);
135
136 ADC1::reset(ahb);
138
139 ccipr.ccipr().modify(|_, w| {
141 unsafe {
143 w.adcsel().bits(0b11);
144 }
145
146 w
147 });
148
149 adc.cr.write(|w| w.deeppwd().clear_bit()); adc.cr.modify(|_, w| w.advregen().set_bit()); delay.delay_us(25);
159
160 adc.cr.modify(|_, w| {
162 w.adcal().set_bit(); w.adcaldif().clear_bit(); w
166 });
167
168 while adc.cr.read().adcal().bit_is_set() {}
169
170 delay.delay_us(1);
172
173 let mut s = Self {
174 adc,
175 common,
176 resolution: Resolution::default(),
177 sample_time: SampleTime::default(),
178 calibrated_vdda: VDDA_CALIB_MV,
179 };
180
181 let mut vref = s.enable_vref(delay);
183
184 s.calibrate(&mut vref);
185
186 s.common.ccr.modify(|_, w| w.vrefen().clear_bit());
187 s
188 }
189
190 pub fn enable_vref(&mut self, delay: &mut impl DelayUs<u32>) -> Vref {
192 self.common.ccr.modify(|_, w| w.vrefen().set_bit());
193
194 delay.delay_us(15);
197
198 Vref {}
199 }
200
201 pub fn enable_temperature(&mut self, delay: &mut impl DelayUs<u32>) -> Temperature {
203 self.common.ccr.modify(|_, w| w.ch17sel().set_bit());
204
205 delay.delay_us(150);
215
216 Temperature {}
217 }
218
219 pub fn enable_vbat(&mut self) -> Vbat {
221 self.common.ccr.modify(|_, w| w.ch18sel().set_bit());
222
223 Vbat {}
224 }
225
226 pub fn calibrate(&mut self, vref: &mut Vref) {
230 let vref_cal = VrefCal::get().read();
231 let old_sample_time = self.sample_time;
232
233 self.set_sample_time(SampleTime::Cycles640_5);
237
238 let vref_samp = self.read(vref).unwrap();
240
241 self.set_sample_time(old_sample_time);
242
243 self.calibrated_vdda = (VDDA_CALIB_MV * u32::from(vref_cal)) / u32::from(vref_samp);
245 }
246
247 pub fn set_resolution(&mut self, resolution: Resolution) {
249 self.resolution = resolution;
250 }
251
252 pub fn set_sample_time(&mut self, sample_time: SampleTime) {
254 self.sample_time = sample_time;
255 }
256
257 pub fn get_max_value(&self) -> u16 {
259 match self.resolution {
260 Resolution::Bits12 => 4095,
261 Resolution::Bits10 => 1023,
262 Resolution::Bits8 => 255,
263 Resolution::Bits6 => 63,
264 }
265 }
266
267 pub fn release(self) -> (ADC1, ADC_COMMON) {
272 (self.adc, self.common)
273 }
274
275 pub fn to_millivolts(&self, sample: u16) -> u16 {
277 ((u32::from(sample) * self.calibrated_vdda) / self.resolution.to_max_count()) as u16
278 }
279
280 pub fn to_degrees_centigrade(&self, sample: u16) -> f32 {
282 let sample = (u32::from(sample) * self.calibrated_vdda) / VDDA_CALIB_MV;
283 (VtempCalHigh::TEMP_DEGREES - VtempCalLow::TEMP_DEGREES) as f32
284 / (VtempCalHigh::get().read() as i32 - VtempCalLow::get().read() as i32) as f32
287 * (sample as i32 - VtempCalLow::get().read() as i32) as f32
289 + 30.0
292 }
293
294 pub fn get_data(&self) -> u16 {
301 self.adc.dr.read().bits() as u16
303 }
304
305 pub fn configure_sequence<C>(
311 &mut self,
312 channel: &mut C,
313 sequence: Sequence,
314 sample_time: SampleTime,
315 ) where
316 C: Channel,
317 {
318 let channel_bits = C::channel();
319 channel.set_sample_time(&self.adc, sample_time);
320
321 unsafe {
322 match sequence {
324 Sequence::One => self.adc.sqr1.modify(|_, w| w.sq1().bits(channel_bits)),
325 Sequence::Two => self.adc.sqr1.modify(|_, w| w.sq2().bits(channel_bits)),
326 Sequence::Three => self.adc.sqr1.modify(|_, w| w.sq3().bits(channel_bits)),
327 Sequence::Four => self.adc.sqr1.modify(|_, w| w.sq4().bits(channel_bits)),
328 Sequence::Five => self.adc.sqr2.modify(|_, w| w.sq5().bits(channel_bits)),
329 Sequence::Six => self.adc.sqr2.modify(|_, w| w.sq6().bits(channel_bits)),
330 Sequence::Seven => self.adc.sqr2.modify(|_, w| w.sq7().bits(channel_bits)),
331 Sequence::Eight => self.adc.sqr2.modify(|_, w| w.sq8().bits(channel_bits)),
332 Sequence::Nine => self.adc.sqr2.modify(|_, w| w.sq9().bits(channel_bits)),
333 Sequence::Ten => self.adc.sqr3.modify(|_, w| w.sq10().bits(channel_bits)),
334 Sequence::Eleven => self.adc.sqr3.modify(|_, w| w.sq11().bits(channel_bits)),
335 Sequence::Twelve => self.adc.sqr3.modify(|_, w| w.sq12().bits(channel_bits)),
336 Sequence::Thirteen => self.adc.sqr3.modify(|_, w| w.sq13().bits(channel_bits)),
337 Sequence::Fourteen => self.adc.sqr3.modify(|_, w| w.sq14().bits(channel_bits)),
338 Sequence::Fifteen => self.adc.sqr4.modify(|_, w| w.sq15().bits(channel_bits)),
339 Sequence::Sixteen => self.adc.sqr4.modify(|_, w| w.sq16().bits(channel_bits)),
340 }
341 }
342
343 let current_seql = self.get_sequence_length();
345 let next_seql: u8 = sequence.into();
346 if next_seql >= current_seql {
347 self.set_sequence_length(sequence.into());
349 }
350 }
351
352 pub(crate) fn get_sequence_length(&self) -> u8 {
354 self.adc.sqr1.read().l().bits()
355 }
356
357 fn set_sequence_length(&mut self, length: u8) {
360 self.adc.sqr1.modify(|_, w| unsafe { w.l().bits(length) });
361 }
362
363 pub fn reset_sequence(&mut self) {
368 self.adc.sqr1.modify(|_, w| unsafe { w.l().bits(0b0000) })
369 }
370
371 pub fn has_completed_conversion(&self) -> bool {
372 self.adc.isr.read().eoc().bit_is_set()
373 }
374
375 pub fn has_completed_sequence(&self) -> bool {
376 self.adc.isr.read().eos().bit_is_set()
377 }
378
379 pub fn clear_end_flags(&mut self) {
380 self.adc
382 .isr
383 .modify(|_, w| w.eos().set_bit().eoc().set_bit());
384 }
385
386 pub fn start_conversion(&mut self) {
387 self.enable();
388 self.clear_end_flags();
389 self.adc.cr.modify(|_, w| w.adstart().set_bit());
390 }
391
392 pub fn is_converting(&self) -> bool {
393 self.adc.cr.read().adstart().bit_is_set()
394 }
395
396 pub fn listen(&mut self, event: Event) {
397 self.adc.ier.modify(|_, w| match event {
398 Event::EndOfRegularSequence => w.eosie().set_bit(),
399 Event::EndOfRegularConversion => w.eocie().set_bit(),
400 });
401 }
402
403 pub fn unlisten(&mut self, event: Event) {
404 self.adc.ier.modify(|_, w| match event {
405 Event::EndOfRegularSequence => w.eosie().clear_bit(),
406 Event::EndOfRegularConversion => w.eocie().clear_bit(),
407 });
408 }
409
410 pub fn enable(&mut self) {
411 if !self.is_enabled() {
412 while self.adc.cr.read().addis().bit_is_set() {}
414
415 self.adc.isr.modify(|_, w| w.adrdy().set_bit());
417 self.adc.cr.modify(|_, w| w.aden().set_bit());
418 while self.adc.isr.read().adrdy().bit_is_clear() {}
419
420 self.adc.cfgr.modify(|_, w| {
422 unsafe { w.res().bits(self.resolution as u8) }
425 });
426 }
427 }
428
429 pub fn is_enabled(&self) -> bool {
430 self.adc.cr.read().aden().bit_is_set()
431 }
432
433 pub fn disable(&mut self) {
434 self.adc.cr.modify(|_, w| w.addis().set_bit());
435 }
436}
437
438impl<C> OneShot<ADC, u16, C> for ADC
439where
440 C: Channel,
441{
442 type Error = Infallible;
443
444 fn read(&mut self, channel: &mut C) -> nb::Result<u16, Self::Error> {
445 self.configure_sequence(channel, Sequence::One, self.sample_time);
446
447 self.start_conversion();
448 while !self.has_completed_sequence() {}
449
450 let _ = self.get_data();
454
455 self.start_conversion();
456 while !self.has_completed_sequence() {}
457
458 let val = self.get_data();
460
461 self.disable();
463
464 Ok(val)
465 }
466}
467
468impl TransferPayload for RxDma<ADC, dma1::C1> {
469 fn start(&mut self) {
470 self.channel.start();
471 }
472
473 fn stop(&mut self) {
474 self.channel.stop();
475 }
476}
477
478impl RxDma<ADC, dma1::C1> {
479 pub fn split(mut self) -> (ADC, dma1::C1) {
480 self.stop();
481 (self.payload, self.channel)
482 }
483}
484
485impl<BUFFER, const N: usize> Transfer<W, BUFFER, RxDma<ADC, dma1::C1>>
486where
487 BUFFER: Sized + StableDeref<Target = [u16; N]> + DerefMut + 'static,
488{
489 pub fn from_adc_dma(
490 dma: RxDma<ADC, dma1::C1>,
491 buffer: BUFFER,
492 dma_mode: DmaMode,
493 transfer_complete_interrupt: bool,
494 ) -> Self {
495 let (adc, channel) = dma.split();
496 Transfer::from_adc(adc, channel, buffer, dma_mode, transfer_complete_interrupt)
497 }
498
499 pub fn from_adc(
506 mut adc: ADC,
507 mut channel: dma1::C1,
508 buffer: BUFFER,
509 dma_mode: DmaMode,
510 transfer_complete_interrupt: bool,
511 ) -> Self {
512 assert!(dma_mode != DmaMode::Disabled);
513
514 let (enable, circular) = match dma_mode {
515 DmaMode::Disabled => (false, false),
516 DmaMode::Oneshot => (true, false),
517 };
518
519 adc.adc
520 .cfgr
521 .modify(|_, w| w.dmaen().bit(enable).dmacfg().bit(circular));
522
523 channel.set_peripheral_address(&adc.adc.dr as *const _ as u32, false);
524
525 channel.set_memory_address(buffer.as_ptr() as u32, true);
528 channel.set_transfer_length(N as u16);
529
530 channel.set_request_line(DmaInput::Adc1).unwrap();
531
532 channel.ccr().modify(|_, w| unsafe {
533 w.mem2mem()
534 .clear_bit()
535 .pl()
537 .bits(0b01)
538 .msize()
540 .bits(0b01)
541 .psize()
543 .bits(0b01)
544 .dir()
546 .clear_bit()
547 .circ()
548 .bit(circular)
549 });
550
551 if transfer_complete_interrupt {
552 channel.listen(DMAEvent::TransferComplete);
553 }
554
555 atomic::compiler_fence(Ordering::Release);
556
557 channel.start();
558 adc.start_conversion();
559
560 Transfer::w(
561 buffer,
562 RxDma {
563 channel,
564 payload: adc,
565 },
566 )
567 }
568}
569
570#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
574pub enum Resolution {
575 Bits12 = 0b00,
577
578 Bits10 = 0b01,
580
581 Bits8 = 0b10,
583
584 Bits6 = 0b11,
586}
587
588impl Default for Resolution {
589 fn default() -> Self {
590 Self::Bits12
591 }
592}
593
594impl Resolution {
595 fn to_max_count(&self) -> u32 {
596 match self {
597 Resolution::Bits12 => (1 << 12) - 1,
598 Resolution::Bits10 => (1 << 10) - 1,
599 Resolution::Bits8 => (1 << 8) - 1,
600 Resolution::Bits6 => (1 << 6) - 1,
601 }
602 }
603}
604
605#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
609pub enum SampleTime {
610 Cycles2_5 = 0b000,
612
613 Cycles6_5 = 0b001,
615
616 Cycles12_5 = 0b010,
618
619 Cycles24_5 = 0b011,
621
622 Cycles47_5 = 0b100,
624
625 Cycles92_5 = 0b101,
627
628 Cycles247_5 = 0b110,
630
631 Cycles640_5 = 0b111,
633}
634
635impl Default for SampleTime {
636 fn default() -> Self {
637 Self::Cycles2_5
638 }
639}
640
641pub trait Channel: EmbeddedHalChannel<ADC, ID = u8> {
643 fn set_sample_time(&mut self, adc: &ADC1, sample_time: SampleTime);
644}
645
646macro_rules! adc_pins {
647 (
648 $(
649 $id:expr,
650 $pin:ty,
651 $smpr:ident,
652 $smp:ident;
653 )*
654 ) => {
655 $(
656 impl EmbeddedHalChannel<ADC> for $pin {
657 type ID = u8;
658
659 fn channel() -> Self::ID {
660 $id
661 }
662 }
663
664 impl Channel for $pin {
665 fn set_sample_time(&mut self,
666 adc: &ADC1,
667 sample_time: SampleTime,
668 ) {
669 adc.$smpr.modify(|_, w| {
670 unsafe {
673 w.$smp().bits(sample_time as u8)
674 }
675 })
676 }
677 }
678 )*
679 };
680}
681
682adc_pins!(
683 0, Vref, smpr1, smp0;
684 1, gpio::PC0<Analog>, smpr1, smp1;
685 2, gpio::PC1<Analog>, smpr1, smp2;
686 3, gpio::PC2<Analog>, smpr1, smp3;
687 4, gpio::PC3<Analog>, smpr1, smp4;
688 5, gpio::PA0<Analog>, smpr1, smp5;
689 6, gpio::PA1<Analog>, smpr1, smp6;
690 7, gpio::PA2<Analog>, smpr1, smp7;
691 8, gpio::PA3<Analog>, smpr1, smp8;
692 9, gpio::PA4<Analog>, smpr1, smp9;
693 10, gpio::PA5<Analog>, smpr2, smp10;
694 11, gpio::PA6<Analog>, smpr2, smp11;
695 12, gpio::PA7<Analog>, smpr2, smp12;
696 13, gpio::PC4<Analog>, smpr2, smp13;
697 14, gpio::PC5<Analog>, smpr2, smp14;
698 15, gpio::PB0<Analog>, smpr2, smp15;
699 16, gpio::PB1<Analog>, smpr2, smp16;
700 17, Temperature, smpr2, smp17;
701 18, Vbat, smpr2, smp18;
702);