1use 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
29register_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
55register_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 8,
84 SWRST 7,
86 SMDIS 5,
88 SMEN 4,
90 MDIS 1,
92 MEN 0
94 ],
95
96 ClockWaveformGenerator [
97 EXP OFFSET(28) NUMBITS(3) [],
99 DATA OFFSET(24) NUMBITS(4) [],
101 STASTO OFFSET(16) NUMBITS(8) [],
103 HIGH OFFSET(8) NUMBITS(8) [],
105 LOW OFFSET(0) NUMBITS(8) []
107 ],
108
109 SmbusTiming [
110 EXP OFFSET(28) NUMBITS(4) [],
112 THMAX OFFSET(16) NUMBITS(8) [],
114 TLWOM OFFSET(8) NUMBITS(8) [],
116 TLOWS OFFSET(0) NUMBITS(8) []
118 ],
119
120 Command [
121 HSMCODE OFFSET(28) NUMBITS(3) [],
123 HS OFFSET(26) NUMBITS(1) [
125 NoHSMode = 0,
126 HSMode = 1
127 ],
128 ACKLAST OFFSET(25) NUMBITS(1) [
130 NackLast = 0,
131 AckLast = 1
132 ],
133 PECEN OFFSET(24) NUMBITS(1) [
135 NoPecByteVerification = 0,
136 PecByteVerification = 1
137 ],
138 NBYTES OFFSET(16) NUMBITS(8) [],
140 VALID OFFSET(15) NUMBITS(1) [],
142 STOP OFFSET(14) NUMBITS(1) [
144 NoSendStop = 0,
145 SendStop = 1
146 ],
147 START OFFSET(13) NUMBITS(1) [
149 NoStartCondition = 0,
150 StartCondition = 1
151 ],
152 REPSAME OFFSET(12) NUMBITS(1) [],
154 TENBIT OFFSET(11) NUMBITS(1) [
156 SevenBitAddressing = 0,
157 TenBitAddressing = 1
158 ],
159 SADR OFFSET(1) NUMBITS(10) [],
161 READ OFFSET(0) NUMBITS(1) [
163 Transmit = 0,
164 Receive = 1
165 ]
166 ],
167
168 ReceiveHolding [
169 RXDATA OFFSET(0) NUMBITS(8) []
171 ],
172
173 TransmitHolding [
174 TXDATA OFFSET(0) NUMBITS(8) []
176 ],
177
178 Status [
179 HSMCACK 17,
181 MENB 16,
183 STOP 14,
185 PECERR 13,
187 TOUT 12,
189 ARBLST 10,
191 DNAK 9,
193 ANAK 8,
195 BUSFREE 5,
197 IDLE 4,
199 CCOMP 3,
201 CRDY 2,
203 TXRDY 1,
205 RXRDY 0
207 ],
208
209 Interrupt [
210 HSMCACK 17,
212 STOP 14,
214 PECERR 13,
216 TOUT 12,
218 ARBLST 10,
220 DNAK 9,
222 ANAK 8,
224 BUSFREE 5,
226 IDLE 4,
228 CCOMP 3,
230 CRDY 2,
232 TXRDY 1,
234 RXRDY 0
236 ],
237
238 StatusClear [
239 HSMCACK 17,
241 STOP 14,
243 PECERR 13,
245 TOUT 12,
247 ARBLST 10,
249 DNAK 9,
251 ANAK 8,
253 CCOMP 3
255 ],
256
257 SlewRate [
258 FILTER OFFSET(28) NUMBITS(2) [
260 StandardOrFast = 2,
261 FastModePlus = 3
262 ],
263 CLSLEW OFFSET(24) NUMBITS(2) [],
265 CLDRIVEL OFFSET(16) NUMBITS(3) [],
267 DASLEW OFFSET(8) NUMBITS(2) [],
269 DADRIVEL OFFSET(0) NUMBITS(3) []
271 ]
272];
273
274register_bitfields![u32,
275 ControlSlave [
276 TENBIT OFFSET(26) NUMBITS(1) [
278 Disable = 0,
279 Enable = 1
280 ],
281 ADR OFFSET(16) NUMBITS(10) [],
283 SODR OFFSET(15) NUMBITS(1) [],
285 SOAM OFFSET(14) NUMBITS(1) [
287 NoStretch = 0,
288 Stretch = 1
289 ],
290 CUP OFFSET(13) NUMBITS(1) [
292 CountDown = 0,
293 CountUp = 1
294 ],
295 ACK OFFSET(12) NUMBITS(1) [
297 AckLow = 0,
298 AckHigh = 1
299 ],
300 PECEN OFFSET(11) NUMBITS(1) [
302 Disable = 0,
303 Enable = 1
304 ],
305 SMHH OFFSET(10) NUMBITS(1) [
307 NoAckHostHeader = 0,
308 AckHostHeader = 1
309 ],
310 SMDA OFFSET(9) NUMBITS(1) [
312 NoAckDefaultAddress = 0,
313 AckDefaultAddress = 1
314 ],
315 SWRST OFFSET(7) NUMBITS(1) [],
317 STREN OFFSET(4) NUMBITS(1) [
319 Disable = 0,
320 Enable = 1
321 ],
322 GCMATCH OFFSET(3) NUMBITS(1) [
324 NoAckGeneralCallAddress = 0,
325 AckGeneralCallAddress = 1
326 ],
327 SMATCH OFFSET(2) NUMBITS(1) [
329 NoAckSlaveAddress = 0,
330 AckSlaveAddress = 1
331 ],
332 SMEN OFFSET(1) NUMBITS(1) [
334 Disable = 0,
335 Enable = 1
336 ],
337 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 EXP OFFSET(28) NUMBITS(4) [],
351 SUDAT OFFSET(16) NUMBITS(8) [],
353 TTOUT OFFSET(8) NUMBITS(8) [],
355 TLOWS OFFSET(0) NUMBITS(8) []
357 ],
358
359 PacketErrorCheck [
360 PEC OFFSET(0) NUMBITS(8) []
362 ],
363
364 StatusSlave [
365 BTF 23,
367 REP 22,
369 STO 21,
371 SMBDAM 20,
373 SMBHHM 19,
375 GCM 17,
377 SAM 16,
379 BUSERR 14,
381 SMBPECERR 13,
383 SMBTOUT 12,
385 NAK 8,
387 ORUN 7,
389 URUN 6,
391 TRA 5,
393 TCOMP 3,
395 SEN 2,
397 TXRDY 1,
399 RXRDY 0
401 ],
402
403 InterruptSlave [
404 BTF 23,
406 REP 22,
408 STO 21,
410 SMBDAM 20,
412 SMBHHM 19,
414 GCM 17,
416 SAM 16,
418 BUSERR 14,
420 SMBPECERR 13,
422 SMBTOUT 12,
424 NAK 8,
426 ORUN 7,
428 URUN 6,
430 TCOMP 3,
432 TXRDY 1,
434 RXRDY 0
436 ],
437
438 StatusClearSlave [
439 BTF 23,
441 REP 22,
443 STO 21,
445 SMBDAM 20,
447 SMBHHM 19,
449 GCM 17,
451 SAM 16,
453 BUSERR 14,
455 SMBPECERR 13,
457 SMBTOUT 12,
459 NAK 8,
461 ORUN 7,
463 URUN 6,
465 TCOMP 3
467 ],
468
469 SlewRateSlave [
470 FILTER OFFSET(28) NUMBITS(2) [],
472 DASLEW OFFSET(8) NUMBITS(2) [],
474 DADRIVEL OFFSET(0) NUMBITS(3) []
476 ]
477];
478
479const 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
489const 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#[derive(Clone, Copy)]
499pub enum Speed {
500 Standard100k,
501 Fast400k,
502 FastPlus1M,
503}
504
505struct 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
529struct 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(); slave_clock.is_enabled()
538 }
539
540 fn enable(&self) {
541 let slave_clock = self.slave.unwrap(); 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(); slave_clock.disable();
551 }
552}
553
554pub 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 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() }
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 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
638impl<'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 fn set_bus_speed(&self, twim: &TWIMRegisterManager) {
725 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 exp += 1;
732 f_prescaled /= 2;
733 }
734
735 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 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 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 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 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 buf[0] = the_byte;
859 client.command_complete(buf, err);
860 });
861 });
862 });
863 } else {
864 {
865 let twim = &TWIMRegisterManager::new(self);
866 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 twim.registers.cr.write(Control::MDIS::SET);
894
895 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 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 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 twim.registers.cr.write(Control::MEN::SET);
935 }
936
937 fn master_enable(&self, twim: &TWIMRegisterManager) {
938 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 pub fn handle_slave_interrupt(&self) {
1027 if self.slave_mmio_address.is_some() {
1028 let twis = &TWISRegisterManager::new(self);
1029
1030 let status = twis.registers.sr.extract();
1032 let imr = twis.registers.imr.extract();
1033 let interrupts = status.bitand(imr.get());
1036
1037 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 if interrupts.is_set(StatusSlave::BUSERR) {
1049 twis.registers.scr.set(status.get());
1051 return;
1052 }
1053
1054 panic!("ERR 0x{:x}", interrupts.get());
1055 }
1056
1057 if interrupts.is_set(StatusSlave::SAM) {
1059 twis.registers.nbytes.write(Nbytes::NBYTES.val(0));
1060
1061 if status.is_set(StatusSlave::TRA) {
1063 twis.registers.scr.write(StatusClearSlave::BTF::SET);
1068
1069 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 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 twis.registers.thr.write(TransmitHolding::TXDATA.val(0x2e));
1096 }
1097
1098 twis.registers.scr.set(status.get());
1100 } else {
1101 self.slave_client.get().map(|client| {
1103 client.read_expected();
1104 });
1105 }
1106 } else {
1107 twis.registers
1111 .ier
1112 .write(InterruptSlave::TCOMP::SET + InterruptSlave::RXRDY::SET);
1113
1114 self.slave_write_buffer_index.set(0);
1116
1117 if self.slave_write_buffer.is_some() {
1118 twis.registers.scr.set(status.get());
1120 } else {
1121 self.slave_client.get().map(|client| {
1124 client.write_expected();
1125 });
1126 }
1127 }
1128 } else {
1129 if interrupts.is_set(StatusSlave::TCOMP) {
1132 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 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 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 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 if self.slave_read_buffer.is_some() {
1182 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 twis.registers.thr.write(TransmitHolding::TXDATA.val(0xdf));
1196 }
1197 } else {
1198 twis.registers.thr.write(TransmitHolding::TXDATA.val(0xdc));
1200 }
1201
1202 twis.registers.scr.set(status.get());
1204 } else if interrupts.is_set(StatusSlave::RXRDY) {
1205 if self.slave_write_buffer.is_some() {
1208 if status.is_set(StatusSlave::BTF)
1216 || self.slave_write_buffer_index.get() > 0
1217 {
1218 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 twis.registers.rhr.get();
1231 }
1232 } else {
1233 twis.registers.rhr.get();
1235 }
1236 } else {
1237 twis.registers.rhr.get();
1239 }
1240
1241 twis.registers.scr.set(status.get());
1242 }
1243 }
1244 }
1245 }
1246
1247 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 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 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 let status = twis.registers.sr.extract();
1292 let imr = twis.registers.imr.extract();
1293 let interrupts = status.bitand(imr.get());
1294
1295 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 twis.registers.thr.write(TransmitHolding::TXDATA.val(0x75));
1313 }
1314
1315 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 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 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 fn enable(&self) {
1363 hil::i2c::I2CSlave::disable(self);
1365
1366 let twim = &TWIMRegisterManager::new(self);
1367
1368 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 self.set_bus_speed(twim);
1375
1376 twim.registers.srr.write(
1378 SlewRate::FILTER::StandardOrFast
1379 + SlewRate::CLDRIVEL.val(7)
1380 + SlewRate::DADRIVEL.val(7),
1381 );
1382
1383 twim.registers.scr.set(!0);
1385 }
1386
1387 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 twis.registers.cr.write(ControlSlave::SEN::SET);
1445 twis.registers.cr.write(ControlSlave::SWRST::SET);
1446 twis.registers.cr.set(0);
1447
1448 twis.registers
1450 .srr
1451 .write(SlewRateSlave::FILTER.val(0x2) + SlewRateSlave::DADRIVEL.val(7));
1452
1453 twis.registers.scr.set(!0);
1455
1456 twis.registers.ier.write(InterruptSlave::SAM::SET);
1460
1461 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 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}