vorago_shared_hal/i2c/
regs.rs

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        /// I2C A base address
10        pub const BASE_ADDR_0: usize = 0x4006_0000;
11        /// I2C B base address
12        pub const BASE_ADDR_1: usize = 0x4006_1000;
13    } else if #[cfg(feature = "vor4x")] {
14        /// I2C 0 base address
15        pub const BASE_ADDR_0: usize = 0x4001_6000;
16        /// I2C 1 base address
17        pub const BASE_ADDR_1: usize = 0x4001_6400;
18        /// I2C 2 base address
19        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    /// Unsafely steal the I2C peripheral block for the given port.
34    ///
35    /// # Safety
36    ///
37    /// Circumvents ownership and safety guarantees by the HAL.
38    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    /// I2C clock is stretched until data is available.
48    #[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    /// I2C clock is stretched until data is available.
58    #[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    /// Enables the analog delay glitch filter.
76    #[bit(5, rw)]
77    analog_filter: bool,
78    /// Enables the digital glitch filter.
79    #[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    /// Clock divide value. Reset value: 0x18.
98    #[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    /// Enables 10-bit addressing mode.
132    #[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    /// Rise time.
291    #[bits(0..=3, rw)]
292    t_rise: u4,
293    /// Fall time.
294    #[bits(4..=7, rw)]
295    t_fall: u4,
296    /// Duty cycle high time of SCL.
297    #[bits(8..=11, rw)]
298    t_high: u4,
299    /// Duty cycle low time of SCL.
300    #[bits(12..=15, rw)]
301    t_low: u4,
302    /// Setup time for STOP.
303    #[bits(16..=19, rw)]
304    tsu_stop: u4,
305    /// Setup time for START.
306    #[bits(20..=23, rw)]
307    tsu_start: u4,
308    /// Data hold time.
309    #[bits(24..=27, rw)]
310    thd_start: u4,
311    /// TBus free time between STOP and START.
312    #[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        /// Will normally be 0 to match both read and write addresses.
370        #[bit(0, rw)]
371        rw_mask: bool,
372        /// Reset value 0x3FF.
373        #[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    /// Vorago 4x: 0x0214_07E9. Vorago 1x: 0x0014_07E1.
633    #[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}