vorago_shared_hal/ioconfig/
regs.rs1use 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 #[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 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}