2
2
3
3
use core:: iter:: TrustedLen ;
4
4
use core:: marker:: PhantomData ;
5
+ use core:: ops:: Deref ;
5
6
use embedded_hal;
6
7
use stm32f7:: stm32f7x6:: {
7
- i2c1:: { self , RegisterBlock } ,
8
+ i2c1,
8
9
RCC ,
10
+ self as device,
9
11
} ;
10
12
11
- // TODO use &mut when svd2rust API has changed (modification should require &mut)
12
- //pub struct I2C<'a>(&'a mut RegisterBlock);
13
+ pub trait I2cTrait : Deref < Target = i2c1:: RegisterBlock > {
14
+
15
+ }
16
+
17
+ impl I2cTrait for device:: I2C1 { }
18
+ impl I2cTrait for device:: I2C2 { }
19
+ impl I2cTrait for device:: I2C3 { }
20
+
13
21
/// Represents an I2C (Inter-Integrated Circuit) bus.
14
- pub struct I2C < ' a > ( & ' a RegisterBlock ) ;
22
+ pub struct I2C < I : I2cTrait > ( I ) ;
15
23
16
24
/// Errors that can happen while accessing the I2C bus.
17
25
#[ derive( Debug ) ]
@@ -49,8 +57,8 @@ fn icr_clear_all(w: &mut i2c1::icr::W) -> &mut i2c1::icr::W {
49
57
/// An active connection to a device on the I2C bus.
50
58
///
51
59
/// Allows reading and writing the registers of the device.
52
- pub struct I2cConnection < ' a , ' i : ' a , T : RegisterType > {
53
- i2c : & ' a mut I2C < ' i > ,
60
+ pub struct I2cConnection < ' a , I : I2cTrait , T : RegisterType > {
61
+ i2c : & ' a mut I2C < I > ,
54
62
device_address : Address ,
55
63
register_type : PhantomData < T > ,
56
64
}
@@ -107,7 +115,7 @@ impl RegisterType for u16 {
107
115
}
108
116
}
109
117
110
- impl < ' a , ' i : ' a , T : RegisterType > I2cConnection < ' a , ' i , T > {
118
+ impl < ' a , I : I2cTrait , T : RegisterType > I2cConnection < ' a , I , T > {
111
119
fn start ( & mut self , read : bool , bytes : u8 ) {
112
120
self . i2c . 0 . cr2 . write ( |w| {
113
121
w. sadd ( ) . bits ( self . device_address . 0 ) ; // slave_address
@@ -213,15 +221,15 @@ impl<'a, 'i: 'a, T: RegisterType> I2cConnection<'a, 'i, T> {
213
221
}
214
222
}
215
223
216
- impl < ' a > I2C < ' a > {
224
+ impl < I : I2cTrait > I2C < I > {
217
225
/// Connects to the specified device and run the closure `f` with the connection as argument.
218
226
///
219
227
/// This function takes an exclusive reference to the `I2C` type because it blocks the I2C
220
228
/// bus. The connection is active until the closure `f` returns.
221
229
pub fn connect < T , F > ( & mut self , device_address : Address , f : F ) -> Result < ( ) , Error >
222
230
where
223
231
T : RegisterType ,
224
- F : FnOnce ( I2cConnection < T > ) -> Result < ( ) , Error > ,
232
+ F : FnOnce ( I2cConnection < I , T > ) -> Result < ( ) , Error > ,
225
233
{
226
234
{
227
235
let conn = I2cConnection {
@@ -384,29 +392,29 @@ impl<'a> I2C<'a> {
384
392
}
385
393
}
386
394
387
- impl < ' a > embedded_hal:: blocking:: i2c:: Read for I2C < ' a > {
395
+ impl < I : I2cTrait > embedded_hal:: blocking:: i2c:: Read for I2C < I > {
388
396
type Error = Error ;
389
397
390
398
fn read ( & mut self , address : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
391
399
self . connect (
392
400
Address :: bits_7 ( address) ,
393
- |mut connection : I2cConnection < u8 > | connection. read_bytes_raw ( buffer. iter_mut ( ) ) ,
401
+ |mut connection : I2cConnection < I , u8 > | connection. read_bytes_raw ( buffer. iter_mut ( ) ) ,
394
402
)
395
403
}
396
404
}
397
405
398
- impl < ' a > embedded_hal:: blocking:: i2c:: Write for I2C < ' a > {
406
+ impl < I : I2cTrait > embedded_hal:: blocking:: i2c:: Write for I2C < I > {
399
407
type Error = Error ;
400
408
401
409
fn write ( & mut self , address : u8 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
402
410
self . connect (
403
411
Address :: bits_7 ( address) ,
404
- |mut connection : I2cConnection < u8 > | connection. write_bytes ( bytes. iter ( ) . map ( |b| * b) ) ,
412
+ |mut connection : I2cConnection < I , u8 > | connection. write_bytes ( bytes. iter ( ) . map ( |b| * b) ) ,
405
413
)
406
414
}
407
415
}
408
416
409
- impl < ' a > embedded_hal:: blocking:: i2c:: WriteRead for I2C < ' a > {
417
+ impl < I : I2cTrait > embedded_hal:: blocking:: i2c:: WriteRead for I2C < I > {
410
418
type Error = Error ;
411
419
412
420
fn write_read (
@@ -417,7 +425,7 @@ impl<'a> embedded_hal::blocking::i2c::WriteRead for I2C<'a> {
417
425
) -> Result < ( ) , Self :: Error > {
418
426
self . connect (
419
427
Address :: bits_7 ( address) ,
420
- |mut connection : I2cConnection < u8 > | {
428
+ |mut connection : I2cConnection < I , u8 > | {
421
429
connection. write_bytes ( bytes. iter ( ) . map ( |b| * b) ) ?;
422
430
connection. read_bytes_raw ( buffer. iter_mut ( ) )
423
431
} ,
@@ -426,12 +434,7 @@ impl<'a> embedded_hal::blocking::i2c::WriteRead for I2C<'a> {
426
434
}
427
435
428
436
/// Initialize the I2C bus and return an `I2C` type.
429
- ///
430
- /// The IC2 type assumes that it has ownership of the I2C buffer. Therefore it is unsafe to access
431
- /// the passed RegisterBlock as long as the I2C lives. (This function should take a
432
- /// `&mut RegisterBlock`, but this is not possible due to the API that svd2rust generates. See
433
- /// [stm32f7-discovery#72](https://github.com/embed-rs/stm32f7-discovery/issues/72) for more info.
434
- pub fn init < ' a > ( i2c : & ' a RegisterBlock , rcc : & mut RCC ) -> I2C < ' a > {
437
+ pub fn init < I : I2cTrait > ( i2c : I , rcc : & mut RCC ) -> I2C < I > {
435
438
// enable clocks
436
439
rcc. apb1enr . modify ( |_, w| w. i2c3en ( ) . enabled ( ) ) ;
437
440
0 commit comments