1
1
//! Blocking I2C API
2
2
//!
3
- //! Slave addresses used by this API are 7-bit I2C addresses ranging from 0 to 127.
3
+ //! This API supports 7-bit and 10-bit addresses. Traits feature an `AddressMode`
4
+ //! marker type parameter. Two implementation of the `AddressMode` exist:
5
+ //! `SevenBitAddress` and `TenBitAddress`.
4
6
//!
5
- //! Operations on 10-bit slave addresses are not supported by the API yet (but applications might
6
- //! be able to emulate some operations).
7
+ //! Through this marker types it is possible to implement each address mode for
8
+ //! the traits independently in `embedded-hal` implementations and device drivers
9
+ //! can depend only on the mode that they support.
10
+ //!
11
+ //! Additionally, the I2C 10-bit address mode has been developed to be fully
12
+ //! backwards compatible with the 7-bit address mode. This allows for a
13
+ //! software-emulated 10-bit addressing implementation if the address mode
14
+ //! is not supported by the hardware.
15
+ //!
16
+ //! Since 7-bit addressing is the mode of the majority of I2C devices,
17
+ //! `SevenBitAddress` has been set as default mode and thus can be omitted if desired.
18
+ //!
19
+ //! ## Examples
20
+ //!
21
+ //! ### `embedded-hal` implementation for an MCU
22
+ //! Here is an example of an embedded-hal implementation of the `Write` trait
23
+ //! for both modes:
24
+ //! ```
25
+ //! # use embedded_hal::blocking::i2c::{SevenBitAddress, TenBitAddress, Write};
26
+ //! /// I2C0 hardware peripheral which supports both 7-bit and 10-bit addressing.
27
+ //! pub struct I2c0;
28
+ //!
29
+ //! impl Write<SevenBitAddress> for I2c0
30
+ //! {
31
+ //! # type Error = ();
32
+ //! #
33
+ //! fn try_write(&mut self, addr: u8, output: &[u8]) -> Result<(), Self::Error> {
34
+ //! // ...
35
+ //! # Ok(())
36
+ //! }
37
+ //! }
38
+ //!
39
+ //! impl Write<TenBitAddress> for I2c0
40
+ //! {
41
+ //! # type Error = ();
42
+ //! #
43
+ //! fn try_write(&mut self, addr: u16, output: &[u8]) -> Result<(), Self::Error> {
44
+ //! // ...
45
+ //! # Ok(())
46
+ //! }
47
+ //! }
48
+ //! ```
49
+ //!
50
+ //! ### Device driver compatible only with 7-bit addresses
51
+ //!
52
+ //! For demonstration purposes the address mode parameter has been omitted in this example.
53
+ //!
54
+ //! ```
55
+ //! # use embedded_hal::blocking::i2c::WriteRead;
56
+ //! const ADDR: u8 = 0x15;
57
+ //! # const TEMP_REGISTER: u8 = 0x1;
58
+ //! pub struct TemperatureSensorDriver<I2C> {
59
+ //! i2c: I2C,
60
+ //! }
61
+ //!
62
+ //! impl<I2C, E> TemperatureSensorDriver<I2C>
63
+ //! where
64
+ //! I2C: WriteRead<Error = E>,
65
+ //! {
66
+ //! pub fn read_temperature(&mut self) -> Result<u8, E> {
67
+ //! let mut temp = [0];
68
+ //! self.i2c
69
+ //! .try_write_read(ADDR, &[TEMP_REGISTER], &mut temp)
70
+ //! .and(Ok(temp[0]))
71
+ //! }
72
+ //! }
73
+ //! ```
74
+ //!
75
+ //! ### Device driver compatible only with 10-bit addresses
76
+ //!
77
+ //! ```
78
+ //! # use embedded_hal::blocking::i2c::{TenBitAddress, WriteRead};
79
+ //! const ADDR: u16 = 0x158;
80
+ //! # const TEMP_REGISTER: u8 = 0x1;
81
+ //! pub struct TemperatureSensorDriver<I2C> {
82
+ //! i2c: I2C,
83
+ //! }
84
+ //!
85
+ //! impl<I2C, E> TemperatureSensorDriver<I2C>
86
+ //! where
87
+ //! I2C: WriteRead<TenBitAddress, Error = E>,
88
+ //! {
89
+ //! pub fn read_temperature(&mut self) -> Result<u8, E> {
90
+ //! let mut temp = [0];
91
+ //! self.i2c
92
+ //! .try_write_read(ADDR, &[TEMP_REGISTER], &mut temp)
93
+ //! .and(Ok(temp[0]))
94
+ //! }
95
+ //! }
96
+ //! ```
97
+
98
+ use crate :: private;
99
+
100
+ /// Address mode (7-bit / 10-bit)
101
+ ///
102
+ /// Note: This trait is sealed and should not be implemented outside of this crate.
103
+ pub trait AddressMode : private:: Sealed { }
104
+
105
+ /// 7-bit address mode type
106
+ pub type SevenBitAddress = u8 ;
107
+
108
+ /// 10-bit address mode type
109
+ pub type TenBitAddress = u16 ;
110
+
111
+ impl AddressMode for SevenBitAddress { }
112
+
113
+ impl AddressMode for TenBitAddress { }
7
114
8
115
/// Blocking read
9
- pub trait Read {
116
+ pub trait Read < A : AddressMode = SevenBitAddress > {
10
117
/// Error type
11
118
type Error ;
12
119
@@ -28,11 +135,11 @@ pub trait Read {
28
135
/// - `MAK` = master acknowledge
29
136
/// - `NMAK` = master no acknowledge
30
137
/// - `SP` = stop condition
31
- fn try_read ( & mut self , address : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > ;
138
+ fn try_read ( & mut self , address : A , buffer : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > ;
32
139
}
33
140
34
141
/// Blocking write
35
- pub trait Write {
142
+ pub trait Write < A : AddressMode = SevenBitAddress > {
36
143
/// Error type
37
144
type Error ;
38
145
@@ -52,11 +159,11 @@ pub trait Write {
52
159
/// - `SAK` = slave acknowledge
53
160
/// - `Bi` = ith byte of data
54
161
/// - `SP` = stop condition
55
- fn try_write ( & mut self , address : u8 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > ;
162
+ fn try_write ( & mut self , address : A , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > ;
56
163
}
57
164
58
165
/// Blocking write (iterator version)
59
- pub trait WriteIter {
166
+ pub trait WriteIter < A : AddressMode = SevenBitAddress > {
60
167
/// Error type
61
168
type Error ;
62
169
@@ -65,13 +172,13 @@ pub trait WriteIter {
65
172
/// # I2C Events (contract)
66
173
///
67
174
/// Same as `Write`
68
- fn try_write_iter < B > ( & mut self , address : u8 , bytes : B ) -> Result < ( ) , Self :: Error >
175
+ fn try_write_iter < B > ( & mut self , address : A , bytes : B ) -> Result < ( ) , Self :: Error >
69
176
where
70
177
B : IntoIterator < Item = u8 > ;
71
178
}
72
179
73
180
/// Blocking write + read
74
- pub trait WriteRead {
181
+ pub trait WriteRead < A : AddressMode = SevenBitAddress > {
75
182
/// Error type
76
183
type Error ;
77
184
@@ -99,14 +206,14 @@ pub trait WriteRead {
99
206
/// - `SP` = stop condition
100
207
fn try_write_read (
101
208
& mut self ,
102
- address : u8 ,
209
+ address : A ,
103
210
bytes : & [ u8 ] ,
104
211
buffer : & mut [ u8 ] ,
105
212
) -> Result < ( ) , Self :: Error > ;
106
213
}
107
214
108
215
/// Blocking write (iterator version) + read
109
- pub trait WriteIterRead {
216
+ pub trait WriteIterRead < A : AddressMode = SevenBitAddress > {
110
217
/// Error type
111
218
type Error ;
112
219
@@ -118,7 +225,7 @@ pub trait WriteIterRead {
118
225
/// Same as the `WriteRead` trait
119
226
fn try_write_iter_read < B > (
120
227
& mut self ,
121
- address : u8 ,
228
+ address : A ,
122
229
bytes : B ,
123
230
buffer : & mut [ u8 ] ,
124
231
) -> Result < ( ) , Self :: Error >
0 commit comments