rp2040/
i2c.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use 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
16// NOTE:
17//
18// This driver is based on the logic from the official pico-sdk:
19// https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_i2c/i2c.c
20// and most of the technical comments were copied verbatim from there.
21//
22// The register operations are almost exactly the same as in the official driver,
23// but have been modified to be non-blocking through the use of IRQs instead of polling.
24// A future improvement would be to use DMA instead for even less overhead.
25//
26// Currently this driver only supports master mode.
27// Reads and slave support are part of the pico-sdk and still need to be ported here.
28
29register_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), // TODO: there are still some registers to list in this gap
48        (0x54 => ic_clr_tx_abrt: ReadOnly<u32, IC_CLR_TX_ABRT::Register>),
49        (0x58 => _reserved3), // TODO: there are still some registers to list in this gap
50        (0x60 => ic_clr_stop_det: ReadOnly<u32, IC_CLR_STOP_DET::Register>),
51        (0x64 => _reserved4), // TODO: there are still some registers to list in this gap
52        (0x6c => ic_enable: ReadWrite<u32, IC_ENABLE::Register>),
53        (0x70 => _reserved5), // TODO: there are still some registers to list in this gap
54        (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), // TODO: there are still some registers to list in this gap
57        (0x88 => ic_dma_cr: ReadWrite<u32, IC_DMA_CR::Register>),
58        (0x8c => _reserved7), // TODO: there are still some registers to list in this gap
59        (0xa0 => ic_fs_spklen: ReadWrite<u32, IC_FS_SPKLEN::Register>),
60        (0xa4 => @END), // TODO: there are still some more registers to list here
61    }
62}
63
64register_bitfields! [u32,
65    /// I2C Control Register
66    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    /// I2C Target Address Register
83    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    /// I2C Slave Address Register
89    IC_SAR [
90        IC_SAR OFFSET(0) NUMBITS(10) [],
91    ],
92    /// I2C Rx/Tx Data Buffer and Command Register
93    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    /// Standard Speed I2C Clock SCL High Count Register
101    IC_SS_SCL_HCNT [
102        IC_SS_SCL_HCNT OFFSET(0) NUMBITS(16) [],
103    ],
104    /// Standard Speed I2C Clock SCL Low Count Register
105    IC_SS_SCL_LCNT [
106        IC_SS_SCL_LCNT OFFSET(0) NUMBITS(16) [],
107    ],
108    /// Fast Mode or Fast Mode Plus I2C Clock SCL High Count Register
109    IC_FS_SCL_HCNT [
110        IC_FS_SCL_HCNT OFFSET(0) NUMBITS(16) [],
111    ],
112    /// Fast Mode or Fast Mode Plus I2C Clock SCL Low Count Register
113    IC_FS_SCL_LCNT [
114        IC_FS_SCL_LCNT OFFSET(0) NUMBITS(16) [],
115    ],
116    /// I2C Interrupt Status Register
117    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    /// I2C Interrupt Mask Register
133    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    /// I2C Raw Interrupt Status Register
149    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    /// I2C Receive FIFO Threshold Register
165    IC_RX_TL [
166        IC_RX_TL OFFSET(0) NUMBITS(8) [],
167    ],
168    /// I2C Transmit FIFO Threshold Register
169    IC_TX_TL [
170        IC_TX_TL OFFSET(0) NUMBITS(8) [],
171    ],
172    /// Clear Combined and Individual Interrupt Register
173    IC_CLR_INTR [
174        CLR_INTR OFFSET(0) NUMBITS(1) [],
175    ],
176    /// Clear TX_ABRT Interrupt Register
177    IC_CLR_TX_ABRT [
178        CLR_TX_ABRT OFFSET(0) NUMBITS(1) [],
179    ],
180    /// Clear STOP_DET Interrupt Register
181    IC_CLR_STOP_DET [
182        CLR_STOP_DET OFFSET(0) NUMBITS(1) [],
183    ],
184    /// I2C Enable Register
185    IC_ENABLE [
186        ENABLE OFFSET(0) NUMBITS(1) [],
187        ABORT OFFSET(1) NUMBITS(1) [],
188        TX_CMD_BLOCK OFFSET(2) NUMBITS(1) [],
189    ],
190    /// I2C SDA Hold Time Length Register
191    IC_SDA_HOLD [
192        IC_SDA_TX_HOLD OFFSET(0) NUMBITS(16) [],
193        IC_SDA_RX_HOLD OFFSET(16) NUMBITS(8) [],
194    ],
195    /// I2C Transmit Abort Source Register
196    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    /// DMA Control Register
217    IC_DMA_CR [
218        RDMAE OFFSET(0) NUMBITS(1) [],
219        TDMAE OFFSET(1) NUMBITS(1) [],
220    ],
221    /// I2C SS, FS or FM+ spike suppression limit
222    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        // I2C is synchronous design that runs from clk_sys
330        let freq_in = self
331            .clocks
332            .map(|clocks| clocks.get_frequency(clocks::Clock::System))
333            .unwrap(); // Unwrap fail = You should call resolve_dependencies before set_baudrate.
334
335        // TODO: as per the comments in the pico-sdk, this block is not 100% correct
336        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        // Per I2C-bus specification a device in standard or fast mode must
343        // internally provide a hold time of at least 300ns for the SDA signal to
344        // bridge the undefined region of the falling edge of SCL. A smaller hold
345        // time of 120ns is used for fast mode plus.
346        let sda_tx_hold_count = if baudrate < 1000000 {
347            // sda_tx_hold_count = freq_in [cycles/s] * 300ns * (1s / 1e9ns)
348            // Reduce 300/1e9 to 3/1e7 to avoid numbers that don't fit in uint.
349            // Add 1 to avoid division truncation.
350            ((freq_in * 3) / 10000000) + 1
351        } else {
352            // sda_tx_hold_count = freq_in [cycles/s] * 120ns * (1s / 1e9ns)
353            // Reduce 120/1e9 to 3/25e6 to avoid numbers that don't fit in uint.
354            // Add 1 to avoid division truncation.
355            ((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        // Always use "fast" mode (<= 400 kHz, works fine for standard mode too)
361        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        // Only enable interrupts that we care about
384        self.registers
385            .ic_intr_mask
386            .write(IC_INTR_MASK::M_STOP_DET::SET);
387
388        // Configure as a fast-mode master with RepStart support, 7-bit addresses
389        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        // Set the TX and RX thresholds to 1 (encoded by the value 0) so that we
398        // get an interrupt whenever a byte is available to be read or written.
399        //
400        // TODO: this is obviously not optimal for efficiency
401        self.registers.ic_tx_tl.set(0);
402        self.registers.ic_rx_tl.set(0);
403
404        // Always enable the DREQ signalling -- harmless if DMA isn't listening
405        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        // Synopsys hw accepts start/stop flags alongside data items in the same
427        // FIFO word, so no 0 byte transfers.
428        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        // The first byte will be written in response to an IRQ
441        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        // As long as the mask bit is not cleared, this function gets called repeatedly.
453        // We thus set it again later if there are still bytes that we want to write.
454        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                // NOTE:
473                //
474                // Clearing the abort flag also clears the reason, and
475                // this instance of flag is clear-on-read! Note also the
476                // IC_CLR_TX_ABRT register always reads as 0.
477                self.registers.ic_clr_tx_abrt.get();
478
479                // If the transaction was aborted or if it completed
480                // successfully wait until the STOP condition has occurred.
481                //
482                // Handled by IRQ and process_stop_det()
483                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(); // Unwrap fail = I2C buffer was not set before a write.
492
493        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                // This will cause a read to start once the write buffer is empty
505                self.state.set(State::WaitingToStartReading);
506                self.registers
507                    .ic_intr_mask
508                    .modify(IC_INTR_MASK::M_TX_EMPTY::SET);
509            } else {
510                // If the transaction was aborted or if it completed
511                // successfully wait until the STOP condition has occurred.
512                //
513                // Handled by IRQ and process_stop_det()
514                self.state.set(State::WaitingForStop);
515            }
516        } else {
517            // Wait until the transmission of the address/data from the internal
518            // shift register has completed. For this to function correctly, the
519            // TX_EMPTY_CTRL flag in IC_CON must be set. The TX_EMPTY_CTRL flag
520            // was set in i2c_init.
521            //
522            // This is handled in IRQ.
523            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        // The first byte will be read in response to an IRQ
559        self.state.set(State::WaitingToReadNextByte);
560        self.registers
561            .ic_intr_mask
562            .modify(IC_INTR_MASK::M_RX_FULL::SET);
563
564        // Set the first read in motion (CMD::SET indicates a read)
565        let data_cmd = IC_DATA_CMD::CMD::SET;
566        let data_cmd = {
567            if self.read_len.get() == 1 {
568                // We need to issue the stop bit together with the last read bit
569                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        // As long as the mask bit is not cleared, this function gets called repeatedly.
581        // We thus set it again later if there are still bytes that we want to read.
582        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        // We copy the register before reading the bit that clears it
590        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            // We have just read the last byte and the stop condition has already
602            // been issued so now we just need to wait for it to be recognized.
603            self.state.set(State::WaitingForStop);
604            return;
605        }
606        self.rw_index.set(idx);
607
608        let data_cmd = IC_DATA_CMD::CMD::SET; // Read direction
609        let data_cmd = {
610            if idx == len - 1 {
611                // The stop bit is issued together with the read bit for the last byte
612                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        // In reading mode we no longer want to know when the TX buffer is empty
629        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        // Reset by read
640        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        // Reset state before the callback in case the client wants to start a
659        // new command inside the callback
660        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        // NOTE:
670        //
671        // The hardware issues a STOP automatically on an abort condition.
672        // Note also the hardware clears RX FIFO as well as TX on abort,
673        // because we set hwparam IC_AVOID_RX_FIFO_FLUSH_ON_TX_ABRT to 0.
674    }
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        // TODO: set as master once we support slave mode too
699    }
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            // The unwrap should not fail because we have just assigned to buf
716            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        // Setting read_len to 0 will result in having just a write
729        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            // The unwrap should not fail because we have just assigned to buf
742            Err((error, self.buf.take().unwrap()))
743        } else {
744            Ok(())
745        }
746    }
747}