#[derive(Clone,Copy,PartialEq,Eq)]
pub enum PinMode {
Output,
InputPullup,
InputFloating
}
pub trait Pin {
fn set_mode(&self, mode: PinMode);
fn toggle(&self);
fn set_on(&self);
fn set_off(&self);
}
pub trait Port
{
}
pub mod base {
pub trait AtmelPortControl {
fn set_as_output(&self,p: u8);
fn set_as_input(&self, p: u8);
fn set_high(&self, p: u8);
fn set_low(&self, p: u8);
fn toggle(&self, p: u8);
}
#[macro_export]
macro_rules! atmel_port_tpl {
($hw_type:ty, $ref:expr, $ddr_set:ident, $ddr_clr:ident, $port_set:ident, $port_clr:ident, $port_tgl:ident) => {
extern crate avr_device_snowgoons as avr_device;
use crate::hal::generic::port::{PinMode,Pin,Port};
use crate::hal::generic::port::base::AtmelPortControl;
pub type PortImpl = $hw_type;
pub type PinImpl<const N: u8> = AtmelPin<N>;
pub struct AtmelPin<const N: u8> {
}
impl<const N: u8> Pin for AtmelPin<N> {
#[inline(always)]
fn set_mode(&self, mode: PinMode) {
unsafe {
match mode {
PinMode::Output => {
(*$ref).$ddr_set.write(|w| w.bits(0x01 << N));
},
PinMode::InputPullup => {
(*$ref).$ddr_clr.write(|w| w.bits(0x01 << N));
todo!("Set pullup on");
},
PinMode::InputFloating => {
(*$ref).$ddr_clr.write(|w| w.bits(0x01 << N));
todo!("Set floating on");
}
}
}
}
#[inline(always)]
fn toggle(&self) {
unsafe {
(*$ref).$port_tgl.write(|w| w.bits(0x01 << N));
}
}
#[inline(always)]
fn set_on(&self) {
unsafe {
(*$ref).$port_set.write(|w| w.bits(0x01 << N));
}
}
#[inline(always)]
fn set_off(&self) {
unsafe {
(*$ref).$port_clr.write(|w| w.bits(0x01 << N));
}
}
}
pub fn instance() -> &'static PortImpl {
unsafe {
&(*$ref)
}
}
impl Port for $hw_type {
}
impl<const N: u8> AtmelPin<N> {
pub fn instance() -> AtmelPin<N> {
AtmelPin::<N> { }
}
}
pub fn pin_instance<const N: u8>() -> AtmelPin<N> {
AtmelPin::<N> { }
}
impl AtmelPortControl for $hw_type {
#[inline(always)]
fn set_as_output(&self, p: u8) {
self.$ddr_set.write(|w| unsafe { w.bits(0x01 << p) });
}
#[inline(always)]
fn set_as_input(&self, p: u8) {
self.$ddr_clr.write(|w| unsafe { w.bits(0x01 << p) });
todo!()
}
#[inline(always)]
fn set_high(&self, p: u8) {
self.$port_set.write(|w| unsafe { w.bits(0x01 << p) });
}
#[inline(always)]
fn set_low(&self, p: u8) {
self.$port_clr.write(|w| unsafe { w.bits(0x01 << p) });
}
#[inline(always)]
fn toggle(&self, p: u8) {
self.$port_tgl.write(|w| unsafe { w.bits(0x01 << p) });
}
}
}
}
}