stm32f1_hal/common/i2c/
mod.rs

1mod i2c_bus_it;
2mod i2c_device;
3mod utils;
4
5pub use crate::common::{bus_device::Operation, embedded_hal::i2c::NoAcknowledgeSource};
6pub use i2c_bus_it::*;
7pub use i2c_device::*;
8
9use crate::common::{embedded_hal::i2c::ErrorKind, fugit::HertzU32, os_trait::prelude::*};
10
11pub trait I2cPeriph {
12    /// Disable all interrupt
13    fn disable_all_interrupt(&mut self);
14    /// Disable receiving data interrupt
15    fn disable_data_interrupt(&mut self);
16    fn it_send_start(&mut self);
17    /// # Returns
18    /// - `Ok()`: finished
19    /// - `Err(true)`: did something but hasn't finished
20    /// - `Err(false)`: did nothing and need to wait
21    fn it_prepare_write(&mut self, addr: Address, step: &mut u8) -> Result<(), bool>;
22    /// # Returns
23    /// - `Ok()`: finished
24    /// - `Err(true)`: did something but hasn't finished
25    /// - `Err(false)`: did nothing and need to wait
26    fn it_prepare_read(
27        &mut self,
28        addr: Address,
29        total_len: usize,
30        last_operation: bool,
31        step: &mut u8,
32    ) -> Result<(), bool>;
33    /// # Returns
34    /// - `Ok()`: finished writing all data
35    /// - `Err(true)`: wrote some data
36    /// - `Err(false)`: did nothing and need to wait
37    fn it_write_with(&mut self, f: impl FnMut() -> Option<u8>) -> Result<(), bool>;
38    fn it_read(&mut self, left_len: usize, last_operation: bool) -> Option<u8>;
39
40    fn send_stop(&mut self);
41    fn is_stopped(&mut self) -> bool;
42    fn is_slave_stopped(&mut self) -> bool;
43
44    /// Read and clean the error flag
45    fn get_and_clean_error(&mut self) -> Option<Error>;
46    fn get_flag(&mut self, flag: Flag) -> bool;
47
48    fn set_speed(&mut self, speed: HertzU32);
49    /// Perform an I2C software reset
50    fn soft_reset(&mut self);
51    fn handle_error(&mut self, err: Error);
52    // fn read_sr(&mut self) -> u32;
53}
54
55pub trait I2cBusInterface {
56    fn transaction(
57        &mut self,
58        slave_addr: Address,
59        speed: HertzU32,
60        operations: &mut [Operation<'_, u8>],
61    ) -> Result<(), Error>;
62}
63
64#[derive(Clone, Copy, Debug, Eq, PartialEq)]
65pub enum Flag {
66    /// Start condition generated
67    Started,
68    /// Busy
69    Busy,
70    /// Address is sent in master mode or received and matches in slave mode
71    AddressSent,
72    /// Byte transfer finished
73    ByteTransferFinished,
74    /// 10-bit header sent
75    Address10Sent,
76    /// Data register not empty
77    RxNotEmpty,
78    /// Data register empty
79    TxEmpty,
80    /// SMBus alert
81    MasterSlave,
82    /// Master/Slave
83    Transmitter,
84    /// General call address (Slave mode)
85    GeneralCall,
86    /// SMBus device default address (Slave mode)
87    SMBusDefault,
88    /// SMBus host header (Slave mode)
89    SMBusHost,
90    /// Dual flag (Slave mode)
91    Dual,
92}
93
94#[derive(Clone, Copy, Debug, Eq, PartialEq)]
95pub enum Address {
96    Seven(u8),
97    Ten(u16),
98}
99
100impl From<u8> for Address {
101    fn from(value: u8) -> Self {
102        Self::Seven(value)
103    }
104}
105
106impl From<u16> for Address {
107    fn from(value: u16) -> Self {
108        Self::Ten(value)
109    }
110}
111
112#[derive(Debug, Eq, PartialEq, Copy, Clone)]
113#[non_exhaustive]
114pub enum Error {
115    Busy,
116    /// Overrun/underrun
117    Overrun,
118    /// No ack received
119    NoAcknowledge(NoAcknowledgeSource),
120    Timeout,
121    /// Bus error
122    Bus,
123    Crc,
124    /// Arbitration was lost
125    ArbitrationLoss,
126    /// SMBus alert
127    SMBusAlert,
128    /// SMBus PEC Error in reception
129    Pec,
130    /// SMBus timeout
131    SMBusTimeout,
132    Buffer,
133    Other,
134}
135
136impl Error {
137    pub(crate) fn nack_addr(self) -> Self {
138        match self {
139            Self::NoAcknowledge(NoAcknowledgeSource::Unknown) => {
140                Self::NoAcknowledge(NoAcknowledgeSource::Address)
141            }
142            e => e,
143        }
144    }
145    pub(crate) fn nack_data(self) -> Self {
146        match self {
147            Self::NoAcknowledge(NoAcknowledgeSource::Unknown) => {
148                Self::NoAcknowledge(NoAcknowledgeSource::Data)
149            }
150            e => e,
151        }
152    }
153}
154
155impl embedded_hal::i2c::Error for Error {
156    fn kind(&self) -> ErrorKind {
157        match *self {
158            Self::Overrun => ErrorKind::Overrun,
159            Self::Bus => ErrorKind::Bus,
160            Self::ArbitrationLoss => ErrorKind::ArbitrationLoss,
161            Self::NoAcknowledge(nack) => ErrorKind::NoAcknowledge(nack),
162            Self::Crc
163            | Self::Timeout
164            | Self::SMBusAlert
165            | Self::SMBusTimeout
166            | Self::Pec
167            | Self::Other
168            | Self::Busy
169            | Self::Buffer => ErrorKind::Other,
170        }
171    }
172}