From 0ef5cec64201a4b002c8678251f0c6bae816165e Mon Sep 17 00:00:00 2001
From: Diego Barrios Romero <eldruin@gmail.com>
Date: Thu, 16 May 2019 18:50:11 +0200
Subject: [PATCH] Use embedded_hal::digital::v2::OutputPin traits

---
 src/ds3232.rs               |  6 ++--
 src/ds3234.rs               | 16 +++++-----
 src/ds323x/alarms.rs        | 12 +++----
 src/ds323x/configuration.rs | 40 +++++++++++------------
 src/ds323x/datetime.rs      | 40 +++++++++++------------
 src/ds323x/mod.rs           |  2 +-
 src/ds323x/status.rs        | 22 ++++++-------
 src/interface.rs            | 63 ++++++++++++++++++-------------------
 src/lib.rs                  |  6 ++--
 tests/common/mod.rs         |  7 +++--
 10 files changed, 108 insertions(+), 106 deletions(-)

diff --git a/src/ds3232.rs b/src/ds3232.rs
index f3de835..110e0d1 100644
--- a/src/ds3232.rs
+++ b/src/ds3232.rs
@@ -35,7 +35,7 @@ where
     /// [`enable_32khz_output()`](#method.enable_32khz_output).
     ///
     /// 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;
         self.write_status_without_clearing_alarm(status)
     }
@@ -46,7 +46,7 @@ where
     /// it enabled. See [`enable_32khz_output()`](#method.enable_32khz_output).
     ///
     /// 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;
         self.write_status_without_clearing_alarm(status)
     }
@@ -58,7 +58,7 @@ where
     /// temperature changes will not be compensated for.
     ///
     /// 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;
         match rate {
             TempConvRate::_64s  => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0,
diff --git a/src/ds3234.rs b/src/ds3234.rs
index 3172204..a2d68e1 100644
--- a/src/ds3234.rs
+++ b/src/ds3234.rs
@@ -6,10 +6,10 @@ use core::marker::PhantomData;
 use super::{ Ds323x, TempConvRate, Register, BitFlags, Error, ic, CONTROL_POR_VALUE };
 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
-    SPI: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>,
-    CS:  hal::digital::OutputPin
+    SPI: blocking::spi::Transfer<u8, Error = CommE> + blocking::spi::Write<u8, Error = CommE>,
+    CS:  hal::digital::v2::OutputPin<Error = PinE>
 {
     /// Create a new instance.
     pub fn new_ds3234(spi: SPI, chip_select: CS) -> Self {
@@ -36,7 +36,7 @@ where
     /// [`enable_32khz_output()`](#method.enable_32khz_output).
     ///
     /// 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;
         self.write_status_without_clearing_alarm(status)
     }
@@ -47,7 +47,7 @@ where
     /// it enabled. See [`enable_32khz_output()`](#method.enable_32khz_output).
     ///
     /// 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;
         self.write_status_without_clearing_alarm(status)
     }
@@ -59,7 +59,7 @@ where
     /// temperature changes will not be compensated for.
     ///
     /// 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;
         match rate {
             TempConvRate::_64s  => status = self.status & !BitFlags::CRATE1 & !BitFlags::CRATE0,
@@ -73,14 +73,14 @@ where
     /// Enable the temperature conversions when battery-powered. (enabled per default)
     ///
     /// 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)
     }
 
     /// Disable the temperature conversions when battery-powered.
     ///
     /// 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)
     }
 }
