use bit_field::BitField;
use prelude::Write;
use reg::Register;
pub enum AlertMode {
Comparator = 0,
Interrupt = 1,
}
pub enum AlertPolarity {
ActiveLow = 0,
ActiveHigh = 1,
}
pub enum AlertSelect {
All = 0,
TCritOnly = 1,
}
pub enum AlertControl {
Disabled = 0,
Enabled = 1,
}
pub enum AlertStatus {
NotAsserted = 0,
Asserted = 1,
}
pub enum InterruptClear {
NoEffect = 0,
ClearInterruptOutput = 1,
}
pub enum WindowLock {
Unlocked = 0,
Locked = 1,
}
pub enum CriticalLock {
Unlocked = 0,
Locked = 1,
}
pub enum ShutdownMode {
Continuous = 0,
Shutdown = 1,
}
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(u8)]
pub enum Hysteresis {
Deg_0_0C = 0b00,
Deg_1_5C = 0b01,
Deg_3_0C = 0b10,
Deg_6_0C = 0b11,
}
const REGISTER_PTR: u8 = 0b0001;
const REGISTER_SIZE: u8 = 2;
pub trait Configuration: Write {
fn get_alert_mode(&self) -> AlertMode;
fn set_alert_mode(&mut self, mode: AlertMode);
fn get_alert_polarity(&self) -> AlertPolarity;
fn set_alert_polarity(&mut self, mode: AlertPolarity);
fn get_alert_select(&self) -> AlertSelect;
fn set_alert_select(&mut self, mode: AlertSelect);
fn get_alert_control(&self) -> AlertControl;
fn set_alert_control(&mut self, mode: AlertControl);
fn get_alert_status(&self) -> AlertStatus;
fn set_alert_status(&mut self, mode: AlertStatus);
fn get_interrupt_clear(&self) -> InterruptClear;
fn set_interrupt_clear(&mut self, mode: InterruptClear);
fn get_window_lock(&self) -> WindowLock;
fn set_window_lock(&mut self, mode: WindowLock);
fn get_critical_lock(&self) -> CriticalLock;
fn set_critical_lock(&mut self, mode: CriticalLock);
fn get_shutdown_mode(&self) -> ShutdownMode;
fn set_shutdown_mode(&mut self, mode: ShutdownMode);
fn set_hysteresis(&mut self, mode: Hysteresis);
fn get_hysteresis(&self) -> Hysteresis;
}
pub fn new() -> Register {
Register::new(REGISTER_PTR, REGISTER_SIZE)
}
impl Configuration for Register {
fn get_alert_mode(&self) -> AlertMode {
if self.get_bit(0) {
return AlertMode::Interrupt;
}
AlertMode::Comparator
}
fn set_alert_mode(&mut self, mode: AlertMode) {
self.set_bit(0, bool(mode as isize));
}
fn get_alert_polarity(&self) -> AlertPolarity {
if self.get_bit(1) {
return AlertPolarity::ActiveHigh;
}
AlertPolarity::ActiveLow
}
fn set_alert_polarity(&mut self, mode: AlertPolarity) {
self.set_bit(1, bool(mode as isize));
}
fn get_alert_select(&self) -> AlertSelect {
if self.get_bit(2) {
return AlertSelect::TCritOnly;
}
AlertSelect::All
}
fn set_alert_select(&mut self, mode: AlertSelect) {
self.set_bit(2, bool(mode as isize));
}
fn get_alert_control(&self) -> AlertControl {
if self.get_bit(3) {
return AlertControl::Enabled;
}
AlertControl::Disabled
}
fn set_alert_control(&mut self, mode: AlertControl) {
self.set_bit(3, bool(mode as isize));
}
fn get_alert_status(&self) -> AlertStatus {
if self.get_bit(4) {
return AlertStatus::Asserted;
}
AlertStatus::NotAsserted
}
fn set_alert_status(&mut self, mode: AlertStatus) {
self.set_bit(4, bool(mode as isize));
}
fn get_interrupt_clear(&self) -> InterruptClear {
if self.get_bit(5) {
return InterruptClear::ClearInterruptOutput;
}
InterruptClear::NoEffect
}
fn set_interrupt_clear(&mut self, mode: InterruptClear) {
self.set_bit(5, bool(mode as isize));
}
fn get_window_lock(&self) -> WindowLock {
if self.get_bit(6) {
return WindowLock::Locked;
}
WindowLock::Unlocked
}
fn set_window_lock(&mut self, mode: WindowLock) {
self.set_bit(6, bool(mode as isize));
}
fn get_critical_lock(&self) -> CriticalLock {
if self.get_bit(7) {
return CriticalLock::Locked;
}
CriticalLock::Unlocked
}
fn set_critical_lock(&mut self, mode: CriticalLock) {
self.set_bit(7, bool(mode as isize));
}
fn get_shutdown_mode(&self) -> ShutdownMode {
if self.get_bit(8) {
return ShutdownMode::Shutdown;
}
ShutdownMode::Continuous
}
fn set_shutdown_mode(&mut self, mode: ShutdownMode) {
self.set_bit(8, bool(mode as isize));
}
#[allow(unused_must_use, clippy::unnecessary_operation)] fn set_hysteresis(&mut self, mode: Hysteresis) {
&self.set_bit(9, (mode as i64).get_bit(0));
&self.set_bit(10, (mode as i64).get_bit(1));
}
fn get_hysteresis(&self) -> Hysteresis {
let val: u8 = &self.get_msb() >> 1 & 0b11u8;
match val {
val if val == Hysteresis::Deg_0_0C as u8 => Hysteresis::Deg_0_0C,
val if val == Hysteresis::Deg_1_5C as u8 => Hysteresis::Deg_1_5C,
val if val == Hysteresis::Deg_3_0C as u8 => Hysteresis::Deg_3_0C,
val if val == Hysteresis::Deg_6_0C as u8 => Hysteresis::Deg_6_0C,
_ => panic!("invalid value"),
}
}
}
fn bool(val: isize) -> bool {
val != 0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hysteresis() {
let mut reg: Register = new();
assert_eq!(reg.get_hysteresis(), Hysteresis::Deg_0_0C);
reg.set_hysteresis(Hysteresis::Deg_1_5C);
assert_eq!(reg.get_hysteresis(), Hysteresis::Deg_1_5C);
reg.set_hysteresis(Hysteresis::Deg_3_0C);
assert_eq!(reg.get_hysteresis(), Hysteresis::Deg_3_0C);
reg.set_hysteresis(Hysteresis::Deg_6_0C);
assert_eq!(reg.get_hysteresis(), Hysteresis::Deg_6_0C);
reg.set_hysteresis(Hysteresis::Deg_0_0C);
assert_eq!(reg.get_hysteresis(), Hysteresis::Deg_0_0C);
}
}