1use crate::rcc;
8use core::cell::Cell;
9use kernel::hil;
10use kernel::platform::chip::ClockInterface;
11use kernel::utilities::cells::OptionalCell;
12use kernel::utilities::registers::interfaces::{ReadWriteable, Readable};
13use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite};
14use kernel::utilities::StaticRef;
15use kernel::ErrorCode;
16
17#[repr(C)]
18struct AdcRegisters {
19 isr: ReadWrite<u32, ISR::Register>,
20 ier: ReadWrite<u32, IER::Register>,
21 cr: ReadWrite<u32, CR::Register>,
22 cfgr: ReadWrite<u32, CFGR::Register>,
23
24 _reserved0: [u32; 1],
25 smpr1: ReadWrite<u32, SMPR1::Register>,
26 smpr2: ReadWrite<u32, SMPR2::Register>,
27
28 _reserved1: [u32; 1],
29 tr1: ReadWrite<u32, TR1::Register>,
30 tr2: ReadWrite<u32, TR2::Register>,
31 tr3: ReadWrite<u32, TR3::Register>,
32
33 _reserved2: [u32; 1],
34 sqr1: ReadWrite<u32, SQR1::Register>,
35 sqr2: ReadWrite<u32, SQR2::Register>,
36 sqr3: ReadWrite<u32, SQR3::Register>,
37 sqr4: ReadWrite<u32, SQR4::Register>,
38 dr: ReadOnly<u32, DR::Register>,
39 _reserved3: [u32; 2],
40
41 jsqr: ReadWrite<u32, JSQR::Register>,
42 _reserved4: [u32; 4],
43
44 ofr1: ReadWrite<u32, OFR::Register>,
45 ofr2: ReadWrite<u32, OFR::Register>,
46 ofr3: ReadWrite<u32, OFR::Register>,
47 ofr4: ReadWrite<u32, OFR::Register>,
48 _reserved5: [u32; 4],
49
50 jdr1: ReadOnly<u32, JDR::Register>,
51 jdr2: ReadOnly<u32, JDR::Register>,
52 jdr3: ReadOnly<u32, JDR::Register>,
53 jdr4: ReadOnly<u32, JDR::Register>,
54 _reserved6: [u32; 4],
55
56 awd2cr: ReadWrite<u32, AWD2CR::Register>,
57 awd3cr: ReadWrite<u32, AWD3CR::Register>,
58 _reserved7: [u32; 2],
59
60 difsel: ReadWrite<u32, DIFSEL::Register>,
61 calfact: ReadWrite<u32, CALFACT::Register>,
62}
63
64#[repr(C)]
65struct AdcCommonRegisters {
66 csr: ReadOnly<u32, CSR::Register>,
67 _reserved0: [u32; 1],
68
69 ccr: ReadWrite<u32, CCR::Register>,
70 cdr: ReadOnly<u32, CDR::Register>,
71}
72
73register_bitfields![u32,
74 ISR [
76 JQOVF OFFSET(10) NUMBITS(1) [],
78 AWD3 OFFSET(9) NUMBITS(1) [],
80 AWD2 OFFSET(8) NUMBITS(1) [],
82 AWD1 OFFSET(7) NUMBITS(1) [],
84 JEOS OFFSET(6) NUMBITS(1) [],
86 JEOC OFFSET(5) NUMBITS(1) [],
88 OVR OFFSET(4) NUMBITS(1) [],
90 EOS OFFSET(3) NUMBITS(1) [],
92 EOC OFFSET(2) NUMBITS(1) [],
94 EOSMP OFFSET(1) NUMBITS(1) [],
96 ADRDY OFFSET(0) NUMBITS(1) []
98 ],
99 IER [
101 JQOVFIE OFFSET(10) NUMBITS(1) [],
103 AWD3IE OFFSET(9) NUMBITS(1) [],
105 AWD2IE OFFSET(8) NUMBITS(1) [],
107 AWD1IE OFFSET(7) NUMBITS(1) [],
109 JEOSIE OFFSET(6) NUMBITS(1) [],
111 JEOCIE OFFSET(5) NUMBITS(1) [],
113 OVRIE OFFSET(4) NUMBITS(1) [],
115 EOSIE OFFSET(3) NUMBITS(1) [],
117 EOCIE OFFSET(2) NUMBITS(1) [],
119 EOSMPIE OFFSET(1) NUMBITS(1) [],
121 ADRDYIE OFFSET(0) NUMBITS(1) []
123 ],
124 CR [
126 ADCAL OFFSET(31) NUMBITS(1) [],
128 ADCALDIF OFFSET(30) NUMBITS(1) [],
130 ADVREGEN OFFSET(28) NUMBITS(2) [],
132 JADSTP OFFSET(5) NUMBITS(1) [],
134 ADSTP OFFSET(4) NUMBITS(1) [],
136 JADSTART OFFSET(3) NUMBITS(1) [],
138 ADSTART OFFSET(2) NUMBITS(1) [],
140 ADDIS OFFSET(1) NUMBITS(1) [],
142 ADEN OFFSET(0) NUMBITS(1) []
144 ],
145 CFGR [
147 AWD1CH OFFSET(26) NUMBITS(5) [],
149 JAUTO OFFSET(25) NUMBITS(1) [],
151 JAWD1EN OFFSET(24) NUMBITS(1) [],
153 AWD1EN OFFSET(23) NUMBITS(1) [],
155 AWD1SGL OFFSET(22) NUMBITS(1) [],
157 JQM OFFSET(21) NUMBITS(1) [],
159 JDISCEN OFFSET(20) NUMBITS(1) [],
161 DISCNUM OFFSET(17) NUMBITS(3) [],
163 DISCEN OFFSET(16) NUMBITS(1) [],
165 AUTDLY OFFSET(14) NUMBITS(1) [],
167 CONT OFFSET(13) NUMBITS(1) [],
169 OVRMOD OFFSET(12) NUMBITS(1) [],
171 EXTEN OFFSET(10) NUMBITS(2) [],
173 EXTSEL OFFSET(6) NUMBITS(4) [],
175 ALIGN OFFSET(5) NUMBITS(1) [],
177 RES OFFSET(3) NUMBITS(2) [],
179 DMACFG OFFSET(1) NUMBITS(1) [],
181 DMAEN OFFSET(0) NUMBITS(1) []
183 ],
184 SMPR1 [
186 SMP9 OFFSET(27) NUMBITS(3) [],
188 SMP8 OFFSET(24) NUMBITS(3) [],
189 SMP7 OFFSET(21) NUMBITS(3) [],
190 SMP6 OFFSET(18) NUMBITS(3) [],
191 SMP5 OFFSET(15) NUMBITS(3) [],
192 SMP4 OFFSET(12) NUMBITS(3) [],
193 SMP3 OFFSET(9) NUMBITS(3) [],
194 SMP2 OFFSET(6) NUMBITS(3) [],
195 SMP1 OFFSET(3) NUMBITS(3) []
196 ],
197 SMPR2 [
199 SMP18 OFFSET(24) NUMBITS(3) [],
201 SMP17 OFFSET(21) NUMBITS(3) [],
202 SMP16 OFFSET(18) NUMBITS(3) [],
203 SMP15 OFFSET(15) NUMBITS(3) [],
204 SMP14 OFFSET(12) NUMBITS(3) [],
205 SMP13 OFFSET(9) NUMBITS(3) [],
206 SMP12 OFFSET(6) NUMBITS(3) [],
207 SMP11 OFFSET(3) NUMBITS(3) [],
208 SMP10 OFFSET(0) NUMBITS(3) []
209 ],
210 TR1 [
212 HT1 OFFSET(16) NUMBITS(12) [],
214 LT1 OFFSET(0) NUMBITS(12) []
216 ],
217 TR2 [
219 HT2 OFFSET(16) NUMBITS(8) [],
221 LT2 OFFSET(0) NUMBITS(8) []
223 ],
224 TR3 [
226 HT3 OFFSET(16) NUMBITS(8) [],
228 LT3 OFFSET(0) NUMBITS(8) []
230 ],
231 SQR1 [
233 SQ4 OFFSET(24) NUMBITS(5) [],
235 SQ3 OFFSET(18) NUMBITS(5) [],
237 SQ2 OFFSET(12) NUMBITS(5) [],
239 SQ1 OFFSET(6) NUMBITS(5) [],
241 L OFFSET(0) NUMBITS(4) []
243 ],
244 SQR2 [
246 SQ9 OFFSET(24) NUMBITS(5) [],
247 SQ8 OFFSET(18) NUMBITS(5) [],
249 SQ7 OFFSET(12) NUMBITS(5) [],
251 SQ6 OFFSET(6) NUMBITS(5) [],
253 SQ5 OFFSET(0) NUMBITS(5) []
255 ],
256 SQR3 [
258 SQ14 OFFSET(24) NUMBITS(5) [],
260 SQ13 OFFSET(18) NUMBITS(5) [],
262 SQ12 OFFSET(12) NUMBITS(5) [],
264 SQ11 OFFSET(6) NUMBITS(5) [],
266 SQ10 OFFSET(0) NUMBITS(5) []
268 ],
269 SQR4 [
271 SQ16 OFFSET(6) NUMBITS(5) [],
273 SQ15 OFFSET(0) NUMBITS(5) []
275 ],
276 DR [
278 RDATA OFFSET(0) NUMBITS(16) []
280 ],
281 JSQR [
283 JSQ4 OFFSET(26) NUMBITS(5) [],
285 JSQ3 OFFSET(20) NUMBITS(5) [],
287 JSQ2 OFFSET(14) NUMBITS(5) [],
289 JSQ1 OFFSET(8) NUMBITS(5) [],
291 JEXTEN OFFSET(6) NUMBITS(2) [],
293 JEXTSEL OFFSET(2) NUMBITS(4) [],
295 JL OFFSET(0) NUMBITS(2) []
297 ],
298 OFR [
300 OFFSET_EN OFFSET(31) NUMBITS(1) [],
302 OFFSET_CH OFFSET(26) NUMBITS(5) [],
304 OFFSETy OFFSET(0) NUMBITS(12) []
306 ],
307 JDR [
309 JDATA OFFSET(0) NUMBITS(16) []
311 ],
312 AWD2CR [
314 AWD2CH OFFSET(1) NUMBITS(18) []
316 ],
317 AWD3CR [
319 AWD3CH OFFSET(1) NUMBITS(18) []
321 ],
322 DIFSEL [
324 DIFSEL OFFSET(1) NUMBITS(18) []
327 ],
328 CALFACT [
330 CALFACT_D OFFSET(16) NUMBITS(7) [],
332 CALFACT_S OFFSET(0) NUMBITS(7) []
334 ],
335 CSR [
337 JQOVF_SLV OFFSET(26) NUMBITS(1) [],
339 AWD3_SLV OFFSET(25) NUMBITS(1) [],
341 AWD2_SLV OFFSET(24) NUMBITS(1) [],
343 AWD1_SLV OFFSET(23) NUMBITS(1) [],
345 JEOS_SLV OFFSET(22) NUMBITS(1) [],
347 JEOC_SLV OFFSET(21) NUMBITS(1) [],
349 OVR_SLV OFFSET(20) NUMBITS(1) [],
351 EOS_SLV OFFSET(19) NUMBITS(1) [],
353 EOC_SLV OFFSET(18) NUMBITS(1) [],
355 EOSMP_SLV OFFSET(17) NUMBITS(1) [],
357 ADRDY_SLV OFFSET(16) NUMBITS(1) [],
359 JQOVF_MST OFFSET(10) NUMBITS(1) [],
361 AWD3_MST OFFSET(9) NUMBITS(1) [],
363 AWD2_MST OFFSET(8) NUMBITS(1) [],
365 AWD1_MST OFFSET(7) NUMBITS(1) [],
367 JEOS_MST OFFSET(6) NUMBITS(1) [],
369 JEOC_MST OFFSET(5) NUMBITS(1) [],
371 OVR_MST OFFSET(4) NUMBITS(1) [],
373 EOS_MST OFFSET(3) NUMBITS(1) [],
375 EOC_MST OFFSET(2) NUMBITS(1) [],
377 EOSMP_MST OFFSET(1) NUMBITS(1) [],
379 ADRDY_MST OFFSET(0) NUMBITS(1) []
381 ],
382 CCR [
384 VBATEN OFFSET(24) NUMBITS(1) [],
386 TSEN OFFSET(23) NUMBITS(1) [],
388 VREFEN OFFSET(22) NUMBITS(1) [],
390 CKMODE OFFSET(16) NUMBITS(2) [],
392 MDMA OFFSET(14) NUMBITS(2) [],
394 DMACFG OFFSET(13) NUMBITS(1) [],
396 DELAY OFFSET(8) NUMBITS(4) [],
398 DUAL OFFSET(0) NUMBITS(5) []
400 ],
401 CDR [
403 RDATA_SLV OFFSET(16) NUMBITS(16) [],
405 RDATA_MST OFFSET(0) NUMBITS(16) []
407 ]
408];
409
410const ADC1_BASE: StaticRef<AdcRegisters> =
411 unsafe { StaticRef::new(0x5000_0000 as *const AdcRegisters) };
412
413const ADC12_COMMON_BASE: StaticRef<AdcCommonRegisters> =
414 unsafe { StaticRef::new(0x5000_0300 as *const AdcCommonRegisters) };
415
416#[allow(dead_code)]
417#[repr(u32)]
418#[derive(Copy, Clone, PartialEq)]
419pub enum Channel {
420 Channel0 = 0b00000,
421 Channel1 = 0b00001,
422 Channel2 = 0b00010,
423 Channel3 = 0b00011,
424 Channel4 = 0b00100,
425 Channel5 = 0b00101,
426 Channel6 = 0b00110,
427 Channel7 = 0b00111,
428 Channel8 = 0b01000,
429 Channel9 = 0b01001,
430 Channel10 = 0b01010,
431 Channel11 = 0b01011,
432 Channel12 = 0b01100,
433 Channel13 = 0b01101,
434 Channel14 = 0b01110,
435 Channel15 = 0b01111,
436 Channel16 = 0b10000,
437 Channel17 = 0b10001,
438 Channel18 = 0b10010,
439}
440
441#[allow(dead_code)]
442#[repr(u32)]
443enum DiscontinuousMode {
444 OneChannels = 0b000,
445 TwoChannels = 0b001,
446 ThreeChannels = 0b010,
447 FourChannels = 0b011,
448 FiveChannels = 0b100,
449 SixChannels = 0b101,
450 SevenChannels = 0b110,
451 EightChannels = 0b111,
452}
453
454#[allow(dead_code)]
455#[repr(u32)]
456enum ExternalTriggerDetection {
457 Disabled = 0b00,
458 RisingEdge = 0b01,
459 FallingEdge = 0b10,
460 RisingAndFalling = 0b11,
461}
462
463#[allow(dead_code)]
464#[repr(u32)]
465enum ExternalTriggerSelection {
466 Event0 = 0b0000,
467 Event1 = 0b0001,
468 Event2 = 0b0010,
469 Event3 = 0b0011,
470 Event4 = 0b0100,
471 Event5 = 0b0101,
472 Event6 = 0b0110,
473 Event7 = 0b0111,
474 Event8 = 0b1000,
475 Event9 = 0b1001,
476 Event10 = 0b1010,
477 Event11 = 0b1011,
478 Event12 = 0b1100,
479 Event13 = 0b1101,
480 Event14 = 0b1110,
481 Event15 = 0b1111,
482}
483
484#[allow(dead_code)]
485#[repr(u32)]
486enum DataResolution {
487 Bit12 = 0b00,
488 Bit10 = 0b01,
489 Bit8 = 0b10,
490 Bit6 = 0b11,
491}
492
493#[derive(Copy, Clone, PartialEq)]
494enum ADCStatus {
495 Idle,
496 Off,
497 PoweringOn,
498 OneSample,
499 Continuous,
500}
501
502pub struct Adc<'a> {
503 registers: StaticRef<AdcRegisters>,
504 common_registers: StaticRef<AdcCommonRegisters>,
505 clock: AdcClock<'a>,
506 status: Cell<ADCStatus>,
507 client: OptionalCell<&'a dyn hil::adc::Client>,
508 requested: Cell<ADCStatus>,
509 requested_channel: Cell<u32>,
510 sc_enabled: Cell<bool>,
511}
512
513impl<'a> Adc<'a> {
514 pub const fn new(rcc: &'a rcc::Rcc) -> Self {
515 Self {
516 registers: ADC1_BASE,
517 common_registers: ADC12_COMMON_BASE,
518 clock: AdcClock(rcc::PeripheralClock::new(
519 rcc::PeripheralClockType::AHB(rcc::HCLK::ADC1),
520 rcc,
521 )),
522 status: Cell::new(ADCStatus::Off),
523 client: OptionalCell::empty(),
524 requested: Cell::new(ADCStatus::Idle),
525 requested_channel: Cell::new(0),
526 sc_enabled: Cell::new(false),
527 }
528 }
529
530 pub fn enable_temperature(&self) {
531 self.common_registers.ccr.modify(CCR::TSEN::SET);
532 }
533
534 pub fn enable(&self) {
535 self.status.set(ADCStatus::PoweringOn);
536
537 self.enable_clock();
539
540 self.common_registers.ccr.modify(CCR::CKMODE.val(0b01));
542
543 self.registers.cr.modify(CR::ADVREGEN.val(0b00));
544 self.registers.cr.modify(CR::ADVREGEN.val(0b01));
545
546 for _i in 0..720 {
551 cortexm4f::support::nop()
552 }
553
554 self.registers.ier.modify(IER::ADRDYIE::SET);
556
557 self.registers.isr.modify(ISR::ADRDY::CLEAR);
559 self.registers.cr.modify(CR::ADEN::CLEAR);
560 self.registers.cr.modify(CR::ADCALDIF::CLEAR);
561 self.registers.cr.modify(CR::ADCAL::SET);
562
563 while self.registers.cr.is_set(CR::ADCAL) {}
565
566 self.registers.cr.modify(CR::ADEN::SET);
568 self.registers.cfgr.modify(CFGR::OVRMOD::SET);
570 }
571
572 pub fn handle_interrupt(&self) {
573 if self.registers.isr.is_set(ISR::ADRDY) {
575 self.registers.ier.modify(IER::ADRDYIE::CLEAR);
577 if self.status.get() == ADCStatus::PoweringOn {
579 self.status.set(ADCStatus::Idle);
580 match self.requested.get() {
581 ADCStatus::OneSample => {
582 let _ = self.sample_u32(self.requested_channel.get());
583 return;
584 }
585 _ => {}
586 }
587 }
588 }
589 if self.registers.isr.is_set(ISR::EOC) {
591 self.registers.ier.modify(IER::EOCIE::CLEAR);
593 let data = self.registers.dr.read(DR::RDATA);
594 self.client
595 .map(|client| client.sample_ready((data as u16) << 4));
596 if self.status.get() == ADCStatus::Continuous {
597 self.registers.ier.modify(IER::EOCIE::SET);
598 }
599 }
600 if self.registers.isr.is_set(ISR::EOS) {
602 self.registers.ier.modify(IER::EOSIE::CLEAR);
604 self.registers.isr.modify(ISR::EOS::SET);
605 if self.status.get() == ADCStatus::OneSample {
606 self.registers.cr.modify(CR::ADSTP::SET);
608 self.status.set(ADCStatus::Idle);
610 }
611 }
612 if self.registers.isr.is_set(ISR::EOSMP) {
614 self.registers.ier.modify(IER::EOSMPIE::CLEAR);
616 self.registers.isr.modify(ISR::EOSMP::SET);
617 }
618 if self.registers.isr.is_set(ISR::OVR) {
620 self.registers.ier.modify(IER::OVRIE::CLEAR);
622 self.registers.isr.modify(ISR::OVR::SET);
623 }
624 }
625
626 pub fn is_enabled_clock(&self) -> bool {
627 self.clock.is_enabled()
628 }
629
630 pub fn enable_clock(&self) {
631 self.clock.enable();
632 }
633
634 pub fn disable_clock(&self) {
635 self.clock.disable();
636 }
637
638 fn enable_special_channels(&self) {
639 if self.requested_channel.get() == 16 {
641 self.sc_enabled.set(true);
642 self.enable_temperature();
643 }
644 }
645
646 fn sample_u32(&self, channel: u32) -> Result<(), ErrorCode> {
647 if !self.sc_enabled.get() {
648 self.enable_special_channels();
649 }
650 if self.status.get() == ADCStatus::Idle {
651 self.requested.set(ADCStatus::Idle);
652 self.status.set(ADCStatus::OneSample);
653 self.registers.smpr2.modify(SMPR2::SMP16.val(0b100));
654 self.registers.sqr1.modify(SQR1::L.val(0b0000));
655 self.registers.sqr1.modify(SQR1::SQ1.val(channel));
656 self.registers.ier.modify(IER::EOSIE::SET);
657 self.registers.ier.modify(IER::EOCIE::SET);
658 self.registers.ier.modify(IER::EOSMPIE::SET);
659 self.registers.cr.modify(CR::ADSTART::SET);
660 Ok(())
661 } else {
662 Err(ErrorCode::BUSY)
663 }
664 }
665}
666
667struct AdcClock<'a>(rcc::PeripheralClock<'a>);
668
669impl ClockInterface for AdcClock<'_> {
670 fn is_enabled(&self) -> bool {
671 self.0.is_enabled()
672 }
673
674 fn enable(&self) {
675 self.0.enable();
676 }
677
678 fn disable(&self) {
679 self.0.disable();
680 }
681}
682
683impl<'a> hil::adc::Adc<'a> for Adc<'a> {
684 type Channel = Channel;
685
686 fn sample(&self, channel: &Self::Channel) -> Result<(), ErrorCode> {
687 if self.status.get() == ADCStatus::Off {
688 self.requested.set(ADCStatus::OneSample);
689 self.requested_channel.set(*channel as u32);
690 self.enable();
691 Ok(())
692 } else {
693 self.sample_u32(*channel as u32)
694 }
695 }
696
697 fn sample_continuous(
698 &self,
699 _channel: &Self::Channel,
700 _frequency: u32,
701 ) -> Result<(), ErrorCode> {
702 Err(ErrorCode::NOSUPPORT)
704 }
705
706 fn stop_sampling(&self) -> Result<(), ErrorCode> {
707 if self.status.get() != ADCStatus::Idle && self.status.get() != ADCStatus::Off {
708 self.registers.cr.modify(CR::ADSTP::SET);
709 if self.registers.cfgr.is_set(CFGR::CONT) {
710 self.registers.cfgr.modify(CFGR::CONT::CLEAR);
711 }
712 Ok(())
713 } else {
714 Err(ErrorCode::BUSY)
715 }
716 }
717
718 fn get_resolution_bits(&self) -> usize {
719 12
720 }
721
722 fn get_voltage_reference_mv(&self) -> Option<usize> {
723 Some(3300)
724 }
725
726 fn set_client(&self, client: &'a dyn hil::adc::Client) {
727 self.client.set(client);
728 }
729}
730
731impl<'a> hil::adc::AdcHighSpeed<'a> for Adc<'a> {
733 fn sample_highspeed(
747 &self,
748 _channel: &Self::Channel,
749 _frequency: u32,
750 buffer1: &'static mut [u16],
751 _length1: usize,
752 buffer2: &'static mut [u16],
753 _length2: usize,
754 ) -> Result<(), (ErrorCode, &'static mut [u16], &'static mut [u16])> {
755 Err((ErrorCode::NOSUPPORT, buffer1, buffer2))
756 }
757
758 fn provide_buffer(
764 &self,
765 buf: &'static mut [u16],
766 _length: usize,
767 ) -> Result<(), (ErrorCode, &'static mut [u16])> {
768 Err((ErrorCode::NOSUPPORT, buf))
769 }
770
771 fn retrieve_buffers(
774 &self,
775 ) -> Result<(Option<&'static mut [u16]>, Option<&'static mut [u16]>), ErrorCode> {
776 Err(ErrorCode::NOSUPPORT)
777 }
778
779 fn set_highspeed_client(&self, _client: &'a dyn hil::adc::HighSpeedClient) {}
780}