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}