sam4l/
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
5//! Implementation of the SAM4L TWIMS peripheral.
6//!
7//! The implementation, especially of repeated starts, is quite sensitive to the
8//! ordering of operations (e.g. setup DMA, then set command register, then next
9//! command register, then enable, then start the DMA transfer). The placement
10//! of writes to interrupt enable/disable registers is also significant, but not
11//! refactored in such a way that's very logical right now.
12//!
13//! The point is that until this changes, and this notice is taken away: IF YOU
14//! CHANGE THIS DRIVER, TEST RIGOROUSLY!!!
15
16use crate::dma::{DMAChannel, DMAClient, DMAPeripheral};
17use crate::pm;
18use core::cell::Cell;
19use kernel::hil;
20use kernel::platform::chip::ClockInterface;
21use kernel::utilities::cells::{OptionalCell, TakeCell};
22use kernel::utilities::peripheral_management::{PeripheralManagement, PeripheralManager};
23use kernel::utilities::registers::interfaces::{Readable, Writeable};
24use kernel::utilities::registers::{
25    register_bitfields, FieldValue, ReadOnly, ReadWrite, WriteOnly,
26};
27use kernel::utilities::StaticRef;
28
29// Listing of all registers related to the TWIM peripheral.
30// Section 27.9 of the datasheet
31#[repr(C)]
32#[allow(dead_code)]
33struct TWIMRegisters {
34    cr: WriteOnly<u32, Control::Register>,
35    cwgr: ReadWrite<u32, ClockWaveformGenerator::Register>,
36    smbtr: ReadWrite<u32, SmbusTiming::Register>,
37    cmdr: ReadWrite<u32, Command::Register>,
38    ncmdr: ReadWrite<u32, Command::Register>,
39    rhr: ReadOnly<u32, ReceiveHolding::Register>,
40    thr: WriteOnly<u32, TransmitHolding::Register>,
41    sr: ReadOnly<u32, Status::Register>,
42    ier: WriteOnly<u32, Interrupt::Register>,
43    idr: WriteOnly<u32, Interrupt::Register>,
44    imr: ReadOnly<u32, Interrupt::Register>,
45    scr: WriteOnly<u32, StatusClear::Register>,
46    pr: ReadOnly<u32>,
47    vr: ReadOnly<u32>,
48    hscwgr: ReadWrite<u32>,
49    srr: ReadWrite<u32, SlewRate::Register>,
50    hssrr: ReadWrite<u32>,
51}
52
53// Listing of all registers related to the TWIS peripheral.
54// Section 28.9 of the datasheet
55#[repr(C)]
56#[allow(dead_code)]
57struct TWISRegisters {
58    cr: ReadWrite<u32, ControlSlave::Register>,
59    nbytes: ReadWrite<u32, Nbytes::Register>,
60    tr: ReadWrite<u32, Timing::Register>,
61    rhr: ReadOnly<u32, ReceiveHolding::Register>,
62    thr: WriteOnly<u32, TransmitHolding::Register>,
63    pecr: ReadOnly<u32, PacketErrorCheck::Register>,
64    sr: ReadOnly<u32, StatusSlave::Register>,
65    ier: WriteOnly<u32, InterruptSlave::Register>,
66    idr: WriteOnly<u32, InterruptSlave::Register>,
67    imr: ReadOnly<u32, InterruptSlave::Register>,
68    scr: WriteOnly<u32, StatusClearSlave::Register>,
69    pr: ReadOnly<u32>,
70    vr: ReadOnly<u32>,
71    hstr: ReadWrite<u32>,
72    srr: ReadWrite<u32, SlewRateSlave::Register>,
73    hssrr: ReadWrite<u32>,
74}
75
76register_bitfields![u32,
77    Control [
78        /// Stop the Current Transfer
79        STOP 8,
80        /// Software Reset
81        SWRST 7,
82        /// SMBus Disable
83        SMDIS 5,
84        /// SMBus Enable
85        SMEN 4,
86        /// Master Disable
87        MDIS 1,
88        /// Master Enable
89        MEN 0
90    ],
91
92    ClockWaveformGenerator [
93        /// Clock Prescaler
94        EXP OFFSET(28) NUMBITS(3) [],
95        /// Data Setup and Hold Cycles
96        DATA OFFSET(24) NUMBITS(4) [],
97        /// START and STOP Cycles
98        STASTO OFFSET(16) NUMBITS(8) [],
99        /// Clock High Cycles
100        HIGH OFFSET(8) NUMBITS(8) [],
101        /// Clock Low Cycles
102        LOW OFFSET(0) NUMBITS(8) []
103    ],
104
105    SmbusTiming [
106        /// SMBus Timeout Clock Prescaler
107        EXP OFFSET(28) NUMBITS(4) [],
108        /// Clock High Maximum Cycles
109        THMAX OFFSET(16) NUMBITS(8) [],
110        /// Master Clock Stretch Maximum Cycles
111        TLWOM OFFSET(8) NUMBITS(8) [],
112        /// Slave Clock Stretch Maximum Cycles
113        TLOWS OFFSET(0) NUMBITS(8) []
114    ],
115
116    Command [
117        /// HS-mode Master Code
118        HSMCODE OFFSET(28) NUMBITS(3) [],
119        /// HS-mode
120        HS OFFSET(26) NUMBITS(1) [
121            NoHSMode = 0,
122            HSMode = 1
123        ],
124        /// ACK Last Master RX Byte
125        ACKLAST OFFSET(25) NUMBITS(1) [
126            NackLast = 0,
127            AckLast = 1
128        ],
129        /// Packet Error Checking Enable
130        PECEN OFFSET(24) NUMBITS(1) [
131            NoPecByteVerification = 0,
132            PecByteVerification = 1
133        ],
134        /// Number of Data Bytes in Transfer
135        NBYTES OFFSET(16) NUMBITS(8) [],
136        /// CMDR Valid
137        VALID OFFSET(15) NUMBITS(1) [],
138        /// Send STOP Condition
139        STOP OFFSET(14) NUMBITS(1) [
140            NoSendStop = 0,
141            SendStop = 1
142        ],
143        /// Send START Condition
144        START OFFSET(13) NUMBITS(1) [
145            NoStartCondition = 0,
146            StartCondition = 1
147        ],
148        /// Transfer is to Same Address as Previous Address
149        REPSAME OFFSET(12) NUMBITS(1) [],
150        /// Ten Bit Addressing Mode
151        TENBIT OFFSET(11) NUMBITS(1) [
152            SevenBitAddressing = 0,
153            TenBitAddressing = 1
154        ],
155        /// Slave Address
156        SADR OFFSET(1) NUMBITS(10) [],
157        /// Transfer Direction
158        READ OFFSET(0) NUMBITS(1) [
159            Transmit = 0,
160            Receive = 1
161        ]
162    ],
163
164    ReceiveHolding [
165        /// Received Data
166        RXDATA OFFSET(0) NUMBITS(8) []
167    ],
168
169    TransmitHolding [
170        /// Data to Transmit
171        TXDATA OFFSET(0) NUMBITS(8) []
172    ],
173
174    Status [
175        /// ACK in HS-mode Master Code Phase Received
176        HSMCACK 17,
177        /// Master Interface Enable
178        MENB 16,
179        /// Stop Request Accepted
180        STOP 14,
181        /// PEC Error
182        PECERR 13,
183        /// Timeout
184        TOUT 12,
185        /// Arbitration Lost
186        ARBLST 10,
187        /// NAK in Data Phase Received
188        DNAK 9,
189        /// NAK in Address Phase Received
190        ANAK 8,
191        /// Two-wire Bus is Free
192        BUSFREE 5,
193        /// Master Interface is Idle
194        IDLE 4,
195        /// Command Complete
196        CCOMP 3,
197        /// Ready for More Commands
198        CRDY 2,
199        /// THR Data Ready
200        TXRDY 1,
201        /// RHR Data Ready
202        RXRDY 0
203    ],
204
205    Interrupt [
206        /// ACK in HS-mode Master Code Phase Received
207        HSMCACK 17,
208        /// Stop Request Accepted
209        STOP 14,
210        /// PEC Error
211        PECERR 13,
212        /// Timeout
213        TOUT 12,
214        /// Arbitration Lost
215        ARBLST 10,
216        /// NAK in Data Phase Received
217        DNAK 9,
218        /// NAK in Address Phase Received
219        ANAK 8,
220        /// Two-wire Bus is Free
221        BUSFREE 5,
222        /// Master Interface is Idle
223        IDLE 4,
224        /// Command Complete
225        CCOMP 3,
226        /// Ready for More Commands
227        CRDY 2,
228        /// THR Data Ready
229        TXRDY 1,
230        /// RHR Data Ready
231        RXRDY 0
232    ],
233
234    StatusClear [
235        /// ACK in HS-mode Master Code Phase Received
236        HSMCACK 17,
237        /// Stop Request Accepted
238        STOP 14,
239        /// PEC Error
240        PECERR 13,
241        /// Timeout
242        TOUT 12,
243        /// Arbitration Lost
244        ARBLST 10,
245        /// NAK in Data Phase Received
246        DNAK 9,
247        /// NAK in Address Phase Received
248        ANAK 8,
249        /// Command Complete
250        CCOMP 3
251    ],
252
253    SlewRate [
254        /// Input Spike Filter Control
255        FILTER OFFSET(28) NUMBITS(2) [
256            StandardOrFast = 2,
257            FastModePlus = 3
258        ],
259        /// Clock Slew Limit
260        CLSLEW OFFSET(24) NUMBITS(2) [],
261        /// Clock Drive Strength LOW
262        CLDRIVEL OFFSET(16) NUMBITS(3) [],
263        /// Data Slew Limit
264        DASLEW OFFSET(8) NUMBITS(2) [],
265        /// Data Drive Strength LOW
266        DADRIVEL OFFSET(0) NUMBITS(3) []
267    ]
268];
269
270register_bitfields![u32,
271    ControlSlave [
272        /// Ten Bit Address Match
273        TENBIT OFFSET(26) NUMBITS(1) [
274            Disable = 0,
275            Enable = 1
276        ],
277        /// Slave Address
278        ADR OFFSET(16) NUMBITS(10) [],
279        /// Stretch Clock on Data Byte Reception
280        SODR OFFSET(15) NUMBITS(1) [],
281        /// Stretch Clock on Address Match
282        SOAM OFFSET(14) NUMBITS(1) [
283            NoStretch = 0,
284            Stretch = 1
285        ],
286        /// NBYTES Count Up
287        CUP OFFSET(13) NUMBITS(1) [
288            CountDown = 0,
289            CountUp = 1
290        ],
291        /// Slave Receiver Data Phase ACK Value
292        ACK OFFSET(12) NUMBITS(1) [
293            AckLow = 0,
294            AckHigh = 1
295        ],
296        /// Packet Error Checking Enable
297        PECEN OFFSET(11) NUMBITS(1) [
298            Disable = 0,
299            Enable = 1
300        ],
301        /// SMBus Host Header
302        SMHH OFFSET(10) NUMBITS(1) [
303            NoAckHostHeader = 0,
304            AckHostHeader = 1
305        ],
306        /// SMBus Default Address
307        SMDA OFFSET(9) NUMBITS(1) [
308            NoAckDefaultAddress = 0,
309            AckDefaultAddress = 1
310        ],
311        /// Software Reset
312        SWRST OFFSET(7) NUMBITS(1) [],
313        /// Clock Stretch Enable
314        STREN OFFSET(4) NUMBITS(1) [
315            Disable = 0,
316            Enable = 1
317        ],
318        /// General Call Address Match
319        GCMATCH OFFSET(3) NUMBITS(1) [
320            NoAckGeneralCallAddress = 0,
321            AckGeneralCallAddress = 1
322        ],
323        /// Slave Address Match
324        SMATCH OFFSET(2) NUMBITS(1) [
325            NoAckSlaveAddress = 0,
326            AckSlaveAddress = 1
327        ],
328        /// SMBus Mode Enable
329        SMEN OFFSET(1) NUMBITS(1) [
330            Disable = 0,
331            Enable = 1
332        ],
333        /// Slave Enable
334        SEN OFFSET(0) NUMBITS(1) [
335            Disable = 0,
336            Enable = 1
337        ]
338    ],
339
340    Nbytes [
341        NBYTES OFFSET(0) NUMBITS(8) []
342    ],
343
344    Timing [
345        /// Clock Prescaler
346        EXP OFFSET(28) NUMBITS(4) [],
347        /// Data Setup Cycles
348        SUDAT OFFSET(16) NUMBITS(8) [],
349        /// SMBus Timeout Cycles
350        TTOUT OFFSET(8) NUMBITS(8) [],
351        /// SMBus Low Cycles
352        TLOWS OFFSET(0) NUMBITS(8) []
353    ],
354
355    PacketErrorCheck [
356        /// Calculated PEC Value
357        PEC OFFSET(0) NUMBITS(8) []
358    ],
359
360    StatusSlave [
361        /// Byte Transfer Finished
362        BTF 23,
363        /// Repeated Start Received
364        REP 22,
365        /// Stop Received
366        STO 21,
367        /// SMBus Default Address Match
368        SMBDAM 20,
369        /// SMBus Host Header Address Match
370        SMBHHM 19,
371        /// General Call Match
372        GCM 17,
373        /// Slave Address Match
374        SAM 16,
375        /// Bus Error
376        BUSERR 14,
377        /// SMBus PEC Error
378        SMBPECERR 13,
379        /// SMBus Timeout
380        SMBTOUT 12,
381        /// NAK Received
382        NAK 8,
383        /// Overrun
384        ORUN 7,
385        /// Underrun
386        URUN 6,
387        /// Transmitter Mode
388        TRA 5,
389        /// Transmission Complete
390        TCOMP 3,
391        /// Slave Enabled
392        SEN 2,
393        /// THR Data Ready
394        TXRDY 1,
395        /// RHR Data Ready
396        RXRDY 0
397    ],
398
399    InterruptSlave [
400        /// Byte Transfer Finished
401        BTF 23,
402        /// Repeated Start Received
403        REP 22,
404        /// Stop Received
405        STO 21,
406        /// SMBus Default Address Match
407        SMBDAM 20,
408        /// SMBus Host Header Address Match
409        SMBHHM 19,
410        /// General Call Match
411        GCM 17,
412        /// Slave Address Match
413        SAM 16,
414        /// Bus Error
415        BUSERR 14,
416        /// SMBus PEC Error
417        SMBPECERR 13,
418        /// SMBus Timeout
419        SMBTOUT 12,
420        /// NAK Received
421        NAK 8,
422        /// Overrun
423        ORUN 7,
424        /// Underrun
425        URUN 6,
426        /// Transmission Complete
427        TCOMP 3,
428        /// THR Data Ready
429        TXRDY 1,
430        /// RHR Data Ready
431        RXRDY 0
432    ],
433
434    StatusClearSlave [
435        /// Byte Transfer Finished
436        BTF 23,
437        /// Repeated Start Received
438        REP 22,
439        /// Stop Received
440        STO 21,
441        /// SMBus Default Address Match
442        SMBDAM 20,
443        /// SMBus Host Header Address Match
444        SMBHHM 19,
445        /// General Call Match
446        GCM 17,
447        /// Slave Address Match
448        SAM 16,
449        /// Bus Error
450        BUSERR 14,
451        /// SMBus PEC Error
452        SMBPECERR 13,
453        /// SMBus Timeout
454        SMBTOUT 12,
455        /// NAK Received
456        NAK 8,
457        /// Overrun
458        ORUN 7,
459        /// Underrun
460        URUN 6,
461        /// Transmission Complete
462        TCOMP 3
463    ],
464
465    SlewRateSlave [
466        /// Input Spike Filter Control
467        FILTER OFFSET(28) NUMBITS(2) [],
468        /// Data Slew Limit
469        DASLEW OFFSET(8) NUMBITS(2) [],
470        /// Data Drive Strength LOW
471        DADRIVEL OFFSET(0) NUMBITS(3) []
472    ]
473];
474
475// The addresses in memory (7.1 of manual) of the TWIM peripherals
476const I2C_BASE_ADDRS: [StaticRef<TWIMRegisters>; 4] = unsafe {
477    [
478        StaticRef::new(0x40018000 as *const TWIMRegisters),
479        StaticRef::new(0x4001C000 as *const TWIMRegisters),
480        StaticRef::new(0x40078000 as *const TWIMRegisters),
481        StaticRef::new(0x4007C000 as *const TWIMRegisters),
482    ]
483};
484
485// The addresses in memory (7.1 of manual) of the TWIM peripherals
486const I2C_SLAVE_BASE_ADDRS: [StaticRef<TWISRegisters>; 2] = unsafe {
487    [
488        StaticRef::new(0x40018400 as *const TWISRegisters),
489        StaticRef::new(0x4001C400 as *const TWISRegisters),
490    ]
491};
492
493// Three main I2C speeds
494#[derive(Clone, Copy)]
495pub enum Speed {
496    Standard100k,
497    Fast400k,
498    FastPlus1M,
499}
500
501/// Wrapper for TWIM clock that ensures TWIS clock is off
502struct TWIMClock {
503    master: pm::Clock,
504    slave: Option<pm::Clock>,
505}
506impl ClockInterface for TWIMClock {
507    fn is_enabled(&self) -> bool {
508        self.master.is_enabled()
509    }
510
511    fn enable(&self) {
512        self.slave.map(|slave_clock| {
513            if slave_clock.is_enabled() {
514                panic!("I2C: Request for master clock, but slave active");
515            }
516        });
517        self.master.enable();
518    }
519
520    fn disable(&self) {
521        self.master.disable();
522    }
523}
524
525/// Wrapper for TWIS clock that ensures TWIM clock is off
526struct TWISClock {
527    master: pm::Clock,
528    slave: Option<pm::Clock>,
529}
530impl ClockInterface for TWISClock {
531    fn is_enabled(&self) -> bool {
532        let slave_clock = self.slave.unwrap(); // Unwrap fail = I2C: Use of slave with no clock
533        slave_clock.is_enabled()
534    }
535
536    fn enable(&self) {
537        let slave_clock = self.slave.unwrap(); // Unwrap fail = I2C: Use of slave with no clock
538        if self.master.is_enabled() {
539            panic!("I2C: Request for slave clock, but master active");
540        }
541        slave_clock.enable();
542    }
543
544    fn disable(&self) {
545        let slave_clock = self.slave.unwrap(); // Unwrap fail = I2C: Use of slave with no clock
546        slave_clock.disable();
547    }
548}
549
550/// Abstraction of the I2C hardware
551pub struct I2CHw<'a> {
552    master_mmio_address: StaticRef<TWIMRegisters>,
553    slave_mmio_address: Option<StaticRef<TWISRegisters>>,
554    master_clock: TWIMClock,
555    slave_clock: TWISClock,
556    dma: OptionalCell<&'static DMAChannel>,
557    dma_pids: (DMAPeripheral, DMAPeripheral),
558    master_client: Cell<Option<&'a dyn hil::i2c::I2CHwMasterClient>>,
559    slave_client: Cell<Option<&'a dyn hil::i2c::I2CHwSlaveClient>>,
560    on_deck: Cell<Option<(DMAPeripheral, usize)>>,
561
562    slave_enabled: Cell<bool>,
563    my_slave_address: Cell<u8>,
564    slave_read_buffer: TakeCell<'static, [u8]>,
565    slave_read_buffer_len: Cell<usize>,
566    slave_read_buffer_index: Cell<usize>,
567    slave_write_buffer: TakeCell<'static, [u8]>,
568    slave_write_buffer_len: Cell<usize>,
569    slave_write_buffer_index: Cell<usize>,
570    pm: &'static pm::PowerManager,
571}
572
573impl PeripheralManagement<TWIMClock> for I2CHw<'_> {
574    type RegisterType = TWIMRegisters;
575
576    fn get_registers(&self) -> &TWIMRegisters {
577        &self.master_mmio_address
578    }
579
580    fn get_clock(&self) -> &TWIMClock {
581        &self.master_clock
582    }
583
584    fn before_peripheral_access(&self, clock: &TWIMClock, _: &TWIMRegisters) {
585        if !clock.is_enabled() {
586            clock.enable();
587        }
588    }
589
590    fn after_peripheral_access(&self, clock: &TWIMClock, registers: &TWIMRegisters) {
591        // If there are no interrupts active then we can disable the clock
592        // for this peripheral.
593        if registers.imr.get() == 0 {
594            clock.disable();
595        }
596    }
597}
598type TWIMRegisterManager<'a, 'm> = PeripheralManager<'m, I2CHw<'a>, TWIMClock>;
599
600impl PeripheralManagement<TWISClock> for I2CHw<'_> {
601    type RegisterType = TWISRegisters;
602
603    fn get_registers(&self) -> &TWISRegisters {
604        self.slave_mmio_address.as_ref().unwrap() // Unwrap fail = Access of non-existent slave
605    }
606
607    fn get_clock(&self) -> &TWISClock {
608        &self.slave_clock
609    }
610
611    fn before_peripheral_access(&self, clock: &TWISClock, _: &TWISRegisters) {
612        if !clock.is_enabled() {
613            clock.enable();
614        }
615    }
616
617    fn after_peripheral_access(&self, clock: &TWISClock, registers: &TWISRegisters) {
618        // If there are no interrupts active then we can disable the clock
619        // for this peripheral.
620        if registers.imr.get() == 0 {
621            clock.disable();
622        }
623    }
624}
625type TWISRegisterManager<'a, 'm> = PeripheralManager<'m, I2CHw<'a>, TWISClock>;
626
627const fn create_twims_clocks(
628    master: pm::Clock,
629    slave: Option<pm::Clock>,
630) -> (TWIMClock, TWISClock) {
631    (TWIMClock { master, slave }, TWISClock { master, slave })
632}
633
634// Need to implement the `new` function on the I2C device as a constructor.
635// This gets called from the device tree.
636impl<'a> I2CHw<'a> {
637    fn new(
638        base_addr: StaticRef<TWIMRegisters>,
639        slave_base_addr: Option<StaticRef<TWISRegisters>>,
640        clocks: (TWIMClock, TWISClock),
641        dma_rx: DMAPeripheral,
642        dma_tx: DMAPeripheral,
643        pm: &'static pm::PowerManager,
644    ) -> I2CHw<'a> {
645        I2CHw {
646            master_mmio_address: base_addr,
647            slave_mmio_address: slave_base_addr,
648            master_clock: clocks.0,
649            slave_clock: clocks.1,
650            dma: OptionalCell::empty(),
651            dma_pids: (dma_rx, dma_tx),
652            master_client: Cell::new(None),
653            slave_client: Cell::new(None),
654            on_deck: Cell::new(None),
655
656            slave_enabled: Cell::new(false),
657            my_slave_address: Cell::new(0),
658            slave_read_buffer: TakeCell::empty(),
659            slave_read_buffer_len: Cell::new(0),
660            slave_read_buffer_index: Cell::new(0),
661            slave_write_buffer: TakeCell::empty(),
662            slave_write_buffer_len: Cell::new(0),
663            slave_write_buffer_index: Cell::new(0),
664            pm,
665        }
666    }
667
668    pub fn new_i2c0(pm: &'static pm::PowerManager) -> Self {
669        I2CHw::new(
670            I2C_BASE_ADDRS[0],
671            Some(I2C_SLAVE_BASE_ADDRS[0]),
672            create_twims_clocks(
673                pm::Clock::PBA(pm::PBAClock::TWIM0),
674                Some(pm::Clock::PBA(pm::PBAClock::TWIS0)),
675            ),
676            DMAPeripheral::TWIM0_RX,
677            DMAPeripheral::TWIM0_TX,
678            pm,
679        )
680    }
681
682    pub fn new_i2c1(pm: &'static pm::PowerManager) -> Self {
683        I2CHw::new(
684            I2C_BASE_ADDRS[1],
685            Some(I2C_SLAVE_BASE_ADDRS[1]),
686            create_twims_clocks(
687                pm::Clock::PBA(pm::PBAClock::TWIM1),
688                Some(pm::Clock::PBA(pm::PBAClock::TWIS1)),
689            ),
690            DMAPeripheral::TWIM1_RX,
691            DMAPeripheral::TWIM1_TX,
692            pm,
693        )
694    }
695
696    pub fn new_i2c2(pm: &'static pm::PowerManager) -> Self {
697        I2CHw::new(
698            I2C_BASE_ADDRS[2],
699            None,
700            create_twims_clocks(pm::Clock::PBA(pm::PBAClock::TWIM2), None),
701            DMAPeripheral::TWIM2_RX,
702            DMAPeripheral::TWIM2_TX,
703            pm,
704        )
705    }
706
707    pub fn new_i2c3(pm: &'static pm::PowerManager) -> Self {
708        I2CHw::new(
709            I2C_BASE_ADDRS[3],
710            None,
711            create_twims_clocks(pm::Clock::PBA(pm::PBAClock::TWIM3), None),
712            DMAPeripheral::TWIM3_RX,
713            DMAPeripheral::TWIM3_TX,
714            pm,
715        )
716    }
717
718    /// Set the clock prescaler and the time widths of the I2C signals
719    /// in the CWGR register to make the bus run at a particular I2C speed.
720    fn set_bus_speed(&self, twim: &TWIMRegisterManager) {
721        // Set I2C waveform timing parameters based on ASF code
722        let system_frequency = self.pm.get_system_frequency();
723        let mut exp = 0;
724        let mut f_prescaled = system_frequency / 400000 / 2;
725        while (f_prescaled > 0xff) && (exp <= 0x7) {
726            // Increase the prescale factor, and update our frequency
727            exp += 1;
728            f_prescaled /= 2;
729        }
730
731        // Check that we have a valid setting
732        if exp > 0x7 {
733            panic!("Cannot setup I2C waveform timing with given system clock.");
734        }
735
736        let low = f_prescaled / 2;
737        let high = f_prescaled - low;
738        let data = 0;
739        let stasto = f_prescaled;
740
741        twim.registers.cwgr.write(
742            ClockWaveformGenerator::EXP.val(exp)
743                + ClockWaveformGenerator::DATA.val(data)
744                + ClockWaveformGenerator::STASTO.val(stasto)
745                + ClockWaveformGenerator::HIGH.val(high)
746                + ClockWaveformGenerator::LOW.val(low),
747        )
748    }
749
750    pub fn set_dma(&self, dma: &'static DMAChannel) {
751        self.dma.set(dma);
752    }
753
754    pub fn handle_interrupt(&self) {
755        let old_status = {
756            let twim = &TWIMRegisterManager::new(self);
757
758            let old_status = twim.registers.sr.extract();
759
760            // Clear all status registers.
761            twim.registers.scr.write(
762                StatusClear::HSMCACK::SET
763                    + StatusClear::STOP::SET
764                    + StatusClear::PECERR::SET
765                    + StatusClear::TOUT::SET
766                    + StatusClear::ARBLST::SET
767                    + StatusClear::DNAK::SET
768                    + StatusClear::ANAK::SET
769                    + StatusClear::CCOMP::SET,
770            );
771
772            old_status
773        };
774
775        let err = if old_status.is_set(Status::ANAK) {
776            Some(Err(hil::i2c::Error::AddressNak))
777        } else if old_status.is_set(Status::DNAK) {
778            Some(Err(hil::i2c::Error::DataNak))
779        } else if old_status.is_set(Status::ARBLST) {
780            Some(Err(hil::i2c::Error::ArbitrationLost))
781        } else if old_status.is_set(Status::CCOMP) {
782            Some(Ok(()))
783        } else {
784            None
785        };
786
787        let on_deck = self.on_deck.get();
788        self.on_deck.set(None);
789        match on_deck {
790            None => {
791                {
792                    let twim = &TWIMRegisterManager::new(self);
793
794                    twim.registers.cmdr.set(0);
795                    twim.registers.ncmdr.set(0);
796                    self.disable_interrupts(twim);
797
798                    if err.is_some() {
799                        // enable, reset, disable
800                        twim.registers.cr.write(Control::MEN::SET);
801                        twim.registers.cr.write(Control::SWRST::SET);
802                        twim.registers.cr.write(Control::MDIS::SET);
803                    }
804                }
805
806                err.map(|err| {
807                    self.master_client.get().map(|client| {
808                        let buf = self.dma.and_then(|dma| {
809                            let b = dma.abort_transfer();
810                            self.dma.set(dma);
811                            b
812                        });
813                        buf.map(|buf| {
814                            client.command_complete(buf, err);
815                        });
816                    });
817                });
818            }
819            Some((dma_periph, len)) => {
820                // Check to see if we are only trying to get one byte. If we
821                // are, and the RXRDY bit is already set, then we already have
822                // that byte in the RHR register. If we setup DMA after we
823                // have the single byte we are looking for, everything breaks
824                // because we will never get another byte and therefore
825                // no more interrupts. So, we just read the byte we have
826                // and call this I2C command complete.
827                if (len == 1) && old_status.is_set(Status::TXRDY) {
828                    let the_byte = {
829                        let twim = &TWIMRegisterManager::new(self);
830
831                        twim.registers.cmdr.set(0);
832                        twim.registers.ncmdr.set(0);
833                        self.disable_interrupts(twim);
834
835                        if err.is_some() {
836                            // enable, reset, disable
837                            twim.registers.cr.write(Control::MEN::SET);
838                            twim.registers.cr.write(Control::SWRST::SET);
839                            twim.registers.cr.write(Control::MDIS::SET);
840                        }
841
842                        twim.registers.rhr.read(ReceiveHolding::RXDATA) as u8
843                    };
844
845                    err.map(|err| {
846                        self.master_client.get().map(|client| {
847                            let buf = self.dma.and_then(|dma| {
848                                let b = dma.abort_transfer();
849                                self.dma.set(dma);
850                                b
851                            });
852                            buf.map(|buf| {
853                                // Save the already read byte.
854                                buf[0] = the_byte;
855                                client.command_complete(buf, err);
856                            });
857                        });
858                    });
859                } else {
860                    {
861                        let twim = &TWIMRegisterManager::new(self);
862                        // Enable transaction error interrupts
863                        twim.registers.ier.write(
864                            Interrupt::CCOMP::SET
865                                + Interrupt::ANAK::SET
866                                + Interrupt::DNAK::SET
867                                + Interrupt::ARBLST::SET,
868                        );
869                    }
870                    self.dma.map(|dma| {
871                        let buf = dma.abort_transfer().unwrap();
872                        dma.prepare_transfer(dma_periph, buf, len);
873                        dma.start_transfer();
874                    });
875                }
876            }
877        }
878    }
879
880    fn setup_transfer(
881        &self,
882        twim: &TWIMRegisterManager,
883        chip: u8,
884        flags: FieldValue<u32, Command::Register>,
885        direction: FieldValue<u32, Command::Register>,
886        len: usize,
887    ) {
888        // disable before configuring
889        twim.registers.cr.write(Control::MDIS::SET);
890
891        // Configure the command register with the settings for this transfer.
892        twim.registers.cmdr.write(
893            Command::SADR.val(chip as u32)
894                + flags
895                + Command::VALID::SET
896                + Command::NBYTES.val(len as u32)
897                + direction,
898        );
899        twim.registers.ncmdr.set(0);
900
901        // Enable transaction error interrupts
902        twim.registers.ier.write(
903            Interrupt::CCOMP::SET
904                + Interrupt::ANAK::SET
905                + Interrupt::DNAK::SET
906                + Interrupt::ARBLST::SET,
907        );
908    }
909
910    fn setup_nextfer(
911        &self,
912        twim: &TWIMRegisterManager,
913        chip: u8,
914        flags: FieldValue<u32, Command::Register>,
915        direction: FieldValue<u32, Command::Register>,
916        len: usize,
917    ) {
918        // disable before configuring
919        twim.registers.cr.write(Control::MDIS::SET);
920
921        twim.registers.ncmdr.write(
922            Command::SADR.val(chip as u32)
923                + flags
924                + Command::VALID::SET
925                + Command::NBYTES.val(len as u32)
926                + direction,
927        );
928
929        // Enable
930        twim.registers.cr.write(Control::MEN::SET);
931    }
932
933    fn master_enable(&self, twim: &TWIMRegisterManager) {
934        // Enable to begin transfer
935        twim.registers.cr.write(Control::MEN::SET);
936    }
937
938    fn write(
939        &self,
940        chip: u8,
941        flags: FieldValue<u32, Command::Register>,
942        data: &'static mut [u8],
943        len: usize,
944    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
945        let twim = &TWIMRegisterManager::new(self);
946        if self.dma.is_some() {
947            self.dma.map(move |dma| {
948                dma.enable();
949                dma.prepare_transfer(self.dma_pids.1, data, len);
950                self.setup_transfer(twim, chip, flags, Command::READ::Transmit, len);
951                self.master_enable(twim);
952                dma.start_transfer();
953            });
954            Ok(())
955        } else {
956            Err((hil::i2c::Error::NotSupported, data))
957        }
958    }
959
960    fn read(
961        &self,
962        chip: u8,
963        flags: FieldValue<u32, Command::Register>,
964        data: &'static mut [u8],
965        len: usize,
966    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
967        let twim = &TWIMRegisterManager::new(self);
968        if self.dma.is_some() {
969            self.dma.map(move |dma| {
970                dma.enable();
971                dma.prepare_transfer(self.dma_pids.0, data, len);
972                self.setup_transfer(twim, chip, flags, Command::READ::Receive, len);
973                self.master_enable(twim);
974                dma.start_transfer();
975            });
976            Ok(())
977        } else {
978            Err((hil::i2c::Error::NotSupported, data))
979        }
980    }
981
982    fn write_read(
983        &self,
984        chip: u8,
985        data: &'static mut [u8],
986        split: usize,
987        read_len: usize,
988    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
989        let twim = &TWIMRegisterManager::new(self);
990        if self.dma.is_some() {
991            self.dma.map(move |dma| {
992                dma.enable();
993                dma.prepare_transfer(self.dma_pids.1, data, split);
994                self.setup_transfer(
995                    twim,
996                    chip,
997                    Command::START::StartCondition,
998                    Command::READ::Transmit,
999                    split,
1000                );
1001                self.setup_nextfer(
1002                    twim,
1003                    chip,
1004                    Command::START::StartCondition + Command::STOP::SendStop,
1005                    Command::READ::Receive,
1006                    read_len,
1007                );
1008                self.on_deck.set(Some((self.dma_pids.0, read_len)));
1009                dma.start_transfer();
1010            });
1011            Ok(())
1012        } else {
1013            Err((hil::i2c::Error::NotSupported, data))
1014        }
1015    }
1016
1017    fn disable_interrupts(&self, twim: &TWIMRegisterManager) {
1018        twim.registers.idr.set(!0);
1019    }
1020
1021    /// Handle possible interrupt for TWIS module.
1022    pub fn handle_slave_interrupt(&self) {
1023        if self.slave_mmio_address.is_some() {
1024            let twis = &TWISRegisterManager::new(self);
1025
1026            // Get current status from the hardware.
1027            let status = twis.registers.sr.extract();
1028            let imr = twis.registers.imr.extract();
1029            // This will still be a "status" register, just with all of the
1030            // status bits corresponding to disabled interrupts cleared.
1031            let interrupts = status.bitand(imr.get());
1032
1033            // Check for errors.
1034            if interrupts.any_matching_bits_set(
1035                StatusSlave::BUSERR::SET
1036                    + StatusSlave::SMBPECERR::SET
1037                    + StatusSlave::SMBTOUT::SET
1038                    + StatusSlave::ORUN::SET
1039                    + StatusSlave::URUN::SET,
1040            ) {
1041                // From the datasheet: If a bus error (misplaced START or STOP)
1042                // condition is detected, the SR.BUSERR bit is set and the TWIS
1043                // waits for a new START condition.
1044                if interrupts.is_set(StatusSlave::BUSERR) {
1045                    // Restart and wait for the next start byte
1046                    twis.registers.scr.set(status.get());
1047                    return;
1048                }
1049
1050                panic!("ERR 0x{:x}", interrupts.get());
1051            }
1052
1053            // Check if we got the address match interrupt
1054            if interrupts.is_set(StatusSlave::SAM) {
1055                twis.registers.nbytes.write(Nbytes::NBYTES.val(0));
1056
1057                // Did we get a read or a write?
1058                if status.is_set(StatusSlave::TRA) {
1059                    // This means the slave is in transmit mode, AKA we got a
1060                    // read.
1061
1062                    // Clear the byte transfer done if set (copied from ASF)
1063                    twis.registers.scr.write(StatusClearSlave::BTF::SET);
1064
1065                    // Setup interrupts that we now care about
1066                    twis.registers
1067                        .ier
1068                        .write(InterruptSlave::TCOMP::SET + InterruptSlave::BTF::SET);
1069                    twis.registers.ier.write(
1070                        InterruptSlave::BUSERR::SET
1071                            + InterruptSlave::SMBPECERR::SET
1072                            + InterruptSlave::SMBTOUT::SET
1073                            + InterruptSlave::ORUN::SET
1074                            + InterruptSlave::URUN::SET,
1075                    );
1076
1077                    if self.slave_read_buffer.is_some() {
1078                        // Have buffer to send, start reading
1079                        self.slave_read_buffer_index.set(0);
1080                        let len = self.slave_read_buffer_len.get();
1081
1082                        if len >= 1 {
1083                            self.slave_read_buffer.map(|buffer| {
1084                                twis.registers
1085                                    .thr
1086                                    .write(TransmitHolding::TXDATA.val(buffer[0] as u32));
1087                            });
1088                            self.slave_read_buffer_index.set(1);
1089                        } else {
1090                            // Send dummy byte
1091                            twis.registers.thr.write(TransmitHolding::TXDATA.val(0x2e));
1092                        }
1093
1094                        // Make it happen by clearing status.
1095                        twis.registers.scr.set(status.get());
1096                    } else {
1097                        // Call to upper layers asking for a buffer to send
1098                        self.slave_client.get().map(|client| {
1099                            client.read_expected();
1100                        });
1101                    }
1102                } else {
1103                    // Slave is in receive mode, AKA we got a write.
1104
1105                    // Get transmission complete and rxready interrupts.
1106                    twis.registers
1107                        .ier
1108                        .write(InterruptSlave::TCOMP::SET + InterruptSlave::RXRDY::SET);
1109
1110                    // Set index to 0
1111                    self.slave_write_buffer_index.set(0);
1112
1113                    if self.slave_write_buffer.is_some() {
1114                        // Clear to continue with existing buffer.
1115                        twis.registers.scr.set(status.get());
1116                    } else {
1117                        // Call to upper layers asking for a buffer to
1118                        // read into.
1119                        self.slave_client.get().map(|client| {
1120                            client.write_expected();
1121                        });
1122                    }
1123                }
1124            } else {
1125                // Did not get address match interrupt.
1126
1127                if interrupts.is_set(StatusSlave::TCOMP) {
1128                    // Transmission complete
1129
1130                    let nbytes = twis.registers.nbytes.get();
1131
1132                    twis.registers.idr.set(!0);
1133                    twis.registers.ier.write(InterruptSlave::SAM::SET);
1134                    twis.registers.scr.set(status.get());
1135
1136                    if status.is_set(StatusSlave::TRA) {
1137                        // read
1138                        self.slave_client.get().map(|client| {
1139                            self.slave_read_buffer.take().map(|buffer| {
1140                                client.command_complete(
1141                                    buffer,
1142                                    nbytes as usize,
1143                                    hil::i2c::SlaveTransmissionType::Read,
1144                                );
1145                            });
1146                        });
1147                    } else {
1148                        // write
1149
1150                        let len = self.slave_write_buffer_len.get();
1151                        let idx = self.slave_write_buffer_index.get();
1152
1153                        if len > idx {
1154                            self.slave_write_buffer.map(|buffer| {
1155                                buffer[idx] = twis.registers.rhr.read(ReceiveHolding::RXDATA) as u8;
1156                            });
1157                            self.slave_write_buffer_index.set(idx + 1);
1158                        } else {
1159                            // Just drop on floor
1160                            twis.registers.rhr.get();
1161                        }
1162
1163                        self.slave_client.get().map(|client| {
1164                            self.slave_write_buffer.take().map(|buffer| {
1165                                client.command_complete(
1166                                    buffer,
1167                                    nbytes as usize,
1168                                    hil::i2c::SlaveTransmissionType::Write,
1169                                );
1170                            });
1171                        });
1172                    }
1173                } else if interrupts.is_set(StatusSlave::BTF) {
1174                    // Byte transfer finished. Send the next byte from the
1175                    // buffer.
1176
1177                    if self.slave_read_buffer.is_some() {
1178                        // Have buffer to send, start reading
1179                        let len = self.slave_read_buffer_len.get();
1180                        let idx = self.slave_read_buffer_index.get();
1181
1182                        if len > idx {
1183                            self.slave_read_buffer.map(|buffer| {
1184                                twis.registers
1185                                    .thr
1186                                    .write(TransmitHolding::TXDATA.val(buffer[idx] as u32));
1187                            });
1188                            self.slave_read_buffer_index.set(idx + 1);
1189                        } else {
1190                            // Send dummy byte
1191                            twis.registers.thr.write(TransmitHolding::TXDATA.val(0xdf));
1192                        }
1193                    } else {
1194                        // Send a default byte
1195                        twis.registers.thr.write(TransmitHolding::TXDATA.val(0xdc));
1196                    }
1197
1198                    // Make it happen by clearing status.
1199                    twis.registers.scr.set(status.get());
1200                } else if interrupts.is_set(StatusSlave::RXRDY) {
1201                    // Receive byte ready.
1202
1203                    if self.slave_write_buffer.is_some() {
1204                        // Check that the BTF byte is set at the beginning of
1205                        // the transfer. Sometimes a spurious RX ready interrupt
1206                        // happens at the beginning (right after the address
1207                        // byte) that we need to ignore, and checking the BTF
1208                        // bit fixes that. However, sometimes in the middle of a
1209                        // transfer we get an RXREADY interrupt where the BTF
1210                        // bit is NOT set. I don't know why.
1211                        if status.is_set(StatusSlave::BTF)
1212                            || self.slave_write_buffer_index.get() > 0
1213                        {
1214                            // Have buffer to read into
1215                            let len = self.slave_write_buffer_len.get();
1216                            let idx = self.slave_write_buffer_index.get();
1217
1218                            if len > idx {
1219                                self.slave_write_buffer.map(|buffer| {
1220                                    buffer[idx] =
1221                                        twis.registers.rhr.read(ReceiveHolding::RXDATA) as u8;
1222                                });
1223                                self.slave_write_buffer_index.set(idx + 1);
1224                            } else {
1225                                // Just drop on floor
1226                                twis.registers.rhr.get();
1227                            }
1228                        } else {
1229                            // Just drop on floor
1230                            twis.registers.rhr.get();
1231                        }
1232                    } else {
1233                        // Just drop on floor
1234                        twis.registers.rhr.get();
1235                    }
1236
1237                    twis.registers.scr.set(status.get());
1238                }
1239            }
1240        }
1241    }
1242
1243    /// Receive the bytes the I2C master is writing to us.
1244    fn slave_write_receive(
1245        &self,
1246        buffer: &'static mut [u8],
1247        len: usize,
1248    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1249        if self.slave_enabled.get() {
1250            if self.slave_mmio_address.is_some() {
1251                self.slave_write_buffer.replace(buffer);
1252                self.slave_write_buffer_len.set(len);
1253                let twis = &TWISRegisterManager::new(self);
1254
1255                let status = twis.registers.sr.extract();
1256                let imr = twis.registers.imr.extract();
1257                let interrupts = status.bitand(imr.get());
1258
1259                // Address match status bit still set, so we need to tell the TWIS
1260                // to continue.
1261                if interrupts.is_set(StatusSlave::SAM) && !status.is_set(StatusSlave::TRA) {
1262                    twis.registers.scr.set(status.get());
1263                }
1264                Ok(())
1265            } else {
1266                Err((hil::i2c::Error::AddressNak, buffer))
1267            }
1268        } else {
1269            Err((hil::i2c::Error::NotSupported, buffer))
1270        }
1271    }
1272
1273    /// Prepare a buffer for the I2C master to read from after a read call.
1274    fn slave_read_send(
1275        &self,
1276        buffer: &'static mut [u8],
1277        len: usize,
1278    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1279        if self.slave_enabled.get() {
1280            if self.slave_mmio_address.is_some() {
1281                self.slave_read_buffer.replace(buffer);
1282                self.slave_read_buffer_len.set(len);
1283                self.slave_read_buffer_index.set(0);
1284                let twis = &TWISRegisterManager::new(self);
1285
1286                // Check to see if we should send the first byte.
1287                let status = twis.registers.sr.extract();
1288                let imr = twis.registers.imr.extract();
1289                let interrupts = status.bitand(imr.get());
1290
1291                // Address match status bit still set. We got this function
1292                // call in response to an incoming read. Send the first
1293                // byte.
1294                if interrupts.is_set(StatusSlave::SAM) && status.is_set(StatusSlave::TRA) {
1295                    twis.registers.scr.write(StatusClearSlave::BTF::SET);
1296
1297                    let len = self.slave_read_buffer_len.get();
1298
1299                    if len >= 1 {
1300                        self.slave_read_buffer.map(|buffer| {
1301                            twis.registers
1302                                .thr
1303                                .write(TransmitHolding::TXDATA.val(buffer[0] as u32));
1304                        });
1305                        self.slave_read_buffer_index.set(1);
1306                    } else {
1307                        // Send dummy byte
1308                        twis.registers.thr.write(TransmitHolding::TXDATA.val(0x75));
1309                    }
1310
1311                    // Make it happen by clearing status.
1312                    twis.registers.scr.set(status.get());
1313                }
1314                Ok(())
1315            } else {
1316                Err((hil::i2c::Error::AddressNak, buffer))
1317            }
1318        } else {
1319            Err((hil::i2c::Error::NotSupported, buffer))
1320        }
1321    }
1322
1323    fn slave_disable_interrupts(&self, twis: &TWISRegisterManager) {
1324        twis.registers.idr.set(!0);
1325    }
1326
1327    fn slave_set_address(&self, address: u8) {
1328        self.my_slave_address.set(address);
1329    }
1330
1331    fn slave_listen(&self) {
1332        if self.slave_mmio_address.is_some() {
1333            let twis = &TWISRegisterManager::new(self);
1334
1335            // Enable and configure
1336            let control = ControlSlave::ADR.val((self.my_slave_address.get() as u32) & 0x7F)
1337                + ControlSlave::SOAM::Stretch
1338                + ControlSlave::CUP::CountUp
1339                + ControlSlave::STREN::Enable
1340                + ControlSlave::SMATCH::AckSlaveAddress;
1341            twis.registers.cr.write(control);
1342
1343            // Set this separately because that makes the HW happy.
1344            twis.registers.cr.write(control + ControlSlave::SEN::Enable);
1345        }
1346    }
1347}
1348
1349impl DMAClient for I2CHw<'_> {
1350    fn transfer_done(&self, _pid: DMAPeripheral) {}
1351}
1352
1353impl<'a> hil::i2c::I2CMaster<'a> for I2CHw<'a> {
1354    fn set_master_client(&self, client: &'a dyn hil::i2c::I2CHwMasterClient) {
1355        self.master_client.set(Some(client));
1356    }
1357    /// This enables the entire I2C peripheral
1358    fn enable(&self) {
1359        //disable the i2c slave peripheral
1360        hil::i2c::I2CSlave::disable(self);
1361
1362        let twim = &TWIMRegisterManager::new(self);
1363
1364        // enable, reset, disable
1365        twim.registers.cr.write(Control::MEN::SET);
1366        twim.registers.cr.write(Control::SWRST::SET);
1367        twim.registers.cr.write(Control::MDIS::SET);
1368
1369        // Init the bus speed
1370        self.set_bus_speed(twim);
1371
1372        // slew
1373        twim.registers.srr.write(
1374            SlewRate::FILTER::StandardOrFast
1375                + SlewRate::CLDRIVEL.val(7)
1376                + SlewRate::DADRIVEL.val(7),
1377        );
1378
1379        // clear interrupts
1380        twim.registers.scr.set(!0);
1381    }
1382
1383    /// This disables the entire I2C peripheral
1384    fn disable(&self) {
1385        let twim = &TWIMRegisterManager::new(self);
1386        twim.registers.cr.write(Control::MDIS::SET);
1387        self.disable_interrupts(twim);
1388    }
1389
1390    fn write(
1391        &self,
1392        addr: u8,
1393        data: &'static mut [u8],
1394        len: usize,
1395    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1396        I2CHw::write(
1397            self,
1398            addr,
1399            Command::START::StartCondition + Command::STOP::SendStop,
1400            data,
1401            len,
1402        )
1403    }
1404
1405    fn read(
1406        &self,
1407        addr: u8,
1408        data: &'static mut [u8],
1409        len: usize,
1410    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1411        I2CHw::read(
1412            self,
1413            addr,
1414            Command::START::StartCondition + Command::STOP::SendStop,
1415            data,
1416            len,
1417        )
1418    }
1419
1420    fn write_read(
1421        &self,
1422        addr: u8,
1423        data: &'static mut [u8],
1424        write_len: usize,
1425        read_len: usize,
1426    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1427        I2CHw::write_read(self, addr, data, write_len, read_len)
1428    }
1429}
1430
1431impl<'a> hil::i2c::I2CSlave<'a> for I2CHw<'a> {
1432    fn set_slave_client(&self, client: &'a dyn hil::i2c::I2CHwSlaveClient) {
1433        self.slave_client.set(Some(client));
1434    }
1435    fn enable(&self) {
1436        if self.slave_mmio_address.is_some() {
1437            let twis = &TWISRegisterManager::new(self);
1438
1439            // enable, reset, disable
1440            twis.registers.cr.write(ControlSlave::SEN::SET);
1441            twis.registers.cr.write(ControlSlave::SWRST::SET);
1442            twis.registers.cr.set(0);
1443
1444            // slew
1445            twis.registers
1446                .srr
1447                .write(SlewRateSlave::FILTER.val(0x2) + SlewRateSlave::DADRIVEL.val(7));
1448
1449            // clear interrupts
1450            twis.registers.scr.set(!0);
1451
1452            // We want to interrupt only on slave address match so we can
1453            // wait for a message from a master and then decide what to do
1454            // based on read/write.
1455            twis.registers.ier.write(InterruptSlave::SAM::SET);
1456
1457            // Also setup all of the error interrupts.
1458            twis.registers.ier.write(
1459                InterruptSlave::BUSERR::SET
1460                    + InterruptSlave::SMBPECERR::SET
1461                    + InterruptSlave::SMBTOUT::SET
1462                    + InterruptSlave::ORUN::SET
1463                    + InterruptSlave::URUN::SET,
1464            );
1465        }
1466
1467        self.slave_enabled.set(true);
1468    }
1469
1470    /// This disables the entire I2C peripheral
1471    fn disable(&self) {
1472        self.slave_enabled.set(false);
1473
1474        if self.slave_mmio_address.is_some() {
1475            let twis = &TWISRegisterManager::new(self);
1476            twis.registers.cr.set(0);
1477            self.slave_disable_interrupts(twis);
1478        }
1479    }
1480
1481    fn set_address(&self, addr: u8) -> Result<(), hil::i2c::Error> {
1482        self.slave_set_address(addr);
1483        Ok(())
1484    }
1485
1486    fn write_receive(
1487        &self,
1488        data: &'static mut [u8],
1489        max_len: usize,
1490    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1491        self.slave_write_receive(data, max_len)
1492    }
1493
1494    fn read_send(
1495        &self,
1496        data: &'static mut [u8],
1497        max_len: usize,
1498    ) -> Result<(), (hil::i2c::Error, &'static mut [u8])> {
1499        self.slave_read_send(data, max_len)
1500    }
1501
1502    fn listen(&self) {
1503        self.slave_listen();
1504    }
1505}