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
+ /// Bus error occurred. e.g. A START or a STOP condition is detected and is not located after a multiple of 9 SCL clock pulses.
123
+ Bus ,
124
+ /// The arbitration was lost, e.g. electrical problems with the clock signal
125
+ ArbitrationLoss ,
126
+ /// The device did not acknowledge its address. The device may be missing.
127
+ NoAcknowledgeAddress ,
128
+ /// The device did not acknowled the data. It may not be ready to process requests at the moment.
129
+ NoAcknowledgeData ,
130
+ /// The peripheral receive buffer was overrun
131
+ Overrun ,
132
+ /// A different error occurred. The original error may contain more information.
133
+ Other ,
134
+ }
135
+
136
+ impl Error for ErrorKind {
137
+ fn kind ( & self ) -> ErrorKind {
138
+ * self
139
+ }
140
+ }
141
+
142
+ impl core:: fmt:: Display for ErrorKind {
143
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
144
+ match self {
145
+ Self :: Bus => write ! ( f, "Bus error occurred" ) ,
146
+ Self :: ArbitrationLoss => write ! ( f, "The arbitration was lost" ) ,
147
+ Self :: NoAcknowledgeAddress => write ! ( f, "The device did not acknowledge its address" ) ,
148
+ Self :: NoAcknowledgeData => write ! ( f, "The device did not acknowledge the data" ) ,
149
+ Self :: Overrun => write ! ( f, "The peripheral receive buffer was overrun" ) ,
150
+ Self :: Other => write ! (
151
+ f,
152
+ "A different error occurred. The original error may contain more information"
153
+ ) ,
154
+ }
155
+ }
156
+ }
157
+
104
158
/// Address mode (7-bit / 10-bit)
105
159
///
106
160
/// Note: This trait is sealed and should not be implemented outside of this crate.
@@ -119,12 +173,12 @@ impl AddressMode for TenBitAddress {}
119
173
/// Blocking I2C traits
120
174
pub mod blocking {
121
175
122
- use super :: { AddressMode , SevenBitAddress } ;
176
+ use super :: { AddressMode , Error , SevenBitAddress } ;
123
177
124
178
/// Blocking read
125
179
pub trait Read < A : AddressMode = SevenBitAddress > {
126
180
/// Error type
127
- type Error : core :: fmt :: Debug ;
181
+ type Error : Error ;
128
182
129
183
/// Reads enough bytes from slave with `address` to fill `buffer`
130
184
///
@@ -158,7 +212,7 @@ pub mod blocking {
158
212
/// Blocking write
159
213
pub trait Write < A : AddressMode = SevenBitAddress > {
160
214
/// Error type
161
- type Error : core :: fmt :: Debug ;
215
+ type Error : Error ;
162
216
163
217
/// Writes bytes to slave with address `address`
164
218
///
@@ -190,7 +244,7 @@ pub mod blocking {
190
244
/// Blocking write (iterator version)
191
245
pub trait WriteIter < A : AddressMode = SevenBitAddress > {
192
246
/// Error type
193
- type Error : core :: fmt :: Debug ;
247
+ type Error : Error ;
194
248
195
249
/// Writes bytes to slave with address `address`
196
250
///
@@ -216,7 +270,7 @@ pub mod blocking {
216
270
/// Blocking write + read
217
271
pub trait WriteRead < A : AddressMode = SevenBitAddress > {
218
272
/// Error type
219
- type Error : core :: fmt :: Debug ;
273
+ type Error : Error ;
220
274
221
275
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
222
276
/// single transaction*
@@ -264,7 +318,7 @@ pub mod blocking {
264
318
/// Blocking write (iterator version) + read
265
319
pub trait WriteIterRead < A : AddressMode = SevenBitAddress > {
266
320
/// Error type
267
- type Error : core :: fmt :: Debug ;
321
+ type Error : Error ;
268
322
269
323
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
270
324
/// single transaction*
@@ -314,7 +368,7 @@ pub mod blocking {
314
368
/// This allows combining operations within an I2C transaction.
315
369
pub trait Transactional < A : AddressMode = SevenBitAddress > {
316
370
/// Error type
317
- type Error : core :: fmt :: Debug ;
371
+ type Error : Error ;
318
372
319
373
/// Execute the provided operations on the I2C bus.
320
374
///
@@ -353,7 +407,7 @@ pub mod blocking {
353
407
/// This allows combining operation within an I2C transaction.
354
408
pub trait TransactionalIter < A : AddressMode = SevenBitAddress > {
355
409
/// Error type
356
- type Error : core :: fmt :: Debug ;
410
+ type Error : Error ;
357
411
358
412
/// Execute the provided operations on the I2C bus (iterator version).
359
413
///
0 commit comments