avr-oxide 0.0.4

An extremely simply Rusty operating system for AVR microcontrollers
/* button.rs
 *
 * Developed by Tim Walls <tim.walls@snowgoons.com>
 * Copyright (c) All Rights Reserved, Tim Walls
 */
//! Simple abstraction of a button attached to a GPIO port.
//!
//!

// Imports ===================================================================
use crate::hal::generic::port::{Pin, PinMode, InterruptMode};
use crate::event::{EventSink, OxideEvent};
use core::marker::PhantomData;


// Declarations ==============================================================
#[derive(PartialEq,Eq,Clone,Copy)]
pub enum ButtonState {
  Pressed,
  Released,
  Unknown
}

pub struct Button<P,S>
where
  P: 'static + Pin,
  S: EventSink
{
  pin: &'static mut P,
  phantom: PhantomData<S>
}

// Code ======================================================================
impl<P,S> Button<P,S>
where
  P: Pin,
  S: EventSink
{
  pub fn using_pin(pin: &'static mut P) -> Self {
    pin.set_mode(PinMode::InputFloating);
    pin.set_interrupt_mode(InterruptMode::BothEdges);

    pin.listen(Some(|state|{
      S::event(OxideEvent::ButtonEvent(match state {
        true  => ButtonState::Pressed,
        false => ButtonState::Released
      }));
    }));

    Button {
      pin,
      phantom: PhantomData::default()
    }
  }

  pub fn is_pressed(&self) -> bool {
    !self.pin.get()
  }

  pub fn state(&self) -> ButtonState {
    match self.pin.get() {
      true => ButtonState::Pressed,
      false => ButtonState::Released
    }
  }
}