ruduino/src/pin.rs

82 lines
2.0 KiB
Rust
Raw Normal View History

2017-08-29 13:48:44 +00:00
use {DataDirection, Register};
/// An IO pin.
pub trait Pin {
2017-09-23 04:44:02 +00:00
/// The associated data direction register.
type DDR: Register<T=u8>;
2017-08-29 13:48:44 +00:00
/// The associated port register.
type PORT: Register<T=u8>;
2017-08-29 13:48:44 +00:00
/// The associated pin register.
///
/// Reads from the register will read input bits.
/// Writes to the register will toggle bits.
type PIN: Register<T=u8>;
2017-08-29 13:48:44 +00:00
/// The mask of the pin used for accessing registers.
const MASK: u8;
/// Sets the data direction of the pin.
#[inline(always)]
fn set_direction(direction: DataDirection) {
match direction {
DataDirection::Input => Self::set_input(),
DataDirection::Output => Self::set_output(),
}
}
/// Sets the pin up as an input.
#[inline(always)]
fn set_input() {
2017-12-13 09:17:28 +00:00
Self::DDR::unset_raw(Self::MASK);
2017-08-29 13:48:44 +00:00
}
/// Sets the pin up as an output.
#[inline(always)]
fn set_output() {
2017-12-13 09:17:28 +00:00
Self::DDR::set_raw(Self::MASK);
2017-08-29 13:48:44 +00:00
}
/// Set the pin to high.
///
/// The pin must be configured as an output.
#[inline(always)]
fn set_high() {
2017-12-13 09:17:28 +00:00
Self::PORT::set_raw(Self::MASK);
2017-08-29 13:48:44 +00:00
}
/// Set the pin to low.
///
/// The pin must be configured as an output.
#[inline(always)]
fn set_low() {
2017-12-13 09:17:28 +00:00
Self::PORT::unset_raw(Self::MASK);
2017-08-29 13:48:44 +00:00
}
/// Toggles the pin.
///
/// The pin must be configured as an output.
#[inline(always)]
fn toggle() {
// FIXME: We can optimise this on post-2006 AVRs.
// http://www.avrfreaks.net/forum/toggle-state-output-pin
// set(Self::PIN, Self::MASK);
2017-12-13 09:17:28 +00:00
Self::PORT::toggle_raw(Self::MASK);
2017-08-29 13:48:44 +00:00
}
/// Check if the pin is currently high.
///
/// The pin must be configured as an input.
#[inline(always)]
fn is_high() -> bool {
2017-12-13 09:17:28 +00:00
Self::PIN::is_set_raw(Self::MASK)
2017-08-29 13:48:44 +00:00
}
/// Checks if the pin is currently low.
///
/// The pin must be configured as an input.
#[inline(always)]
fn is_low() -> bool {
2017-12-13 09:17:28 +00:00
Self::PIN::is_clear_raw(Self::MASK)
2017-08-29 13:48:44 +00:00
}
}