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(true) => {
187 sens.sar_i2c_ctrl().modify(|r, w| {
188 let mut value = r.sar_i2c_ctrl().bits();
189 value &= !(0xFF << 19);
190 value |= (byte as u32) << 19;
191 value |= 1 << 27;
192 unsafe { w.sar_i2c_ctrl().bits(value) }
193 });
194 self.i2c
195 .register_block()
196 .int_clr()
197 .write(|w| w.tx_data().clear_bit_by_one());
198 }
199 Ok(false) => panic!("Peripheral didn't wait for data"),
200 Err(err) => {
201 sens.sar_i2c_ctrl().modify(|_, w| {
203 w.sar_i2c_start_force().clear_bit();
204 w.sar_i2c_start().clear_bit()
205 });
206
207 return Err(err);
208 }
209 }
210 }
211
212 let result = self.wait_for_complete_interrupt();
213
214 sens.sar_i2c_ctrl().write(|w| {
216 w.sar_i2c_start_force().clear_bit();
217 w.sar_i2c_start().clear_bit()
218 });
219
220 result
221 }
222
223 pub(super) fn read_bytes(
224 &mut self,
225 address: u8,
226 register: u8,
227 data: &mut [u8],
228 ) -> Result<(), Error> {
229 let sens = unsafe { crate::pac::SENS::steal() };
230
231 if data.len() > u8::MAX as usize {
232 return Err(Error::TransactionSizeLimitExceeded);
233 }
234
235 self.write_cmd(
237 2,
238 Command::Write {
239 ack_exp: Ack::Ack,
240 ack_check_en: true,
241 length: 2,
242 },
243 );
244 self.write_cmd(3, Command::Start);
246 self.write_cmd(
247 4,
248 Command::Write {
249 ack_exp: Ack::Ack,
250 ack_check_en: true,
251 length: 1,
253 },
254 );
255 if data.len() > 1 {
256 self.write_cmd(
257 5,
258 Command::Read {
259 ack_value: Ack::Ack,
260 length: (data.len() - 1) as _,
261 },
262 );
263 self.write_cmd(
264 6,
265 Command::Read {
266 ack_value: Ack::Nack,
267 length: 1,
268 },
269 );
270 self.write_cmd(7, Command::Stop);
271 } else {
272 self.write_cmd(
273 5,
274 Command::Read {
275 ack_value: Ack::Nack,
276 length: 1,
277 },
278 );
279 self.write_cmd(6, Command::Stop);
280 }
281
282 self.clear_interrupts();
283
284 let ctrl = {
286 let mut result = 0;
287 result |= address as u32;
288 result |= (register as u32) << 11;
289 result |= 0u32 << 27; result
291 };
292 sens.sar_i2c_ctrl().write(|w| {
293 unsafe { w.sar_i2c_ctrl().bits(ctrl) };
294 w.sar_i2c_start_force().set_bit();
295 w.sar_i2c_start().set_bit()
296 });
297
298 for byte in data {
299 match self.wait_for_rx_interrupt() {
300 Ok(true) => {
301 *byte = self.i2c.register_block().data().read().i2c_rdata().bits();
302 self.i2c
303 .register_block()
304 .int_clr()
305 .write(|w| w.rx_data().clear_bit_by_one());
306 }
307 Ok(false) => panic!("Peripheral didn't wait for data to be read"),
308 Err(err) => {
309 sens.sar_i2c_ctrl().modify(|_, w| {
311 w.sar_i2c_start_force().clear_bit();
312 w.sar_i2c_start().clear_bit()
313 });
314
315 return Err(err);
316 }
317 }
318 }
319
320 let result = self.wait_for_complete_interrupt();
321
322 sens.sar_i2c_ctrl().modify(|_, w| {
324 w.sar_i2c_start_force().clear_bit();
325 w.sar_i2c_start().clear_bit()
326 });
327
328 result
329 }
330
331 fn clear_interrupts(&self) {
332 self.i2c.register_block().int_clr().write(|w| {
333 w.trans_complete().clear_bit_by_one();
334 w.tx_data().clear_bit_by_one();
335 w.rx_data().clear_bit_by_one();
336 w.ack_err().clear_bit_by_one();
337 w.time_out().clear_bit_by_one();
338 w.arbitration_lost().clear_bit_by_one()
339 });
340 }
341
342 fn wait_for_tx_interrupt(&self) -> Result<bool, Error> {
343 loop {
344 let int_raw = self.i2c.register_block().int_raw().read();
345 if int_raw.tx_data().bit_is_set() {
346 break Ok(true);
347 } else if int_raw.trans_complete().bit_is_set() {
348 break Ok(false);
349 } else if int_raw.time_out().bit_is_set() {
350 break Err(Error::TimeOut);
351 } else if int_raw.ack_err().bit_is_set() {
352 break Err(Error::AckCheckFailed);
353 } else if int_raw.arbitration_lost().bit_is_set() {
354 break Err(Error::ArbitrationLost);
355 }
356 }
357 }
358
359 fn wait_for_rx_interrupt(&self) -> Result<bool, Error> {
360 loop {
361 let int_raw = self.i2c.register_block().int_raw().read();
362 if int_raw.rx_data().bit_is_set() {
363 break Ok(true);
364 } else if int_raw.trans_complete().bit_is_set() {
365 break Ok(false);
366 } else if int_raw.time_out().bit_is_set() {
367 break Err(Error::TimeOut);
368 } else if int_raw.ack_err().bit_is_set() {
369 break Err(Error::AckCheckFailed);
370 } else if int_raw.arbitration_lost().bit_is_set() {
371 break Err(Error::ArbitrationLost);
372 }
373 }
374 }
375
376 fn wait_for_complete_interrupt(&self) -> Result<(), Error> {
377 loop {
378 let int_raw = self.i2c.register_block().int_raw().read();
379 if int_raw.trans_complete().bit_is_set() {
380 break Ok(());
381 } else if int_raw.time_out().bit_is_set() {
382 break Err(Error::TimeOut);
383 } else if int_raw.ack_err().bit_is_set() {
384 break Err(Error::AckCheckFailed);
385 } else if int_raw.arbitration_lost().bit_is_set() {
386 break Err(Error::ArbitrationLost);
387 }
388 }
389 }
390
391 fn write_cmd(&self, idx: usize, command: Command) {
392 let cmd = command.into();
393 self.i2c
394 .register_block()
395 .cmd(idx)
396 .write(|w| unsafe { w.command().bits(cmd) });
397 }
398
399 pub(super) fn disable(&mut self) {
400 SENS::regs()
402 .sar_peri_reset_conf()
403 .modify(|_, w| w.sar_rtc_i2c_reset().set_bit());
404
405 SENS::regs()
406 .sar_peri_clk_gate_conf()
407 .modify(|_, w| w.rtc_i2c_clk_en().clear_bit());
408 }
409}
410
411#[derive(Debug, Clone, Copy, PartialEq)]
413#[cfg_attr(feature = "defmt", derive(defmt::Format))]
414#[non_exhaustive]
415pub enum ConfigError {
416 TimeoutTooLong,
418}
419
420#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, procmacros::BuilderLite)]
422#[cfg_attr(feature = "defmt", derive(defmt::Format))]
423#[non_exhaustive]
424pub struct Config {
425 timing: Timing,
427
428 timeout: Duration,
430}
431
432#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, procmacros::BuilderLite)]
434#[cfg_attr(feature = "defmt", derive(defmt::Format))]
435pub struct Timing {
436 scl_low_period: u32,
438 scl_high_period: u32,
440 sda_duty: u32,
442 scl_start_period: u32,
444 scl_stop_period: u32,
446}
447
448impl Timing {
449 pub fn standard_mode() -> Self {
451 Self::default()
452 .with_scl_low_period(clock_from_micros(5))
453 .with_scl_high_period(clock_from_micros(5))
454 .with_sda_duty(clock_from_micros(2))
455 .with_scl_start_period(clock_from_micros(3))
456 .with_scl_stop_period(clock_from_micros(6))
457 }
458
459 pub fn fast_mode() -> Self {
461 Self::default()
462 .with_scl_low_period(clock_from_nanos(1_400))
463 .with_scl_high_period(clock_from_nanos(300))
464 .with_sda_duty(clock_from_nanos(1_000))
465 .with_scl_start_period(clock_from_nanos(2_000))
466 .with_scl_stop_period(clock_from_nanos(1_300))
467 }
468}
469
470fn clock_from_micros(micros: u64) -> u32 {
471 nanos_to_clock(micros * 1_000)
472}
473
474fn clock_from_nanos(nanos: u64) -> u32 {
475 nanos_to_clock(nanos)
476}
477
478fn nanos_to_clock(nanos: u64) -> u32 {
479 ((nanos as u128 * crate::soc::clocks::rc_fast_clk_frequency() as u128) / 1_000_000_000) as u32
480}
481
482enum Command {
484 Start,
485 Stop,
486 Write {
487 ack_exp: Ack,
489 ack_check_en: bool,
492 length: u8,
495 },
496 Read {
497 ack_value: Ack,
500 length: u8,
503 },
504}
505
506#[derive(Eq, PartialEq, Copy, Clone)]
507enum Ack {
508 Ack,
509 Nack,
510}
511
512impl From<Command> for u16 {
513 fn from(c: Command) -> u16 {
514 let opcode = match c {
515 Command::Start => 0,
516 Command::Stop => 3,
517 Command::Write { .. } => 1,
518 Command::Read { .. } => 2,
519 };
520
521 let length = match c {
522 Command::Start | Command::Stop => 0,
523 Command::Write { length: l, .. } | Command::Read { length: l, .. } => l,
524 };
525
526 let ack_exp = match c {
527 Command::Start | Command::Stop | Command::Read { .. } => Ack::Nack,
528 Command::Write { ack_exp: exp, .. } => exp,
529 };
530
531 let ack_check_en = match c {
532 Command::Start | Command::Stop | Command::Read { .. } => false,
533 Command::Write {
534 ack_check_en: en, ..
535 } => en,
536 };
537
538 let ack_value = match c {
539 Command::Start | Command::Stop | Command::Write { .. } => Ack::Nack,
540 Command::Read { ack_value: ack, .. } => ack,
541 };
542
543 let mut cmd: u16 = length.into();
544
545 if ack_check_en {
546 cmd |= 1 << 8;
547 } else {
548 cmd &= !(1 << 8);
549 }
550
551 if ack_exp == Ack::Nack {
552 cmd |= 1 << 9;
553 } else {
554 cmd &= !(1 << 9);
555 }
556
557 if ack_value == Ack::Nack {
558 cmd |= 1 << 10;
559 } else {
560 cmd &= !(1 << 10);
561 }
562
563 cmd |= opcode << 11;
564
565 cmd
566 }
567}