Use embedded_hal::digital::v2::OutputPin traits

pull/4/head
Diego Barrios Romero 2019-05-16 18:50:11 +02:00
parent f9a4918354
commit 0ef5cec642
10 changed files with 108 additions and 106 deletions

View File

@ -35,7 +35,7 @@ where
/// [`enable_32khz_output()`](#method.enable_32khz_output). /// [`enable_32khz_output()`](#method.enable_32khz_output).
/// ///
/// Note: This is only available for DS3232 and DS3234 devices. /// Note: This is only available for DS3232 and DS3234 devices.
pub fn enable_32khz_output_on_battery(&mut self) -> Result<(), Error<E>> { pub fn enable_32khz_output_on_battery(&mut self) -> Result<(), Error<E, ()>> {
let status = self.status | BitFlags::BB32KHZ; let status = self.status | BitFlags::BB32KHZ;
self.write_status_without_clearing_alarm(status) self.write_status_without_clearing_alarm(status)
} }
@ -46,7 +46,7 @@ where
/// it enabled. See [`enable_32khz_output()`](#method.enable_32khz_output). /// it enabled. See [`enable_32khz_output()`](#method.enable_32khz_output).
/// ///
/// Note: This is only available for DS3232 and DS3234 devices. /// Note: This is only available for DS3232 and DS3234 devices.
pub fn disable_32khz_output_on_battery(&mut self) -> Result<(), Error<E>> { pub fn disable_32khz_output_on_battery(&mut self) -> Result<(), Error<E, ()>> {
let status = self.status & !BitFlags::BB32KHZ; let status = self.status & !BitFlags::BB32KHZ;
self.write_status_without_clearing_alarm(status) self.write_status_without_clearing_alarm(status)
} }
@ -58,7 +58,7 @@ where
/// temperature changes will not be compensated for. /// temperature changes will not be compensated for.
/// ///
/// Note: This is only available for DS3232 and DS3234 devices. /// Note: This is only available for DS3232 and DS3234 devices.
pub fn set_temperature_conversion_rate(&mut self, rate: TempConvRate) -> Result<(), Error<E>> { pub fn set_temperature_conversion_rate(&mut self, rate: TempConvRate) -> Result<(), Error<E, ()>> {
let status; let status;
match rate { match rate {
TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0, TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0,

View File

@ -6,10 +6,10 @@ use core::marker::PhantomData;
use super::{ Ds323x, TempConvRate, Register, BitFlags, Error, ic, CONTROL_POR_VALUE }; use super::{ Ds323x, TempConvRate, Register, BitFlags, Error, ic, CONTROL_POR_VALUE };
use interface::{ SpiInterface, WriteData }; use interface::{ SpiInterface, WriteData };
impl<SPI, CS, E> Ds323x<SpiInterface<SPI, CS>, ic::DS3234> impl<SPI, CS, CommE, PinE> Ds323x<SpiInterface<SPI, CS>, ic::DS3234>
where where
SPI: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, SPI: blocking::spi::Transfer<u8, Error = CommE> + blocking::spi::Write<u8, Error = CommE>,
CS: hal::digital::OutputPin CS: hal::digital::v2::OutputPin<Error = PinE>
{ {
/// Create a new instance. /// Create a new instance.
pub fn new_ds3234(spi: SPI, chip_select: CS) -> Self { pub fn new_ds3234(spi: SPI, chip_select: CS) -> Self {
@ -36,7 +36,7 @@ where
/// [`enable_32khz_output()`](#method.enable_32khz_output). /// [`enable_32khz_output()`](#method.enable_32khz_output).
/// ///
/// Note: This is only available for DS3232 and DS3234 devices. /// Note: This is only available for DS3232 and DS3234 devices.
pub fn enable_32khz_output_on_battery(&mut self) -> Result<(), Error<E>> { pub fn enable_32khz_output_on_battery(&mut self) -> Result<(), Error<CommE, PinE>> {
let status = self.status | BitFlags::BB32KHZ; let status = self.status | BitFlags::BB32KHZ;
self.write_status_without_clearing_alarm(status) self.write_status_without_clearing_alarm(status)
} }
@ -47,7 +47,7 @@ where
/// it enabled. See [`enable_32khz_output()`](#method.enable_32khz_output). /// it enabled. See [`enable_32khz_output()`](#method.enable_32khz_output).
/// ///
/// Note: This is only available for DS3232 and DS3234 devices. /// Note: This is only available for DS3232 and DS3234 devices.
pub fn disable_32khz_output_on_battery(&mut self) -> Result<(), Error<E>> { pub fn disable_32khz_output_on_battery(&mut self) -> Result<(), Error<CommE, PinE>> {
let status = self.status & !BitFlags::BB32KHZ; let status = self.status & !BitFlags::BB32KHZ;
self.write_status_without_clearing_alarm(status) self.write_status_without_clearing_alarm(status)
} }
@ -59,7 +59,7 @@ where
/// temperature changes will not be compensated for. /// temperature changes will not be compensated for.
/// ///
/// Note: This is only available for DS3232 and DS3234 devices. /// Note: This is only available for DS3232 and DS3234 devices.
pub fn set_temperature_conversion_rate(&mut self, rate: TempConvRate) -> Result<(), Error<E>> { pub fn set_temperature_conversion_rate(&mut self, rate: TempConvRate) -> Result<(), Error<CommE, PinE>> {
let status; let status;
match rate { match rate {
TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0, TempConvRate::_64s => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0,
@ -73,14 +73,14 @@ where
/// Enable the temperature conversions when battery-powered. (enabled per default) /// Enable the temperature conversions when battery-powered. (enabled per default)
/// ///
/// Note: This is only available for DS3234 devices. /// Note: This is only available for DS3234 devices.
pub fn enable_temperature_conversions_on_battery(&mut self) -> Result<(), Error<E>> { pub fn enable_temperature_conversions_on_battery(&mut self) -> Result<(), Error<CommE, PinE>> {
self.iface.write_register(Register::TEMP_CONV, 0) self.iface.write_register(Register::TEMP_CONV, 0)
} }
/// Disable the temperature conversions when battery-powered. /// Disable the temperature conversions when battery-powered.
/// ///
/// Note: This is only available for DS3234 devices. /// Note: This is only available for DS3234 devices.
pub fn disable_temperature_conversions_on_battery(&mut self) -> Result<(), Error<E>> { pub fn disable_temperature_conversions_on_battery(&mut self) -> Result<(), Error<CommE, PinE>> {
self.iface.write_register(Register::TEMP_CONV, BitFlags::TEMP_CONV_BAT) self.iface.write_register(Register::TEMP_CONV, BitFlags::TEMP_CONV_BAT)
} }
} }

View File

@ -104,14 +104,14 @@ fn get_matching_mask_alarm2(matching: Alarm2Matching) -> [u8; 3] {
} }
impl<DI, IC, E> Ds323x<DI, IC> impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
where where
DI: ReadData<Error = E> + WriteData<Error = E> DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>
{ {
/// Set Alarm1 for day of the month. /// Set Alarm1 for day of the month.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
pub fn set_alarm1_day(&mut self, when: DayAlarm1, matching: Alarm1Matching) -> Result<(), Error<E>> { pub fn set_alarm1_day(&mut self, when: DayAlarm1, matching: Alarm1Matching) -> Result<(), Error<CommE, PinE>> {
if when.day < 1 || when.day > 31 || if when.day < 1 || when.day > 31 ||
when.minute > 59 || when.minute > 59 ||
when.second > 59 { when.second > 59 {
@ -129,7 +129,7 @@ where
/// Set Alarm1 for weekday. /// Set Alarm1 for weekday.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
pub fn set_alarm1_weekday(&mut self, when: WeekdayAlarm1, matching: Alarm1Matching) -> Result<(), Error<E>> { pub fn set_alarm1_weekday(&mut self, when: WeekdayAlarm1, matching: Alarm1Matching) -> Result<(), Error<CommE, PinE>> {
if when.weekday < 1 || when.weekday > 7 || if when.weekday < 1 || when.weekday > 7 ||
when.minute > 59 || when.minute > 59 ||
when.second > 59 { when.second > 59 {
@ -147,7 +147,7 @@ where
/// Set Alarm2 for date (day of month). /// Set Alarm2 for date (day of month).
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
pub fn set_alarm2_day(&mut self, when: DayAlarm2, matching: Alarm2Matching) -> Result<(), Error<E>> { pub fn set_alarm2_day(&mut self, when: DayAlarm2, matching: Alarm2Matching) -> Result<(), Error<CommE, PinE>> {
if when.day < 1 || when.day > 31 || if when.day < 1 || when.day > 31 ||
when.minute > 59 { when.minute > 59 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
@ -163,7 +163,7 @@ where
/// Set Alarm2 for weekday. /// Set Alarm2 for weekday.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
pub fn set_alarm2_weekday(&mut self, when: WeekdayAlarm2, matching: Alarm2Matching) -> Result<(), Error<E>> { pub fn set_alarm2_weekday(&mut self, when: WeekdayAlarm2, matching: Alarm2Matching) -> Result<(), Error<CommE, PinE>> {
if when.weekday < 1 || when.weekday > 7 || if when.weekday < 1 || when.weekday > 7 ||
when.minute > 59 { when.minute > 59 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);

View File

@ -4,18 +4,18 @@ extern crate embedded_hal as hal;
use super::super::{ Ds323x, SqWFreq, Register, BitFlags, Error }; use super::super::{ Ds323x, SqWFreq, Register, BitFlags, Error };
use interface::{ ReadData, WriteData }; use interface::{ ReadData, WriteData };
impl<DI, IC, E> Ds323x<DI, IC> impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
where where
DI: ReadData<Error = E> + WriteData<Error = E> DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>
{ {
/// Enable the oscillator (set the clock running) (default). /// Enable the oscillator (set the clock running) (default).
pub fn enable(&mut self) -> Result<(), Error<E>> { pub fn enable(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control & !BitFlags::EOSC) self.write_control(control & !BitFlags::EOSC)
} }
/// Disable the oscillator (stops the clock). /// Disable the oscillator (stops the clock).
pub fn disable(&mut self) -> Result<(), Error<E>> { pub fn disable(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control | BitFlags::EOSC) self.write_control(control | BitFlags::EOSC)
} }
@ -23,7 +23,7 @@ where
/// Force a temperature conversion and time compensation with TXCO algorithm. /// Force a temperature conversion and time compensation with TXCO algorithm.
/// ///
/// The *busy* status should be checked before doing this. See [`is_busy()`](#method.is_busy) /// The *busy* status should be checked before doing this. See [`is_busy()`](#method.is_busy)
pub fn convert_temperature(&mut self) -> Result<(), Error<E>> { pub fn convert_temperature(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.iface.read_register(Register::CONTROL)?; let control = self.iface.read_register(Register::CONTROL)?;
// do not overwrite if a conversion is in progress // do not overwrite if a conversion is in progress
if (control & BitFlags::TEMP_CONV) == 0 { if (control & BitFlags::TEMP_CONV) == 0 {
@ -33,54 +33,54 @@ where
} }
/// Enable the 32kHz output. (enabled per default) /// Enable the 32kHz output. (enabled per default)
pub fn enable_32khz_output(&mut self) -> Result<(), Error<E>> { pub fn enable_32khz_output(&mut self) -> Result<(), Error<CommE, PinE>> {
let status = self.status | BitFlags::EN32KHZ; let status = self.status | BitFlags::EN32KHZ;
self.write_status_without_clearing_alarm(status) self.write_status_without_clearing_alarm(status)
} }
/// Disable the 32kHz output. /// Disable the 32kHz output.
pub fn disable_32khz_output(&mut self) -> Result<(), Error<E>> { pub fn disable_32khz_output(&mut self) -> Result<(), Error<CommE, PinE>> {
let status = self.status & !BitFlags::EN32KHZ; let status = self.status & !BitFlags::EN32KHZ;
self.write_status_without_clearing_alarm(status) self.write_status_without_clearing_alarm(status)
} }
/// Set the aging offset. /// Set the aging offset.
pub fn set_aging_offset(&mut self, offset: i8) -> Result<(), Error<E>> { pub fn set_aging_offset(&mut self, offset: i8) -> Result<(), Error<CommE, PinE>> {
self.iface.write_register(Register::AGING_OFFSET, offset as u8) self.iface.write_register(Register::AGING_OFFSET, offset as u8)
} }
/// Read the aging offset. /// Read the aging offset.
pub fn get_aging_offset(&mut self) -> Result<i8, Error<E>> { pub fn get_aging_offset(&mut self) -> Result<i8, Error<CommE, PinE>> {
let offset = self.iface.read_register(Register::AGING_OFFSET)?; let offset = self.iface.read_register(Register::AGING_OFFSET)?;
Ok(offset as i8) Ok(offset as i8)
} }
/// Set the interrupt/square-wave output to be used as interrupt output. /// Set the interrupt/square-wave output to be used as interrupt output.
pub fn use_int_sqw_output_as_interrupt(&mut self) -> Result<(), Error<E>> { pub fn use_int_sqw_output_as_interrupt(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control | BitFlags::INTCN) self.write_control(control | BitFlags::INTCN)
} }
/// Set the interrupt/square-wave output to be used as square-wave output. (default) /// Set the interrupt/square-wave output to be used as square-wave output. (default)
pub fn use_int_sqw_output_as_square_wave(&mut self) -> Result<(), Error<E>> { pub fn use_int_sqw_output_as_square_wave(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control & !BitFlags::INTCN) self.write_control(control & !BitFlags::INTCN)
} }
/// Enable battery-backed square wave generation. /// Enable battery-backed square wave generation.
pub fn enable_square_wave(&mut self) -> Result<(), Error<E>> { pub fn enable_square_wave(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control | BitFlags::BBSQW) self.write_control(control | BitFlags::BBSQW)
} }
/// Disable battery-backed square wave generation. /// Disable battery-backed square wave generation.
pub fn disable_square_wave(&mut self) -> Result<(), Error<E>> { pub fn disable_square_wave(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control & !BitFlags::BBSQW) self.write_control(control & !BitFlags::BBSQW)
} }
/// Set the square-wave output frequency. /// Set the square-wave output frequency.
pub fn set_square_wave_frequency(&mut self, freq: SqWFreq) -> Result<(), Error<E>> { pub fn set_square_wave_frequency(&mut self, freq: SqWFreq) -> Result<(), Error<CommE, PinE>> {
let new_control; let new_control;
match freq { match freq {
SqWFreq::_1Hz => new_control = self.control & !BitFlags::RS2 & !BitFlags::RS1, SqWFreq::_1Hz => new_control = self.control & !BitFlags::RS2 & !BitFlags::RS1,
@ -92,36 +92,36 @@ where
} }
/// Enable Alarm1 interrupts. /// Enable Alarm1 interrupts.
pub fn enable_alarm1_interrupts(&mut self) -> Result<(), Error<E>> { pub fn enable_alarm1_interrupts(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control | BitFlags::ALARM1_INT_EN) self.write_control(control | BitFlags::ALARM1_INT_EN)
} }
/// Disable Alarm1 interrupts. /// Disable Alarm1 interrupts.
pub fn disable_alarm1_interrupts(&mut self) -> Result<(), Error<E>> { pub fn disable_alarm1_interrupts(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control & !BitFlags::ALARM1_INT_EN) self.write_control(control & !BitFlags::ALARM1_INT_EN)
} }
/// Enable Alarm2 interrupts. /// Enable Alarm2 interrupts.
pub fn enable_alarm2_interrupts(&mut self) -> Result<(), Error<E>> { pub fn enable_alarm2_interrupts(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control | BitFlags::ALARM2_INT_EN) self.write_control(control | BitFlags::ALARM2_INT_EN)
} }
/// Disable Alarm2 interrupts. /// Disable Alarm2 interrupts.
pub fn disable_alarm2_interrupts(&mut self) -> Result<(), Error<E>> { pub fn disable_alarm2_interrupts(&mut self) -> Result<(), Error<CommE, PinE>> {
let control = self.control; let control = self.control;
self.write_control(control & !BitFlags::ALARM2_INT_EN) self.write_control(control & !BitFlags::ALARM2_INT_EN)
} }
fn write_control(&mut self, control: u8) -> Result<(), Error<E>> { fn write_control(&mut self, control: u8) -> Result<(), Error<CommE, PinE>> {
self.iface.write_register(Register::CONTROL, control)?; self.iface.write_register(Register::CONTROL, control)?;
self.control = control; self.control = control;
Ok(()) Ok(())
} }
pub(crate) fn write_status_without_clearing_alarm(&mut self, status: u8) -> Result<(), Error<E>> { pub(crate) fn write_status_without_clearing_alarm(&mut self, status: u8) -> Result<(), Error<CommE, PinE>> {
// avoid clearing alarm flags // avoid clearing alarm flags
let new_status = status | BitFlags::ALARM2F | BitFlags::ALARM1F; let new_status = status | BitFlags::ALARM2F | BitFlags::ALARM1F;
self.iface.write_register(Register::STATUS, new_status)?; self.iface.write_register(Register::STATUS, new_status)?;

View File

@ -35,45 +35,45 @@ pub enum Hours {
H24(u8), H24(u8),
} }
impl<DI, IC, E> Ds323x<DI, IC> impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
where where
DI: ReadData<Error = E> + WriteData<Error = E> DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>
{ {
/// Read the seconds. /// Read the seconds.
pub fn get_seconds(&mut self) -> Result<u8, Error<E>> { pub fn get_seconds(&mut self) -> Result<u8, Error<CommE, PinE>> {
self.read_register_decimal(Register::SECONDS) self.read_register_decimal(Register::SECONDS)
} }
/// Read the minutes. /// Read the minutes.
pub fn get_minutes(&mut self) -> Result<u8, Error<E>> { pub fn get_minutes(&mut self) -> Result<u8, Error<CommE, PinE>> {
self.read_register_decimal(Register::MINUTES) self.read_register_decimal(Register::MINUTES)
} }
/// Read the hours. /// Read the hours.
pub fn get_hours(&mut self) -> Result<Hours, Error<E>> { pub fn get_hours(&mut self) -> Result<Hours, Error<CommE, PinE>> {
let data = self.iface.read_register(Register::HOURS)?; let data = self.iface.read_register(Register::HOURS)?;
Ok(hours_from_register(data)) Ok(hours_from_register(data))
} }
/// Read the day of the week [1-7]. /// Read the day of the week [1-7].
pub fn get_weekday(&mut self) -> Result<u8, Error<E>> { pub fn get_weekday(&mut self) -> Result<u8, Error<CommE, PinE>> {
self.read_register_decimal(Register::DOW) self.read_register_decimal(Register::DOW)
} }
/// Read the day of the month [1-31]. /// Read the day of the month [1-31].
pub fn get_day(&mut self) -> Result<u8, Error<E>> { pub fn get_day(&mut self) -> Result<u8, Error<CommE, PinE>> {
self.read_register_decimal(Register::DOM) self.read_register_decimal(Register::DOM)
} }
/// Read the month [1-12]. /// Read the month [1-12].
pub fn get_month(&mut self) -> Result<u8, Error<E>> { pub fn get_month(&mut self) -> Result<u8, Error<CommE, PinE>> {
let data = self.iface.read_register(Register::MONTH)?; let data = self.iface.read_register(Register::MONTH)?;
let value = data & !BitFlags::CENTURY; let value = data & !BitFlags::CENTURY;
Ok(packed_bcd_to_decimal(value)) Ok(packed_bcd_to_decimal(value))
} }
/// Read the year [2000-2100]. /// Read the year [2000-2100].
pub fn get_year(&mut self) -> Result<u16, Error<E>> { pub fn get_year(&mut self) -> Result<u16, Error<CommE, PinE>> {
let mut data = [0; 3]; let mut data = [0; 3];
data[0] = Register::MONTH; data[0] = Register::MONTH;
self.iface.read_data(&mut data)?; self.iface.read_data(&mut data)?;
@ -81,7 +81,7 @@ where
} }
/// Read the date and time. /// Read the date and time.
pub fn get_datetime(&mut self) -> Result<DateTime, Error<E>> { pub fn get_datetime(&mut self) -> Result<DateTime, Error<CommE, PinE>> {
let mut data = [0; 8]; let mut data = [0; 8];
self.iface.read_data(&mut data)?; self.iface.read_data(&mut data)?;
Ok(DateTime { Ok(DateTime {
@ -95,7 +95,7 @@ where
}) })
} }
fn read_register_decimal(&mut self, register: u8) -> Result<u8, Error<E>> { fn read_register_decimal(&mut self, register: u8) -> Result<u8, Error<CommE, PinE>> {
let data = self.iface.read_register(register)?; let data = self.iface.read_register(register)?;
Ok(packed_bcd_to_decimal(data)) Ok(packed_bcd_to_decimal(data))
} }
@ -103,7 +103,7 @@ where
/// Set the seconds [0-59]. /// Set the seconds [0-59].
/// ///
/// Will return an `Error::InvalidInputData` if the seconds are out of range. /// Will return an `Error::InvalidInputData` if the seconds are out of range.
pub fn set_seconds(&mut self, seconds: u8) -> Result<(), Error<E>> { pub fn set_seconds(&mut self, seconds: u8) -> Result<(), Error<CommE, PinE>> {
if seconds > 59 { if seconds > 59 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
@ -113,7 +113,7 @@ where
/// Set the minutes [0-59]. /// Set the minutes [0-59].
/// ///
/// Will return an `Error::InvalidInputData` if the minutes are out of range. /// Will return an `Error::InvalidInputData` if the minutes are out of range.
pub fn set_minutes(&mut self, minutes: u8) -> Result<(), Error<E>> { pub fn set_minutes(&mut self, minutes: u8) -> Result<(), Error<CommE, PinE>> {
if minutes > 59 { if minutes > 59 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
@ -125,7 +125,7 @@ where
/// Changes the operating mode to 12h/24h depending on the parameter. /// Changes the operating mode to 12h/24h depending on the parameter.
/// ///
/// Will return an `Error::InvalidInputData` if the hours are out of range. /// Will return an `Error::InvalidInputData` if the hours are out of range.
pub fn set_hours(&mut self, hours: Hours) -> Result<(), Error<E>> { pub fn set_hours(&mut self, hours: Hours) -> Result<(), Error<CommE, PinE>> {
let value = hours_to_register(hours)?; let value = hours_to_register(hours)?;
self.iface.write_register(Register::HOURS, value) self.iface.write_register(Register::HOURS, value)
} }
@ -133,7 +133,7 @@ where
/// Set the day of week [1-7]. /// Set the day of week [1-7].
/// ///
/// Will return an `Error::InvalidInputData` if the day is out of range. /// Will return an `Error::InvalidInputData` if the day is out of range.
pub fn set_weekday(&mut self, weekday: u8) -> Result<(), Error<E>> { pub fn set_weekday(&mut self, weekday: u8) -> Result<(), Error<CommE, PinE>> {
if weekday < 1 || weekday > 7 { if weekday < 1 || weekday > 7 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
@ -143,7 +143,7 @@ where
/// Set the day of month [1-31]. /// Set the day of month [1-31].
/// ///
/// Will return an `Error::InvalidInputData` if the day is out of range. /// Will return an `Error::InvalidInputData` if the day is out of range.
pub fn set_day(&mut self, day: u8) -> Result<(), Error<E>> { pub fn set_day(&mut self, day: u8) -> Result<(), Error<CommE, PinE>> {
if day < 1 || day > 7 { if day < 1 || day > 7 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
@ -153,7 +153,7 @@ where
/// Set the month [1-12]. /// Set the month [1-12].
/// ///
/// Will return an `Error::InvalidInputData` if the month is out of range. /// Will return an `Error::InvalidInputData` if the month is out of range.
pub fn set_month(&mut self, month: u8) -> Result<(), Error<E>> { pub fn set_month(&mut self, month: u8) -> Result<(), Error<CommE, PinE>> {
if month < 1 || month > 12 { if month < 1 || month > 12 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
@ -166,7 +166,7 @@ where
/// Set the year [2000-2100]. /// Set the year [2000-2100].
/// ///
/// Will return an `Error::InvalidInputData` if the year is out of range. /// Will return an `Error::InvalidInputData` if the year is out of range.
pub fn set_year(&mut self, year: u16) -> Result<(), Error<E>> { pub fn set_year(&mut self, year: u16) -> Result<(), Error<CommE, PinE>> {
if year < 2000 || year > 2100 { if year < 2000 || year > 2100 {
return Err(Error::InvalidInputData); return Err(Error::InvalidInputData);
} }
@ -188,7 +188,7 @@ where
/// Set the date and time. /// Set the date and time.
/// ///
/// Will return an `Error::InvalidInputData` if any of the parameters is out of range. /// Will return an `Error::InvalidInputData` if any of the parameters is out of range.
pub fn set_datetime(&mut self, datetime: &DateTime) -> Result<(), Error<E>> { pub fn set_datetime(&mut self, datetime: &DateTime) -> Result<(), Error<CommE, PinE>> {
if datetime.year < 2000 || datetime.year > 2100 || if datetime.year < 2000 || datetime.year > 2100 ||
datetime.month < 1 || datetime.month > 12 || datetime.month < 1 || datetime.month > 12 ||
datetime.day < 1 || datetime.day > 31 || datetime.day < 1 || datetime.day > 31 ||
@ -208,7 +208,7 @@ where
self.iface.write_data(&mut payload) self.iface.write_data(&mut payload)
} }
fn write_register_decimal(&mut self, register: u8, decimal_number: u8) -> Result<(), Error<E>> { fn write_register_decimal(&mut self, register: u8, decimal_number: u8) -> Result<(), Error<CommE, PinE>> {
self.iface.write_register(register, decimal_to_packed_bcd(decimal_number)) self.iface.write_register(register, decimal_to_packed_bcd(decimal_number))
} }
} }

View File

@ -17,7 +17,7 @@ fn packed_bcd_to_decimal(bcd: u8) -> u8 {
(bcd >> 4) * 10 + (bcd & 0xF) (bcd >> 4) * 10 + (bcd & 0xF)
} }
fn hours_to_register<E>(hours: Hours) -> Result<u8, Error<E>> { fn hours_to_register<CommE, PinE>(hours: Hours) -> Result<u8, Error<CommE, PinE>> {
match hours { match hours {
Hours::H24(h) if h > 23 => Err(Error::InvalidInputData), Hours::H24(h) if h > 23 => Err(Error::InvalidInputData),
Hours::H24(h) => Ok(decimal_to_packed_bcd(h)), Hours::H24(h) => Ok(decimal_to_packed_bcd(h)),

View File

@ -4,18 +4,18 @@ extern crate embedded_hal as hal;
use super::super::{ Ds323x, Register, BitFlags, Error }; use super::super::{ Ds323x, Register, BitFlags, Error };
use interface::{ ReadData, WriteData }; use interface::{ ReadData, WriteData };
impl<DI, IC, E> Ds323x<DI, IC> impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
where where
DI: ReadData<Error = E> + WriteData<Error = E> DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>
{ {
/// Read whether the oscillator is running /// Read whether the oscillator is running
pub fn is_running(&mut self) -> Result<bool, Error<E>> { pub fn is_running(&mut self) -> Result<bool, Error<CommE, PinE>> {
let control = self.iface.read_register(Register::CONTROL)?; let control = self.iface.read_register(Register::CONTROL)?;
Ok((control & BitFlags::EOSC) == 0) Ok((control & BitFlags::EOSC) == 0)
} }
/// Read the busy status /// Read the busy status
pub fn is_busy(&mut self) -> Result<bool, Error<E>> { pub fn is_busy(&mut self) -> Result<bool, Error<CommE, PinE>> {
let status = self.iface.read_register(Register::STATUS)?; let status = self.iface.read_register(Register::STATUS)?;
Ok((status & BitFlags::BUSY) != 0) Ok((status & BitFlags::BUSY) != 0)
} }
@ -27,7 +27,7 @@ where
/// ///
/// Once this is true, it will stay as such until cleared with /// Once this is true, it will stay as such until cleared with
/// [`clear_has_been_stopped_flag()`](#method.clear_has_been_stopped_flag) /// [`clear_has_been_stopped_flag()`](#method.clear_has_been_stopped_flag)
pub fn has_been_stopped(&mut self) -> Result<bool, Error<E>> { pub fn has_been_stopped(&mut self) -> Result<bool, Error<CommE, PinE>> {
let status = self.iface.read_register(Register::STATUS)?; let status = self.iface.read_register(Register::STATUS)?;
Ok((status & BitFlags::OSC_STOP) != 0) Ok((status & BitFlags::OSC_STOP) != 0)
} }
@ -36,7 +36,7 @@ where
/// stopped at some point. /// stopped at some point.
/// ///
/// See also: [`has_been_stopped()`](#method.has_been_stopped) /// See also: [`has_been_stopped()`](#method.has_been_stopped)
pub fn clear_has_been_stopped_flag(&mut self) -> Result<(), Error<E>> { pub fn clear_has_been_stopped_flag(&mut self) -> Result<(), Error<CommE, PinE>> {
let status = self.status & !BitFlags::OSC_STOP; let status = self.status & !BitFlags::OSC_STOP;
self.write_status_without_clearing_alarm(status) self.write_status_without_clearing_alarm(status)
} }
@ -45,7 +45,7 @@ where
/// ///
/// Once this is true, it will stay as such until cleared with /// Once this is true, it will stay as such until cleared with
/// [`clear_alarm1_matched_flag()`](#method.clear_alarm1_matched_flag) /// [`clear_alarm1_matched_flag()`](#method.clear_alarm1_matched_flag)
pub fn has_alarm1_matched(&mut self) -> Result<bool, Error<E>> { pub fn has_alarm1_matched(&mut self) -> Result<bool, Error<CommE, PinE>> {
let status = self.iface.read_register(Register::STATUS)?; let status = self.iface.read_register(Register::STATUS)?;
Ok((status & BitFlags::ALARM1F) != 0) Ok((status & BitFlags::ALARM1F) != 0)
} }
@ -53,7 +53,7 @@ where
/// Clear flag signalling whether the Alarm1 has matched at some point. /// Clear flag signalling whether the Alarm1 has matched at some point.
/// ///
/// See also: [`has_alarm1_matched()`](#method.has_alarm1_matched) /// See also: [`has_alarm1_matched()`](#method.has_alarm1_matched)
pub fn clear_alarm1_matched_flag(&mut self) -> Result<(), Error<E>> { pub fn clear_alarm1_matched_flag(&mut self) -> Result<(), Error<CommE, PinE>> {
let status = self.status | BitFlags::ALARM2F; let status = self.status | BitFlags::ALARM2F;
self.iface.write_register(Register::STATUS, status) self.iface.write_register(Register::STATUS, status)
} }
@ -62,7 +62,7 @@ where
/// ///
/// Once this is true, it will stay as such until cleared with /// Once this is true, it will stay as such until cleared with
/// [`clear_alarm2_matched_flag()`](#method.clear_alarm2_matched_flag) /// [`clear_alarm2_matched_flag()`](#method.clear_alarm2_matched_flag)
pub fn has_alarm2_matched(&mut self) -> Result<bool, Error<E>> { pub fn has_alarm2_matched(&mut self) -> Result<bool, Error<CommE, PinE>> {
let status = self.iface.read_register(Register::STATUS)?; let status = self.iface.read_register(Register::STATUS)?;
Ok((status & BitFlags::ALARM2F) != 0) Ok((status & BitFlags::ALARM2F) != 0)
} }
@ -70,7 +70,7 @@ where
/// Clear flag signalling whether the Alarm2 has matched at some point. /// Clear flag signalling whether the Alarm2 has matched at some point.
/// ///
/// See also: [`has_alarm2_matched()`](#method.has_alarm2_matched) /// See also: [`has_alarm2_matched()`](#method.has_alarm2_matched)
pub fn clear_alarm2_matched_flag(&mut self) -> Result<(), Error<E>> { pub fn clear_alarm2_matched_flag(&mut self) -> Result<(), Error<CommE, PinE>> {
let status = self.status | BitFlags::ALARM1F; let status = self.status | BitFlags::ALARM1F;
self.iface.write_register(Register::STATUS, status) self.iface.write_register(Register::STATUS, status)
} }
@ -79,7 +79,7 @@ where
/// ///
/// Note: It is possible to manually force a temperature conversion with /// Note: It is possible to manually force a temperature conversion with
/// [`convert_temperature()`](#method.convert_temperature) /// [`convert_temperature()`](#method.convert_temperature)
pub fn get_temperature(&mut self) -> Result<f32, Error<E>> { pub fn get_temperature(&mut self) -> Result<f32, Error<CommE, PinE>> {
let mut data = [Register::TEMP_MSB, 0, 0]; let mut data = [Register::TEMP_MSB, 0, 0];
self.iface.read_data(&mut data)?; self.iface.read_data(&mut data)?;
let is_negative = (data[1] & 0b1000_0000) != 0; let is_negative = (data[1] & 0b1000_0000) != 0;

View File

@ -24,56 +24,56 @@ pub trait WriteData {
/// Error type /// Error type
type Error; type Error;
/// Write to an u8 register /// Write to an u8 register
fn write_register(&mut self, register: u8, data: u8) -> Result<(), Error<Self::Error>>; fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error>;
/// Write data. The first element corresponds to the starting address. /// Write data. The first element corresponds to the starting address.
fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Error<Self::Error>>; fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error>;
} }
impl<I2C, E> WriteData for I2cInterface<I2C> impl<I2C, E> WriteData for I2cInterface<I2C>
where where
I2C: blocking::i2c::Write<Error = E> I2C: blocking::i2c::Write<Error = E>
{ {
type Error = E; type Error = Error<E, ()>;
fn write_register(&mut self, register: u8, data: u8) -> Result<(), Error<E>> { fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> {
let payload: [u8; 2] = [register, data]; let payload: [u8; 2] = [register, data];
self.i2c self.i2c
.write(DEVICE_ADDRESS, &payload) .write(DEVICE_ADDRESS, &payload)
.map_err(Error::Comm) .map_err(Error::Comm)
} }
fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Error<Self::Error>> { fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> {
self.i2c self.i2c
.write(DEVICE_ADDRESS, &payload) .write(DEVICE_ADDRESS, &payload)
.map_err(Error::Comm) .map_err(Error::Comm)
} }
} }
impl<SPI, CS, E> WriteData for SpiInterface<SPI, CS> impl<SPI, CS, CommE, PinE> WriteData for SpiInterface<SPI, CS>
where where
SPI: blocking::spi::Write<u8, Error = E>, SPI: blocking::spi::Write<u8, Error = CommE>,
CS: hal::digital::OutputPin CS: hal::digital::v2::OutputPin<Error = PinE>
{ {
type Error = E; type Error = Error<CommE, PinE>;
fn write_register(&mut self, register: u8, data: u8) -> Result<(), Error<E>> { fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> {
self.cs.set_low(); self.cs.set_low().map_err(Error::Pin)?;
let payload: [u8; 2] = [register + 0x80, data]; let payload: [u8; 2] = [register + 0x80, data];
let result = self.spi let result = self.spi
.write(&payload) .write(&payload)
.map_err(Error::Comm); .map_err(Error::Comm);
self.cs.set_high(); self.cs.set_high().map_err(Error::Pin)?;
result result
} }
fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Error<Self::Error>> { fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> {
self.cs.set_low(); self.cs.set_low().map_err(Error::Pin)?;
payload[0] += 0x80; payload[0] += 0x80;
let result = self.spi let result = self.spi
.write(&payload) .write(&payload)
.map_err(Error::Comm); .map_err(Error::Comm);
self.cs.set_high(); self.cs.set_high().map_err(Error::Pin)?;
result result
} }
} }
@ -84,17 +84,17 @@ pub trait ReadData {
/// Error type /// Error type
type Error; type Error;
/// Read an u8 register /// Read an u8 register
fn read_register(&mut self, register: u8) -> Result<u8, Error<Self::Error>>; fn read_register(&mut self, register: u8) -> Result<u8, Self::Error>;
/// Read some data. The first element corresponds to the starting address. /// Read some data. The first element corresponds to the starting address.
fn read_data(&mut self, payload: &mut [u8]) -> Result<(), Error<Self::Error>>; fn read_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error>;
} }
impl<I2C, E> ReadData for I2cInterface<I2C> impl<I2C, E> ReadData for I2cInterface<I2C>
where where
I2C: blocking::i2c::WriteRead<Error = E> I2C: blocking::i2c::WriteRead<Error = E>
{ {
type Error = E; type Error = Error<E, ()>;
fn read_register(&mut self, register: u8) -> Result<u8, Error<E>> { fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
let mut data = [0]; let mut data = [0];
self.i2c self.i2c
.write_read(DEVICE_ADDRESS, &[register], &mut data) .write_read(DEVICE_ADDRESS, &[register], &mut data)
@ -102,7 +102,7 @@ where
.and(Ok(data[0])) .and(Ok(data[0]))
} }
fn read_data(&mut self, payload: &mut [u8]) -> Result<(), Error<Self::Error>> { fn read_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> {
let len = payload.len(); let len = payload.len();
self.i2c self.i2c
.write_read(DEVICE_ADDRESS, &[payload[0]], &mut payload[1..len]) .write_read(DEVICE_ADDRESS, &[payload[0]], &mut payload[1..len])
@ -110,29 +110,28 @@ where
} }
} }
impl<SPI, CS, E> ReadData for SpiInterface<SPI, CS> impl<SPI, CS, CommE, PinE> ReadData for SpiInterface<SPI, CS>
where where
SPI: blocking::spi::Transfer<u8, Error = E>, SPI: blocking::spi::Transfer<u8, Error = CommE>,
CS: hal::digital::OutputPin CS: hal::digital::v2::OutputPin<Error = PinE>
{ {
type Error = E; type Error = Error<CommE, PinE>;
fn read_register(&mut self, register: u8) -> Result<u8, Error<E>> { fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
self.cs.set_low(); self.cs.set_low().map_err(Error::Pin)?;
let mut data = [register, 0]; let mut data = [register, 0];
let result = self.spi let result = self.spi
.transfer(&mut data) .transfer(&mut data)
.map_err(Error::Comm); .map_err(Error::Comm);
self.cs.set_high(); self.cs.set_high().map_err(Error::Pin)?;
let result = result?; Ok(result?[1])
Ok(result[1])
} }
fn read_data(&mut self, mut payload: &mut [u8]) -> Result<(), Error<Self::Error>> { fn read_data(&mut self, mut payload: &mut [u8]) -> Result<(), Self::Error> {
self.cs.set_low(); self.cs.set_low().map_err(Error::Pin)?;
let result = self.spi let result = self.spi
.transfer(&mut payload) .transfer(&mut payload)
.map_err(Error::Comm); .map_err(Error::Comm);
self.cs.set_high(); self.cs.set_high().map_err(Error::Pin)?;
result?; result?;
Ok(()) Ok(())
} }

View File

@ -448,9 +448,11 @@ use core::marker::PhantomData;
/// All possible errors in this crate /// All possible errors in this crate
#[derive(Debug)] #[derive(Debug)]
pub enum Error<E> { pub enum Error<CommE, PinE> {
/// I²C/SPI bus error /// I²C/SPI bus error
Comm(E), Comm(CommE),
/// Pin setting error
Pin(PinE),
/// Invalid input data provided /// Invalid input data provided
InvalidInputData InvalidInputData
} }

View File

@ -60,9 +60,10 @@ impl BitFlags {
pub struct DummyOutputPin; pub struct DummyOutputPin;
impl embedded_hal::digital::OutputPin for DummyOutputPin { impl embedded_hal::digital::v2::OutputPin for DummyOutputPin {
fn set_low(&mut self) {} type Error = ();
fn set_high(&mut self) {} fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) }
fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) }
} }