lpc55s6x/inputmux.rs
1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2025.
4
5//! Input Multiplexer (INPUTMUX) driver for the LPC55S6x family.
6//!
7//! The Inputmux block provides flexible routing of internal and external
8//! signals to on‑chip peripherals. It allows software to dynamically select
9//! which pin or internal source drives a given peripheral input.
10//!
11//! Features supported:
12//! - Connects GPIO pins to **Pin Interrupts (PINT)** and **Pattern Match** logic
13//! - Routes capture inputs for **CTIMER0–4** and **SCT0**
14//! - Selects trigger sources for **DMA0/DMA1 channels**
15//! - Provides secure and non‑secure pin interrupt selection
16//! - Supports frequency measurement reference/target clock selection
17//!
18//! Reference: *LPC55S6x/LPC55S2x/LPC552x User Manual* (NXP).
19
20use enum_primitive::{cast::FromPrimitive, enum_from_primitive};
21use kernel::utilities::registers::interfaces::ReadWriteable;
22use kernel::utilities::registers::{register_bitfields, register_structs, ReadWrite, WriteOnly};
23use kernel::utilities::StaticRef;
24
25register_structs! {
26 /// Input multiplexing (INPUT MUX)
27 pub InputmuxRegisters {
28 /// Input mux register for SCT0 input
29 (0x000 => sct0_inmux_0: ReadWrite<u32>),
30 /// Input mux register for SCT0 input
31 (0x004 => sct0_inmux_1: ReadWrite<u32>),
32 /// Input mux register for SCT0 input
33 (0x008 => sct0_inmux_2: ReadWrite<u32>),
34 /// Input mux register for SCT0 input
35 (0x00C => sct0_inmux_3: ReadWrite<u32>),
36 /// Input mux register for SCT0 input
37 (0x010 => sct0_inmux_4: ReadWrite<u32>),
38 /// Input mux register for SCT0 input
39 (0x014 => sct0_inmux_5: ReadWrite<u32>),
40 /// Input mux register for SCT0 input
41 (0x018 => sct0_inmux_6: ReadWrite<u32>),
42 (0x01C => _reserved0),
43 /// Capture select registers for TIMER0 inputs
44 (0x020 => timer0captsel_0: ReadWrite<u32>),
45 /// Capture select registers for TIMER0 inputs
46 (0x024 => timer0captsel_1: ReadWrite<u32>),
47 /// Capture select registers for TIMER0 inputs
48 (0x028 => timer0captsel_2: ReadWrite<u32>),
49 /// Capture select registers for TIMER0 inputs
50 (0x02C => timer0captsel_3: ReadWrite<u32>),
51 (0x030 => _reserved1),
52 /// Capture select registers for TIMER1 inputs
53 (0x040 => timer1captsel_0: ReadWrite<u32>),
54 /// Capture select registers for TIMER1 inputs
55 (0x044 => timer1captsel_1: ReadWrite<u32>),
56 /// Capture select registers for TIMER1 inputs
57 (0x048 => timer1captsel_2: ReadWrite<u32>),
58 /// Capture select registers for TIMER1 inputs
59 (0x04C => timer1captsel_3: ReadWrite<u32>),
60 (0x050 => _reserved2),
61 /// Capture select registers for TIMER2 inputs
62 (0x060 => timer2captsel_0: ReadWrite<u32>),
63 /// Capture select registers for TIMER2 inputs
64 (0x064 => timer2captsel_1: ReadWrite<u32>),
65 /// Capture select registers for TIMER2 inputs
66 (0x068 => timer2captsel_2: ReadWrite<u32>),
67 /// Capture select registers for TIMER2 inputs
68 (0x06C => timer2captsel_3: ReadWrite<u32>),
69 (0x070 => _reserved3),
70 /// Pin interrupt select register
71 (0x0C0 => pintsel_0: ReadWrite<u32, PINTSEL::Register>),
72 /// Pin interrupt select register
73 (0x0C4 => pintsel_1: ReadWrite<u32, PINTSEL::Register>),
74 /// Pin interrupt select register
75 (0x0C8 => pintsel_2: ReadWrite<u32, PINTSEL::Register>),
76 /// Pin interrupt select register
77 (0x0CC => pintsel_3: ReadWrite<u32, PINTSEL::Register>),
78 /// Pin interrupt select register
79 (0x0D0 => pintsel_4: ReadWrite<u32, PINTSEL::Register>),
80 /// Pin interrupt select register
81 (0x0D4 => pintsel_5: ReadWrite<u32, PINTSEL::Register>),
82 /// Pin interrupt select register
83 (0x0D8 => pintsel_6: ReadWrite<u32, PINTSEL::Register>),
84 /// Pin interrupt select register
85 (0x0DC => pintsel_7: ReadWrite<u32, PINTSEL::Register>),
86 /// Trigger select register for DMA0 channel
87 (0x0E0 => dma0_itrig_inmux_0: ReadWrite<u32>),
88 /// Trigger select register for DMA0 channel
89 (0x0E4 => dma0_itrig_inmux_1: ReadWrite<u32>),
90 /// Trigger select register for DMA0 channel
91 (0x0E8 => dma0_itrig_inmux_2: ReadWrite<u32>),
92 /// Trigger select register for DMA0 channel
93 (0x0EC => dma0_itrig_inmux_3: ReadWrite<u32>),
94 /// Trigger select register for DMA0 channel
95 (0x0F0 => dma0_itrig_inmux_4: ReadWrite<u32>),
96 /// Trigger select register for DMA0 channel
97 (0x0F4 => dma0_itrig_inmux_5: ReadWrite<u32>),
98 /// Trigger select register for DMA0 channel
99 (0x0F8 => dma0_itrig_inmux_6: ReadWrite<u32>),
100 /// Trigger select register for DMA0 channel
101 (0x0FC => dma0_itrig_inmux_7: ReadWrite<u32>),
102 /// Trigger select register for DMA0 channel
103 (0x100 => dma0_itrig_inmux_8: ReadWrite<u32>),
104 /// Trigger select register for DMA0 channel
105 (0x104 => dma0_itrig_inmux_9: ReadWrite<u32>),
106 /// Trigger select register for DMA0 channel
107 (0x108 => dma0_itrig_inmux_10: ReadWrite<u32>),
108 /// Trigger select register for DMA0 channel
109 (0x10C => dma0_itrig_inmux_11: ReadWrite<u32>),
110 /// Trigger select register for DMA0 channel
111 (0x110 => dma0_itrig_inmux_12: ReadWrite<u32>),
112 /// Trigger select register for DMA0 channel
113 (0x114 => dma0_itrig_inmux_13: ReadWrite<u32>),
114 /// Trigger select register for DMA0 channel
115 (0x118 => dma0_itrig_inmux_14: ReadWrite<u32>),
116 /// Trigger select register for DMA0 channel
117 (0x11C => dma0_itrig_inmux_15: ReadWrite<u32>),
118 /// Trigger select register for DMA0 channel
119 (0x120 => dma0_itrig_inmux_16: ReadWrite<u32>),
120 /// Trigger select register for DMA0 channel
121 (0x124 => dma0_itrig_inmux_17: ReadWrite<u32>),
122 /// Trigger select register for DMA0 channel
123 (0x128 => dma0_itrig_inmux_18: ReadWrite<u32>),
124 /// Trigger select register for DMA0 channel
125 (0x12C => dma0_itrig_inmux_19: ReadWrite<u32>),
126 /// Trigger select register for DMA0 channel
127 (0x130 => dma0_itrig_inmux_20: ReadWrite<u32>),
128 /// Trigger select register for DMA0 channel
129 (0x134 => dma0_itrig_inmux_21: ReadWrite<u32>),
130 /// Trigger select register for DMA0 channel
131 (0x138 => dma0_itrig_inmux_22: ReadWrite<u32>),
132 (0x13C => _reserved4),
133 /// DMA0 output trigger selection to become DMA0 trigger
134 (0x160 => dma0_otrig_inmux_0: ReadWrite<u32>),
135 /// DMA0 output trigger selection to become DMA0 trigger
136 (0x164 => dma0_otrig_inmux_1: ReadWrite<u32>),
137 /// DMA0 output trigger selection to become DMA0 trigger
138 (0x168 => dma0_otrig_inmux_2: ReadWrite<u32>),
139 /// DMA0 output trigger selection to become DMA0 trigger
140 (0x16C => dma0_otrig_inmux_3: ReadWrite<u32>),
141 (0x170 => _reserved5),
142 /// Selection for frequency measurement reference clock
143 (0x180 => freqmeas_ref: ReadWrite<u32>),
144 /// Selection for frequency measurement target clock
145 (0x184 => freqmeas_target: ReadWrite<u32>),
146 (0x188 => _reserved6),
147 /// Capture select registers for TIMER3 inputs
148 (0x1A0 => timer3captsel_0: ReadWrite<u32>),
149 /// Capture select registers for TIMER3 inputs
150 (0x1A4 => timer3captsel_1: ReadWrite<u32>),
151 /// Capture select registers for TIMER3 inputs
152 (0x1A8 => timer3captsel_2: ReadWrite<u32>),
153 /// Capture select registers for TIMER3 inputs
154 (0x1AC => timer3captsel_3: ReadWrite<u32>),
155 (0x1B0 => _reserved7),
156 /// Capture select registers for TIMER4 inputs
157 (0x1C0 => timer4captsel_0: ReadWrite<u32>),
158 /// Capture select registers for TIMER4 inputs
159 (0x1C4 => timer4captsel_1: ReadWrite<u32>),
160 /// Capture select registers for TIMER4 inputs
161 (0x1C8 => timer4captsel_2: ReadWrite<u32>),
162 /// Capture select registers for TIMER4 inputs
163 (0x1CC => timer4captsel_3: ReadWrite<u32>),
164 (0x1D0 => _reserved8),
165 /// Pin interrupt secure select register
166 (0x1E0 => pintsecsel_0: ReadWrite<u32>),
167 /// Pin interrupt secure select register
168 (0x1E4 => pintsecsel_1: ReadWrite<u32>),
169 (0x1E8 => _reserved9),
170 /// Trigger select register for DMA1 channel
171 (0x200 => dma1_itrig_inmux_0: ReadWrite<u32>),
172 /// Trigger select register for DMA1 channel
173 (0x204 => dma1_itrig_inmux_1: ReadWrite<u32>),
174 /// Trigger select register for DMA1 channel
175 (0x208 => dma1_itrig_inmux_2: ReadWrite<u32>),
176 /// Trigger select register for DMA1 channel
177 (0x20C => dma1_itrig_inmux_3: ReadWrite<u32>),
178 /// Trigger select register for DMA1 channel
179 (0x210 => dma1_itrig_inmux_4: ReadWrite<u32>),
180 /// Trigger select register for DMA1 channel
181 (0x214 => dma1_itrig_inmux_5: ReadWrite<u32>),
182 /// Trigger select register for DMA1 channel
183 (0x218 => dma1_itrig_inmux_6: ReadWrite<u32>),
184 /// Trigger select register for DMA1 channel
185 (0x21C => dma1_itrig_inmux_7: ReadWrite<u32>),
186 /// Trigger select register for DMA1 channel
187 (0x220 => dma1_itrig_inmux_8: ReadWrite<u32>),
188 /// Trigger select register for DMA1 channel
189 (0x224 => dma1_itrig_inmux_9: ReadWrite<u32>),
190 (0x228 => _reserved10),
191 /// DMA1 output trigger selection to become DMA1 trigger
192 (0x240 => dma1_otrig_inmux_0: ReadWrite<u32>),
193 /// DMA1 output trigger selection to become DMA1 trigger
194 (0x244 => dma1_otrig_inmux_1: ReadWrite<u32>),
195 /// DMA1 output trigger selection to become DMA1 trigger
196 (0x248 => dma1_otrig_inmux_2: ReadWrite<u32>),
197 /// DMA1 output trigger selection to become DMA1 trigger
198 (0x24C => dma1_otrig_inmux_3: ReadWrite<u32>),
199 (0x250 => _reserved11),
200 /// Enable DMA0 requests
201 (0x740 => dma0_req_ena: ReadWrite<u32>),
202 (0x744 => _reserved12),
203 /// Set one or several bits in DMA0_REQ_ENA register
204 (0x748 => dma0_req_ena_set: WriteOnly<u32>),
205 (0x74C => _reserved13),
206 /// Clear one or several bits in DMA0_REQ_ENA register
207 (0x750 => dma0_req_ena_clr: WriteOnly<u32>),
208 (0x754 => _reserved14),
209 /// Enable DMA1 requests
210 (0x760 => dma1_req_ena: ReadWrite<u32>),
211 (0x764 => _reserved15),
212 /// Set one or several bits in DMA1_REQ_ENA register
213 (0x768 => dma1_req_ena_set: WriteOnly<u32>),
214 (0x76C => _reserved16),
215 /// Clear one or several bits in DMA1_REQ_ENA register
216 (0x770 => dma1_req_ena_clr: WriteOnly<u32>),
217 (0x774 => _reserved17),
218 /// Enable DMA0 triggers
219 (0x780 => dma0_itrig_ena: ReadWrite<u32>),
220 (0x784 => _reserved18),
221 /// Set one or several bits in DMA0_ITRIG_ENA register
222 (0x788 => dma0_itrig_ena_set: WriteOnly<u32>),
223 (0x78C => _reserved19),
224 /// Clear one or several bits in DMA0_ITRIG_ENA register
225 (0x790 => dma0_itrig_ena_clr: WriteOnly<u32>),
226 (0x794 => _reserved20),
227 /// Enable DMA1 triggers
228 (0x7A0 => dma1_itrig_ena: ReadWrite<u32>),
229 (0x7A4 => _reserved21),
230 /// Set one or several bits in DMA1_ITRIG_ENA register
231 (0x7A8 => dma1_itrig_ena_set: WriteOnly<u32>),
232 (0x7AC => _reserved22),
233 /// Clear one or several bits in DMA1_ITRIG_ENA register
234 (0x7B0 => dma1_itrig_ena_clr: WriteOnly<u32>),
235 (0x7B4 => @END),
236 }
237}
238register_bitfields![u32,
239PINTSEL [
240 /// Pin number select for pin interrupt or pattern match engine input. For PIOx_y: I
241 INTPIN OFFSET(0) NUMBITS(7) []
242],
243];
244const INPUTMUX_BASE: StaticRef<InputmuxRegisters> =
245 unsafe { StaticRef::new(0x50006000 as *const InputmuxRegisters) };
246
247pub struct Inputmux {
248 registers: StaticRef<InputmuxRegisters>,
249}
250
251enum_from_primitive! {
252 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
253 pub enum PintChannel {
254 Ch0 = 0,
255 Ch1 = 1,
256 Ch2 = 2,
257 Ch3 = 3,
258 Ch4 = 4,
259 Ch5 = 5,
260 Ch6 = 6,
261 Ch7 = 7,
262 }
263}
264
265impl Inputmux {
266 pub const fn new() -> Self {
267 Inputmux {
268 registers: INPUTMUX_BASE,
269 }
270 }
271
272 pub fn registers(&self) -> &InputmuxRegisters {
273 &self.registers
274 }
275
276 pub fn set_pintsel(&self, channel: PintChannel, pin: u8) {
277 let pintsel = match channel {
278 PintChannel::Ch0 => &self.registers.pintsel_0,
279 PintChannel::Ch1 => &self.registers.pintsel_1,
280 PintChannel::Ch2 => &self.registers.pintsel_2,
281 PintChannel::Ch3 => &self.registers.pintsel_3,
282 PintChannel::Ch4 => &self.registers.pintsel_4,
283 PintChannel::Ch5 => &self.registers.pintsel_5,
284 PintChannel::Ch6 => &self.registers.pintsel_6,
285 PintChannel::Ch7 => &self.registers.pintsel_7,
286 };
287
288 pintsel.modify(PINTSEL::INTPIN.val(pin as u32));
289 }
290}