22
33use core:: iter:: TrustedLen ;
44use core:: marker:: PhantomData ;
5+ use core:: ops:: Deref ;
56use embedded_hal;
67use stm32f7:: stm32f7x6:: {
7- i2c1:: { self , RegisterBlock } ,
8+ i2c1,
89 RCC ,
10+ self as device,
911} ;
1012
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+
1321/// Represents an I2C (Inter-Integrated Circuit) bus.
14- pub struct I2C < ' a > ( & ' a RegisterBlock ) ;
22+ pub struct I2C < I : I2cTrait > ( I ) ;
1523
1624/// Errors that can happen while accessing the I2C bus.
1725#[ derive( Debug ) ]
@@ -49,8 +57,8 @@ fn icr_clear_all(w: &mut i2c1::icr::W) -> &mut i2c1::icr::W {
4957/// An active connection to a device on the I2C bus.
5058///
5159/// 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 > ,
5462 device_address : Address ,
5563 register_type : PhantomData < T > ,
5664}
@@ -107,7 +115,7 @@ impl RegisterType for u16 {
107115 }
108116}
109117
110- impl < ' a , ' i : ' a , T : RegisterType > I2cConnection < ' a , ' i , T > {
118+ impl < ' a , I : I2cTrait , T : RegisterType > I2cConnection < ' a , I , T > {
111119 fn start ( & mut self , read : bool , bytes : u8 ) {
112120 self . i2c . 0 . cr2 . write ( |w| {
113121 w. sadd ( ) . bits ( self . device_address . 0 ) ; // slave_address
@@ -213,15 +221,15 @@ impl<'a, 'i: 'a, T: RegisterType> I2cConnection<'a, 'i, T> {
213221 }
214222}
215223
216- impl < ' a > I2C < ' a > {
224+ impl < I : I2cTrait > I2C < I > {
217225 /// Connects to the specified device and run the closure `f` with the connection as argument.
218226 ///
219227 /// This function takes an exclusive reference to the `I2C` type because it blocks the I2C
220228 /// bus. The connection is active until the closure `f` returns.
221229 pub fn connect < T , F > ( & mut self , device_address : Address , f : F ) -> Result < ( ) , Error >
222230 where
223231 T : RegisterType ,
224- F : FnOnce ( I2cConnection < T > ) -> Result < ( ) , Error > ,
232+ F : FnOnce ( I2cConnection < I , T > ) -> Result < ( ) , Error > ,
225233 {
226234 {
227235 let conn = I2cConnection {
@@ -384,29 +392,29 @@ impl<'a> I2C<'a> {
384392 }
385393}
386394
387- impl < ' a > embedded_hal:: blocking:: i2c:: Read for I2C < ' a > {
395+ impl < I : I2cTrait > embedded_hal:: blocking:: i2c:: Read for I2C < I > {
388396 type Error = Error ;
389397
390398 fn read ( & mut self , address : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
391399 self . connect (
392400 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 ( ) ) ,
394402 )
395403 }
396404}
397405
398- impl < ' a > embedded_hal:: blocking:: i2c:: Write for I2C < ' a > {
406+ impl < I : I2cTrait > embedded_hal:: blocking:: i2c:: Write for I2C < I > {
399407 type Error = Error ;
400408
401409 fn write ( & mut self , address : u8 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
402410 self . connect (
403411 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) ) ,
405413 )
406414 }
407415}
408416
409- impl < ' a > embedded_hal:: blocking:: i2c:: WriteRead for I2C < ' a > {
417+ impl < I : I2cTrait > embedded_hal:: blocking:: i2c:: WriteRead for I2C < I > {
410418 type Error = Error ;
411419
412420 fn write_read (
@@ -417,7 +425,7 @@ impl<'a> embedded_hal::blocking::i2c::WriteRead for I2C<'a> {
417425 ) -> Result < ( ) , Self :: Error > {
418426 self . connect (
419427 Address :: bits_7 ( address) ,
420- |mut connection : I2cConnection < u8 > | {
428+ |mut connection : I2cConnection < I , u8 > | {
421429 connection. write_bytes ( bytes. iter ( ) . map ( |b| * b) ) ?;
422430 connection. read_bytes_raw ( buffer. iter_mut ( ) )
423431 } ,
@@ -426,12 +434,7 @@ impl<'a> embedded_hal::blocking::i2c::WriteRead for I2C<'a> {
426434}
427435
428436/// 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 > {
435438 // enable clocks
436439 rcc. apb1enr . modify ( |_, w| w. i2c3en ( ) . enabled ( ) ) ;
437440
0 commit comments