Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32U5: Add ADC drivers #3688

Merged
merged 17 commits into from
Dec 31, 2024
Merged
Prev Previous commit
Next Next commit
WIP: add u5 adc4
  • Loading branch information
klownfish committed Sep 24, 2024
commit 3ce40f41fb25d7e473fc4a9584d6d9273ef08403
9 changes: 7 additions & 2 deletions embassy-stm32/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1188,13 +1188,12 @@ fn main() {
// ========
// Generate dma_trait_impl!

let signals: HashMap<_, _> = [
let mut signals: HashMap<_, _> = [
// (kind, signal) => trait
(("adc", "ADC"), quote!(crate::adc::RxDma)),
(("adc", "ADC1"), quote!(crate::adc::RxDma)),
(("adc", "ADC2"), quote!(crate::adc::RxDma)),
(("adc", "ADC3"), quote!(crate::adc::RxDma)),
(("adc", "ADC4"), quote!(crate::adc::RxDma)),
(("ucpd", "RX"), quote!(crate::ucpd::RxDma)),
(("ucpd", "TX"), quote!(crate::ucpd::TxDma)),
(("usart", "RX"), quote!(crate::usart::RxDma)),
Expand Down Expand Up @@ -1228,6 +1227,12 @@ fn main() {
]
.into();

if chip_name.starts_with("stm32u5") {
signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma4));
} else {
signals.insert(("adc", "ADC4"), quote!(crate::adc::RxDma));
}

for p in METADATA.peripherals {
if let Some(regs) = &p.registers {
// FIXME: stm32u5a crash on Cordic driver
Expand Down
38 changes: 38 additions & 0 deletions embassy-stm32/src/adc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ pub use _version::*;
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_l0, adc_f3_v1_1))]
use embassy_sync::waitqueue::AtomicWaker;

#[cfg(adc_u5)]
#[path = "u5_adc4.rs"]
pub mod adc4;

pub use crate::pac::adc::vals;
#[cfg(not(any(adc_f1, adc_f3_v2)))]
pub use crate::pac::adc::vals::Res as Resolution;
pub use crate::pac::adc::vals::SampleTime;
use crate::peripherals;

dma_trait!(RxDma, Instance);
#[cfg(adc_u5)]
dma_trait!(RxDma4, adc4::Instance);

/// Analog to Digital driver.
pub struct Adc<'d, T: Instance> {
Expand Down Expand Up @@ -159,6 +165,38 @@ impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> {
}
}

#[cfg(adc_u5)]
foreach_adc!(
(ADC4, $common_inst:ident, $clock:ident) => {
impl crate::adc::adc4::SealedInstance for peripherals::ADC4 {
fn regs() -> crate::pac::adc::Adc4 {
crate::pac::ADC4
}
}

impl crate::adc::adc4::Instance for peripherals::ADC4 {
type Interrupt = crate::_generated::peripheral_interrupts::ADC4::GLOBAL;
}
};

($inst:ident, $common_inst:ident, $clock:ident) => {
impl crate::adc::SealedInstance for peripherals::$inst {
fn regs() -> crate::pac::adc::Adc {
crate::pac::$inst
}

fn common_regs() -> crate::pac::adccommon::AdcCommon {
return crate::pac::$common_inst
}
}

impl crate::adc::Instance for peripherals::$inst {
type Interrupt = crate::_generated::peripheral_interrupts::$inst::GLOBAL;
}
};
);

#[cfg(not(adc_u5))]
foreach_adc!(
($inst:ident, $common_inst:ident, $clock:ident) => {
impl crate::adc::SealedInstance for peripherals::$inst {
Expand Down
16 changes: 1 addition & 15 deletions embassy-stm32/src/adc/u5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{pac, rcc, Peripheral};

const MAX_ADC_CLK_FREQ: Hertz = Hertz::mhz(55);

const VREF_CHANNEL: u8 = 1;
const VREF_CHANNEL: u8 = 0;
const VBAT_CHANNEL: u8 = 18;
const TEMP_CHANNEL: u8 = 19;

Expand Down Expand Up @@ -132,23 +132,9 @@ pub enum Averaging {
Samples1024,
}

// TODO
// impl Instance for ADC4 {

// }

impl<'d, T: Instance> Adc<'d, T> {
/// Create a new ADC driver.
pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
// move to u5 init (RCC)?
PWR.svmcr().modify(|w| {
w.set_avm1en(true);
});
while !PWR.svmsr().read().vdda1rdy() {}
PWR.svmcr().modify(|w| {
w.set_asv(true);
});

embassy_hal_internal::into_ref!(adc);
rcc::enable_and_reset::<T>();
let prescaler = Prescaler::from_ker_ck(T::frequency());
Expand Down
Loading