2626//! Here is an example of an embedded-hal implementation of the `Write` trait
2727//! for both modes:
2828//! ```
29- //! # use embedded_hal::i2c::{SevenBitAddress, TenBitAddress, blocking::Write};
29+ //! # use embedded_hal::i2c::{ErrorKind, SevenBitAddress, TenBitAddress, blocking::Write};
3030//! /// I2C0 hardware peripheral which supports both 7-bit and 10-bit addressing.
3131//! pub struct I2c0;
3232//!
3333//! impl Write<SevenBitAddress> for I2c0
3434//! {
35- //! # type Error = () ;
35+ //! # type Error = ErrorKind ;
3636//! #
3737//! fn write(&mut self, addr: u8, output: &[u8]) -> Result<(), Self::Error> {
3838//! // ...
4242//!
4343//! impl Write<TenBitAddress> for I2c0
4444//! {
45- //! # type Error = () ;
45+ //! # type Error = ErrorKind ;
4646//! #
4747//! fn write(&mut self, addr: u16, output: &[u8]) -> Result<(), Self::Error> {
4848//! // ...
5656//! For demonstration purposes the address mode parameter has been omitted in this example.
5757//!
5858//! ```
59- //! # use embedded_hal::i2c::blocking::WriteRead;
59+ //! # use embedded_hal::i2c::{ blocking::WriteRead, Error} ;
6060//! const ADDR: u8 = 0x15;
6161//! # const TEMP_REGISTER: u8 = 0x1;
6262//! pub struct TemperatureSensorDriver<I2C> {
6363//! i2c: I2C,
6464//! }
6565//!
66- //! impl<I2C, E: core::fmt::Debug > TemperatureSensorDriver<I2C>
66+ //! impl<I2C, E: Error > TemperatureSensorDriver<I2C>
6767//! where
6868//! I2C: WriteRead<Error = E>,
6969//! {
7979//! ### Device driver compatible only with 10-bit addresses
8080//!
8181//! ```
82- //! # use embedded_hal::i2c::{TenBitAddress, blocking::WriteRead};
82+ //! # use embedded_hal::i2c::{Error, TenBitAddress, blocking::WriteRead};
8383//! const ADDR: u16 = 0x158;
8484//! # const TEMP_REGISTER: u8 = 0x1;
8585//! pub struct TemperatureSensorDriver<I2C> {
8686//! i2c: I2C,
8787//! }
8888//!
89- //! impl<I2C, E: core::fmt::Debug > TemperatureSensorDriver<I2C>
89+ //! impl<I2C, E: Error > TemperatureSensorDriver<I2C>
9090//! where
9191//! I2C: WriteRead<TenBitAddress, Error = E>,
9292//! {
101101
102102use crate :: private;
103103
104+ /// I2C error
105+ pub trait Error : core:: fmt:: Debug {
106+ /// Convert error to a generic I2C error kind
107+ ///
108+ /// By using this method, I2C errors freely defined by HAL implementations
109+ /// can be converted to a set of generic I2C errors upon which generic
110+ /// code can act.
111+ fn kind ( & self ) -> ErrorKind ;
112+ }
113+
114+ /// I2C error kind
115+ ///
116+ /// This represents a common set of I2C operation errors. HAL implementations are
117+ /// free to define more specific or additional error types. However, by providing
118+ /// a mapping to these common I2C errors, generic code can still react to them.
119+ #[ derive( Debug , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
120+ #[ non_exhaustive]
121+ pub enum ErrorKind {
122+ /// An unspecific bus error occurred
123+ Bus ,
124+ /// The arbitration was lost, e.g. electrical problems with the clock signal
125+ ArbitrationLoss ,
126+ /// A bus operation was not acknowledged, e.g. due to the addressed device not being available on
127+ /// the bus or the device not being ready to process requests at the moment
128+ NoAcknowledge ,
129+ /// The peripheral receive buffer was overrun
130+ Overrun ,
131+ /// A different error occurred. The original error may contain more information.
132+ Other ,
133+ }
134+
135+ impl Error for ErrorKind {
136+ fn kind ( & self ) -> ErrorKind {
137+ * self
138+ }
139+ }
140+
141+ impl core:: fmt:: Display for ErrorKind {
142+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
143+ match self {
144+ Self :: Bus => write ! ( f, "An unspecific bus error occurred" ) ,
145+ Self :: ArbitrationLoss => write ! ( f, "The arbitration was lost" ) ,
146+ Self :: NoAcknowledge => write ! ( f, "A bus operation was not acknowledged" ) ,
147+ Self :: Overrun => write ! ( f, "The peripheral receive buffer was overrun" ) ,
148+ Self :: Other => write ! (
149+ f,
150+ "A different error occurred. The original error may contain more information"
151+ ) ,
152+ }
153+ }
154+ }
155+
104156/// Address mode (7-bit / 10-bit)
105157///
106158/// Note: This trait is sealed and should not be implemented outside of this crate.
@@ -119,12 +171,12 @@ impl AddressMode for TenBitAddress {}
119171/// Blocking I2C traits
120172pub mod blocking {
121173
122- use super :: { AddressMode , SevenBitAddress } ;
174+ use super :: { AddressMode , Error , SevenBitAddress } ;
123175
124176 /// Blocking read
125177 pub trait Read < A : AddressMode = SevenBitAddress > {
126178 /// Error type
127- type Error : core :: fmt :: Debug ;
179+ type Error : Error ;
128180
129181 /// Reads enough bytes from slave with `address` to fill `buffer`
130182 ///
@@ -150,7 +202,7 @@ pub mod blocking {
150202 /// Blocking write
151203 pub trait Write < A : AddressMode = SevenBitAddress > {
152204 /// Error type
153- type Error : core :: fmt :: Debug ;
205+ type Error : Error ;
154206
155207 /// Writes bytes to slave with address `address`
156208 ///
@@ -174,7 +226,7 @@ pub mod blocking {
174226 /// Blocking write (iterator version)
175227 pub trait WriteIter < A : AddressMode = SevenBitAddress > {
176228 /// Error type
177- type Error : core :: fmt :: Debug ;
229+ type Error : Error ;
178230
179231 /// Writes bytes to slave with address `address`
180232 ///
@@ -189,7 +241,7 @@ pub mod blocking {
189241 /// Blocking write + read
190242 pub trait WriteRead < A : AddressMode = SevenBitAddress > {
191243 /// Error type
192- type Error : core :: fmt :: Debug ;
244+ type Error : Error ;
193245
194246 /// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
195247 /// single transaction*
@@ -224,7 +276,7 @@ pub mod blocking {
224276 /// Blocking write (iterator version) + read
225277 pub trait WriteIterRead < A : AddressMode = SevenBitAddress > {
226278 /// Error type
227- type Error : core :: fmt :: Debug ;
279+ type Error : Error ;
228280
229281 /// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
230282 /// single transaction*
@@ -258,7 +310,7 @@ pub mod blocking {
258310 /// This allows combining operations within an I2C transaction.
259311 pub trait Transactional < A : AddressMode = SevenBitAddress > {
260312 /// Error type
261- type Error : core :: fmt :: Debug ;
313+ type Error : Error ;
262314
263315 /// Execute the provided operations on the I2C bus.
264316 ///
@@ -285,7 +337,7 @@ pub mod blocking {
285337 /// This allows combining operation within an I2C transaction.
286338 pub trait TransactionalIter < A : AddressMode = SevenBitAddress > {
287339 /// Error type
288- type Error : core :: fmt :: Debug ;
340+ type Error : Error ;
289341
290342 /// Execute the provided operations on the I2C bus (iterator version).
291343 ///
0 commit comments