#![macro_use]
#![allow(missing_docs)] mod v1;
#[allow(unused)]
pub use v1::*;
use core::marker::PhantomData;
use embassy_sync::waitqueue::AtomicWaker;
pub use crate::pac::adc::vals;
pub use crate::pac::adc::vals::Res as Resolution;
pub use crate::pac::adc::vals::SampleTime;
use crate::peripherals;
dma_trait!(RxDma, Instance);
pub struct Adc<'d, T: Instance> {
#[allow(unused)]
adc: crate::PeripheralRef<'d, T>,
sample_time: SampleTime,
}
pub struct State {
pub waker: AtomicWaker,
}
impl State {
pub const fn new() -> Self {
Self {
waker: AtomicWaker::new(),
}
}
}
trait SealedInstance {
#[allow(unused)]
fn regs() -> crate::pac::adc::Adc;
fn state() -> &'static State;
}
pub(crate) trait SealedAdcChannel<T> {
fn setup(&mut self) {}
#[allow(unused)]
fn channel(&self) -> u8;
}
#[allow(unused)]
pub(crate) fn blocking_delay_us(us: u32) {
#[cfg(feature = "time")]
embassy_time::block_for(embassy_time::Duration::from_micros(us as u64));
#[cfg(not(feature = "time"))]
{
let freq = unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 as u64;
let us = us as u64;
let cycles = freq * us / 1_000_000;
cortex_m::asm::delay(cycles as u32);
}
}
#[allow(private_bounds)]
pub trait Instance: SealedInstance + crate::Peripheral<P = Self> + crate::rcc::RccPeripheral {
type Interrupt: crate::interrupt::typelevel::Interrupt;
}
#[allow(private_bounds)]
pub trait AdcChannel<T>: SealedAdcChannel<T> + Sized {
#[allow(unused_mut)]
fn degrade_adc(mut self) -> AnyAdcChannel<T> {
self.setup();
AnyAdcChannel {
channel: self.channel(),
_phantom: PhantomData,
}
}
}
pub struct AnyAdcChannel<T> {
channel: u8,
_phantom: PhantomData<T>,
}
impl<T: Instance> AdcChannel<T> for AnyAdcChannel<T> {}
impl<T: Instance> SealedAdcChannel<T> for AnyAdcChannel<T> {
fn channel(&self) -> u8 {
self.channel
}
}
foreach_adc!(
($inst:ident, $common_inst:ident, $clock:ident) => {
impl crate::adc::SealedInstance for peripherals::$inst {
fn regs() -> crate::pac::adc::Adc {
crate::pac::$inst
}
fn state() -> &'static State {
static STATE: State = State::new();
&STATE
}
}
impl crate::adc::Instance for peripherals::$inst {
type Interrupt = crate::_generated::peripheral_interrupts::$inst::GLOBAL;
}
};
);
macro_rules! impl_adc_pin {
($inst:ident, $pin:ident, $ch:expr) => {
impl crate::adc::AdcChannel<peripherals::$inst> for crate::peripherals::$pin {}
impl crate::adc::SealedAdcChannel<peripherals::$inst> for crate::peripherals::$pin {
fn setup(&mut self) {
<Self as crate::gpio::SealedPin>::set_as_analog(self);
}
fn channel(&self) -> u8 {
$ch
}
}
};
}
pub const fn resolution_to_max_count(res: Resolution) -> u32 {
match res {
Resolution::BITS12 => (1 << 12) - 1,
Resolution::BITS10 => (1 << 10) - 1,
Resolution::BITS8 => (1 << 8) - 1,
Resolution::BITS6 => (1 << 6) - 1,
#[allow(unreachable_patterns)]
_ => core::unreachable!(),
}
}