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> 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> 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 ;
179
+ type Error : Error ;
128
180
129
181
/// Reads enough bytes from slave with `address` to fill `buffer`
130
182
///
@@ -150,7 +202,7 @@ pub mod blocking {
150
202
/// Blocking write
151
203
pub trait Write < A : AddressMode = SevenBitAddress > {
152
204
/// Error type
153
- type Error ;
205
+ type Error : Error ;
154
206
155
207
/// Writes bytes to slave with address `address`
156
208
///
@@ -174,7 +226,7 @@ pub mod blocking {
174
226
/// Blocking write (iterator version)
175
227
pub trait WriteIter < A : AddressMode = SevenBitAddress > {
176
228
/// Error type
177
- type Error ;
229
+ type Error : Error ;
178
230
179
231
/// Writes bytes to slave with address `address`
180
232
///
@@ -189,7 +241,7 @@ pub mod blocking {
189
241
/// Blocking write + read
190
242
pub trait WriteRead < A : AddressMode = SevenBitAddress > {
191
243
/// Error type
192
- type Error ;
244
+ type Error : Error ;
193
245
194
246
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
195
247
/// single transaction*
@@ -224,7 +276,7 @@ pub mod blocking {
224
276
/// Blocking write (iterator version) + read
225
277
pub trait WriteIterRead < A : AddressMode = SevenBitAddress > {
226
278
/// Error type
227
- type Error ;
279
+ type Error : Error ;
228
280
229
281
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
230
282
/// single transaction*
@@ -258,7 +310,7 @@ pub mod blocking {
258
310
/// This allows combining operations within an I2C transaction.
259
311
pub trait Transactional < A : AddressMode = SevenBitAddress > {
260
312
/// Error type
261
- type Error ;
313
+ type Error : Error ;
262
314
263
315
/// Execute the provided operations on the I2C bus.
264
316
///
@@ -285,7 +337,7 @@ pub mod blocking {
285
337
/// This allows combining operation within an I2C transaction.
286
338
pub trait TransactionalIter < A : AddressMode = SevenBitAddress > {
287
339
/// Error type
288
- type Error ;
340
+ type Error : Error ;
289
341
290
342
/// Execute the provided operations on the I2C bus (iterator version).
291
343
///
0 commit comments