1use crate::{
7 gpio::{
8 LpPin,
9 lp_io::{LpFunction, low_level},
10 },
11 i2c::lp_i2c::{Error, LpI2c, Scl, Sda},
12 peripherals::{GPIO, RTC_IO, SENS},
13 time::Duration,
14};
15
16fn bind_pin(pin: &impl LpPin, function: LpFunction) {
17 let lp = pin.lp_number();
18
19 GPIO::regs()
20 .pin(pin.number() as usize)
21 .modify(|_, w| w.pad_driver().bit(true));
22 RTC_IO::regs()
23 .touch_pad(lp as usize)
24 .modify(|_, w| w.rue().bit(true).rde().bit(false));
25 RTC_IO::regs()
26 .rtc_gpio_enable_w1ts()
27 .write(|w| unsafe { w.rtc_gpio_enable_w1ts().bits(1 << lp) });
28 low_level::set_config(lp, true, true, function);
29}
30
31for_each_lp_function! {
32 (($_func:ident, SAR_I2C_SCL_n, $n:literal), $gpio:ident, $af:ident, $_lp_in:tt $_lp_out:tt) => {
33 impl Scl for crate::peripherals::$gpio<'_> {
34 fn connect_scl(&self) {
35 bind_pin(self, LpFunction::$af);
36 RTC_IO::regs().sar_i2c_io().modify(|_, w| unsafe {
38 w.sar_i2c_scl_sel().bits($n)
39 });
40 }
41 }
42 };
43 (($_func:ident, SAR_I2C_SDA_n, $n:literal), $gpio:ident, $af:ident, $_lp_in:tt $_lp_out:tt) => {
44 impl Sda for crate::peripherals::$gpio<'_> {
45 fn connect_sda(&self) {
46 bind_pin(self, LpFunction::$af);
47 RTC_IO::regs().sar_i2c_io().modify(|_, w| unsafe {
49 w.sar_i2c_sda_sel().bits($n)
50 });
51 }
52 }
53 };
54}
55
56impl<'d> LpI2c<'d> {
57 pub(super) fn init(&mut self) {
58 self.i2c.register_block().ctrl().reset();
60 SENS::regs().sar_i2c_ctrl().reset();
61
62 SENS::regs()
64 .sar_peri_reset_conf()
65 .modify(|_, w| w.sar_rtc_i2c_reset().set_bit());
66 self.i2c
67 .register_block()
68 .ctrl()
69 .modify(|_, w| w.i2c_reset().set_bit());
70 crate::rom::ets_delay_us(20);
72 self.i2c
73 .register_block()
74 .ctrl()
75 .modify(|_, w| w.i2c_reset().clear_bit());
76 SENS::regs()
77 .sar_peri_reset_conf()
78 .modify(|_, w| w.sar_rtc_i2c_reset().clear_bit());
79
80 self.i2c.register_block().ctrl().modify(|_, w| {
82 w.sda_force_out().clear_bit();
83 w.scl_force_out().clear_bit()
84 });
85
86 SENS::regs()
88 .sar_peri_clk_gate_conf()
89 .modify(|_, w| w.rtc_i2c_clk_en().set_bit());
90
91 self.i2c
93 .register_block()
94 .ctrl()
95 .modify(|_, w| w.ms_mode().set_bit());
96 self.i2c
97 .register_block()
98 .ctrl()
99 .modify(|_, w| w.i2c_ctrl_clk_gate_en().set_bit());
100 }
101
102 pub(super) fn configure(&mut self, config: &Config) -> Result<(), ConfigError> {
103 let ticks = nanos_to_clock(config.timeout.as_micros().saturating_mul(1_000));
104
105 if ticks > (1 << 20) - 1 {
107 return Err(ConfigError::TimeoutTooLong);
108 }
109
110 self.i2c
111 .register_block()
112 .scl_low()
113 .write(|w| unsafe { w.period().bits(config.timing.scl_low_period) });
114 self.i2c
115 .register_block()
116 .scl_high()
117 .write(|w| unsafe { w.period().bits(config.timing.scl_high_period) });
118 self.i2c
119 .register_block()
120 .sda_duty()
121 .write(|w| unsafe { w.num().bits(config.timing.sda_duty) });
122 self.i2c
123 .register_block()
124 .scl_start_period()
125 .write(|w| unsafe { w.scl_start_period().bits(config.timing.scl_start_period) });
126 self.i2c
127 .register_block()
128 .scl_stop_period()
129 .write(|w| unsafe { w.scl_stop_period().bits(config.timing.scl_stop_period) });
130
131 self.i2c
132 .register_block()
133 .to()
134 .write(|w| unsafe { w.time_out().bits(ticks) });
135
136 Ok(())
137 }
138
139 pub(super) fn write_bytes(
140 &mut self,
141 address: u8,
142 register: u8,
143 data: &[u8],
144 ) -> Result<(), Error> {
145 let sens = unsafe { crate::pac::SENS::steal() };
146
147 if data.len() > u8::MAX as usize - 2 {
148 return Err(Error::TransactionSizeLimitExceeded);
149 }
150
151 self.write_cmd(
152 0,
153 Command::Write {
154 ack_exp: Ack::Ack,
155 ack_check_en: true,
156 length: 2 + (data.len() as u8),
158 },
159 );
160 self.write_cmd(1, Command::Stop);
161
162 self.clear_interrupts();
163
164 let ctrl = {
165 let mut result = 0;
166 result |= address as u32;
168 result |= (register as u32) << 11;
170 result |= (data[0] as u32) << 19;
172 result |= 1u32 << 27; result
174 };
175 sens.sar_i2c_ctrl()
176 .write(|w| unsafe { w.sar_i2c_ctrl().bits(ctrl) });
177
178 sens.sar_i2c_ctrl().modify(|_, w| {
180 w.sar_i2c_start_force().set_bit();
181 w.sar_i2c_start().set_bit()
182 });
183
184 for &byte in data.iter().skip(1) {
185 match self.wait_for_tx_interrupt() {
186 Ok(is_tx) => {
187 if is_tx {
188 sens.sar_i2c_ctrl().modify(|r, w| {
189 let mut value = r.sar_i2c_ctrl().bits();
190 value &= !(0xFF << 19);
191 value |= (byte as u32) << 19;
192 value |= 1 << 27;
193 unsafe { w.sar_i2c_ctrl().bits(value) }
194 });
195 self.i2c
196 .register_block()
197 .int_clr()
198 .write(|w| w.tx_data().clear_bit_by_one());
199 } else {
200 core::panic!("Peripheral didn't wait for data");
201 }
202 }
203 Err(err) => {
204 sens.sar_i2c_ctrl().modify(|_, w| {
206 w.sar_i2c_start_force().clear_bit();
207 w.sar_i2c_start().clear_bit()
208 });
209
210 return Err(err);
211 }
212 }
213 }
214
215 let result = self.wait_for_complete_interrupt();
216
217 sens.sar_i2c_ctrl().write(|w| {
219 w.sar_i2c_start_force().clear_bit();
220 w.sar_i2c_start().clear_bit()
221 });
222
223 result
224 }
225
226 pub(super) fn read_bytes(
227 &mut self,
228 address: u8,
229 register: u8,
230 data: &mut [u8],
231 ) -> Result<(), Error> {
232 let sens = unsafe { crate::pac::SENS::steal() };
233
234 if data.len() > u8::MAX as usize {
235 return Err(Error::TransactionSizeLimitExceeded);
236 }
237
238 self.write_cmd(
240 2,
241 Command::Write {
242 ack_exp: Ack::Ack,
243 ack_check_en: true,
244 length: 2,
245 },
246 );
247 self.write_cmd(3, Command::Start);
249 self.write_cmd(
250 4,
251 Command::Write {
252 ack_exp: Ack::Ack,
253 ack_check_en: true,
254 length: 1,
256 },
257 );
258 if data.len() > 1 {
259 self.write_cmd(
260 5,
261 Command::Read {
262 ack_value: Ack::Ack,
263 length: (data.len() - 1) as _,
264 },
265 );
266 self.write_cmd(
267 6,
268 Command::Read {
269 ack_value: Ack::Nack,
270 length: 1,
271 },
272 );
273 self.write_cmd(7, Command::Stop);
274 } else {
275 self.write_cmd(
276 5,
277 Command::Read {
278 ack_value: Ack::Nack,
279 length: 1,
280 },
281 );
282 self.write_cmd(6, Command::Stop);
283 }
284
285 self.clear_interrupts();
286
287 let ctrl = {
289 let mut result = 0;
290 result |= address as u32;
291 result |= (register as u32) << 11;
292 result |= 0u32 << 27; result
294 };
295 sens.sar_i2c_ctrl().write(|w| {
296 unsafe { w.sar_i2c_ctrl().bits(ctrl) };
297 w.sar_i2c_start_force().set_bit();
298 w.sar_i2c_start().set_bit()
299 });
300
301 for byte in data {
302 match self.wait_for_rx_interrupt() {
303 Ok(is_rx) => {
304 if is_rx {
305 *byte = self.i2c.register_block().data().read().i2c_rdata().bits();
306 self.i2c
307 .register_block()
308 .int_clr()
309 .write(|w| w.rx_data().clear_bit_by_one());
310 } else {
311 core::panic!("Peripheral didn't wait for data to be read");
312 }
313 }
314 Err(err) => {
315 sens.sar_i2c_ctrl().modify(|_, w| {
317 w.sar_i2c_start_force().clear_bit();
318 w.sar_i2c_start().clear_bit()
319 });
320
321 return Err(err);
322 }
323 }
324 }
325
326 let result = self.wait_for_complete_interrupt();
327
328 sens.sar_i2c_ctrl().modify(|_, w| {
330 w.sar_i2c_start_force().clear_bit();
331 w.sar_i2c_start().clear_bit()
332 });
333
334 result
335 }
336
337 fn clear_interrupts(&self) {
338 self.i2c.register_block().int_clr().write(|w| {
339 w.trans_complete().clear_bit_by_one();
340 w.tx_data().clear_bit_by_one();
341 w.rx_data().clear_bit_by_one();
342 w.ack_err().clear_bit_by_one();
343 w.time_out().clear_bit_by_one();
344 w.arbitration_lost().clear_bit_by_one()
345 });
346 }
347
348 fn wait_for_tx_interrupt(&self) -> Result<bool, Error> {
349 loop {
350 let int_raw = self.i2c.register_block().int_raw().read();
351 if int_raw.tx_data().bit_is_set() {
352 break Ok(true);
353 } else if int_raw.trans_complete().bit_is_set() {
354 break Ok(false);
355 } else if int_raw.time_out().bit_is_set() {
356 break Err(Error::TimeOut);
357 } else if int_raw.ack_err().bit_is_set() {
358 break Err(Error::AckCheckFailed);
359 } else if int_raw.arbitration_lost().bit_is_set() {
360 break Err(Error::ArbitrationLost);
361 }
362 }
363 }
364
365 fn wait_for_rx_interrupt(&self) -> Result<bool, Error> {
366 loop {
367 let int_raw = self.i2c.register_block().int_raw().read();
368 if int_raw.rx_data().bit_is_set() {
369 break Ok(true);
370 } else if int_raw.trans_complete().bit_is_set() {
371 break Ok(false);
372 } else if int_raw.time_out().bit_is_set() {
373 break Err(Error::TimeOut);
374 } else if int_raw.ack_err().bit_is_set() {
375 break Err(Error::AckCheckFailed);
376 } else if int_raw.arbitration_lost().bit_is_set() {
377 break Err(Error::ArbitrationLost);
378 }
379 }
380 }
381
382 fn wait_for_complete_interrupt(&self) -> Result<(), Error> {
383 loop {
384 let int_raw = self.i2c.register_block().int_raw().read();
385 if int_raw.trans_complete().bit_is_set() {
386 break Ok(());
387 } else if int_raw.time_out().bit_is_set() {
388 break Err(Error::TimeOut);
389 } else if int_raw.ack_err().bit_is_set() {
390 break Err(Error::AckCheckFailed);
391 } else if int_raw.arbitration_lost().bit_is_set() {
392 break Err(Error::ArbitrationLost);
393 }
394 }
395 }
396
397 fn write_cmd(&self, idx: usize, command: Command) {
398 let cmd = command.into();
399 self.i2c
400 .register_block()
401 .cmd(idx)
402 .write(|w| unsafe { w.command().bits(cmd) });
403 }
404
405 pub(super) fn disable(&mut self) {
406 SENS::regs()
408 .sar_peri_reset_conf()
409 .modify(|_, w| w.sar_rtc_i2c_reset().set_bit());
410
411 SENS::regs()
412 .sar_peri_clk_gate_conf()
413 .modify(|_, w| w.rtc_i2c_clk_en().clear_bit());
414 }
415}
416
417#[derive(Debug, Clone, Copy, PartialEq)]
419#[cfg_attr(feature = "defmt", derive(defmt::Format))]
420#[non_exhaustive]
421pub enum ConfigError {
422 TimeoutTooLong,
424}
425
426#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, procmacros::BuilderLite)]
428#[cfg_attr(feature = "defmt", derive(defmt::Format))]
429#[non_exhaustive]
430pub struct Config {
431 timing: Timing,
433
434 timeout: Duration,
436}
437
438#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, procmacros::BuilderLite)]
440#[cfg_attr(feature = "defmt", derive(defmt::Format))]
441pub struct Timing {
442 scl_low_period: u32,
444 scl_high_period: u32,
446 sda_duty: u32,
448 scl_start_period: u32,
450 scl_stop_period: u32,
452}
453
454impl Timing {
455 pub fn standard_mode() -> Self {
457 Self::default()
458 .with_scl_low_period(clock_from_micros(5))
459 .with_scl_high_period(clock_from_micros(5))
460 .with_sda_duty(clock_from_micros(2))
461 .with_scl_start_period(clock_from_micros(3))
462 .with_scl_stop_period(clock_from_micros(6))
463 }
464
465 pub fn fast_mode() -> Self {
467 Self::default()
468 .with_scl_low_period(clock_from_nanos(1_400))
469 .with_scl_high_period(clock_from_nanos(300))
470 .with_sda_duty(clock_from_nanos(1_000))
471 .with_scl_start_period(clock_from_nanos(2_000))
472 .with_scl_stop_period(clock_from_nanos(1_300))
473 }
474}
475
476fn clock_from_micros(micros: u64) -> u32 {
477 nanos_to_clock(micros * 1_000)
478}
479
480fn clock_from_nanos(nanos: u64) -> u32 {
481 nanos_to_clock(nanos)
482}
483
484fn nanos_to_clock(nanos: u64) -> u32 {
485 ((nanos as u128 * crate::soc::clocks::rc_fast_clk_frequency() as u128) / 1_000_000_000) as u32
486}
487
488enum Command {
490 Start,
491 Stop,
492 Write {
493 ack_exp: Ack,
495 ack_check_en: bool,
498 length: u8,
501 },
502 Read {
503 ack_value: Ack,
506 length: u8,
509 },
510}
511
512#[derive(Eq, PartialEq, Copy, Clone)]
513enum Ack {
514 Ack,
515 Nack,
516}
517
518impl From<Command> for u16 {
519 fn from(c: Command) -> u16 {
520 let opcode = match c {
521 Command::Start => 0,
522 Command::Stop => 3,
523 Command::Write { .. } => 1,
524 Command::Read { .. } => 2,
525 };
526
527 let length = match c {
528 Command::Start | Command::Stop => 0,
529 Command::Write { length: l, .. } | Command::Read { length: l, .. } => l,
530 };
531
532 let ack_exp = match c {
533 Command::Start | Command::Stop | Command::Read { .. } => Ack::Nack,
534 Command::Write { ack_exp: exp, .. } => exp,
535 };
536
537 let ack_check_en = match c {
538 Command::Start | Command::Stop | Command::Read { .. } => false,
539 Command::Write {
540 ack_check_en: en, ..
541 } => en,
542 };
543
544 let ack_value = match c {
545 Command::Start | Command::Stop | Command::Write { .. } => Ack::Nack,
546 Command::Read { ack_value: ack, .. } => ack,
547 };
548
549 let mut cmd: u16 = length.into();
550
551 if ack_check_en {
552 cmd |= 1 << 8;
553 } else {
554 cmd &= !(1 << 8);
555 }
556
557 if ack_exp == Ack::Nack {
558 cmd |= 1 << 9;
559 } else {
560 cmd &= !(1 << 9);
561 }
562
563 if ack_value == Ack::Nack {
564 cmd |= 1 << 10;
565 } else {
566 cmd &= !(1 << 10);
567 }
568
569 cmd |= opcode << 11;
570
571 cmd
572 }
573}