lpc8xx_hal/i2c/error.rs
1use super::{master, Instance};
2
3/// I2C error
4#[derive(Debug, Eq, PartialEq)]
5#[non_exhaustive]
6pub enum Error {
7 /// Event Timeout
8 ///
9 /// Corresponds to the EVENTTIMEOUT flag in the STAT register.
10 EventTimeout,
11
12 /// Master Arbitration Loss
13 ///
14 /// Corresponds to the MSTARBLOSS flag in the STAT register.
15 MasterArbitrationLoss,
16
17 /// Master Start/Stop Error
18 ///
19 /// Corresponds to the MSTSTSTPERR flag in the STAT register.
20 MasterStartStopError,
21
22 /// Monitor Overflow
23 ///
24 /// Corresponds to the MONOV flag in the STAT register.
25 MonitorOverflow,
26
27 /// SCL Timeout
28 ///
29 /// Corresponds to the SCLTIMEOUT flag in the STAT register.
30 SclTimeout,
31
32 /// The I2C code encountered an unexpected hardware state
33 UnexpectedState {
34 /// The state that was expected
35 expected: master::State,
36
37 /// The state that was actually set
38 ///
39 /// The `Ok` variant represents a valid state. The `Err` variant
40 /// represents an invalid bit pattern in the MSTSTATE field.
41 actual: Result<master::State, u8>,
42 },
43
44 /// An unencodable address was specified.
45 ///
46 /// Currently, only seven-bit addressing is implemented.
47 AddressOutOfRange,
48
49 /// While in slave mode, an unknown state was detected
50 UnknownSlaveState(u8),
51}
52
53impl Error {
54 pub(super) fn check_address(address: u8) -> Result<(), Self> {
55 if address > 0b111_1111 {
56 return Err(Self::AddressOutOfRange);
57 }
58
59 Ok(())
60 }
61
62 pub(super) fn read<I: Instance>() -> Result<(), Self> {
63 // Sound, as we're only reading from the STAT register.
64 let i2c = unsafe { &*I::REGISTERS };
65
66 let stat = i2c.stat.read();
67
68 // Check for error flags. If one is set, clear it and return the error.
69 if stat.mstarbloss().bit_is_set() {
70 i2c.stat.write(|w| w.mstarbloss().set_bit());
71 return Err(Self::MasterArbitrationLoss);
72 }
73 if stat.mstststperr().bit_is_set() {
74 i2c.stat.write(|w| w.mstststperr().set_bit());
75 return Err(Self::MasterStartStopError);
76 }
77 if stat.monov().bit_is_set() {
78 i2c.stat.write(|w| w.monov().set_bit());
79 return Err(Self::MonitorOverflow);
80 }
81 if stat.eventtimeout().bit_is_set() {
82 i2c.stat.write(|w| w.eventtimeout().set_bit());
83 return Err(Self::EventTimeout);
84 }
85 if stat.scltimeout().bit_is_set() {
86 i2c.stat.write(|w| w.scltimeout().set_bit());
87 return Err(Self::SclTimeout);
88 }
89
90 Ok(())
91 }
92}