1use core::marker::PhantomData;
2
3use arbitrary_int::{u4, u5, u9, u10, u11, u20};
4
5pub use crate::shared::{FifoClear, TriggerLevel};
6
7cfg_if::cfg_if! {
8 if #[cfg(feature = "vor1x")] {
9 pub const BASE_ADDR_0: usize = 0x4006_0000;
11 pub const BASE_ADDR_1: usize = 0x4006_1000;
13 } else if #[cfg(feature = "vor4x")] {
14 pub const BASE_ADDR_0: usize = 0x4001_6000;
16 pub const BASE_ADDR_1: usize = 0x4001_6400;
18 pub const BASE_ADDR_2: usize = 0x4001_6800;
20 }
21}
22
23#[derive(Debug, PartialEq, Eq, Copy, Clone)]
24#[cfg_attr(feature = "defmt", derive(defmt::Format))]
25pub enum Bank {
26 I2c0 = 0,
27 I2c1 = 1,
28 #[cfg(feature = "vor4x")]
29 I2c2 = 2,
30}
31
32impl Bank {
33 pub unsafe fn steal_regs(&self) -> MmioI2c<'static> {
39 I2c::new_mmio(*self)
40 }
41}
42
43#[bitbybit::bitenum(u1, exhaustive = true)]
44#[derive(Default, Debug, PartialEq, Eq)]
45#[cfg_attr(feature = "defmt", derive(defmt::Format))]
46pub enum TxFifoEmptyMode {
47 #[default]
49 Stall = 0,
50 EndTransaction = 1,
51}
52
53#[bitbybit::bitenum(u1, exhaustive = true)]
54#[derive(Default, Debug, PartialEq, Eq)]
55#[cfg_attr(feature = "defmt", derive(defmt::Format))]
56pub enum RxFifoFullMode {
57 #[default]
59 Stall = 0,
60 Nack = 1,
61}
62
63#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"))]
64pub struct Control {
65 #[bit(0, r)]
66 clk_enabled: bool,
67 #[bit(1, r)]
68 enabled: bool,
69 #[bit(2, rw)]
70 enable: bool,
71 #[bit(3, rw)]
72 tx_fifo_empty_mode: TxFifoEmptyMode,
73 #[bit(4, rw)]
74 rx_fifo_full_mode: RxFifoFullMode,
75 #[bit(5, rw)]
77 analog_filter: bool,
78 #[bit(6, rw)]
80 digital_filter: bool,
81 #[bit(8, rw)]
82 loopback: bool,
83 #[bit(9, rw)]
84 enable_timing_config: bool,
85}
86
87#[derive(Debug, PartialEq, Eq)]
88#[bitbybit::bitenum(u1, exhaustive = true)]
89#[cfg_attr(feature = "defmt", derive(defmt::Format))]
90pub enum I2cSpeed {
91 Regular100khz = 0,
92 Fast400khz = 1,
93}
94
95#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_fields(feature = "defmt"))]
96pub struct ClockScale {
97 #[bits(0..=7, rw)]
99 div: u8,
100 #[bit(31, rw)]
101 fastmode: I2cSpeed,
102}
103
104#[derive(Debug, Copy, Clone, PartialEq, Eq)]
105pub struct Words(arbitrary_int::UInt<u32, 11>);
106
107impl Words {
108 pub const fn new(value: u11) -> Self {
109 Words(arbitrary_int::UInt::<u32, 11>::new(value.value() as u32))
110 }
111 pub const fn value(&self) -> u11 {
112 u11::new(self.0.value() as u16)
113 }
114}
115
116#[bitbybit::bitenum(u1, exhaustive = true)]
117#[derive(Default, Debug, PartialEq, Eq)]
118#[cfg_attr(feature = "defmt", derive(defmt::Format))]
119pub enum Direction {
120 #[default]
121 Send = 0,
122 Receive = 1,
123}
124
125#[bitbybit::bitfield(u32, default = 0x0, debug, defmt_bitfields(feature = "defmt"))]
126pub struct Address {
127 #[bit(0, rw)]
128 direction: Direction,
129 #[bits(1..=10, rw)]
130 address: u10,
131 #[bit(15, rw)]
133 a10_mode: bool,
134}
135
136#[derive(Debug, PartialEq, Eq, Clone, Copy)]
137pub struct Data(arbitrary_int::UInt<u32, 8>);
138
139impl Data {
140 pub const fn new(value: u8) -> Self {
141 Data(arbitrary_int::UInt::<u32, 8>::new(value as u32))
142 }
143
144 pub const fn data(&self) -> u8 {
145 self.0.value() as u8
146 }
147}
148
149#[bitbybit::bitfield(u32, default = 0x0)]
150#[derive(Debug)]
151pub struct Command {
152 #[bit(0, w)]
153 start: bool,
154 #[bit(1, w)]
155 stop: bool,
156 #[bit(2, w)]
157 cancel: bool,
158}
159
160#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
161pub struct Status {
162 #[bit(0, r)]
163 i2c_idle: bool,
164 #[bit(1, r)]
165 idle: bool,
166 #[bit(2, r)]
167 waiting: bool,
168 #[bit(3, r)]
169 stalled: bool,
170 #[bit(4, r)]
171 arb_lost: bool,
172 #[bit(5, r)]
173 nack_addr: bool,
174 #[bit(6, r)]
175 nack_data: bool,
176 #[bit(8, r)]
177 rx_not_empty: bool,
178 #[bit(9, r)]
179 rx_full: bool,
180 #[bit(11, r)]
181 rx_trigger: bool,
182 #[bit(12, r)]
183 tx_empty: bool,
184 #[bit(13, r)]
185 tx_not_full: bool,
186 #[bit(15, r)]
187 tx_trigger: bool,
188 #[bit(30, r)]
189 raw_sda: bool,
190 #[bit(31, r)]
191 raw_scl: bool,
192}
193
194#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
195pub struct State {
196 #[bits(0..=3, rw)]
197 state: u4,
198 #[bits(4..=7, rw)]
199 step: u4,
200 #[bits(8..=12, rw)]
201 rx_fifo: u5,
202 #[bits(14..=18, rw)]
203 tx_fifo: u5,
204 #[bits(20..=28, rw)]
205 bitstate: u9,
206}
207
208#[derive(Debug, PartialEq, Eq, Clone, Copy)]
209#[cfg_attr(feature = "defmt", derive(defmt::Format))]
210pub struct DataCount(arbitrary_int::UInt<u32, 11>);
211
212#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
213pub struct InterruptControl {
214 #[bit(0, rw)]
215 i2c_idle: bool,
216 #[bit(1, rw)]
217 idle: bool,
218 #[bit(2, rw)]
219 waiting: bool,
220 #[bit(3, rw)]
221 stalled: bool,
222 #[bit(4, rw)]
223 arb_lost: bool,
224 #[bit(5, rw)]
225 nack_addr: bool,
226 #[bit(6, rw)]
227 nack_data: bool,
228 #[bit(7, rw)]
229 clock_timeout: bool,
230 #[bit(10, rw)]
231 tx_overflow: bool,
232 #[bit(11, rw)]
233 rx_overflow: bool,
234 #[bit(12, rw)]
235 tx_ready: bool,
236 #[bit(13, rw)]
237 rx_ready: bool,
238 #[bit(14, rw)]
239 tx_empty: bool,
240 #[bit(15, rw)]
241 rx_full: bool,
242}
243
244#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
245pub struct InterruptStatus {
246 #[bit(0, r)]
247 i2c_idle: bool,
248 #[bit(1, r)]
249 idle: bool,
250 #[bit(2, r)]
251 waiting: bool,
252 #[bit(3, r)]
253 stalled: bool,
254 #[bit(4, r)]
255 arb_lost: bool,
256 #[bit(5, r)]
257 nack_addr: bool,
258 #[bit(6, r)]
259 nack_data: bool,
260 #[bit(7, r)]
261 clock_timeout: bool,
262 #[bit(10, r)]
263 tx_overflow: bool,
264 #[bit(11, r)]
265 rx_overflow: bool,
266 #[bit(12, r)]
267 tx_ready: bool,
268 #[bit(13, r)]
269 rx_ready: bool,
270 #[bit(14, r)]
271 tx_empty: bool,
272 #[bit(15, r)]
273 rx_full: bool,
274}
275
276#[bitbybit::bitfield(u32, default = 0x0)]
277#[derive(Debug)]
278pub struct InterruptClear {
279 #[bit(7, w)]
280 clock_timeout: bool,
281 #[bit(10, w)]
282 tx_overflow: bool,
283 #[bit(11, w)]
284 rx_overflow: bool,
285}
286
287#[bitbybit::bitfield(u32)]
288#[derive(Debug)]
289pub struct TimingConfig {
290 #[bits(0..=3, rw)]
292 t_rise: u4,
293 #[bits(4..=7, rw)]
295 t_fall: u4,
296 #[bits(8..=11, rw)]
298 t_high: u4,
299 #[bits(12..=15, rw)]
301 t_low: u4,
302 #[bits(16..=19, rw)]
304 tsu_stop: u4,
305 #[bits(20..=23, rw)]
307 tsu_start: u4,
308 #[bits(24..=27, rw)]
310 thd_start: u4,
311 #[bits(28..=31, rw)]
313 t_buf: u4,
314}
315
316pub struct ClockTimeoutLimit(pub arbitrary_int::UInt<u32, 20>);
317
318impl ClockTimeoutLimit {
319 pub fn new(value: u20) -> Self {
320 ClockTimeoutLimit(arbitrary_int::UInt::<u32, 20>::new(value.value()))
321 }
322 pub fn value(&self) -> u20 {
323 self.0
324 }
325}
326
327pub mod slave {
328 use super::{Data, DataCount, FifoClear, RxFifoFullMode, TriggerLevel, TxFifoEmptyMode};
329 use arbitrary_int::{u3, u4, u5, u10, u11};
330
331 #[bitbybit::bitfield(u32)]
332 #[derive(Debug)]
333 pub struct Control {
334 #[bit(0, r)]
335 clk_enabled: bool,
336 #[bit(1, r)]
337 enabled: bool,
338 #[bit(2, rw)]
339 enable: bool,
340 #[bit(3, rw)]
341 tx_fifo_empty_mode: TxFifoEmptyMode,
342 #[bit(4, rw)]
343 rx_fifo_full_mode: RxFifoFullMode,
344 }
345
346 #[bitbybit::bitfield(u32)]
347 #[derive(Debug)]
348 pub struct Maxwords {
349 #[bits(0..=10, rw)]
350 maxwords: u11,
351 #[bit(31, rw)]
352 enable: bool,
353 }
354
355 #[bitbybit::bitfield(u32)]
356 #[derive(Debug)]
357 pub struct Address {
358 #[bit(0, rw)]
359 rw: bool,
360 #[bits(1..=10, rw)]
361 address: u10,
362 #[bit(15, rw)]
363 a10_mode: bool,
364 }
365
366 #[bitbybit::bitfield(u32)]
367 #[derive(Debug)]
368 pub struct AddressMask {
369 #[bit(0, rw)]
371 rw_mask: bool,
372 #[bits(1..=10, rw)]
374 mask: u10,
375 }
376
377 #[bitbybit::bitenum(u1, exhaustive = true)]
378 #[derive(Default, Debug, PartialEq, Eq)]
379 pub enum Direction {
380 #[default]
381 MasterSend = 0,
382 MasterReceive = 1,
383 }
384
385 #[bitbybit::bitfield(u32)]
386 #[derive(Debug)]
387 pub struct LastAddress {
388 #[bit(0, rw)]
389 direction: Direction,
390 #[bits(1..=10, rw)]
391 address: u10,
392 }
393
394 #[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"))]
395 pub struct Status {
396 #[bit(0, r)]
397 completed: bool,
398 #[bit(1, r)]
399 idle: bool,
400 #[bit(2, r)]
401 waiting: bool,
402 #[bit(3, r)]
403 tx_stalled: bool,
404 #[bit(4, r)]
405 rx_stalled: bool,
406 #[bit(5, r)]
407 address_match: bool,
408 #[bit(6, r)]
409 nack_data: bool,
410 #[bit(7, r)]
411 rx_data_first: bool,
412 #[bit(8, r)]
413 rx_not_empty: bool,
414 #[bit(9, r)]
415 rx_full: bool,
416 #[bit(11, r)]
417 rx_trigger: bool,
418 #[bit(12, r)]
419 tx_empty: bool,
420 #[bit(13, r)]
421 tx_not_full: bool,
422 #[bit(15, r)]
423 tx_trigger: bool,
424 #[bit(28, r)]
425 raw_busy: bool,
426 #[bit(30, r)]
427 raw_sda: bool,
428 #[bit(31, r)]
429 raw_scl: bool,
430 }
431
432 #[bitbybit::bitfield(u32)]
433 #[derive(Debug)]
434 pub struct State {
435 #[bits(0..=2, rw)]
436 state: u3,
437 #[bits(4..=7, rw)]
438 step: u4,
439 #[bits(8..=12, rw)]
440 rx_fifo: u5,
441 #[bits(14..=18, rw)]
442 tx_fifo: u5,
443 }
444
445 #[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"))]
446 pub struct InterruptControl {
447 #[bit(0, rw)]
448 completed: bool,
449 #[bit(1, rw)]
450 idle: bool,
451 #[bit(2, rw)]
452 waiting: bool,
453 #[bit(3, rw)]
454 tx_stalled: bool,
455 #[bit(4, rw)]
456 rx_stalled: bool,
457 #[bit(5, rw)]
458 address_match: bool,
459 #[bit(6, rw)]
460 nack_data: bool,
461 #[bit(7, rw)]
462 rx_data_first: bool,
463
464 #[bit(8, rw)]
465 i2c_start: bool,
466 #[bit(9, rw)]
467 i2c_stop: bool,
468 #[bit(10, rw)]
469 tx_underflow: bool,
470 #[bit(11, rw)]
471 rx_underflow: bool,
472 #[bit(12, rw)]
473 tx_ready: bool,
474 #[bit(13, rw)]
475 rx_ready: bool,
476 #[bit(14, rw)]
477 tx_empty: bool,
478 #[bit(15, rw)]
479 rx_full: bool,
480 }
481
482 #[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
483 pub struct InterruptStatus {
484 #[bit(0, r)]
485 completed: bool,
486 #[bit(1, r)]
487 idle: bool,
488 #[bit(2, r)]
489 waiting: bool,
490 #[bit(3, r)]
491 tx_stalled: bool,
492 #[bit(4, r)]
493 rx_stalled: bool,
494 #[bit(5, r)]
495 address_match: bool,
496 #[bit(6, r)]
497 nack_data: bool,
498 #[bit(7, r)]
499 rx_data_first: bool,
500
501 #[bit(8, r)]
502 i2c_start: bool,
503 #[bit(9, r)]
504 i2c_stop: bool,
505 #[bit(10, r)]
506 tx_underflow: bool,
507 #[bit(11, r)]
508 rx_underflow: bool,
509 #[bit(12, r)]
510 tx_ready: bool,
511 #[bit(13, r)]
512 rx_ready: bool,
513 #[bit(14, r)]
514 tx_empty: bool,
515 #[bit(15, r)]
516 rx_full: bool,
517 }
518
519 #[bitbybit::bitfield(u32, default = 0x0)]
520 #[derive(Debug)]
521 pub struct InterruptClear {
522 #[bit(0, w)]
523 completed: bool,
524 #[bit(1, w)]
525 idle: bool,
526 #[bit(2, w)]
527 waiting: bool,
528 #[bit(3, w)]
529 tx_stalled: bool,
530 #[bit(4, w)]
531 rx_stalled: bool,
532 #[bit(5, w)]
533 address_match: bool,
534 #[bit(6, w)]
535 nack_data: bool,
536 #[bit(7, w)]
537 rx_data_first: bool,
538
539 #[bit(8, w)]
540 i2c_start: bool,
541 #[bit(9, w)]
542 i2c_stop: bool,
543 #[bit(10, w)]
544 tx_underflow: bool,
545 #[bit(11, w)]
546 rx_underflow: bool,
547 #[bit(12, w)]
548 tx_ready: bool,
549 #[bit(13, w)]
550 rx_ready: bool,
551 #[bit(14, w)]
552 tx_empty: bool,
553 #[bit(15, w)]
554 rx_full: bool,
555 }
556
557 #[derive(derive_mmio::Mmio)]
558 #[repr(C)]
559 pub struct I2cSlave {
560 s0_ctrl: Control,
561 s0_maxwords: Maxwords,
562 s0_address: Address,
563 s0_addressmask: AddressMask,
564 s0_data: Data,
565 s0_lastaddress: LastAddress,
566 #[mmio(PureRead)]
567 s0_status: Status,
568 #[mmio(PureRead)]
569 s0_state: State,
570 #[mmio(PureRead)]
571 s0_tx_count: DataCount,
572 #[mmio(PureRead)]
573 s0_rx_count: DataCount,
574 s0_irq_enb: InterruptControl,
575 #[mmio(PureRead)]
576 s0_irq_raw: InterruptStatus,
577 #[mmio(PureRead)]
578 s0_irq_status: InterruptStatus,
579 #[mmio(Write)]
580 s0_irq_clear: InterruptClear,
581 s0_rx_fifo_trigger: TriggerLevel,
582 s0_tx_fifo_trigger: TriggerLevel,
583 #[mmio(Write)]
584 s0_fifo_clear: FifoClear,
585 s0_address_b: Address,
586 s0_addressmask_b: AddressMask,
587 }
588}
589#[derive(derive_mmio::Mmio)]
590#[mmio(no_ctors)]
591#[repr(C)]
592pub struct I2c {
593 control: Control,
594 clkscale: ClockScale,
595 words: Words,
596 address: Address,
597 data: Data,
598 #[mmio(Write)]
599 cmd: Command,
600 #[mmio(PureRead)]
601 status: Status,
602 #[mmio(PureRead)]
603 state: State,
604 #[mmio(PureRead)]
605 tx_count: DataCount,
606 #[mmio(PureRead)]
607 rx_count: DataCount,
608 irq_enb: InterruptControl,
609 #[mmio(PureRead)]
610 irq_raw: InterruptStatus,
611 #[mmio(PureRead)]
612 irq_status: InterruptStatus,
613 #[mmio(Write)]
614 irq_clear: InterruptClear,
615 rx_fifo_trigger: TriggerLevel,
616 tx_fifo_trigger: TriggerLevel,
617 #[mmio(Write)]
618 fifo_clear: FifoClear,
619 timing_config: TimingConfig,
620 clk_timeout_limit: ClockTimeoutLimit,
621
622 _reserved_0: [u32; 0x2D],
623
624 #[mmio(Inner)]
625 slave: slave::I2cSlave,
626
627 #[cfg(feature = "vor1x")]
628 _reserved_1: [u32; 0x3AC],
629 #[cfg(feature = "vor4x")]
630 _reserved_1: [u32; 0xAC],
631
632 #[mmio(PureRead)]
634 perid: u32,
635}
636
637cfg_if::cfg_if! {
638 if #[cfg(feature = "vor1x")] {
639 static_assertions::const_assert_eq!(core::mem::size_of::<I2c>(), 0x1000);
640 } else if #[cfg(feature = "vor4x")] {
641 static_assertions::const_assert_eq!(core::mem::size_of::<I2c>(), 0x400);
642 }
643}
644
645impl I2c {
646 fn new_mmio_at(base: usize) -> MmioI2c<'static> {
647 MmioI2c {
648 ptr: base as *mut _,
649 phantom: PhantomData,
650 }
651 }
652
653 pub fn new_mmio(bank: Bank) -> MmioI2c<'static> {
654 match bank {
655 Bank::I2c0 => Self::new_mmio_at(BASE_ADDR_0),
656 Bank::I2c1 => Self::new_mmio_at(BASE_ADDR_1),
657 #[cfg(feature = "vor4x")]
658 Bank::I2c2 => Self::new_mmio_at(BASE_ADDR_2),
659 }
660 }
661}