diff --git a/src/ds323x/alarms.rs b/src/ds323x/alarms.rs
index c893963..cadd3e1 100644
--- a/src/ds323x/alarms.rs
+++ b/src/ds323x/alarms.rs
@@ -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
-    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.
     ///
     /// 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 ||
            when.minute > 59 ||
            when.second > 59 {
@@ -129,7 +129,7 @@ where
     /// Set Alarm1 for weekday.
     ///
     /// 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 ||
            when.minute > 59 ||
            when.second > 59 {
@@ -147,7 +147,7 @@ where
     /// Set Alarm2 for date (day of month).
     ///
     /// 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 ||
            when.minute > 59 {
             return Err(Error::InvalidInputData);
@@ -163,7 +163,7 @@ where
     /// Set Alarm2 for weekday.
     ///
     /// 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 ||
            when.minute > 59 {
             return Err(Error::InvalidInputData);
diff --git a/src/ds323x/configuration.rs b/src/ds323x/configuration.rs
index 9f58ca0..e4fb8e7 100644
--- a/src/ds323x/configuration.rs
+++ b/src/ds323x/configuration.rs
@@ -4,18 +4,18 @@ extern crate embedded_hal as hal;
 use super::super::{ Ds323x, SqWFreq, Register, BitFlags, Error };
 use interface::{ ReadData, WriteData };
 
-impl<DI, IC, E> Ds323x<DI, IC>
+impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
 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).
-    pub fn enable(&mut self) -> Result<(), Error<E>> {
+    pub fn enable(&mut self) -> Result<(), Error<CommE, PinE>> {
         let control = self.control;
         self.write_control(control & !BitFlags::EOSC)
     }
 
     /// 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;
         self.write_control(control | BitFlags::EOSC)
     }
@@ -23,7 +23,7 @@ where
     /// 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)
-    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)?;
         // do not overwrite if a conversion is in progress
         if (control & BitFlags::TEMP_CONV) == 0 {
@@ -33,54 +33,54 @@ where
     }
 
     /// 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;
         self.write_status_without_clearing_alarm(status)
     }
 
     /// 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;
         self.write_status_without_clearing_alarm(status)
     }
 
     /// 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)
     }
 
     /// 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)?;
         Ok(offset as i8)
     }
 
     /// 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;
         self.write_control(control | BitFlags::INTCN)
     }
 
     /// 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;
         self.write_control(control & !BitFlags::INTCN)
     }
 
     /// 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;
         self.write_control(control | BitFlags::BBSQW)
     }
 
     /// 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;
         self.write_control(control & !BitFlags::BBSQW)
     }
 
     /// 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;
         match freq {
             SqWFreq::_1Hz     => new_control = self.control & !BitFlags::RS2 & !BitFlags::RS1,
@@ -92,36 +92,36 @@ where
     }
 
     /// 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;
         self.write_control(control | BitFlags::ALARM1_INT_EN)
     }
 
     /// 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;
         self.write_control(control & !BitFlags::ALARM1_INT_EN)
     }
 
     /// 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;
         self.write_control(control | BitFlags::ALARM2_INT_EN)
     }
 
     /// 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;
         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.control = control;
         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
         let new_status = status | BitFlags::ALARM2F | BitFlags::ALARM1F;
         self.iface.write_register(Register::STATUS, new_status)?;
diff --git a/src/ds323x/datetime.rs b/src/ds323x/datetime.rs
index e4427e3..6a0c3ac 100644
--- a/src/ds323x/datetime.rs
+++ b/src/ds323x/datetime.rs
@@ -35,45 +35,45 @@ pub enum Hours {
     H24(u8),
 }
 
-impl<DI, IC, E> Ds323x<DI, IC>
+impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
 where
-    DI: ReadData<Error = E> + WriteData<Error = E>
+    DI: ReadData<Error = Error<CommE, PinE>> + WriteData<Error = Error<CommE, PinE>>
 {
     /// 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)
     }
 
     /// 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)
     }
 
     /// 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)?;
         Ok(hours_from_register(data))
     }
 
     /// 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)
     }
 
     /// 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)
     }
 
     /// 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 value = data & !BitFlags::CENTURY;
         Ok(packed_bcd_to_decimal(value))
     }
 
     /// 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];
         data[0] = Register::MONTH;
         self.iface.read_data(&mut data)?;
@@ -81,7 +81,7 @@ where
     }
 
     /// 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];
         self.iface.read_data(&mut data)?;
         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)?;
         Ok(packed_bcd_to_decimal(data))
     }
@@ -103,7 +103,7 @@ where
     /// Set the seconds [0-59].
     ///
     /// 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 {
             return Err(Error::InvalidInputData);
         }
@@ -113,7 +113,7 @@ where
     /// Set the minutes [0-59].
     ///
     /// 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 {
             return Err(Error::InvalidInputData);
         }
@@ -125,7 +125,7 @@ where
     /// Changes the operating mode to 12h/24h depending on the parameter.
     ///
     /// 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)?;
         self.iface.write_register(Register::HOURS, value)
     }
@@ -133,7 +133,7 @@ where
     /// Set the day of week [1-7].
     ///
     /// 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 {
             return Err(Error::InvalidInputData);
         }
