Skip to main content

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