|
12 | 12 | use cortex_m::asm;
|
13 | 13 | use embedded_hal::adc::{Channel, OneShot};
|
14 | 14 |
|
15 |
| -use crate::{ |
16 |
| - gpio::{self, Analog}, |
17 |
| - pac::{ |
18 |
| - adc1::{cfgr::ALIGN_A, smpr1::SMP9_A, smpr2::SMP18_A}, |
19 |
| - adc1_2::ccr::CKMODE_A, |
20 |
| - ADC1, ADC1_2, ADC2, |
21 |
| - }, |
22 |
| - rcc::{Clocks, AHB}, |
| 15 | +use crate::gpio::{self, Analog}; |
| 16 | +use crate::pac::{ |
| 17 | + adc1::{cfgr::ALIGN_A, smpr1::SMP9_A, smpr2::SMP18_A}, |
| 18 | + adc1_2::ccr::CKMODE_A, |
| 19 | + ADC1, ADC1_2, ADC2, ADC3_4, |
23 | 20 | };
|
| 21 | +use crate::pac::{adc1, adc1_2}; |
| 22 | +use crate::rcc::{Clocks, AHB}; |
24 | 23 |
|
25 | 24 | #[cfg(any(
|
26 | 25 | feature = "stm32f303xb",
|
@@ -108,6 +107,8 @@ impl From<SampleTime> for SMP18_A {
|
108 | 107 | }
|
109 | 108 | }
|
110 | 109 |
|
| 110 | +impl |
| 111 | + |
111 | 112 | /// ADC operation mode
|
112 | 113 | // TODO: Implement other modes (DMA, Differential,…)
|
113 | 114 | // TODO(Sh3Rm4n): Maybe make operation modes to type states to better
|
@@ -313,32 +314,34 @@ macro_rules! adc_hal {
|
313 | 314 | ///
|
314 | 315 | pub fn $adcx(
|
315 | 316 | adc: $ADC,
|
| 317 | + frequency: impl Into<Generic<u32>>, |
316 | 318 | adc_common : &mut $ADC_COMMON,
|
317 | 319 | ahb: &mut AHB,
|
318 |
| - clock_mode: ClockMode, |
319 | 320 | clocks: Clocks,
|
320 | 321 | ) -> Self {
|
321 |
| - let mut this_adc = Self { |
| 322 | + let mut adc = Self { |
322 | 323 | adc,
|
323 | 324 | clocks,
|
324 |
| - clock_mode, |
325 |
| - operation_mode: None, |
326 | 325 | };
|
327 |
| - if !(this_adc.clocks_welldefined(clocks)) { |
| 326 | + if !(adc.clocks_welldefined(clocks)) { |
328 | 327 | crate::panic!("Clock settings not well defined");
|
329 | 328 | }
|
330 |
| - if !(this_adc.enable_clock(ahb, adc_common)){ |
| 329 | + if !(adc.enable_clock(ahb, adc_common)){ |
331 | 330 | crate::panic!("Clock already enabled with a different setting");
|
332 | 331 | }
|
333 |
| - this_adc.set_align(Align::default()); |
334 |
| - this_adc.calibrate(); |
| 332 | + |
| 333 | + common.ccr.modify(|_, w| w |
| 334 | + .ckmode().variant(self.clock_mode.into()) |
| 335 | + ); |
| 336 | + adc.set_align(Align::default()); |
| 337 | + adc.calibrate(); |
335 | 338 | // ADEN bit cannot be set during ADCAL=1
|
336 | 339 | // and 4 ADC clock cycle after the ADCAL
|
337 | 340 | // bit is cleared by hardware
|
338 |
| - this_adc.wait_adc_clk_cycles(4); |
339 |
| - this_adc.enable(); |
| 341 | + adc.wait_adc_clk_cycles(4); |
| 342 | + adc.enable(); |
340 | 343 |
|
341 |
| - this_adc |
| 344 | + adc |
342 | 345 | }
|
343 | 346 |
|
344 | 347 | /// Releases the ADC peripheral and associated pins
|
@@ -422,10 +425,10 @@ macro_rules! adc_hal {
|
422 | 425 | }
|
423 | 426 |
|
424 | 427 | /// Calibrate according to RM0316 15.3.8
|
425 |
| - fn calibrate(&mut self) { |
| 428 | + fn calibrate(&mut self, clocks: Clocks) { |
426 | 429 | if !self.adc.cr.read().advregen().is_enabled() {
|
427 | 430 | self.advregen_enable();
|
428 |
| - self.wait_advregen_startup(); |
| 431 | + self.wait_advregen_startup(clocks); |
429 | 432 | }
|
430 | 433 |
|
431 | 434 | self.disable();
|
@@ -458,8 +461,8 @@ macro_rules! adc_hal {
|
458 | 461 | /// wait for the advregen to startup.
|
459 | 462 | ///
|
460 | 463 | /// This is based on the MAX_ADVREGEN_STARTUP_US of the device.
|
461 |
| - fn wait_advregen_startup(&self) { |
462 |
| - asm::delay((MAX_ADVREGEN_STARTUP_US * 1_000_000) / self.clocks.sysclk().0); |
| 464 | + fn wait_advregen_startup(&self, clocks: Clocks) { |
| 465 | + asm::delay((MAX_ADVREGEN_STARTUP_US * 1_000_000) / clocks.sysclk().0); |
463 | 466 | }
|
464 | 467 |
|
465 | 468 | /// busy ADC read
|
@@ -542,6 +545,43 @@ macro_rules! adc_hal {
|
542 | 545 | }
|
543 | 546 | }
|
544 | 547 |
|
| 548 | +/// ADC Instance |
| 549 | +pub trait Instance: |
| 550 | + Deref<Target = adc1::RegisterBlock> + crate::private::Sealed |
| 551 | +{ |
| 552 | + /// Shared Instance / Registerblock between multiple ADCs |
| 553 | + type SharedInstance; |
| 554 | + #[doc(hidden)] |
| 555 | + fn enable_clock(ahb: &mut AHB, common: &mut Self::SharedInstance); |
| 556 | + #[doc(hidden)] |
| 557 | + fn clock(clocks: &Clocks) -> Hertz; |
| 558 | +} |
| 559 | + |
| 560 | +/// Shared ADC Register Block |
| 561 | +pub trait SharedInstance: |
| 562 | + Deref<Target = adc1_2::RegisterBlock> + crate::private::Sealed |
| 563 | +{ |
| 564 | +} |
| 565 | + |
| 566 | + |
| 567 | + |
| 568 | +// Macro to implement ADC functionallity for ADC1 and ADC2 |
| 569 | +// TODO: Extend/differentiate beyond f303. |
| 570 | +impl Instance for ADC1 { |
| 571 | + type SharedInstance = ADC1_2; |
| 572 | + fn enable_clock(&self, ahb: &mut AHB, common: &mut Self::SharedInstance) { |
| 573 | + ahb.enr().modify(|_, w| w.adc12en().enabled()); |
| 574 | + // TODO: Check how to handle adc commeon |
| 575 | + adc_common.ccr.modify(|_, w| w |
| 576 | + .ckmode().variant(self.clock_mode.into()) |
| 577 | + ); |
| 578 | + } |
| 579 | + |
| 580 | + fn clock(clocks: &Clocks) -> Hertz { |
| 581 | + |
| 582 | + } |
| 583 | +} |
| 584 | + |
545 | 585 | // Macro to implement ADC functionallity for ADC1 and ADC2
|
546 | 586 | // TODO: Extend/differentiate beyond f303.
|
547 | 587 | macro_rules! adc12_hal {
|
|
0 commit comments