@@ -143,7 +143,7 @@ where
     /// Set the day of month [1-31].
     ///
     /// 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 {
             return Err(Error::InvalidInputData);
         }
@@ -153,7 +153,7 @@ where
     /// Set the month [1-12].
     ///
     /// 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 {
             return Err(Error::InvalidInputData);
         }
@@ -166,7 +166,7 @@ where
     /// Set the year [2000-2100].
     ///
     /// 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 {
             return Err(Error::InvalidInputData);
         }
@@ -188,7 +188,7 @@ where
     /// Set the date and time.
     ///
     /// 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 ||
            datetime.month < 1   || datetime.month > 12  ||
            datetime.day < 1     || datetime.day > 31    ||
@@ -208,7 +208,7 @@ where
         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))
     }
 }
diff --git a/src/ds323x/mod.rs b/src/ds323x/mod.rs
index 96326dd..f7d8db9 100644
--- a/src/ds323x/mod.rs
+++ b/src/ds323x/mod.rs
@@ -17,7 +17,7 @@ fn packed_bcd_to_decimal(bcd: u8) -> u8 {
     (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 {
         Hours::H24(h) if h > 23 => Err(Error::InvalidInputData),
         Hours::H24(h) => Ok(decimal_to_packed_bcd(h)),
diff --git a/src/ds323x/status.rs b/src/ds323x/status.rs
index 9a9c7cd..912cf40 100644
--- a/src/ds323x/status.rs
+++ b/src/ds323x/status.rs
@@ -4,18 +4,18 @@ extern crate embedded_hal as hal;
 use super::super::{ Ds323x, Register, BitFlags, Error };
 use interface::{ ReadData, WriteData };
 
-impl<DI, IC, E> Ds323x<DI, IC>
+impl<DI, IC, CommE, PinE> Ds323x<DI, IC>
 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
-    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)?;
         Ok((control & BitFlags::EOSC) == 0)
     }
 
     /// 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)?;
         Ok((status & BitFlags::BUSY) != 0)
     }
@@ -27,7 +27,7 @@ where
     ///
     /// Once this is true, it will stay as such until cleared with
     /// [`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)?;
         Ok((status & BitFlags::OSC_STOP) != 0)
     }
@@ -36,7 +36,7 @@ where
     /// stopped at some point.
     ///
     /// 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;
         self.write_status_without_clearing_alarm(status)
     }
@@ -45,7 +45,7 @@ where
     ///
     /// Once this is true, it will stay as such until cleared with
     /// [`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)?;
         Ok((status & BitFlags::ALARM1F) != 0)
     }
@@ -53,7 +53,7 @@ where
     /// Clear flag signalling whether the Alarm1 has matched at some point.
     ///
     /// 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;
         self.iface.write_register(Register::STATUS, status)
     }
@@ -62,7 +62,7 @@ where
     ///
     /// Once this is true, it will stay as such until cleared with
     /// [`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)?;
         Ok((status & BitFlags::ALARM2F) != 0)
     }
@@ -70,7 +70,7 @@ where
     /// Clear flag signalling whether the Alarm2 has matched at some point.
     ///
     /// 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;
         self.iface.write_register(Register::STATUS, status)
     }
@@ -79,7 +79,7 @@ where
     ///
     /// Note: It is possible to manually force a temperature conversion with
     /// [`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];
         self.iface.read_data(&mut data)?;
         let is_negative = (data[1] & 0b1000_0000) != 0;
