1use crate::clocks;
6use crate::resets;
7use core::cell::Cell;
8use kernel::debug;
9use kernel::hil;
10use kernel::utilities::cells::{OptionalCell, TakeCell};
11use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
12use kernel::utilities::registers::LocalRegisterCopy;
13use kernel::utilities::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite};
14use kernel::utilities::StaticRef;
15
16register_structs! {
30 I2cRegisters {
31 (0x00 => ic_con: ReadWrite<u32, IC_CON::Register>),
32 (0x04 => ic_tar: ReadWrite<u32, IC_TAR::Register>),
33 (0x08 => ic_sar: ReadWrite<u32, IC_SAR::Register>),
34 (0x0c => _reserved0),
35 (0x10 => ic_data_cmd: ReadWrite<u32, IC_DATA_CMD::Register>),
36 (0x14 => ic_ss_scl_hcnt: ReadWrite<u32, IC_SS_SCL_HCNT::Register>),
37 (0x18 => ic_ss_scl_lcnt: ReadWrite<u32, IC_SS_SCL_LCNT::Register>),
38 (0x1c => ic_fs_scl_hcnt: ReadWrite<u32, IC_FS_SCL_HCNT::Register>),
39 (0x20 => ic_fs_scl_lcnt: ReadWrite<u32, IC_FS_SCL_LCNT::Register>),
40 (0x24 => _reserved1),
41 (0x2c => ic_intr_stat: ReadOnly<u32, IC_INTR_STAT::Register>),
42 (0x30 => ic_intr_mask: ReadWrite<u32, IC_INTR_MASK::Register>),
43 (0x34 => ic_raw_intr_stat: ReadOnly<u32, IC_RAW_INTR_STAT::Register>),
44 (0x38 => ic_rx_tl: ReadWrite<u32, IC_RX_TL::Register>),
45 (0x3c => ic_tx_tl: ReadWrite<u32, IC_TX_TL::Register>),
46 (0x40 => ic_clr_intr: ReadOnly<u32, IC_CLR_INTR::Register>),
47 (0x44 => _reserved2), (0x54 => ic_clr_tx_abrt: ReadOnly<u32, IC_CLR_TX_ABRT::Register>),
49 (0x58 => _reserved3), (0x60 => ic_clr_stop_det: ReadOnly<u32, IC_CLR_STOP_DET::Register>),
51 (0x64 => _reserved4), (0x6c => ic_enable: ReadWrite<u32, IC_ENABLE::Register>),
53 (0x70 => _reserved5), (0x7c => ic_sda_hold: ReadWrite<u32, IC_SDA_HOLD::Register>),
55 (0x80 => ic_tx_abrt_source: ReadOnly<u32, IC_TX_ABRT_SOURCE::Register>),
56 (0x84 => _reserved6), (0x88 => ic_dma_cr: ReadWrite<u32, IC_DMA_CR::Register>),
58 (0x8c => _reserved7), (0xa0 => ic_fs_spklen: ReadWrite<u32, IC_FS_SPKLEN::Register>),
60 (0xa4 => @END), }
62}
63
64register_bitfields! [u32,
65 IC_CON [
67 MASTER_MODE OFFSET(0) NUMBITS(1) [],
68 SPEED OFFSET(1) NUMBITS(2) [
69 STANDARD = 0x1,
70 FAST = 0x2,
71 HIGH = 0x3,
72 ],
73 IC_10BITADDR_SLAVE OFFSET(3) NUMBITS(1) [],
74 IC_10BITADDR_MASTER OFFSET(4) NUMBITS(1) [],
75 IC_RESTART_EN OFFSET(5) NUMBITS(1) [],
76 IC_SLAVE_DISABLE OFFSET(6) NUMBITS(1) [],
77 STOP_DET_IFADDRESSED OFFSET(7) NUMBITS(1) [],
78 TX_EMPTY_CTRL OFFSET(8) NUMBITS(1) [],
79 RX_FIFO_FULL_HLD_CTRL OFFSET(9) NUMBITS(1) [],
80 STOP_DET_IF_MASTER_ACTIVE OFFSET(10) NUMBITS(1) [],
81 ],
82 IC_TAR [
84 IC_TAR OFFSET(0) NUMBITS(10) [],
85 GC_OR_START OFFSET(10) NUMBITS(1) [],
86 SPECIAL OFFSET(11) NUMBITS(1) [],
87 ],
88 IC_SAR [
90 IC_SAR OFFSET(0) NUMBITS(10) [],
91 ],
92 IC_DATA_CMD [
94 DAT OFFSET(0) NUMBITS(8) [],
95 CMD OFFSET(8) NUMBITS(1) [],
96 STOP OFFSET(9) NUMBITS(1) [],
97 RESTART OFFSET(10) NUMBITS(1) [],
98 FIRST_DATA_BYTE OFFSET(11) NUMBITS(1) [],
99 ],
100 IC_SS_SCL_HCNT [
102 IC_SS_SCL_HCNT OFFSET(0) NUMBITS(16) [],
103 ],
104 IC_SS_SCL_LCNT [
106 IC_SS_SCL_LCNT OFFSET(0) NUMBITS(16) [],
107 ],
108 IC_FS_SCL_HCNT [
110 IC_FS_SCL_HCNT OFFSET(0) NUMBITS(16) [],
111 ],
112 IC_FS_SCL_LCNT [
114 IC_FS_SCL_LCNT OFFSET(0) NUMBITS(16) [],
115 ],
116 IC_INTR_STAT [
118 R_RX_UNDER OFFSET(0) NUMBITS(1) [],
119 R_RX_OVER OFFSET(1) NUMBITS(1) [],
120 R_RX_FULL OFFSET(2) NUMBITS(1) [],
121 R_TX_OVER OFFSET(3) NUMBITS(1) [],
122 R_TX_EMPTY OFFSET(4) NUMBITS(1) [],
123 R_RD_REQ OFFSET(5) NUMBITS(1) [],
124 R_TX_ABRT OFFSET(6) NUMBITS(1) [],
125 R_RX_DONE OFFSET(7) NUMBITS(1) [],
126 R_ACTIVITY OFFSET(8) NUMBITS(1) [],
127 R_STOP_DET OFFSET(9) NUMBITS(1) [],
128 R_START_DET OFFSET(10) NUMBITS(1) [],
129 R_GEN_CALL OFFSET(11) NUMBITS(1) [],
130 R_RESTART_DET OFFSET(12) NUMBITS(1) [],
131 ],
132 IC_INTR_MASK [
134 M_RX_UNDER OFFSET(0) NUMBITS(1) [],
135 M_RX_OVER OFFSET(1) NUMBITS(1) [],
136 M_RX_FULL OFFSET(2) NUMBITS(1) [],
137 M_TX_OVER OFFSET(3) NUMBITS(1) [],
138 M_TX_EMPTY OFFSET(4) NUMBITS(1) [],
139 M_RD_REQ OFFSET(5) NUMBITS(1) [],
140 M_TX_ABRT OFFSET(6) NUMBITS(1) [],
141 M_RX_DONE OFFSET(7) NUMBITS(1) [],
142 M_ACTIVITY OFFSET(8) NUMBITS(1) [],
143 M_STOP_DET OFFSET(9) NUMBITS(1) [],
144 M_START_DET OFFSET(10) NUMBITS(1) [],
145 M_GEN_CALL OFFSET(11) NUMBITS(1) [],
146 M_RESTART_DET OFFSET(12) NUMBITS(1) [],
147 ],
148 IC_RAW_INTR_STAT [
150 RX_UNDER OFFSET(0) NUMBITS(1) [],
151 RX_OVER OFFSET(1) NUMBITS(1) [],
152 RX_FULL OFFSET(2) NUMBITS(1) [],
153 TX_OVER OFFSET(3) NUMBITS(1) [],
154 TX_EMPTY OFFSET(4) NUMBITS(1) [],
155 RD_REQ OFFSET(5) NUMBITS(1) [],
156 TX_ABRT OFFSET(6) NUMBITS(1) [],
157 RX_DONE OFFSET(7) NUMBITS(1) [],
158 ACTIVITY OFFSET(8) NUMBITS(1) [],
159 STOP_DET OFFSET(9) NUMBITS(1) [],
160 START_DET OFFSET(10) NUMBITS(1) [],
161 GEN_CALL OFFSET(11) NUMBITS(1) [],
162 RESTART_DET OFFSET(12) NUMBITS(1) [],
163 ],
164 IC_RX_TL [
166 IC_RX_TL OFFSET(0) NUMBITS(8) [],
167 ],
168 IC_TX_TL [
170 IC_TX_TL OFFSET(0) NUMBITS(8) [],
171 ],
172 IC_CLR_INTR [
174 CLR_INTR OFFSET(0) NUMBITS(1) [],
175 ],
176 IC_CLR_TX_ABRT [
178 CLR_TX_ABRT OFFSET(0) NUMBITS(1) [],
179 ],
180 IC_CLR_STOP_DET [
182 CLR_STOP_DET OFFSET(0) NUMBITS(1) [],
183 ],
184 IC_ENABLE [
186 ENABLE OFFSET(0) NUMBITS(1) [],
187 ABORT OFFSET(1) NUMBITS(1) [],
188 TX_CMD_BLOCK OFFSET(2) NUMBITS(1) [],
189 ],
190 IC_SDA_HOLD [
192 IC_SDA_TX_HOLD OFFSET(0) NUMBITS(16) [],
193 IC_SDA_RX_HOLD OFFSET(16) NUMBITS(8) [],
194 ],
195 IC_TX_ABRT_SOURCE [
197 ABRT_7B_ADDR_NOACK OFFSET(0) NUMBITS(1) [],
198 ABRT_10ADDR1_NOACK OFFSET(1) NUMBITS(1) [],
199 ABRT_10ADDR2_NOACK OFFSET(2) NUMBITS(1) [],
200 ABRT_TXDATA_NOACK OFFSET(3) NUMBITS(1) [],
201 ABRT_GCALL_NOACK OFFSET(4) NUMBITS(1) [],
202 ABRT_GCALL_READ OFFSET(5) NUMBITS(1) [],
203 ABRT_HS_ACKDET OFFSET(6) NUMBITS(1) [],
204 ABRT_SBYTE_ACKDET OFFSET(7) NUMBITS(1) [],
205 ABRT_HS_NORSTRT OFFSET(8) NUMBITS(1) [],
206 ABRT_SBYTE_NORSTRT OFFSET(9) NUMBITS(1) [],
207 ABRT_10B_RD_NORSTRT OFFSET(10) NUMBITS(1) [],
208 ABRT_MASTER_DIS OFFSET(11) NUMBITS(1) [],
209 ARB_LOST OFFSET(12) NUMBITS(1) [],
210 ABRT_SLVFLUSH_TXFIFO OFFSET(13) NUMBITS(1) [],
211 ABRT_SLV_ARBLOST OFFSET(14) NUMBITS(1) [],
212 ABRT_SLVRD_INTX OFFSET(15) NUMBITS(1) [],
213 ABRT_USER_ABRT OFFSET(16) NUMBITS(1) [],
214 TX_FLUSH_CNT OFFSET(23) NUMBITS(9) [],
215 ],
216 IC_DMA_CR [
218 RDMAE OFFSET(0) NUMBITS(1) [],
219 TDMAE OFFSET(1) NUMBITS(1) [],
220 ],
221 IC_FS_SPKLEN [
223 IC_FS_SPKLEN OFFSET(0) NUMBITS(8) [],
224 ],
225];
226
227const INSTANCES: [StaticRef<I2cRegisters>; 2] = unsafe {
228 [
229 StaticRef::new(0x40044000 as *const I2cRegisters),
230 StaticRef::new(0x40048000 as *const I2cRegisters),
231 ]
232};
233
234#[derive(Clone, Copy, PartialEq)]
235enum State {
236 Uninitialized,
237 Idle,
238 WaitingToWriteNextByte,
239 WaitingToReadNextByte,
240 WaitingToStartReading,
241 WaitingForStop,
242}
243
244pub struct I2c<'a, 'c> {
245 instance_num: u8,
246 registers: StaticRef<I2cRegisters>,
247 clocks: OptionalCell<&'a clocks::Clocks>,
248 resets: OptionalCell<&'a resets::Resets>,
249
250 client: OptionalCell<&'c dyn hil::i2c::I2CHwMasterClient>,
251 buf: TakeCell<'static, [u8]>,
252
253 state: Cell<State>,
254 addr: Cell<u8>,
255 write_len: Cell<i32>,
256 read_len: Cell<i32>,
257 rw_index: Cell<i32>,
258
259 abort_reason: OptionalCell<LocalRegisterCopy<u32, IC_TX_ABRT_SOURCE::Register>>,
260}
261
262impl<'a> I2c<'a, '_> {
263 fn new(instance_num: u8) -> Self {
264 Self {
265 instance_num,
266 registers: INSTANCES[instance_num as usize],
267 clocks: OptionalCell::empty(),
268 resets: OptionalCell::empty(),
269
270 client: OptionalCell::empty(),
271 buf: TakeCell::empty(),
272
273 state: Cell::new(State::Uninitialized),
274 addr: Cell::new(0),
275 write_len: Cell::new(0),
276 read_len: Cell::new(0),
277 rw_index: Cell::new(0),
278
279 abort_reason: OptionalCell::empty(),
280 }
281 }
282
283 pub fn new_i2c0() -> Self {
284 I2c::new(0)
285 }
286
287 pub fn new_i2c1() -> Self {
288 I2c::new(1)
289 }
290
291 pub fn resolve_dependencies(&self, clocks: &'a clocks::Clocks, resets: &'a resets::Resets) {
292 self.clocks.set(clocks);
293 self.resets.set(resets);
294 }
295
296 fn reset(&self) {
297 self.resets.map_or_else(
298 || panic!("You should call resolve_dependencies before reset."),
299 |resets| match self.instance_num {
300 0 => resets.reset(&[resets::Peripheral::I2c0]),
301 1 => resets.reset(&[resets::Peripheral::I2c1]),
302 _ => unreachable!(),
303 },
304 );
305 }
306
307 fn unreset(&self) {
308 self.resets.map_or_else(
309 || panic!("You should call resolve_dependencies before unreset."),
310 |resets| match self.instance_num {
311 0 => resets.unreset(&[resets::Peripheral::I2c0], true),
312 1 => resets.unreset(&[resets::Peripheral::I2c1], true),
313 _ => unreachable!(),
314 },
315 );
316 }
317
318 fn disable(&self) {
319 self.registers.ic_enable.set(0);
320 }
321
322 fn enable(&self) {
323 self.registers.ic_enable.modify(IC_ENABLE::ENABLE::SET);
324 }
325
326 fn set_baudrate(&self, baudrate: u32) -> u32 {
327 assert!(baudrate != 0);
328
329 let freq_in = self
331 .clocks
332 .map(|clocks| clocks.get_frequency(clocks::Clock::System))
333 .unwrap(); let period = (freq_in + baudrate / 2) / baudrate;
337 let lcnt = period * 3 / 5;
338 let hcnt = period - lcnt;
339 assert!(hcnt >= 8);
340 assert!(lcnt >= 8);
341
342 let sda_tx_hold_count = if baudrate < 1000000 {
347 ((freq_in * 3) / 10000000) + 1
351 } else {
352 ((freq_in * 3) / 25000000) + 1
356 };
357 assert!(sda_tx_hold_count <= lcnt - 2);
358
359 self.registers.ic_enable.modify(IC_ENABLE::ENABLE::CLEAR);
360 self.registers.ic_con.modify(IC_CON::SPEED::FAST);
362 self.registers.ic_fs_scl_hcnt.set(hcnt);
363 self.registers.ic_fs_scl_lcnt.set(lcnt);
364 self.registers.ic_fs_spklen.set({
365 if lcnt < 16 {
366 1
367 } else {
368 lcnt / 16
369 }
370 });
371 self.registers
372 .ic_sda_hold
373 .modify(IC_SDA_HOLD::IC_SDA_TX_HOLD.val(sda_tx_hold_count));
374
375 freq_in / period
376 }
377
378 pub fn init(&self, baudrate: u32) {
379 self.reset();
380 self.unreset();
381 self.disable();
382
383 self.registers
385 .ic_intr_mask
386 .write(IC_INTR_MASK::M_STOP_DET::SET);
387
388 self.registers.ic_con.write(
390 IC_CON::SPEED::FAST
391 + IC_CON::MASTER_MODE::SET
392 + IC_CON::IC_SLAVE_DISABLE::SET
393 + IC_CON::IC_RESTART_EN::SET
394 + IC_CON::TX_EMPTY_CTRL::SET,
395 );
396
397 self.registers.ic_tx_tl.set(0);
402 self.registers.ic_rx_tl.set(0);
403
404 self.registers
406 .ic_dma_cr
407 .write(IC_DMA_CR::TDMAE::SET + IC_DMA_CR::RDMAE::SET);
408
409 self.set_baudrate(baudrate);
410 self.enable();
411 self.state.set(State::Idle);
412 }
413
414 fn write_then_read(
415 &self,
416 addr: u8,
417 write_len: usize,
418 read_len: usize,
419 ) -> Result<(), hil::i2c::Error> {
420 let state = self.state.get();
421 assert!(state != State::Uninitialized);
422 if state != State::Idle {
423 return Err(hil::i2c::Error::Busy);
424 }
425
426 let write_len = write_len as i32;
429 assert!(write_len >= 1);
430
431 self.addr.set(addr);
432 self.rw_index.set(0);
433 self.write_len.set(write_len);
434 self.read_len.set(read_len as i32);
435
436 self.registers.ic_enable.set(0);
437 self.registers.ic_tar.set(addr as u32);
438 self.registers.ic_enable.set(1);
439
440 self.state.set(State::WaitingToWriteNextByte);
442 self.registers
443 .ic_intr_mask
444 .modify(IC_INTR_MASK::M_TX_EMPTY::SET);
445
446 Ok(())
447 }
448
449 fn write_next_byte(&self) {
450 assert!(self.state.get() == State::WaitingToWriteNextByte);
451
452 self.registers
455 .ic_intr_mask
456 .modify(IC_INTR_MASK::M_TX_EMPTY::CLEAR);
457
458 let idx = self.rw_index.get();
459 let len = self.write_len.get();
460
461 let first = idx == 0;
462 let last = idx == len - 1;
463 let read_to_follow = self.read_len.get() != 0;
464
465 if first {
466 self.abort_reason.clear();
467 } else {
468 let abort_reason = self.registers.ic_tx_abrt_source.extract();
469 if abort_reason.get() != 0 {
470 self.abort_reason.set(abort_reason);
471
472 self.registers.ic_clr_tx_abrt.get();
478
479 self.state.set(State::WaitingForStop);
484 return;
485 }
486 }
487
488 let byte = self
489 .buf
490 .map_or(None, |buf| Some(buf[idx as usize]))
491 .unwrap(); let data_cmd = IC_DATA_CMD::DAT.val(byte as u32) + IC_DATA_CMD::RESTART::CLEAR;
494 let data_cmd = {
495 if last && !read_to_follow {
496 data_cmd + IC_DATA_CMD::STOP::SET
497 } else {
498 data_cmd + IC_DATA_CMD::STOP::CLEAR
499 }
500 };
501
502 if last {
503 if read_to_follow {
504 self.state.set(State::WaitingToStartReading);
506 self.registers
507 .ic_intr_mask
508 .modify(IC_INTR_MASK::M_TX_EMPTY::SET);
509 } else {
510 self.state.set(State::WaitingForStop);
515 }
516 } else {
517 self.state.set(State::WaitingToWriteNextByte);
524 self.registers
525 .ic_intr_mask
526 .modify(IC_INTR_MASK::M_TX_EMPTY::SET);
527 }
528
529 self.registers.ic_data_cmd.write(data_cmd);
530 self.rw_index.set(idx + 1);
531 }
532
533 fn read(&self, addr: u8, len: usize) -> Result<(), hil::i2c::Error> {
534 let state = self.state.get();
535 assert!(state != State::Uninitialized);
536 if state != State::Idle {
537 return Err(hil::i2c::Error::Busy);
538 }
539
540 let len = len as i32;
541 assert!(len >= 1);
542
543 self.addr.set(addr);
544 self.read_len.set(len);
545 self.start_reading();
546
547 Ok(())
548 }
549
550 fn start_reading(&self) {
551 self.abort_reason.clear();
552 self.rw_index.set(0);
553
554 self.registers.ic_enable.set(0);
555 self.registers.ic_tar.set(self.addr.get() as u32);
556 self.registers.ic_enable.set(1);
557
558 self.state.set(State::WaitingToReadNextByte);
560 self.registers
561 .ic_intr_mask
562 .modify(IC_INTR_MASK::M_RX_FULL::SET);
563
564 let data_cmd = IC_DATA_CMD::CMD::SET;
566 let data_cmd = {
567 if self.read_len.get() == 1 {
568 data_cmd + IC_DATA_CMD::STOP::SET
570 } else {
571 data_cmd
572 }
573 };
574 self.registers.ic_data_cmd.write(data_cmd);
575 }
576
577 fn read_next_byte(&self) {
578 assert!(self.state.get() == State::WaitingToReadNextByte);
579
580 self.registers
583 .ic_intr_mask
584 .modify(IC_INTR_MASK::M_RX_FULL::CLEAR);
585
586 let idx = self.rw_index.get();
587 let len = self.read_len.get();
588
589 let abort_reason = self.registers.ic_tx_abrt_source.extract();
591 if self.registers.ic_clr_tx_abrt.get() != 0 {
592 self.abort_reason.set(abort_reason);
593 return;
594 }
595
596 let byte = self.registers.ic_data_cmd.read(IC_DATA_CMD::DAT) as u8;
597 self.buf.map(|buf| buf[idx as usize] = byte);
598
599 let idx = idx + 1;
600 if idx > len - 1 {
601 self.state.set(State::WaitingForStop);
604 return;
605 }
606 self.rw_index.set(idx);
607
608 let data_cmd = IC_DATA_CMD::CMD::SET; let data_cmd = {
610 if idx == len - 1 {
611 data_cmd + IC_DATA_CMD::STOP::SET
613 } else {
614 data_cmd
615 }
616 };
617
618 self.state.set(State::WaitingToReadNextByte);
619 self.registers
620 .ic_intr_mask
621 .modify(IC_INTR_MASK::M_RX_FULL::SET);
622 self.registers.ic_data_cmd.write(data_cmd);
623 }
624
625 fn start_reading_after_write(&self) {
626 assert!(self.state.get() == State::WaitingToStartReading);
627
628 self.registers
630 .ic_intr_mask
631 .modify(IC_INTR_MASK::M_TX_EMPTY::CLEAR);
632
633 self.start_reading();
634 }
635
636 fn process_stop_det(&self) {
637 assert!(self.state.get() == State::WaitingForStop);
638
639 self.registers.ic_clr_stop_det.get();
641
642 let status = {
643 if let Some(reason) = self.abort_reason.take() {
644 if reason.matches_all(IC_TX_ABRT_SOURCE::ABRT_7B_ADDR_NOACK::SET) {
645 Err(hil::i2c::Error::AddressNak)
646 } else if reason.matches_all(IC_TX_ABRT_SOURCE::ABRT_TXDATA_NOACK::SET) {
647 Err(hil::i2c::Error::DataNak)
648 } else if reason.matches_all(IC_TX_ABRT_SOURCE::ARB_LOST::SET) {
649 Err(hil::i2c::Error::ArbitrationLost)
650 } else {
651 Err(hil::i2c::Error::NotSupported)
652 }
653 } else {
654 Ok(())
655 }
656 };
657
658 self.state.set(State::Idle);
661
662 self.client.map(|client| match self.buf.take() {
663 None => {}
664 Some(buf) => {
665 client.command_complete(buf, status);
666 }
667 });
668
669 }
675
676 pub fn handle_interrupt(&self) {
677 match self.state.get() {
678 State::Uninitialized => debug!(
679 "Unexpected IRQ for uninitialized I2C device {}",
680 self.instance_num
681 ),
682 State::Idle => debug!("Unexpected IRQ for idle I2C device {}", self.instance_num),
683 State::WaitingToWriteNextByte => self.write_next_byte(),
684 State::WaitingToReadNextByte => self.read_next_byte(),
685 State::WaitingToStartReading => self.start_reading_after_write(),
686 State::WaitingForStop => self.process_stop_det(),
687 }
688 }
689}
690
691impl<'c> hil::i2c::I2CMaster<'c> for I2c<'_, 'c> {
692 fn set_master_client(&self, client: &'c dyn hil::i2c::I2CHwMasterClient) {
693 self.client.set(client);
694 }
695
696 fn enable(&self) {
697 self.enable();
698 }
700
701 fn disable(&self) {
702 self.disable();
703 }
704
705 fn write_read(
706 &self,
707 addr: u8,
708 data: &'static mut [u8],
709 write_len: usize,
710 read_len: usize,
711 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
712 self.buf.put(Some(data));
713
714 if let Err(error) = self.write_then_read(addr, write_len, read_len) {
715 Err((error, self.buf.take().unwrap()))
717 } else {
718 Ok(())
719 }
720 }
721
722 fn write(
723 &self,
724 addr: u8,
725 data: &'static mut [u8],
726 len: usize,
727 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
728 self.write_read(addr, data, len, 0)
730 }
731
732 fn read(
733 &self,
734 addr: u8,
735 buffer: &'static mut [u8],
736 len: usize,
737 ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
738 self.buf.put(Some(buffer));
739
740 if let Err(error) = self.read(addr, len) {
741 Err((error, self.buf.take().unwrap()))
743 } else {
744 Ok(())
745 }
746 }
747}