ra-hal 0.3.0

Hardware Abstraction Layer (HAL) for the Renesas RA family of MCUs.
#![allow(missing_docs)]

use core::marker::PhantomData;

use crate::{
    gpio::{Basic, Flex, Pin},
    module_stop::ModuleStop,
};
use embassy_hal_internal::{Peri, PeripheralType};

#[allow(private_bounds)]
pub trait Instance: SealedInstance + ModuleStop + PeripheralType + 'static + Send {}

pub(crate) trait SealedInstance {}

#[derive(Copy, Clone)]
pub enum LcdPinKind {
    Common,
    Segment,
}

pub struct LcdPin<'d, I: Instance> {
    kind: LcdPinKind,
    pin: Flex<'d, Basic>,
    phantom: PhantomData<I>,
}

impl<'d, I: Instance> LcdPin<'d, I> {
    pub fn new_seg<const C: usize>(pin: Peri<'d, impl SegPin<I, C>>) -> Self {
        pin.set_as_seg();

        Self {
            kind: LcdPinKind::Segment,
            pin: Flex::new(pin),
            phantom: PhantomData,
        }
    }

    pub fn new_common<const C: usize>(pin: Peri<'d, impl CommonPin<I, C>>) -> Self {
        pin.set_as_common();

        Self {
            kind: LcdPinKind::Common,
            pin: Flex::new(pin),
            phantom: PhantomData,
        }
    }
}

#[allow(private_bounds)]
pub trait SegPin<I: Instance, const C: usize>: SealedSegPin<I> {
    #[inline(always)]
    fn set_as_seg(&self) {
        trace!("P{}{:02}: SegPin::new", self.port(), self.pin());
        self.set_as_pf(Self::PERIPHERAL_FUNC);
    }
}

pub(crate) trait SealedSegPin<I: SealedInstance>: Pin + PeripheralType {
    const PERIPHERAL_FUNC: crate::gpio::PortFunction;
}

macro_rules! seg_pin {
    ($slcdc:ident, $channel:literal, $pin:ident, $pfunc:ident) => {
        impl crate::slcdc::SegPin<crate::peripherals::$slcdc, $channel>
            for crate::peripherals::$pin
        {
        }

        impl crate::slcdc::SealedSegPin<crate::peripherals::$slcdc> for crate::peripherals::$pin {
            const PERIPHERAL_FUNC: crate::gpio::PortFunction = crate::gpio::PortFunction::$pfunc;
        }
    };
}
pub(crate) use seg_pin;

/// Segment LCD power supply pin.
#[allow(private_bounds)]
pub trait VlPin<I: Instance, const C: usize>: SealedVlPin<I> {
    #[inline(always)]
    fn set_as_vl(&self) {
        trace!("P{}{:02}: VlPin::new", self.port(), self.pin());
        self.set_as_pf(Self::PERIPHERAL_FUNC);
    }
}

pub(crate) trait SealedVlPin<I: SealedInstance>: Pin + PeripheralType {
    const PERIPHERAL_FUNC: crate::gpio::PortFunction;
}

macro_rules! vl_pin {
    ($slcdc:ident, $channel:literal, $pin:ident, $pfunc:ident) => {
        impl crate::slcdc::VlPin<crate::peripherals::$slcdc, $channel>
            for crate::peripherals::$pin
        {
        }
        impl crate::slcdc::SealedVlPin<crate::peripherals::$slcdc> for crate::peripherals::$pin {
            const PERIPHERAL_FUNC: crate::gpio::PortFunction = crate::gpio::PortFunction::$pfunc;
        }
    };
}
pub(crate) use vl_pin;

#[allow(private_bounds)]
pub trait CommonPin<I: Instance, const C: usize>: SealedCommonPin<I> {
    #[inline(always)]
    fn set_as_common(&self) {
        trace!("P{}{:02}: CommonPin::new", self.port(), self.pin());
        self.set_as_pf(Self::PERIPHERAL_FUNC);
    }
}

pub(crate) trait SealedCommonPin<I: SealedInstance>: Pin + PeripheralType {
    const PERIPHERAL_FUNC: crate::gpio::PortFunction;
}

macro_rules! com_pin {
    ($slcdc:ident, $channel:literal, $pin:ident, $pfunc:ident) => {
        impl crate::slcdc::CommonPin<crate::peripherals::$slcdc, $channel>
            for crate::peripherals::$pin
        {
        }
        impl crate::slcdc::SealedCommonPin<crate::peripherals::$slcdc>
            for crate::peripherals::$pin
        {
            const PERIPHERAL_FUNC: crate::gpio::PortFunction = crate::gpio::PortFunction::$pfunc;
        }
    };
}
pub(crate) use com_pin;

#[allow(private_bounds)]
pub trait CapHPin<I: Instance>: SealedCapHPin<I> {
    #[inline(always)]
    fn set_as_caph(&self) {
        trace!("P{}{:02}: CapHPin::new", self.port(), self.pin());
        self.set_as_pf(Self::PERIPHERAL_FUNC);
    }
}

pub(crate) trait SealedCapHPin<I: SealedInstance>: Pin + PeripheralType {
    const PERIPHERAL_FUNC: crate::gpio::PortFunction;
}

macro_rules! caph_pin {
    ($slcdc:ident, $pin:ident, $pfunc:ident) => {
        impl crate::slcdc::CapHPin<crate::peripherals::$slcdc> for crate::peripherals::$pin {}
        impl crate::slcdc::SealedCapHPin<crate::peripherals::$slcdc> for crate::peripherals::$pin {
            const PERIPHERAL_FUNC: crate::gpio::PortFunction = crate::gpio::PortFunction::$pfunc;
        }
    };
}
pub(crate) use caph_pin;

#[allow(private_bounds)]
pub trait CapLPin<I: Instance>: SealedCapLPin<I> {
    #[inline(always)]
    fn set_as_capl(&self) {
        trace!("P{}{:02}: CapLPin::new", self.port(), self.pin());
        self.set_as_pf(Self::PERIPHERAL_FUNC);
    }
}

pub(crate) trait SealedCapLPin<I: SealedInstance>: Pin + PeripheralType {
    const PERIPHERAL_FUNC: crate::gpio::PortFunction;
}

macro_rules! capl_pin {
    ($slcdc:ident, $pin:ident, $pfunc:ident) => {
        impl crate::slcdc::CapLPin<crate::peripherals::$slcdc> for crate::peripherals::$pin {}
        impl crate::slcdc::SealedCapLPin<crate::peripherals::$slcdc> for crate::peripherals::$pin {
            const PERIPHERAL_FUNC: crate::gpio::PortFunction = crate::gpio::PortFunction::$pfunc;
        }
    };
}
pub(crate) use capl_pin;

impl Instance for crate::peripherals::SLCDC {}
impl SealedInstance for crate::peripherals::SLCDC {}