1use crate::dma;
4use crate::int::InterruptSource;
5use crate::pac::{I2C1, I2C2};
6use crate::time::Hertz;
7use embedded_hal::i2c::{ErrorKind, NoAcknowledgeSource, Operation, SevenBitAddress};
8use embedded_hal_0_2::blocking;
9use mips_mcu::fmt::virt_to_phys;
10use mips_mcu::PhysicalAddress;
11
12#[repr(u32)]
16pub enum Fscl {
17 F100KHZ = 204248,
18 F400KHZ = 872600,
19 F1000KHZ = 2525253,
20}
21
22#[derive(Debug, Clone)]
24pub enum Error {
25 TransactionFailed,
26 InvalidState,
27}
28
29impl embedded_hal::i2c::Error for Error {
30 fn kind(&self) -> ErrorKind {
31 match self {
32 Self::TransactionFailed => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Unknown),
33 Self::InvalidState => ErrorKind::Other,
34 }
35 }
36}
37
38pub struct I2c<I2C> {
44 i2c: I2C,
45 transaction_ongoing: bool,
46}
47
48pub trait Ops {
50 fn transmit(&mut self, data: &[u8]) -> Result<(), Error>;
53
54 unsafe fn transmit_dma<D: dma::Ops>(
62 &mut self,
63 dma: &mut D,
64 addr: PhysicalAddress,
65 len: usize,
66 ) -> Result<(), Error>;
67
68 fn start(&mut self);
70
71 fn stop(&mut self);
73
74 fn receive(&mut self, data: &mut [u8], nack_last: bool) -> Result<(), Error>;
80}
81
82macro_rules! i2c_impl {
83 ($Id:ident, $I2c:ident) => {
84 impl I2c<$I2c> {
85 pub fn $Id(i2c: $I2c, pb_clock: Hertz, fscl: Fscl) -> I2c<$I2c> {
87 let divisor = fscl as u32;
88 let round = if pb_clock.0 % divisor > divisor / 2 {
89 1
90 } else {
91 0
92 };
93 let brg = pb_clock.0 / divisor - 2 + round;
94 unsafe {
95 i2c.brg.write(|w| w.brg().bits(brg as u16));
96 i2c.cont.write(|w| w.on().bit(true).disslw().bit(true));
98 }
99 I2c {
100 i2c,
101 transaction_ongoing: false,
102 }
103 }
104
105 pub fn free(self) -> $I2c {
107 self.i2c
108 }
109
110 fn i2c_busy(&self) -> bool {
112 (self.i2c.cont.read().bits() & 0x1f) != 0
113 }
114 }
115
116 impl Ops for I2c<$I2c> {
117 fn transmit(&mut self, data: &[u8]) -> Result<(), Error> {
118 if !self.transaction_ongoing {
119 while self.i2c_busy() {}
120 self.i2c.contset.write(|w| w.sen().bit(true));
122 self.transaction_ongoing = true;
123 }
124 for byte in data {
125 while self.i2c_busy() {}
126 unsafe { self.i2c.trn.write(|w| w.trn().bits(*byte)) };
127 while self.i2c.stat.read().trstat().bit() {}
129 if self.i2c.stat.read().ackstat().bit() {
131 self.stop();
132 return Err(Error::TransactionFailed);
133 }
134 }
135 Ok(())
136 }
137
138 unsafe fn transmit_dma<D: dma::Ops>(
139 &mut self,
140 dma: &mut D,
141 addr: PhysicalAddress,
142 len: usize,
143 ) -> Result<(), Error> {
144 if !self.transaction_ongoing {
145 while self.i2c_busy() {}
146 self.i2c.contset.write(|w| w.sen().bit(true));
148 self.transaction_ongoing = true;
149 }
150 dma.set_source(addr, len);
151 let trn = &self.i2c.trn as *const _ as *mut u32;
152 dma.set_dest(virt_to_phys(trn), 1);
153 dma.set_cell_size(1);
154 dma.set_start_event(Some(InterruptSource::I2C1_MASTER));
155 dma.enable(dma::XferMode::OneShot);
156 dma.force();
157 Ok(())
158 }
159
160 fn start(&mut self) {
161 while self.i2c_busy() {}
162 if self.transaction_ongoing {
163 self.i2c.contset.write(|w| w.rsen().bit(true));
165 } else {
166 self.i2c.contset.write(|w| w.sen().bit(true));
168 self.transaction_ongoing = true;
169 }
170 }
171
172 fn stop(&mut self) {
173 while self.i2c_busy() {}
174 self.i2c.contset.write(|w| w.pen().bit(true));
175 self.transaction_ongoing = false;
176 }
177
178 fn receive(&mut self, data: &mut [u8], nack_last: bool) -> Result<(), Error> {
179 if !self.transaction_ongoing {
180 return Err(Error::InvalidState);
181 }
182 let len = data.len();
183 for (i, byte) in data.iter_mut().enumerate() {
184 while self.i2c_busy() {}
185 self.i2c.contset.write(|w| w.rcen().bit(true));
186 while self.i2c_busy() {}
187 *byte = self.i2c.rcv.read().rcv().bits();
188 if (i == len - 1) && nack_last {
189 self.i2c.contset.write(|w| w.ackdt().bit(true));
191 } else {
192 self.i2c.contclr.write(|w| w.ackdt().bit(true));
193 }
194 self.i2c.contset.write(|w| w.acken().bit(true));
195 }
196 Ok(())
197 }
198 }
199
200 impl blocking::i2c::Write for I2c<$I2c> {
201 type Error = Error;
202
203 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
204 self.transmit(&[addr << 1])?;
205 self.transmit(bytes)?;
206 self.stop();
207 Ok(())
208 }
209 }
210
211 impl blocking::i2c::Read for I2c<$I2c> {
212 type Error = Error;
213
214 fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
215 self.transmit(&[(addr << 1) | 0x01])?;
216 self.receive(buffer, true)?;
217 self.stop();
218 Ok(())
219 }
220 }
221
222 impl blocking::i2c::WriteRead for I2c<$I2c> {
223 type Error = Error;
224
225 fn write_read(
226 &mut self,
227 addr: u8,
228 bytes: &[u8],
229 buffer: &mut [u8],
230 ) -> Result<(), Self::Error> {
231 self.transmit(&[addr << 1])?;
232 self.transmit(bytes)?;
233 self.start();
234 self.transmit(&[(addr << 1) | 0x01])?;
235 self.receive(buffer, true)?;
236 self.stop();
237 Ok(())
238 }
239 }
240
241 impl embedded_hal::i2c::ErrorType for I2c<$I2c> {
242 type Error = Error;
243 }
244
245 impl embedded_hal::i2c::I2c<SevenBitAddress> for I2c<$I2c> {
246 fn transaction(
247 &mut self,
248 address: SevenBitAddress,
249 operations: &mut [Operation<'_>],
250 ) -> Result<(), Self::Error> {
251 let ops_len = operations.len();
252 let mut prev_rw = false;
253 for (i, op) in operations.iter_mut().enumerate() {
254 let last = i == ops_len - 1;
255 let rw = matches!(op, Operation::Read(_));
256 if i == 0 || prev_rw != rw {
257 self.start();
258 self.transmit(&[address << 1 | rw as u8])?;
259 }
260 prev_rw = rw;
261 match op {
262 Operation::Read(bytes) => {
263 self.receive(bytes, last)?;
264 }
265 Operation::Write(bytes) => {
266 self.transmit(bytes)?;
267 }
268 }
269 }
270 self.stop();
271 Ok(())
272 }
273 }
274 };
275}
276
277i2c_impl!(i2c1, I2C1);
278i2c_impl!(i2c2, I2C2);