use crate::{interface, BitFlags, Config, Error, Mcp794xx, OutputPinLevel, Register, SqWFreq};
pub mod alarm;
pub mod conversion;
pub mod datetime;
pub mod sram;
impl Config {
pub(crate) fn with_high(self, mask: u8) -> Self {
Config {
bits: self.bits | mask,
}
}
pub(crate) fn with_low(self, mask: u8) -> Self {
Config {
bits: self.bits & !mask,
}
}
}
impl<DI, E, IC> Mcp794xx<DI, IC>
where
DI: interface::WriteData<Error = Error<E>> + interface::ReadData<Error = Error<E>>,
{
pub fn enable(&mut self) -> Result<(), Error<E>> {
let seconds = self.iface.read_register(Register::SECONDS)?;
self.iface
.write_register(Register::SECONDS, seconds | BitFlags::ST)?;
self.is_enabled = true;
Ok(())
}
pub fn disable(&mut self) -> Result<(), Error<E>> {
let seconds = self.iface.read_register(Register::SECONDS)?;
self.iface
.write_register(Register::SECONDS, seconds & !BitFlags::ST)?;
self.is_enabled = false;
Ok(())
}
#[allow(clippy::wrong_self_convention)]
pub fn is_oscillator_running(&mut self) -> Result<bool, Error<E>> {
let data = self.iface.read_register(Register::WEEKDAY)?;
Ok((data & BitFlags::OSCRUN) != 0)
}
pub fn enable_external_oscillator(&mut self) -> Result<(), Error<E>> {
self.write_control(self.control.with_high(BitFlags::EXTOSC))
}
pub fn disable_external_oscillator(&mut self) -> Result<(), Error<E>> {
self.write_control(self.control.with_low(BitFlags::EXTOSC))
}
pub fn enable_square_wave(&mut self) -> Result<(), Error<E>> {
self.write_control(self.control.with_high(BitFlags::SQWEN))
}
pub fn disable_square_wave(&mut self) -> Result<(), Error<E>> {
self.write_control(self.control.with_low(BitFlags::SQWEN))
}
pub fn set_square_wave_frequency(&mut self, frequency: SqWFreq) -> Result<(), Error<E>> {
let bits = match frequency {
SqWFreq::Hz1 => 0,
SqWFreq::Hz4_096 => 1,
SqWFreq::Hz8_192 => 2,
SqWFreq::Hz32_768 => 3,
};
let control = Config {
bits: (self.control.bits & 0b1111_1100) | bits,
};
self.write_control(control)
}
pub fn set_output_pin(&mut self, level: OutputPinLevel) -> Result<(), Error<E>> {
let control = match level {
OutputPinLevel::High => self.control.with_high(BitFlags::OUT),
OutputPinLevel::Low => self.control.with_low(BitFlags::OUT),
};
self.write_control(control)
}
pub fn enable_coarse_trim(&mut self) -> Result<(), Error<E>> {
self.write_control(self.control.with_high(BitFlags::CRSTRIM))
}
pub fn disable_coarse_trim(&mut self) -> Result<(), Error<E>> {
self.write_control(self.control.with_low(BitFlags::CRSTRIM))
}
pub fn set_trimming(&mut self, value: i8) -> Result<(), Error<E>> {
if value < 0 && value != -128 {
let rest = !(value - 1) as u8;
self.iface
.write_register(Register::OSCTRIM, 0b1000_0000 | rest)
} else {
self.iface.write_register(Register::OSCTRIM, value as u8)
}
}
fn write_control(&mut self, control: Config) -> Result<(), Error<E>> {
self.iface.write_register(Register::CONTROL, control.bits)?;
self.control = control;
Ok(())
}
#[allow(clippy::needless_pass_by_value)]
fn check_lt<T: PartialOrd>(value: T, reference: T) -> Result<(), Error<E>> {
if value < reference {
Ok(())
} else {
Err(Error::InvalidInputData)
}
}
#[allow(clippy::needless_pass_by_value)]
fn check_gt<T: PartialOrd>(value: T, reference: T) -> Result<(), Error<E>> {
if value > reference {
Ok(())
} else {
Err(Error::InvalidInputData)
}
}
}