1use 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#[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#[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 8,
80        SWRST 7,
82        SMDIS 5,
84        SMEN 4,
86        MDIS 1,
88        MEN 0
90    ],
91
92    ClockWaveformGenerator [
93        EXP OFFSET(28) NUMBITS(3) [],
95        DATA OFFSET(24) NUMBITS(4) [],
97        STASTO OFFSET(16) NUMBITS(8) [],
99        HIGH OFFSET(8) NUMBITS(8) [],
101        LOW OFFSET(0) NUMBITS(8) []
103    ],
104
105    SmbusTiming [
106        EXP OFFSET(28) NUMBITS(4) [],
108        THMAX OFFSET(16) NUMBITS(8) [],
110        TLWOM OFFSET(8) NUMBITS(8) [],
112        TLOWS OFFSET(0) NUMBITS(8) []
114    ],
115
116    Command [
117        HSMCODE OFFSET(28) NUMBITS(3) [],
119        HS OFFSET(26) NUMBITS(1) [
121            NoHSMode = 0,
122            HSMode = 1
123        ],
124        ACKLAST OFFSET(25) NUMBITS(1) [
126            NackLast = 0,
127            AckLast = 1
128        ],
129        PECEN OFFSET(24) NUMBITS(1) [
131            NoPecByteVerification = 0,
132            PecByteVerification = 1
133        ],
134        NBYTES OFFSET(16) NUMBITS(8) [],
136        VALID OFFSET(15) NUMBITS(1) [],
138        STOP OFFSET(14) NUMBITS(1) [
140            NoSendStop = 0,
141            SendStop = 1
142        ],
143        START OFFSET(13) NUMBITS(1) [
145            NoStartCondition = 0,
146            StartCondition = 1
147        ],
148        REPSAME OFFSET(12) NUMBITS(1) [],
150        TENBIT OFFSET(11) NUMBITS(1) [
152            SevenBitAddressing = 0,
153            TenBitAddressing = 1
154        ],
155        SADR OFFSET(1) NUMBITS(10) [],
157        READ OFFSET(0) NUMBITS(1) [
159            Transmit = 0,
160            Receive = 1
161        ]
162    ],
163
164    ReceiveHolding [
165        RXDATA OFFSET(0) NUMBITS(8) []
167    ],
168
169    TransmitHolding [
170        TXDATA OFFSET(0) NUMBITS(8) []
172    ],
173
174    Status [
175        HSMCACK 17,
177        MENB 16,
179        STOP 14,
181        PECERR 13,
183        TOUT 12,
185        ARBLST 10,
187        DNAK 9,
189        ANAK 8,
191        BUSFREE 5,
193        IDLE 4,
195        CCOMP 3,
197        CRDY 2,
199        TXRDY 1,
201        RXRDY 0
203    ],
204
205    Interrupt [
206        HSMCACK 17,
208        STOP 14,
210        PECERR 13,
212        TOUT 12,
214        ARBLST 10,
216        DNAK 9,
218        ANAK 8,
220        BUSFREE 5,
222        IDLE 4,
224        CCOMP 3,
226        CRDY 2,
228        TXRDY 1,
230        RXRDY 0
232    ],
233
234    StatusClear [
235        HSMCACK 17,
237        STOP 14,
239        PECERR 13,
241        TOUT 12,
243        ARBLST 10,
245        DNAK 9,
247        ANAK 8,
249        CCOMP 3
251    ],
252
253    SlewRate [
254        FILTER OFFSET(28) NUMBITS(2) [
256            StandardOrFast = 2,
257            FastModePlus = 3
258        ],
259        CLSLEW OFFSET(24) NUMBITS(2) [],
261        CLDRIVEL OFFSET(16) NUMBITS(3) [],
263        DASLEW OFFSET(8) NUMBITS(2) [],
265        DADRIVEL OFFSET(0) NUMBITS(3) []
267    ]
268];
269
270register_bitfields![u32,
271    ControlSlave [
272        TENBIT OFFSET(26) NUMBITS(1) [
274            Disable = 0,
275            Enable = 1
276        ],
277        ADR OFFSET(16) NUMBITS(10) [],
279        SODR OFFSET(15) NUMBITS(1) [],
281        SOAM OFFSET(14) NUMBITS(1) [
283            NoStretch = 0,
284            Stretch = 1
285        ],
286        CUP OFFSET(13) NUMBITS(1) [
288            CountDown = 0,
289            CountUp = 1
290        ],
291        ACK OFFSET(12) NUMBITS(1) [
293            AckLow = 0,
294            AckHigh = 1
295        ],
296        PECEN OFFSET(11) NUMBITS(1) [
298            Disable = 0,
299            Enable = 1
300        ],
301        SMHH OFFSET(10) NUMBITS(1) [
303            NoAckHostHeader = 0,
304            AckHostHeader = 1
305        ],
306        SMDA OFFSET(9) NUMBITS(1) [
308            NoAckDefaultAddress = 0,
309            AckDefaultAddress = 1
310        ],
311        SWRST OFFSET(7) NUMBITS(1) [],
313        STREN OFFSET(4) NUMBITS(1) [
315            Disable = 0,
316            Enable = 1
317        ],
318        GCMATCH OFFSET(3) NUMBITS(1) [
320            NoAckGeneralCallAddress = 0,
321            AckGeneralCallAddress = 1
322        ],
323        SMATCH OFFSET(2) NUMBITS(1) [
325            NoAckSlaveAddress = 0,
326            AckSlaveAddress = 1
327        ],
328        SMEN OFFSET(1) NUMBITS(1) [
330            Disable = 0,
331            Enable = 1
332        ],
333        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        EXP OFFSET(28) NUMBITS(4) [],
347        SUDAT OFFSET(16) NUMBITS(8) [],
349        TTOUT OFFSET(8) NUMBITS(8) [],
351        TLOWS OFFSET(0) NUMBITS(8) []
353    ],
354
355    PacketErrorCheck [
356        PEC OFFSET(0) NUMBITS(8) []
358    ],
359
360    StatusSlave [
361        BTF 23,
363        REP 22,
365        STO 21,
367        SMBDAM 20,
369        SMBHHM 19,
371        GCM 17,
373        SAM 16,
375        BUSERR 14,
377        SMBPECERR 13,
379        SMBTOUT 12,
381        NAK 8,
383        ORUN 7,
385        URUN 6,
387        TRA 5,
389        TCOMP 3,
391        SEN 2,
393        TXRDY 1,
395        RXRDY 0
397    ],
398
399    InterruptSlave [
400        BTF 23,
402        REP 22,
404        STO 21,
406        SMBDAM 20,
408        SMBHHM 19,
410        GCM 17,
412        SAM 16,
414        BUSERR 14,
416        SMBPECERR 13,
418        SMBTOUT 12,
420        NAK 8,
422        ORUN 7,
424        URUN 6,
426        TCOMP 3,
428        TXRDY 1,
430        RXRDY 0
432    ],
433
434    StatusClearSlave [
435        BTF 23,
437        REP 22,
439        STO 21,
441        SMBDAM 20,
443        SMBHHM 19,
445        GCM 17,
447        SAM 16,
449        BUSERR 14,
451        SMBPECERR 13,
453        SMBTOUT 12,
455        NAK 8,
457        ORUN 7,
459        URUN 6,
461        TCOMP 3
463    ],
464
465    SlewRateSlave [
466        FILTER OFFSET(28) NUMBITS(2) [],
468        DASLEW OFFSET(8) NUMBITS(2) [],
470        DADRIVEL OFFSET(0) NUMBITS(3) []
472    ]
473];
474
475const 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
485const 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#[derive(Clone, Copy)]
495pub enum Speed {
496    Standard100k,
497    Fast400k,
498    FastPlus1M,
499}
500
501struct 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
525struct 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(); slave_clock.is_enabled()
534    }
535
536    fn enable(&self) {
537        let slave_clock = self.slave.unwrap(); 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(); slave_clock.disable();
547    }
548}
549
550pub 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 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() }
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 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
634impl<'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    fn set_bus_speed(&self, twim: &TWIMRegisterManager) {
721        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            exp += 1;
728            f_prescaled /= 2;
729        }
730
731        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            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                        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                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                            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                                buf[0] = the_byte;
855                                client.command_complete(buf, err);
856                            });
857                        });
858                    });
859                } else {
860                    {
861                        let twim = &TWIMRegisterManager::new(self);
862                        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        twim.registers.cr.write(Control::MDIS::SET);
890
891        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        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        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        twim.registers.cr.write(Control::MEN::SET);
931    }
932
933    fn master_enable(&self, twim: &TWIMRegisterManager) {
934        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    pub fn handle_slave_interrupt(&self) {
1023        if self.slave_mmio_address.is_some() {
1024            let twis = &TWISRegisterManager::new(self);
1025
1026            let status = twis.registers.sr.extract();
1028            let imr = twis.registers.imr.extract();
1029            let interrupts = status.bitand(imr.get());
1032
1033            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                if interrupts.is_set(StatusSlave::BUSERR) {
1045                    twis.registers.scr.set(status.get());
1047                    return;
1048                }
1049
1050                panic!("ERR 0x{:x}", interrupts.get());
1051            }
1052
1053            if interrupts.is_set(StatusSlave::SAM) {
1055                twis.registers.nbytes.write(Nbytes::NBYTES.val(0));
1056
1057                if status.is_set(StatusSlave::TRA) {
1059                    twis.registers.scr.write(StatusClearSlave::BTF::SET);
1064
1065                    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                        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                            twis.registers.thr.write(TransmitHolding::TXDATA.val(0x2e));
1092                        }
1093
1094                        twis.registers.scr.set(status.get());
1096                    } else {
1097                        self.slave_client.get().map(|client| {
1099                            client.read_expected();
1100                        });
1101                    }
1102                } else {
1103                    twis.registers
1107                        .ier
1108                        .write(InterruptSlave::TCOMP::SET + InterruptSlave::RXRDY::SET);
1109
1110                    self.slave_write_buffer_index.set(0);
1112
1113                    if self.slave_write_buffer.is_some() {
1114                        twis.registers.scr.set(status.get());
1116                    } else {
1117                        self.slave_client.get().map(|client| {
1120                            client.write_expected();
1121                        });
1122                    }
1123                }
1124            } else {
1125                if interrupts.is_set(StatusSlave::TCOMP) {
1128                    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                        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                        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                            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                    if self.slave_read_buffer.is_some() {
1178                        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                            twis.registers.thr.write(TransmitHolding::TXDATA.val(0xdf));
1192                        }
1193                    } else {
1194                        twis.registers.thr.write(TransmitHolding::TXDATA.val(0xdc));
1196                    }
1197
1198                    twis.registers.scr.set(status.get());
1200                } else if interrupts.is_set(StatusSlave::RXRDY) {
1201                    if self.slave_write_buffer.is_some() {
1204                        if status.is_set(StatusSlave::BTF)
1212                            || self.slave_write_buffer_index.get() > 0
1213                        {
1214                            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                                twis.registers.rhr.get();
1227                            }
1228                        } else {
1229                            twis.registers.rhr.get();
1231                        }
1232                    } else {
1233                        twis.registers.rhr.get();
1235                    }
1236
1237                    twis.registers.scr.set(status.get());
1238                }
1239            }
1240        }
1241    }
1242
1243    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                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    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                let status = twis.registers.sr.extract();
1288                let imr = twis.registers.imr.extract();
1289                let interrupts = status.bitand(imr.get());
1290
1291                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                        twis.registers.thr.write(TransmitHolding::TXDATA.val(0x75));
1309                    }
1310
1311                    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            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            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    fn enable(&self) {
1359        hil::i2c::I2CSlave::disable(self);
1361
1362        let twim = &TWIMRegisterManager::new(self);
1363
1364        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        self.set_bus_speed(twim);
1371
1372        twim.registers.srr.write(
1374            SlewRate::FILTER::StandardOrFast
1375                + SlewRate::CLDRIVEL.val(7)
1376                + SlewRate::DADRIVEL.val(7),
1377        );
1378
1379        twim.registers.scr.set(!0);
1381    }
1382
1383    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            twis.registers.cr.write(ControlSlave::SEN::SET);
1441            twis.registers.cr.write(ControlSlave::SWRST::SET);
1442            twis.registers.cr.set(0);
1443
1444            twis.registers
1446                .srr
1447                .write(SlewRateSlave::FILTER.val(0x2) + SlewRateSlave::DADRIVEL.val(7));
1448
1449            twis.registers.scr.set(!0);
1451
1452            twis.registers.ier.write(InterruptSlave::SAM::SET);
1456
1457            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    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}