@@ -10,33 +10,50 @@ use crate::gpio::gpioc::PC9;
10
10
use crate :: gpio:: gpiof:: { PF0 , PF1 } ;
11
11
use crate :: gpio:: gpioh:: { PH4 , PH5 , PH7 , PH8 } ;
12
12
use 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
+ } ;
14
17
use crate :: pac:: { DWT , I2C1 , I2C2 , I2C3 } ;
15
18
use 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;
18
20
19
21
use cast:: u16;
20
22
21
23
/// I2C error
22
24
#[ derive( Debug , Eq , PartialEq ) ]
23
25
#[ non_exhaustive]
24
26
pub 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.
26
29
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
32
37
Overrun ,
33
- /// Bus is busy
34
- Busy ,
38
+ /// Timeout
39
+ Timeout ,
35
40
// Pec, // SMBUS mode only
36
41
// Timeout, // SMBUS mode only
37
42
// Alert, // SMBUS mode only
38
43
}
39
44
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
+
40
57
/// SPI mode. The user should make sure that the requested frequency can be
41
58
/// generated considering the buses clocks.
42
59
#[ derive( Debug , PartialEq ) ]
@@ -354,20 +371,22 @@ macro_rules! check_status_flag {
354
371
355
372
if isr. berr( ) . bit_is_set( ) {
356
373
$i2c. icr. write( |w| w. berrcf( ) . set_bit( ) ) ;
357
- Err ( Other ( Error :: Bus ) )
374
+ Err ( nb :: Error :: Other ( Error :: Bus ) )
358
375
} else if isr. arlo( ) . bit_is_set( ) {
359
376
$i2c. icr. write( |w| w. arlocf( ) . set_bit( ) ) ;
360
- Err ( Other ( Error :: Arbitration ) )
377
+ Err ( nb :: Error :: Other ( Error :: ArbitrationLoss ) )
361
378
} else if isr. nackf( ) . bit_is_set( ) {
362
379
$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
+ ) ) )
364
383
} else if isr. ovr( ) . bit_is_set( ) {
365
384
$i2c. icr. write( |w| w. stopcf( ) . set_bit( ) . ovrcf( ) . set_bit( ) ) ;
366
- Err ( Other ( Error :: Overrun ) )
385
+ Err ( nb :: Error :: Other ( Error :: Overrun ) )
367
386
} else if isr. $flag( ) . $status( ) {
368
387
Ok ( ( ) )
369
388
} else {
370
- Err ( WouldBlock )
389
+ Err ( nb :: Error :: WouldBlock )
371
390
}
372
391
} } ;
373
392
}
@@ -376,7 +395,7 @@ macro_rules! busy_wait {
376
395
( $nb_expr: expr, $exit_cond: expr) => { {
377
396
loop {
378
397
let res = $nb_expr;
379
- if res != Err ( WouldBlock ) {
398
+ if res != Err ( nb :: Error :: WouldBlock ) {
380
399
break res;
381
400
}
382
401
if $exit_cond {
@@ -397,6 +416,17 @@ macro_rules! busy_wait_cycles {
397
416
} } ;
398
417
}
399
418
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
+
400
430
// Generate the same code for both I2Cs
401
431
macro_rules! hal {
402
432
( $( $I2CX: ident: ( $i2cX: ident) , ) +) => {
@@ -531,25 +561,19 @@ macro_rules! hal {
531
561
532
562
/// Wait for a byte to be read and return it (ie for RXNE flag
533
563
/// to be set)
534
- fn wait_byte_read( & self ) -> NbResult <u8 , Error > {
564
+ fn wait_byte_read( & self ) -> Result <u8 , Error > {
535
565
// 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) ) ;
540
567
541
568
Ok ( self . nb. i2c. rxdr. read( ) . rxdata( ) . bits( ) )
542
569
}
543
570
544
571
/// Wait the write data register to be empty (ie for TXIS flag
545
572
/// 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 > {
547
574
// Wait until we are allowed to send data
548
575
// (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) ) ;
553
577
554
578
// Put byte on the wire
555
579
self . nb. i2c. txdr. write( |w| w. txdata( ) . bits( byte) ) ;
@@ -564,7 +588,7 @@ macro_rules! hal {
564
588
}
565
589
566
590
impl <SCL , SDA > Write for BlockingI2c <$I2CX, SCL , SDA > {
567
- type Error = NbError < Error > ;
591
+ type Error = Error ;
568
592
569
593
/// Write bytes to I2C. Currently, `bytes.len()` must be less or
570
594
/// equal than 255
@@ -592,7 +616,7 @@ macro_rules! hal {
592
616
}
593
617
594
618
impl <SCL , SDA > Read for BlockingI2c <$I2CX, SCL , SDA > {
595
- type Error = NbError < Error > ;
619
+ type Error = Error ;
596
620
597
621
/// Reads enough bytes from slave with `address` to fill `buffer`
598
622
fn read( & mut self , addr: u8 , buffer: & mut [ u8 ] ) -> Result <( ) , Self :: Error > {
@@ -620,7 +644,7 @@ macro_rules! hal {
620
644
}
621
645
622
646
impl <SCL , SDA > WriteRead for BlockingI2c <$I2CX, SCL , SDA > {
623
- type Error = NbError < Error > ;
647
+ type Error = Error ;
624
648
625
649
fn write_read(
626
650
& mut self ,
@@ -642,10 +666,7 @@ macro_rules! hal {
642
666
643
667
// Wait until the write finishes before beginning to read.
644
668
// 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) ) ;
649
670
650
671
// reSTART and prepare to receive bytes into `buffer`
651
672
self . nb. start( addr, buffer. len( ) as u8 , true , true ) ;
0 commit comments