@@ -10,33 +10,50 @@ use crate::gpio::gpioc::PC9;
1010use crate :: gpio:: gpiof:: { PF0 , PF1 } ;
1111use crate :: gpio:: gpioh:: { PH4 , PH5 , PH7 , PH8 } ;
1212use crate :: gpio:: AlternateOD ;
13- use crate :: hal:: blocking:: i2c:: { Read , Write , WriteRead } ;
13+ use crate :: hal:: i2c:: {
14+ self ,
15+ blocking:: { Read , Write , WriteRead } ,
16+ } ;
1417use crate :: pac:: { DWT , I2C1 , I2C2 , I2C3 } ;
1518use crate :: rcc:: { Clocks , Enable , GetBusFreq , RccBus , Reset } ;
16- use nb:: Error :: { Other , WouldBlock } ;
17- use nb:: { Error as NbError , Result as NbResult } ;
19+ use nb;
1820
1921use cast:: u16;
2022
2123/// I2C error
2224#[ derive( Debug , Eq , PartialEq ) ]
2325#[ non_exhaustive]
2426pub enum Error {
25- /// Bus error
27+ /// Bus error occurred. e.g. A START or a STOP condition is detected and is not
28+ /// located after a multiple of 9 SCL clock pulses.
2629 Bus ,
27- /// Arbitration loss
28- Arbitration ,
29- /// No ack received
30- Acknowledge ,
31- /// Overrun/underrun
30+ /// The arbitration was lost, e.g. electrical problems with the clock signal
31+ ArbitrationLoss ,
32+ /// A bus operation was not acknowledged, e.g. due to the addressed device not
33+ /// being available on the bus or the device not being ready to process requests
34+ /// at the moment
35+ NoAcknowledge ( i2c:: NoAcknowledgeSource ) ,
36+ /// The peripheral receive buffer was overrun
3237 Overrun ,
33- /// Bus is busy
34- Busy ,
38+ /// Timeout
39+ Timeout ,
3540 // Pec, // SMBUS mode only
3641 // Timeout, // SMBUS mode only
3742 // Alert, // SMBUS mode only
3843}
3944
45+ impl i2c:: Error for Error {
46+ fn kind ( & self ) -> i2c:: ErrorKind {
47+ match * self {
48+ Error :: Bus => i2c:: ErrorKind :: Bus ,
49+ Error :: ArbitrationLoss => i2c:: ErrorKind :: ArbitrationLoss ,
50+ Error :: NoAcknowledge ( s) => i2c:: ErrorKind :: NoAcknowledge ( s) ,
51+ Error :: Overrun => i2c:: ErrorKind :: Overrun ,
52+ _ => i2c:: ErrorKind :: Other ,
53+ }
54+ }
55+ }
56+
4057/// SPI mode. The user should make sure that the requested frequency can be
4158/// generated considering the buses clocks.
4259#[ derive( Debug , PartialEq ) ]
@@ -354,20 +371,22 @@ macro_rules! check_status_flag {
354371
355372 if isr. berr( ) . bit_is_set( ) {
356373 $i2c. icr. write( |w| w. berrcf( ) . set_bit( ) ) ;
357- Err ( Other ( Error :: Bus ) )
374+ Err ( nb :: Error :: Other ( Error :: Bus ) )
358375 } else if isr. arlo( ) . bit_is_set( ) {
359376 $i2c. icr. write( |w| w. arlocf( ) . set_bit( ) ) ;
360- Err ( Other ( Error :: Arbitration ) )
377+ Err ( nb :: Error :: Other ( Error :: ArbitrationLoss ) )
361378 } else if isr. nackf( ) . bit_is_set( ) {
362379 $i2c. icr. write( |w| w. stopcf( ) . set_bit( ) . nackcf( ) . set_bit( ) ) ;
363- Err ( Other ( Error :: Acknowledge ) )
380+ Err ( nb:: Error :: Other ( Error :: NoAcknowledge (
381+ i2c:: NoAcknowledgeSource :: Unknown ,
382+ ) ) )
364383 } else if isr. ovr( ) . bit_is_set( ) {
365384 $i2c. icr. write( |w| w. stopcf( ) . set_bit( ) . ovrcf( ) . set_bit( ) ) ;
366- Err ( Other ( Error :: Overrun ) )
385+ Err ( nb :: Error :: Other ( Error :: Overrun ) )
367386 } else if isr. $flag( ) . $status( ) {
368387 Ok ( ( ) )
369388 } else {
370- Err ( WouldBlock )
389+ Err ( nb :: Error :: WouldBlock )
371390 }
372391 } } ;
373392}
@@ -376,7 +395,7 @@ macro_rules! busy_wait {
376395 ( $nb_expr: expr, $exit_cond: expr) => { {
377396 loop {
378397 let res = $nb_expr;
379- if res != Err ( WouldBlock ) {
398+ if res != Err ( nb :: Error :: WouldBlock ) {
380399 break res;
381400 }
382401 if $exit_cond {
@@ -397,6 +416,17 @@ macro_rules! busy_wait_cycles {
397416 } } ;
398417}
399418
419+ // Map non-blocking errors to blocking errors
420+ macro_rules! nbError_to_Error {
421+ ( $nb_expr: expr) => { {
422+ match $nb_expr {
423+ Ok ( ( ) ) => { }
424+ Err ( nb:: Error :: WouldBlock ) => return Err ( Error :: Timeout ) ,
425+ Err ( nb:: Error :: Other ( error) ) => return Err ( error) ,
426+ } ;
427+ } } ;
428+ }
429+
400430// Generate the same code for both I2Cs
401431macro_rules! hal {
402432 ( $( $I2CX: ident: ( $i2cX: ident) , ) +) => {
@@ -531,25 +561,19 @@ macro_rules! hal {
531561
532562 /// Wait for a byte to be read and return it (ie for RXNE flag
533563 /// to be set)
534- fn wait_byte_read( & self ) -> NbResult <u8 , Error > {
564+ fn wait_byte_read( & self ) -> Result <u8 , Error > {
535565 // Wait until we have received something
536- busy_wait_cycles!(
537- check_status_flag!( self . nb. i2c, rxne, is_not_empty) ,
538- self . data_timeout
539- ) ?;
566+ nbError_to_Error!( busy_wait_cycles!( check_status_flag!( self . nb. i2c, rxne, is_not_empty) , self . data_timeout) ) ;
540567
541568 Ok ( self . nb. i2c. rxdr. read( ) . rxdata( ) . bits( ) )
542569 }
543570
544571 /// Wait the write data register to be empty (ie for TXIS flag
545572 /// to be set) and write the byte to it
546- fn wait_byte_write( & self , byte: u8 ) -> NbResult <( ) , Error > {
573+ fn wait_byte_write( & self , byte: u8 ) -> Result <( ) , Error > {
547574 // Wait until we are allowed to send data
548575 // (START has been ACKed or last byte when through)
549- busy_wait_cycles!(
550- check_status_flag!( self . nb. i2c, txis, is_empty) ,
551- self . data_timeout
552- ) ?;
576+ nbError_to_Error!( busy_wait_cycles!( check_status_flag!( self . nb. i2c, txis, is_empty) , self . data_timeout) ) ;
553577
554578 // Put byte on the wire
555579 self . nb. i2c. txdr. write( |w| w. txdata( ) . bits( byte) ) ;
@@ -564,7 +588,7 @@ macro_rules! hal {
564588 }
565589
566590 impl <SCL , SDA > Write for BlockingI2c <$I2CX, SCL , SDA > {
567- type Error = NbError < Error > ;
591+ type Error = Error ;
568592
569593 /// Write bytes to I2C. Currently, `bytes.len()` must be less or
570594 /// equal than 255
@@ -592,7 +616,7 @@ macro_rules! hal {
592616 }
593617
594618 impl <SCL , SDA > Read for BlockingI2c <$I2CX, SCL , SDA > {
595- type Error = NbError < Error > ;
619+ type Error = Error ;
596620
597621 /// Reads enough bytes from slave with `address` to fill `buffer`
598622 fn read( & mut self , addr: u8 , buffer: & mut [ u8 ] ) -> Result <( ) , Self :: Error > {
@@ -620,7 +644,7 @@ macro_rules! hal {
620644 }
621645
622646 impl <SCL , SDA > WriteRead for BlockingI2c <$I2CX, SCL , SDA > {
623- type Error = NbError < Error > ;
647+ type Error = Error ;
624648
625649 fn write_read(
626650 & mut self ,
@@ -642,10 +666,7 @@ macro_rules! hal {
642666
643667 // Wait until the write finishes before beginning to read.
644668 // busy_wait2!(self.nb.i2c, tc, is_complete);
645- busy_wait_cycles!(
646- check_status_flag!( self . nb. i2c, tc, is_complete) ,
647- self . data_timeout
648- ) ?;
669+ nbError_to_Error!( busy_wait_cycles!( check_status_flag!( self . nb. i2c, tc, is_complete) , self . data_timeout) ) ;
649670
650671 // reSTART and prepare to receive bytes into `buffer`
651672 self . nb. start( addr, buffer. len( ) as u8 , true , true ) ;
0 commit comments