vorago_shared_hal/ioconfig/
regs.rs

1use core::marker::PhantomData;
2
3use crate::{NUM_PORT_A, NUM_PORT_B, gpio::DynPinId};
4#[cfg(feature = "vor4x")]
5use crate::{NUM_PORT_DEFAULT, NUM_PORT_G};
6
7#[cfg(feature = "vor1x")]
8pub const BASE_ADDR: usize = 0x4000_2000;
9#[cfg(feature = "vor4x")]
10pub const BASE_ADDR: usize = 0x4001_1000;
11
12#[bitbybit::bitenum(u3)]
13#[derive(Debug, PartialEq, Eq)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15pub enum FilterType {
16    SysClk = 0,
17    DirectInput = 1,
18    FilterOneCycle = 2,
19    FilterTwoCycles = 3,
20    FilterThreeCycles = 4,
21    FilterFourCycles = 5,
22}
23
24#[derive(Debug, PartialEq, Eq)]
25#[bitbybit::bitenum(u3, exhaustive = true)]
26#[cfg_attr(feature = "defmt", derive(defmt::Format))]
27pub enum FilterClockSelect {
28    SysClk = 0,
29    Clk1 = 1,
30    Clk2 = 2,
31    Clk3 = 3,
32    Clk4 = 4,
33    Clk5 = 5,
34    Clk6 = 6,
35    Clk7 = 7,
36}
37
38#[derive(Debug, PartialEq, Eq)]
39#[bitbybit::bitenum(u1, exhaustive = true)]
40#[cfg_attr(feature = "defmt", derive(defmt::Format))]
41pub enum Pull {
42    Up = 0,
43    Down = 1,
44}
45
46#[derive(Debug, Eq, PartialEq)]
47#[bitbybit::bitenum(u2, exhaustive = true)]
48#[cfg_attr(feature = "defmt", derive(defmt::Format))]
49pub enum FunctionSelect {
50    Sel0 = 0b00,
51    Sel1 = 0b01,
52    Sel2 = 0b10,
53    Sel3 = 0b11,
54}
55
56#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"))]
57pub struct Config {
58    #[bit(16, rw)]
59    io_disable: bool,
60    #[bits(13..=14, rw)]
61    funsel: FunctionSelect,
62    #[bit(12, rw)]
63    pull_when_output_active: bool,
64    #[bit(11, rw)]
65    pull_enable: bool,
66    #[bit(10, rw)]
67    pull_dir: Pull,
68    #[bit(9, rw)]
69    invert_output: bool,
70    #[bit(8, rw)]
71    open_drain: bool,
72    /// IEWO bit. Allows monitoring of output values.
73    #[bit(7, rw)]
74    input_enable_when_output: bool,
75    #[bit(6, rw)]
76    invert_input: bool,
77    #[bits(3..=5, rw)]
78    filter_clk_sel: FilterClockSelect,
79    #[bits(0..=2, rw)]
80    filter_type: Option<FilterType>,
81}
82
83#[derive(derive_mmio::Mmio)]
84#[mmio(no_ctors)]
85#[repr(C)]
86pub struct IoConfig {
87    port_a: [Config; NUM_PORT_A],
88    port_b: [Config; NUM_PORT_B],
89    #[cfg(feature = "vor4x")]
90    port_c: [Config; NUM_PORT_DEFAULT],
91    #[cfg(feature = "vor4x")]
92    port_d: [Config; NUM_PORT_DEFAULT],
93    #[cfg(feature = "vor4x")]
94    port_e: [Config; NUM_PORT_DEFAULT],
95    #[cfg(feature = "vor4x")]
96    port_f: [Config; NUM_PORT_DEFAULT],
97    #[cfg(feature = "vor4x")]
98    port_g: [Config; NUM_PORT_G],
99    #[cfg(feature = "vor4x")]
100    _reserved0: [u32; 0x8],
101    #[cfg(feature = "vor4x")]
102    #[mmio(PureRead)]
103    clk_div_0: u32,
104    #[cfg(feature = "vor4x")]
105    clk_div_1: u32,
106    #[cfg(feature = "vor4x")]
107    clk_div_2: u32,
108    #[cfg(feature = "vor4x")]
109    clk_div_3: u32,
110    #[cfg(feature = "vor4x")]
111    clk_div_4: u32,
112    #[cfg(feature = "vor4x")]
113    clk_div_5: u32,
114    #[cfg(feature = "vor4x")]
115    clk_div_6: u32,
116    #[cfg(feature = "vor4x")]
117    clk_div_7: u32,
118    #[cfg(feature = "vor4x")]
119    _reserved1: [u32; 0x387],
120    #[cfg(feature = "vor1x")]
121    _reserved1: [u32; 0x3c7],
122    #[mmio(PureRead)]
123    /// Reset value: 0x0282_07E9 for Vorago 4x, and 0x0182_07E1 for Vorago 1x
124    perid: u32,
125}
126
127static_assertions::const_assert_eq!(core::mem::size_of::<IoConfig>(), 0x1000);
128
129impl IoConfig {
130    pub const fn new_mmio() -> MmioIoConfig<'static> {
131        MmioIoConfig {
132            ptr: BASE_ADDR as *mut _,
133            phantom: PhantomData,
134        }
135    }
136}
137
138impl MmioIoConfig<'_> {
139    pub fn read_pin_config(&self, id: DynPinId) -> Config {
140        let offset = id.offset();
141        match id.port() {
142            crate::Port::A => unsafe { self.read_port_a_unchecked(offset) },
143            crate::Port::B => unsafe { self.read_port_b_unchecked(offset) },
144            #[cfg(feature = "vor4x")]
145            crate::Port::C => unsafe { self.read_port_c_unchecked(offset) },
146            #[cfg(feature = "vor4x")]
147            crate::Port::D => unsafe { self.read_port_d_unchecked(offset) },
148            #[cfg(feature = "vor4x")]
149            crate::Port::E => unsafe { self.read_port_e_unchecked(offset) },
150            #[cfg(feature = "vor4x")]
151            crate::Port::F => unsafe { self.read_port_f_unchecked(offset) },
152            #[cfg(feature = "vor4x")]
153            crate::Port::G => unsafe { self.read_port_g_unchecked(offset) },
154        }
155    }
156
157    pub fn modify_pin_config<F: FnOnce(Config) -> Config>(&mut self, id: DynPinId, f: F) {
158        let config = self.read_pin_config(id);
159        self.write_pin_config(id, f(config))
160    }
161
162    pub fn write_pin_config(&mut self, id: DynPinId, config: Config) {
163        let offset = id.offset();
164        match id.port() {
165            crate::Port::A => unsafe { self.write_port_a_unchecked(offset, config) },
166            crate::Port::B => unsafe { self.write_port_b_unchecked(offset, config) },
167            #[cfg(feature = "vor4x")]
168            crate::Port::C => unsafe { self.write_port_c_unchecked(offset, config) },
169            #[cfg(feature = "vor4x")]
170            crate::Port::D => unsafe { self.write_port_d_unchecked(offset, config) },
171            #[cfg(feature = "vor4x")]
172            crate::Port::E => unsafe { self.write_port_e_unchecked(offset, config) },
173            #[cfg(feature = "vor4x")]
174            crate::Port::F => unsafe { self.write_port_f_unchecked(offset, config) },
175            #[cfg(feature = "vor4x")]
176            crate::Port::G => unsafe { self.write_port_g_unchecked(offset, config) },
177        }
178    }
179}