diff --git a/src/interface.rs b/src/interface.rs
index f9a2d38..0f7ee26 100644
--- a/src/interface.rs
+++ b/src/interface.rs
@@ -24,56 +24,56 @@ pub trait WriteData {
     /// Error type
     type Error;
     /// 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.
-    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>
 where
     I2C: blocking::i2c::Write<Error = E>
 {
-    type Error = E;
-    fn write_register(&mut self, register: u8, data: u8) -> Result<(), Error<E>> {
+    type Error = Error<E, ()>;
+    fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> {
         let payload: [u8; 2] = [register, data];
         self.i2c
             .write(DEVICE_ADDRESS, &payload)
             .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
             .write(DEVICE_ADDRESS, &payload)
             .map_err(Error::Comm)
     }
 }
 
-impl<SPI, CS, E> WriteData for SpiInterface<SPI, CS>
+impl<SPI, CS, CommE, PinE> WriteData for SpiInterface<SPI, CS>
 where
-    SPI: blocking::spi::Write<u8, Error = E>,
-    CS:  hal::digital::OutputPin
+    SPI: blocking::spi::Write<u8, Error = CommE>,
+    CS:  hal::digital::v2::OutputPin<Error = PinE>
 {
-    type Error = E;
-    fn write_register(&mut self, register: u8, data: u8) -> Result<(), Error<E>> {
-        self.cs.set_low();
+    type Error = Error<CommE, PinE>;
+    fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> {
+        self.cs.set_low().map_err(Error::Pin)?;
 
         let payload: [u8; 2] = [register + 0x80, data];
         let result = self.spi
                          .write(&payload)
                          .map_err(Error::Comm);
 
-        self.cs.set_high();
+        self.cs.set_high().map_err(Error::Pin)?;
         result
     }
 
-    fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Error<Self::Error>> {
-        self.cs.set_low();
+    fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> {
+        self.cs.set_low().map_err(Error::Pin)?;
         payload[0] += 0x80;
         let result = self.spi
                          .write(&payload)
                          .map_err(Error::Comm);
 
-        self.cs.set_high();
+        self.cs.set_high().map_err(Error::Pin)?;
         result
     }
 }
@@ -84,17 +84,17 @@ pub trait ReadData {
     /// Error type
     type Error;
     /// 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.
-    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>
 where
     I2C: blocking::i2c::WriteRead<Error = E>
 {
-    type Error = E;
-    fn read_register(&mut self, register: u8) -> Result<u8, Error<E>> {
+    type Error = Error<E, ()>;
+    fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
         let mut data = [0];
         self.i2c
             .write_read(DEVICE_ADDRESS, &[register], &mut data)
@@ -102,7 +102,7 @@ where
             .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();
         self.i2c
             .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
-    SPI: blocking::spi::Transfer<u8, Error = E>,
-    CS:  hal::digital::OutputPin
+    SPI: blocking::spi::Transfer<u8, Error = CommE>,
+    CS:  hal::digital::v2::OutputPin<Error = PinE>
 {
-    type Error = E;
-    fn read_register(&mut self, register: u8) -> Result<u8, Error<E>> {
-        self.cs.set_low();
+    type Error = Error<CommE, PinE>;
+    fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
+        self.cs.set_low().map_err(Error::Pin)?;
         let mut data = [register, 0];
         let result = self.spi
                          .transfer(&mut data)
                          .map_err(Error::Comm);
-        self.cs.set_high();
-        let result = result?;
-        Ok(result[1])
+        self.cs.set_high().map_err(Error::Pin)?;
+        Ok(result?[1])
     }
 
-    fn read_data(&mut self, mut payload: &mut [u8]) -> Result<(), Error<Self::Error>> {
-        self.cs.set_low();
+    fn read_data(&mut self, mut payload: &mut [u8]) -> Result<(), Self::Error> {
+        self.cs.set_low().map_err(Error::Pin)?;
         let result = self.spi
                          .transfer(&mut payload)
                          .map_err(Error::Comm);
-        self.cs.set_high();
+        self.cs.set_high().map_err(Error::Pin)?;
         result?;
         Ok(())
     }
diff --git a/src/lib.rs b/src/lib.rs
index 25012b9..f44ead7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -448,9 +448,11 @@ use core::marker::PhantomData;
 
 /// All possible errors in this crate
 #[derive(Debug)]
-pub enum Error<E> {
+pub enum Error<CommE, PinE> {
     /// I²C/SPI bus error
-    Comm(E),
+    Comm(CommE),
+    /// Pin setting error
+    Pin(PinE),
     /// Invalid input data provided
     InvalidInputData
 }
diff --git a/tests/common/mod.rs b/tests/common/mod.rs
index bb4a88c..dd83483 100644
--- a/tests/common/mod.rs
+++ b/tests/common/mod.rs
@@ -60,9 +60,10 @@ impl BitFlags {
 
 pub struct DummyOutputPin;
 
-impl embedded_hal::digital::OutputPin for DummyOutputPin {
-    fn set_low(&mut self) {}
-    fn set_high(&mut self) {}
+impl embedded_hal::digital::v2::OutputPin for DummyOutputPin {
+    type Error = ();
+    fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) }
+    fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) }
 }