26
26
//! Here is an example of an embedded-hal implementation of the `Write` trait
27
27
//! for both modes:
28
28
//! ```
29
- //! # use embedded_hal::i2c::{SevenBitAddress, TenBitAddress, blocking::Write};
29
+ //! # use embedded_hal::i2c::{ErrorKind, SevenBitAddress, TenBitAddress, blocking::Write};
30
30
//! /// I2C0 hardware peripheral which supports both 7-bit and 10-bit addressing.
31
31
//! pub struct I2c0;
32
32
//!
33
33
//! impl Write<SevenBitAddress> for I2c0
34
34
//! {
35
- //! # type Error = () ;
35
+ //! # type Error = ErrorKind ;
36
36
//! #
37
37
//! fn write(&mut self, addr: u8, output: &[u8]) -> Result<(), Self::Error> {
38
38
//! // ...
42
42
//!
43
43
//! impl Write<TenBitAddress> for I2c0
44
44
//! {
45
- //! # type Error = () ;
45
+ //! # type Error = ErrorKind ;
46
46
//! #
47
47
//! fn write(&mut self, addr: u16, output: &[u8]) -> Result<(), Self::Error> {
48
48
//! // ...
56
56
//! For demonstration purposes the address mode parameter has been omitted in this example.
57
57
//!
58
58
//! ```
59
- //! # use embedded_hal::i2c::blocking::WriteRead;
59
+ //! # use embedded_hal::i2c::{ blocking::WriteRead, Error} ;
60
60
//! const ADDR: u8 = 0x15;
61
61
//! # const TEMP_REGISTER: u8 = 0x1;
62
62
//! pub struct TemperatureSensorDriver<I2C> {
63
63
//! i2c: I2C,
64
64
//! }
65
65
//!
66
- //! impl<I2C, E: core::fmt::Debug > TemperatureSensorDriver<I2C>
66
+ //! impl<I2C, E: Error > TemperatureSensorDriver<I2C>
67
67
//! where
68
68
//! I2C: WriteRead<Error = E>,
69
69
//! {
79
79
//! ### Device driver compatible only with 10-bit addresses
80
80
//!
81
81
//! ```
82
- //! # use embedded_hal::i2c::{TenBitAddress, blocking::WriteRead};
82
+ //! # use embedded_hal::i2c::{Error, TenBitAddress, blocking::WriteRead};
83
83
//! const ADDR: u16 = 0x158;
84
84
//! # const TEMP_REGISTER: u8 = 0x1;
85
85
//! pub struct TemperatureSensorDriver<I2C> {
86
86
//! i2c: I2C,
87
87
//! }
88
88
//!
89
- //! impl<I2C, E: core::fmt::Debug > TemperatureSensorDriver<I2C>
89
+ //! impl<I2C, E: Error > TemperatureSensorDriver<I2C>
90
90
//! where
91
91
//! I2C: WriteRead<TenBitAddress, Error = E>,
92
92
//! {
101
101
102
102
use crate :: private;
103
103
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
+
104
156
/// Address mode (7-bit / 10-bit)
105
157
///
106
158
/// Note: This trait is sealed and should not be implemented outside of this crate.
@@ -119,12 +171,12 @@ impl AddressMode for TenBitAddress {}
119
171
/// Blocking I2C traits
120
172
pub mod blocking {
121
173
122
- use super :: { AddressMode , SevenBitAddress } ;
174
+ use super :: { AddressMode , Error , SevenBitAddress } ;
123
175
124
176
/// Blocking read
125
177
pub trait Read < A : AddressMode = SevenBitAddress > {
126
178
/// Error type
127
- type Error : core :: fmt :: Debug ;
179
+ type Error : Error ;
128
180
129
181
/// Reads enough bytes from slave with `address` to fill `buffer`
130
182
///
@@ -158,7 +210,7 @@ pub mod blocking {
158
210
/// Blocking write
159
211
pub trait Write < A : AddressMode = SevenBitAddress > {
160
212
/// Error type
161
- type Error : core :: fmt :: Debug ;
213
+ type Error : Error ;
162
214
163
215
/// Writes bytes to slave with address `address`
164
216
///
@@ -190,7 +242,7 @@ pub mod blocking {
190
242
/// Blocking write (iterator version)
191
243
pub trait WriteIter < A : AddressMode = SevenBitAddress > {
192
244
/// Error type
193
- type Error : core :: fmt :: Debug ;
245
+ type Error : Error ;
194
246
195
247
/// Writes bytes to slave with address `address`
196
248
///
@@ -216,7 +268,7 @@ pub mod blocking {
216
268
/// Blocking write + read
217
269
pub trait WriteRead < A : AddressMode = SevenBitAddress > {
218
270
/// Error type
219
- type Error : core :: fmt :: Debug ;
271
+ type Error : Error ;
220
272
221
273
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
222
274
/// single transaction*
@@ -264,7 +316,7 @@ pub mod blocking {
264
316
/// Blocking write (iterator version) + read
265
317
pub trait WriteIterRead < A : AddressMode = SevenBitAddress > {
266
318
/// Error type
267
- type Error : core :: fmt :: Debug ;
319
+ type Error : Error ;
268
320
269
321
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
270
322
/// single transaction*
@@ -314,7 +366,7 @@ pub mod blocking {
314
366
/// This allows combining operations within an I2C transaction.
315
367
pub trait Transactional < A : AddressMode = SevenBitAddress > {
316
368
/// Error type
317
- type Error : core :: fmt :: Debug ;
369
+ type Error : Error ;
318
370
319
371
/// Execute the provided operations on the I2C bus.
320
372
///
@@ -353,7 +405,7 @@ pub mod blocking {
353
405
/// This allows combining operation within an I2C transaction.
354
406
pub trait TransactionalIter < A : AddressMode = SevenBitAddress > {
355
407
/// Error type
356
- type Error : core :: fmt :: Debug ;
408
+ type Error : Error ;
357
409
358
410
/// Execute the provided operations on the I2C bus (iterator version).
359
411
///
0 commit comments