use crate::gpio;
use crate::pac::PPS;
pub trait PpsExt {
type Parts;
fn split(self) -> Self::Parts;
}
pub struct Parts {
pub inputs: input::Inputs,
pub outputs: output::Outputs,
}
pub trait MapPin<P, V> {
fn map_pin(self, virt_pin: V) -> MappedPin<P, V>;
}
pub struct NoPin;
impl NoPin {
#[allow(clippy::new_without_default)]
pub fn new() -> NoPin {
NoPin
}
}
#[macro_export]
macro_rules! pps_no_pin {
($VPIN:expr) => { NoPin::new().map_pin($VPIN) }
}
impl<V> MapPin<NoPin, V> for NoPin {
fn map_pin(self, virt_pin: V) -> MappedPin<NoPin, V> {
MappedPin {
phys: self,
virt: virt_pin,
}
}
}
pub trait IsConnected {
const IS_CONNECTED: bool = true;
fn is_connected(&self) -> bool {
Self::IS_CONNECTED
}
}
impl<V> IsConnected for MappedPin<NoPin, V> {
const IS_CONNECTED: bool = false;
}
pub struct MappedPin<P, V> {
phys: P,
virt: V,
}
macro_rules! pps_tables {
{ {$( $IDTYPE:ident, $IDNAME:ident );+ ;}
{$( $ODTYPE:ident, $ODNAME:ident );+ ;}
{$( $VINTYPE:ident, $INREG:ident { $( $INPTYPE:path, $INVAL:expr; )+ } )+ }
{$( $OPTYPE:path, $OREG:ident { $( $VOUTTYPE:ident, $OVAL:expr; )+ } )+ } }
=> {
pub mod input {
$(
pub struct $IDTYPE {
pub(super) _dummy: ()
}
)+
pub struct Inputs {
$(
pub $IDNAME: $IDTYPE,
)+
}
}
pub mod output {
$(
pub struct $ODTYPE {
pub(super) _dummy: (),
}
)+
pub struct Outputs {
$(
pub $ODNAME: $ODTYPE,
)+
}
}
impl PpsExt for PPS {
type Parts = Parts;
fn split(self) -> Self::Parts {
Parts {
inputs: input::Inputs {
$(
$IDNAME: input::$IDTYPE { _dummy: () },
)+
},
outputs: output::Outputs {
$(
$ODNAME: output::$ODTYPE { _dummy: () },
)+
}
}
}
}
$(
$(
impl<MODE> MapPin<$INPTYPE, input::$VINTYPE> for $INPTYPE {
fn map_pin(self, virt_pin: input::$VINTYPE) -> MappedPin<$INPTYPE, input::$VINTYPE> {
unsafe {(*PPS::ptr()).$INREG.write(|w| w.$INREG().bits($INVAL))};
MappedPin{ phys: self, virt: virt_pin }
}
}
impl<MODE> IsConnected for MappedPin<$INPTYPE, input::$VINTYPE> {}
impl<MODE> MappedPin<$INPTYPE, input::$VINTYPE> {
pub fn unmap_pin(self) -> ($INPTYPE, input::$VINTYPE) {
(self.phys, self.virt)
}
}
)+
)+
$(
$(
impl<MODE> MapPin<$OPTYPE, output::$VOUTTYPE> for $OPTYPE {
fn map_pin(self, virt_pin: output::$VOUTTYPE) -> MappedPin<$OPTYPE, output::$VOUTTYPE> {
unsafe {(*PPS::ptr()).$OREG.write(|w| w.$OREG().bits($OVAL))};
MappedPin { phys: self, virt: virt_pin}
}
}
impl <MODE> IsConnected for MappedPin<$OPTYPE, output::$VOUTTYPE> {}
impl<MODE> MappedPin<$OPTYPE, output::$VOUTTYPE> {
pub fn unmap_pin(self) -> ($OPTYPE, output::$VOUTTYPE) {
unsafe { (*PPS::ptr()).$OREG.write(|w| w.$OREG().bits(0)) };
(self.phys, self.virt)
}
}
)+
)+
}}
include!("pps_tables.rs");