use crate::pac;
pub struct Led<const ID: usize>;
impl<const ID: usize> embedded_hal::digital::v2::OutputPin for Led<ID> {
type Error = core::convert::Infallible;
fn set_low(&mut self) -> Result<(), Self::Error> {
unsafe {
let mask = 1 << ID;
let fpgaio = &*pac::FPGAIO::ptr();
fpgaio.led.modify(|r, w| w.bits(r.bits() & !mask));
}
Ok(())
}
fn set_high(&mut self) -> Result<(), Self::Error> {
unsafe {
let mask = 1 << ID;
let fpgaio = &*pac::FPGAIO::ptr();
fpgaio.led.modify(|r, w| w.bits(r.bits() | mask));
}
Ok(())
}
}
impl<const ID: usize> embedded_hal::digital::v2::StatefulOutputPin for Led<ID> {
fn is_set_high(&self) -> Result<bool, Self::Error> {
unsafe {
let mask = 1 << ID;
let fpgaio = &*pac::FPGAIO::ptr();
Ok(fpgaio.led.read().bits() & mask == mask)
}
}
fn is_set_low(&self) -> Result<bool, Self::Error> {
unsafe {
let mask = 1 << ID;
let fpgaio = &*pac::FPGAIO::ptr();
Ok(fpgaio.led.read().bits() & mask == 0)
}
}
}
impl<const ID: usize> embedded_hal::digital::v2::toggleable::Default for Led<ID> {}
pub struct Button<const _ID: usize>;
impl<const ID: usize> embedded_hal::digital::v2::InputPin for Button<ID> {
type Error = core::convert::Infallible;
fn is_high(&self) -> Result<bool, Self::Error> {
unsafe {
let mask = 1 << ID;
let fpgaio = &*pac::FPGAIO::ptr();
Ok(fpgaio.button.read().bits() & mask == mask)
}
}
fn is_low(&self) -> Result<bool, Self::Error> {
unsafe {
let mask = 1 << ID;
let fpgaio = &*pac::FPGAIO::ptr();
Ok(fpgaio.button.read().bits() & mask == 0)
}
}
}
pub struct Switch<const _ID: usize>;
impl<const ID: usize> embedded_hal::digital::v2::InputPin for Switch<ID> {
type Error = core::convert::Infallible;
fn is_high(&self) -> Result<bool, Self::Error> {
unsafe {
let mask = 1 << ID;
let fpgaio = &*pac::FPGAIO::ptr();
Ok(fpgaio.switches.read().bits() & mask == mask)
}
}
fn is_low(&self) -> Result<bool, Self::Error> {
unsafe {
let mask = 1 << ID;
let fpgaio = &*pac::FPGAIO::ptr();
Ok(fpgaio.switches.read().bits() & mask == 0)
}
}
}
pub struct Clocks;
impl Clocks {
pub fn clk1hz(&self) -> u32 {
unsafe {
let fpgaio = &*pac::FPGAIO::ptr();
fpgaio.clk1hz.read().bits()
}
}
pub fn clk100hz(&self) -> u32 {
unsafe {
let fpgaio = &*pac::FPGAIO::ptr();
fpgaio.clk100hz.read().bits()
}
}
pub fn counter(&mut self) -> &pac::fpgaio::COUNTER {
unsafe {
let fpgaio = &*pac::FPGAIO::ptr();
&fpgaio.counter
}
}
pub fn prescaler(&mut self) -> &pac::fpgaio::PRESCALER {
unsafe {
let fpgaio = &*pac::FPGAIO::ptr();
&fpgaio.prescaler
}
}
pub fn pscntr(&mut self) -> &pac::fpgaio::PSCNTR {
unsafe {
let fpgaio = &*pac::FPGAIO::ptr();
&fpgaio.pscntr
}
}
}
pub struct Parts {
pub ul0: Led<0>,
pub ul1: Led<1>,
pub ul2: Led<2>,
pub ul3: Led<3>,
pub ul4: Led<4>,
pub ul5: Led<5>,
pub ul6: Led<6>,
pub ul7: Led<7>,
pub pb1led: Led<8>,
pub pb2led: Led<9>,
pub button0: Button<0>,
pub button1: Button<1>,
pub switch0: Switch<0>,
pub switch1: Switch<1>,
pub switch2: Switch<2>,
pub switch3: Switch<3>,
pub switch4: Switch<4>,
pub switch5: Switch<5>,
pub switch6: Switch<6>,
pub switch7: Switch<7>,
pub clocks: Clocks,
}
pub trait FPGAIOExt {
fn split(self) -> Parts;
}
macro_rules! impl_ext {
($p:path) => {
impl FPGAIOExt for $p {
fn split(self) -> Parts {
Parts {
ul0: Led,
ul1: Led,
ul2: Led,
ul3: Led,
ul4: Led,
ul5: Led,
ul6: Led,
ul7: Led,
pb1led: Led,
pb2led: Led,
button0: Button,
button1: Button,
switch0: Switch,
switch1: Switch,
switch2: Switch,
switch3: Switch,
switch4: Switch,
switch5: Switch,
switch6: Switch,
switch7: Switch,
clocks: Clocks,
}
}
}
};
}
impl_ext!(super::pac::FPGAIO);
impl_ext!(super::pac::FPGAIO_SECURE);