avr-oxide 0.0.6

An extremely simple 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 ==============================================================
/**
 * Button states passed in Oxide events.
 */
#[derive(PartialEq,Eq,Clone,Copy)]
pub enum ButtonState {
  /// Button was pressed
  Pressed,
  /// Button was released
  Released,
  /// Button is in an unknown state
  Unknown
}

/**
 * Encapsulation of a Button attached to a standard GPIO pin.  Generates Oxide
 * events on button events (press/release.)
 */
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(|source, state|{
      S::event(OxideEvent::ButtonEvent(
        source,
        match state {
        true  => ButtonState::Pressed,
        false => ButtonState::Released
      }));
    }));

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

  /**
   * Enable or disable the internal pullup on this pin
   */
  pub fn pullup(self, enable: bool) -> Self {
    match enable {
      true => self.pin.set_mode(PinMode::InputPullup),
      false => self.pin.set_mode(PinMode::InputFloating)
    }
    self
  }

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

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