lpc55s6x/pint.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//! Pin Interrupt (PINT) driver for the LPC55S6x family.
6//!
7//! The PINT block provides edge‑sensitive and pattern‑match interrupt
8//! generation from GPIO pins. It works in conjunction with the IOCON and
9//! INPUTMUX modules to route physical pins into the PINT channels.
10//!
11//! Features supported:
12//! - Up to 8 independent pin interrupt channels
13//! - Configurable rising, falling, or both‑edge detection
14//! - Pattern match engine for complex multi‑pin conditions
15//! - Interrupt status and enable/disable control per channel
16//! - Integration with NVIC for interrupt delivery to the Cortex‑M33 core
17//!
18//! Reference: *LPC55S6x/LPC55S2x/LPC552x User Manual* (NXP).
19
20use kernel::utilities::cells::OptionalCell;
21use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
22use kernel::utilities::registers::{register_bitfields, register_structs, ReadWrite, WriteOnly};
23use kernel::utilities::StaticRef;
24
25register_structs! {
26 pub PintRegisters {
27 /// Pin Interrupt Mode register
28 (0x00 => isel: ReadWrite<u32, ISEL::Register>),
29 /// Pin interrupt level or rising edge interrupt enable register
30 (0x04 => ienr: ReadWrite<u32, IENR::Register>),
31 /// Pin interrupt level or rising edge interrupt set register
32 (0x08 => sienr: WriteOnly<u32, SIENR::Register>),
33 /// Pin interrupt level (rising edge interrupt) clear register
34 (0x0C => cienr: WriteOnly<u32, CIENR::Register>),
35 /// Pin interrupt active level or falling edge interrupt enable register
36 (0x10 => ienf: ReadWrite<u32, IENF::Register>),
37 /// Pin interrupt active level or falling edge interrupt set register
38 (0x14 => sienf: WriteOnly<u32, SIENF::Register>),
39 /// Pin interrupt active level or falling edge interrupt clear register
40 (0x18 => cienf: WriteOnly<u32, CIENF::Register>),
41 /// Pin interrupt rising edge register
42 (0x1C => rise: ReadWrite<u32, RISE::Register>),
43 /// Pin interrupt falling edge register
44 (0x20 => fall: ReadWrite<u32, FALL::Register>),
45 /// Pin interrupt status register
46 (0x24 => ist: ReadWrite<u32, IST::Register>),
47 (0x28 => @END),
48 }
49}
50register_bitfields![u32,
51ISEL [
52 /// Selects the interrupt mode for each pin interrupt. Bit n configures the pin inte
53 PMODE OFFSET(0) NUMBITS(8) []
54],
55IENR [
56 /// Enables the rising edge or level interrupt for each pin interrupt. Bit n configu
57 ENRL OFFSET(0) NUMBITS(8) []
58],
59SIENR [
60 /// Ones written to this address set bits in the IENR, thus enabling interrupts. Bit
61 SETENRL OFFSET(0) NUMBITS(8) []
62],
63CIENR [
64 /// Ones written to this address clear bits in the IENR, thus disabling the interrup
65 CENRL OFFSET(0) NUMBITS(8) []
66],
67IENF [
68 /// Enables the falling edge or configures the active level interrupt for each pin i
69 ENAF OFFSET(0) NUMBITS(8) []
70],
71SIENF [
72 /// Ones written to this address set bits in the IENF, thus enabling interrupts. Bit
73 SETENAF OFFSET(0) NUMBITS(8) []
74],
75CIENF [
76 /// Ones written to this address clears bits in the IENF, thus disabling interrupts.
77 CENAF OFFSET(0) NUMBITS(8) []
78],
79RISE [
80 /// Rising edge detect. Bit n detects the rising edge of the pin selected in PINTSEL
81 RDET OFFSET(0) NUMBITS(8) []
82],
83FALL [
84 /// Falling edge detect. Bit n detects the falling edge of the pin selected in PINTS
85 FDET OFFSET(0) NUMBITS(8) []
86],
87IST [
88 /// Pin interrupt status. Bit n returns the status, clears the edge interrupt, or in
89 PSTAT OFFSET(0) NUMBITS(8) []
90],
91PMCTRL [
92 /// Specifies whether the 8 pin interrupts are controlled by the pin interrupt funct
93 SEL_PMATCH OFFSET(0) NUMBITS(1) [
94 /// Pin interrupt. Interrupts are driven in response to the standard pin interrupt f
95 PinInterruptInterruptsAreDrivenInResponseToTheStandardPinInterruptFunction = 0,
96 /// Pattern match. Interrupts are driven in response to pattern matches.
97 PatternMatchInterruptsAreDrivenInResponseToPatternMatches = 1
98 ],
99 /// Enables the RXEV output to the CPU and/or to a GPIO output when the specified bo
100 ENA_RXEV OFFSET(1) NUMBITS(1) [
101 /// Disabled. RXEV output to the CPU is disabled.
102 DisabledRXEVOutputToTheCPUIsDisabled = 0,
103 /// Enabled. RXEV output to the CPU is enabled.
104 EnabledRXEVOutputToTheCPUIsEnabled = 1
105 ],
106 /// This field displays the current state of pattern matches. A 1 in any bit of this
107 PMAT OFFSET(24) NUMBITS(8) []
108],
109PMSRC [
110 /// Selects the input source for bit slice 0
111 SRC0 OFFSET(8) NUMBITS(3) [
112 /// Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit
113 Input0SelectsThePinSelectedInThePINTSEL0RegisterAsTheSourceToBitSlice0 = 0,
114 /// Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit
115 Input1SelectsThePinSelectedInThePINTSEL1RegisterAsTheSourceToBitSlice0 = 1,
116 /// Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit
117 Input2SelectsThePinSelectedInThePINTSEL2RegisterAsTheSourceToBitSlice0 = 2,
118 /// Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit
119 Input3SelectsThePinSelectedInThePINTSEL3RegisterAsTheSourceToBitSlice0 = 3,
120 /// Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit
121 Input4SelectsThePinSelectedInThePINTSEL4RegisterAsTheSourceToBitSlice0 = 4,
122 /// Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit
123 Input5SelectsThePinSelectedInThePINTSEL5RegisterAsTheSourceToBitSlice0 = 5,
124 /// Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit
125 Input6SelectsThePinSelectedInThePINTSEL6RegisterAsTheSourceToBitSlice0 = 6,
126 /// Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit
127 Input7SelectsThePinSelectedInThePINTSEL7RegisterAsTheSourceToBitSlice0 = 7
128 ],
129 /// Selects the input source for bit slice 1
130 SRC1 OFFSET(11) NUMBITS(3) [
131 /// Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit
132 Input0SelectsThePinSelectedInThePINTSEL0RegisterAsTheSourceToBitSlice1 = 0,
133 /// Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit
134 Input1SelectsThePinSelectedInThePINTSEL1RegisterAsTheSourceToBitSlice1 = 1,
135 /// Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit
136 Input2SelectsThePinSelectedInThePINTSEL2RegisterAsTheSourceToBitSlice1 = 2,
137 /// Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit
138 Input3SelectsThePinSelectedInThePINTSEL3RegisterAsTheSourceToBitSlice1 = 3,
139 /// Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit
140 Input4SelectsThePinSelectedInThePINTSEL4RegisterAsTheSourceToBitSlice1 = 4,
141 /// Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit
142 Input5SelectsThePinSelectedInThePINTSEL5RegisterAsTheSourceToBitSlice1 = 5,
143 /// Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit
144 Input6SelectsThePinSelectedInThePINTSEL6RegisterAsTheSourceToBitSlice1 = 6,
145 /// Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit
146 Input7SelectsThePinSelectedInThePINTSEL7RegisterAsTheSourceToBitSlice1 = 7
147 ],
148 /// Selects the input source for bit slice 2
149 SRC2 OFFSET(14) NUMBITS(3) [
150 /// Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit
151 Input0SelectsThePinSelectedInThePINTSEL0RegisterAsTheSourceToBitSlice2 = 0,
152 /// Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit
153 Input1SelectsThePinSelectedInThePINTSEL1RegisterAsTheSourceToBitSlice2 = 1,
154 /// Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit
155 Input2SelectsThePinSelectedInThePINTSEL2RegisterAsTheSourceToBitSlice2 = 2,
156 /// Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit
157 Input3SelectsThePinSelectedInThePINTSEL3RegisterAsTheSourceToBitSlice2 = 3,
158 /// Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit
159 Input4SelectsThePinSelectedInThePINTSEL4RegisterAsTheSourceToBitSlice2 = 4,
160 /// Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit
161 Input5SelectsThePinSelectedInThePINTSEL5RegisterAsTheSourceToBitSlice2 = 5,
162 /// Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit
163 Input6SelectsThePinSelectedInThePINTSEL6RegisterAsTheSourceToBitSlice2 = 6,
164 /// Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit
165 Input7SelectsThePinSelectedInThePINTSEL7RegisterAsTheSourceToBitSlice2 = 7
166 ],
167 /// Selects the input source for bit slice 3
168 SRC3 OFFSET(17) NUMBITS(3) [
169 /// Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit
170 Input0SelectsThePinSelectedInThePINTSEL0RegisterAsTheSourceToBitSlice3 = 0,
171 /// Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit
172 Input1SelectsThePinSelectedInThePINTSEL1RegisterAsTheSourceToBitSlice3 = 1,
173 /// Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit
174 Input2SelectsThePinSelectedInThePINTSEL2RegisterAsTheSourceToBitSlice3 = 2,
175 /// Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit
176 Input3SelectsThePinSelectedInThePINTSEL3RegisterAsTheSourceToBitSlice3 = 3,
177 /// Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit
178 Input4SelectsThePinSelectedInThePINTSEL4RegisterAsTheSourceToBitSlice3 = 4,
179 /// Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit
180 Input5SelectsThePinSelectedInThePINTSEL5RegisterAsTheSourceToBitSlice3 = 5,
181 /// Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit
182 Input6SelectsThePinSelectedInThePINTSEL6RegisterAsTheSourceToBitSlice3 = 6,
183 /// Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit
184 Input7SelectsThePinSelectedInThePINTSEL7RegisterAsTheSourceToBitSlice3 = 7
185 ],
186 /// Selects the input source for bit slice 4
187 SRC4 OFFSET(20) NUMBITS(3) [
188 /// Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit
189 Input0SelectsThePinSelectedInThePINTSEL0RegisterAsTheSourceToBitSlice4 = 0,
190 /// Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit
191 Input1SelectsThePinSelectedInThePINTSEL1RegisterAsTheSourceToBitSlice4 = 1,
192 /// Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit
193 Input2SelectsThePinSelectedInThePINTSEL2RegisterAsTheSourceToBitSlice4 = 2,
194 /// Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit
195 Input3SelectsThePinSelectedInThePINTSEL3RegisterAsTheSourceToBitSlice4 = 3,
196 /// Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit
197 Input4SelectsThePinSelectedInThePINTSEL4RegisterAsTheSourceToBitSlice4 = 4,
198 /// Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit
199 Input5SelectsThePinSelectedInThePINTSEL5RegisterAsTheSourceToBitSlice4 = 5,
200 /// Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit
201 Input6SelectsThePinSelectedInThePINTSEL6RegisterAsTheSourceToBitSlice4 = 6,
202 /// Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit
203 Input7SelectsThePinSelectedInThePINTSEL7RegisterAsTheSourceToBitSlice4 = 7
204 ],
205 /// Selects the input source for bit slice 5
206 SRC5 OFFSET(23) NUMBITS(3) [
207 /// Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit
208 Input0SelectsThePinSelectedInThePINTSEL0RegisterAsTheSourceToBitSlice5 = 0,
209 /// Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit
210 Input1SelectsThePinSelectedInThePINTSEL1RegisterAsTheSourceToBitSlice5 = 1,
211 /// Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit
212 Input2SelectsThePinSelectedInThePINTSEL2RegisterAsTheSourceToBitSlice5 = 2,
213 /// Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit
214 Input3SelectsThePinSelectedInThePINTSEL3RegisterAsTheSourceToBitSlice5 = 3,
215 /// Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit
216 Input4SelectsThePinSelectedInThePINTSEL4RegisterAsTheSourceToBitSlice5 = 4,
217 /// Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit
218 Input5SelectsThePinSelectedInThePINTSEL5RegisterAsTheSourceToBitSlice5 = 5,
219 /// Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit
220 Input6SelectsThePinSelectedInThePINTSEL6RegisterAsTheSourceToBitSlice5 = 6,
221 /// Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit
222 Input7SelectsThePinSelectedInThePINTSEL7RegisterAsTheSourceToBitSlice5 = 7
223 ],
224 /// Selects the input source for bit slice 6
225 SRC6 OFFSET(26) NUMBITS(3) [
226 /// Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit
227 Input0SelectsThePinSelectedInThePINTSEL0RegisterAsTheSourceToBitSlice6 = 0,
228 /// Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit
229 Input1SelectsThePinSelectedInThePINTSEL1RegisterAsTheSourceToBitSlice6 = 1,
230 /// Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit
231 Input2SelectsThePinSelectedInThePINTSEL2RegisterAsTheSourceToBitSlice6 = 2,
232 /// Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit
233 Input3SelectsThePinSelectedInThePINTSEL3RegisterAsTheSourceToBitSlice6 = 3,
234 /// Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit
235 Input4SelectsThePinSelectedInThePINTSEL4RegisterAsTheSourceToBitSlice6 = 4,
236 /// Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit
237 Input5SelectsThePinSelectedInThePINTSEL5RegisterAsTheSourceToBitSlice6 = 5,
238 /// Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit
239 Input6SelectsThePinSelectedInThePINTSEL6RegisterAsTheSourceToBitSlice6 = 6,
240 /// Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit
241 Input7SelectsThePinSelectedInThePINTSEL7RegisterAsTheSourceToBitSlice6 = 7
242 ],
243 /// Selects the input source for bit slice 7
244 SRC7 OFFSET(29) NUMBITS(3) [
245 /// Input 0. Selects the pin selected in the PINTSEL0 register as the source to bit
246 Input0SelectsThePinSelectedInThePINTSEL0RegisterAsTheSourceToBitSlice7 = 0,
247 /// Input 1. Selects the pin selected in the PINTSEL1 register as the source to bit
248 Input1SelectsThePinSelectedInThePINTSEL1RegisterAsTheSourceToBitSlice7 = 1,
249 /// Input 2. Selects the pin selected in the PINTSEL2 register as the source to bit
250 Input2SelectsThePinSelectedInThePINTSEL2RegisterAsTheSourceToBitSlice7 = 2,
251 /// Input 3. Selects the pin selected in the PINTSEL3 register as the source to bit
252 Input3SelectsThePinSelectedInThePINTSEL3RegisterAsTheSourceToBitSlice7 = 3,
253 /// Input 4. Selects the pin selected in the PINTSEL4 register as the source to bit
254 Input4SelectsThePinSelectedInThePINTSEL4RegisterAsTheSourceToBitSlice7 = 4,
255 /// Input 5. Selects the pin selected in the PINTSEL5 register as the source to bit
256 Input5SelectsThePinSelectedInThePINTSEL5RegisterAsTheSourceToBitSlice7 = 5,
257 /// Input 6. Selects the pin selected in the PINTSEL6 register as the source to bit
258 Input6SelectsThePinSelectedInThePINTSEL6RegisterAsTheSourceToBitSlice7 = 6,
259 /// Input 7. Selects the pin selected in the PINTSEL7 register as the source to bit
260 Input7SelectsThePinSelectedInThePINTSEL7RegisterAsTheSourceToBitSlice7 = 7
261 ]
262],
263PMCFG [
264 /// Determines whether slice 0 is an endpoint.
265 PROD_ENDPTS0 OFFSET(0) NUMBITS(1) [
266 /// No effect. Slice 0 is not an endpoint.
267 NoEffectSlice0IsNotAnEndpoint = 0,
268 /// endpoint. Slice 0 is the endpoint of a product term (minterm). Pin interrupt 0 i
269 ENDPOINT = 1
270 ],
271 /// Determines whether slice 1 is an endpoint.
272 PROD_ENDPTS1 OFFSET(1) NUMBITS(1) [
273 /// No effect. Slice 1 is not an endpoint.
274 NoEffectSlice1IsNotAnEndpoint = 0,
275 /// endpoint. Slice 1 is the endpoint of a product term (minterm). Pin interrupt 1 i
276 ENDPOINT = 1
277 ],
278 /// Determines whether slice 2 is an endpoint.
279 PROD_ENDPTS2 OFFSET(2) NUMBITS(1) [
280 /// No effect. Slice 2 is not an endpoint.
281 NoEffectSlice2IsNotAnEndpoint = 0,
282 /// endpoint. Slice 2 is the endpoint of a product term (minterm). Pin interrupt 2 i
283 ENDPOINT = 1
284 ],
285 /// Determines whether slice 3 is an endpoint.
286 PROD_ENDPTS3 OFFSET(3) NUMBITS(1) [
287 /// No effect. Slice 3 is not an endpoint.
288 NoEffectSlice3IsNotAnEndpoint = 0,
289 /// endpoint. Slice 3 is the endpoint of a product term (minterm). Pin interrupt 3 i
290 ENDPOINT = 1
291 ],
292 /// Determines whether slice 4 is an endpoint.
293 PROD_ENDPTS4 OFFSET(4) NUMBITS(1) [
294 /// No effect. Slice 4 is not an endpoint.
295 NoEffectSlice4IsNotAnEndpoint = 0,
296 /// endpoint. Slice 4 is the endpoint of a product term (minterm). Pin interrupt 4 i
297 ENDPOINT = 1
298 ],
299 /// Determines whether slice 5 is an endpoint.
300 PROD_ENDPTS5 OFFSET(5) NUMBITS(1) [
301 /// No effect. Slice 5 is not an endpoint.
302 NoEffectSlice5IsNotAnEndpoint = 0,
303 /// endpoint. Slice 5 is the endpoint of a product term (minterm). Pin interrupt 5 i
304 ENDPOINT = 1
305 ],
306 /// Determines whether slice 6 is an endpoint.
307 PROD_ENDPTS6 OFFSET(6) NUMBITS(1) [
308 /// No effect. Slice 6 is not an endpoint.
309 NoEffectSlice6IsNotAnEndpoint = 0,
310 /// endpoint. Slice 6 is the endpoint of a product term (minterm). Pin interrupt 6 i
311 ENDPOINT = 1
312 ],
313 /// Specifies the match contribution condition for bit slice 0.
314 CFG0 OFFSET(8) NUMBITS(3) [
315 /// Constant HIGH. This bit slice always contributes to a product term match.
316 ConstantHIGHThisBitSliceAlwaysContributesToAProductTermMatch = 0,
317 /// Sticky rising edge. Match occurs if a rising edge on the specified input has occ
318 STICKY_RISING_EDGE = 1,
319 /// Sticky falling edge. Match occurs if a falling edge on the specified input has o
320 STICKY_FALLING_EDGE = 2,
321 /// Sticky rising or falling edge. Match occurs if either a rising or falling edge o
322 STICKY_RISING_FALLING_EDGE = 3,
323 /// High level. Match (for this bit slice) occurs when there is a high level on the
324 HIGH_LEVEL = 4,
325 /// Low level. Match occurs when there is a low level on the specified input.
326 LowLevelMatchOccursWhenThereIsALowLevelOnTheSpecifiedInput = 5,
327 /// Constant 0. This bit slice never contributes to a match (should be used to disab
328 CONSTANT_ZERO = 6,
329 /// Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when e
330 EVENT = 7
331 ],
332 /// Specifies the match contribution condition for bit slice 1.
333 CFG1 OFFSET(11) NUMBITS(3) [
334 /// Constant HIGH. This bit slice always contributes to a product term match.
335 ConstantHIGHThisBitSliceAlwaysContributesToAProductTermMatch = 0,
336 /// Sticky rising edge. Match occurs if a rising edge on the specified input has occ
337 STICKY_RISING_EDGE = 1,
338 /// Sticky falling edge. Match occurs if a falling edge on the specified input has o
339 STICKY_FALLING_EDGE = 2,
340 /// Sticky rising or falling edge. Match occurs if either a rising or falling edge o
341 STICKY_RISING_FALLING_EDGE = 3,
342 /// High level. Match (for this bit slice) occurs when there is a high level on the
343 HIGH_LEVEL = 4,
344 /// Low level. Match occurs when there is a low level on the specified input.
345 LowLevelMatchOccursWhenThereIsALowLevelOnTheSpecifiedInput = 5,
346 /// Constant 0. This bit slice never contributes to a match (should be used to disab
347 CONSTANT_ZERO = 6,
348 /// Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when e
349 EVENT = 7
350 ],
351 /// Specifies the match contribution condition for bit slice 2.
352 CFG2 OFFSET(14) NUMBITS(3) [
353 /// Constant HIGH. This bit slice always contributes to a product term match.
354 ConstantHIGHThisBitSliceAlwaysContributesToAProductTermMatch = 0,
355 /// Sticky rising edge. Match occurs if a rising edge on the specified input has occ
356 STICKY_RISING_EDGE = 1,
357 /// Sticky falling edge. Match occurs if a falling edge on the specified input has o
358 STICKY_FALLING_EDGE = 2,
359 /// Sticky rising or falling edge. Match occurs if either a rising or falling edge o
360 STICKY_RISING_FALLING_EDGE = 3,
361 /// High level. Match (for this bit slice) occurs when there is a high level on the
362 HIGH_LEVEL = 4,
363 /// Low level. Match occurs when there is a low level on the specified input.
364 LowLevelMatchOccursWhenThereIsALowLevelOnTheSpecifiedInput = 5,
365 /// Constant 0. This bit slice never contributes to a match (should be used to disab
366 CONSTANT_ZERO = 6,
367 /// Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when e
368 EVENT = 7
369 ],
370 /// Specifies the match contribution condition for bit slice 3.
371 CFG3 OFFSET(17) NUMBITS(3) [
372 /// Constant HIGH. This bit slice always contributes to a product term match.
373 ConstantHIGHThisBitSliceAlwaysContributesToAProductTermMatch = 0,
374 /// Sticky rising edge. Match occurs if a rising edge on the specified input has occ
375 STICKY_RISING_EDGE = 1,
376 /// Sticky falling edge. Match occurs if a falling edge on the specified input has o
377 STICKY_FALLING_EDGE = 2,
378 /// Sticky rising or falling edge. Match occurs if either a rising or falling edge o
379 STICKY_RISING_FALLING_EDGE = 3,
380 /// High level. Match (for this bit slice) occurs when there is a high level on the
381 HIGH_LEVEL = 4,
382 /// Low level. Match occurs when there is a low level on the specified input.
383 LowLevelMatchOccursWhenThereIsALowLevelOnTheSpecifiedInput = 5,
384 /// Constant 0. This bit slice never contributes to a match (should be used to disab
385 CONSTANT_ZERO = 6,
386 /// Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when e
387 EVENT = 7
388 ],
389 /// Specifies the match contribution condition for bit slice 4.
390 CFG4 OFFSET(20) NUMBITS(3) [
391 /// Constant HIGH. This bit slice always contributes to a product term match.
392 ConstantHIGHThisBitSliceAlwaysContributesToAProductTermMatch = 0,
393 /// Sticky rising edge. Match occurs if a rising edge on the specified input has occ
394 STICKY_RISING_EDGE = 1,
395 /// Sticky falling edge. Match occurs if a falling edge on the specified input has o
396 STICKY_FALLING_EDGE = 2,
397 /// Sticky rising or falling edge. Match occurs if either a rising or falling edge o
398 STICKY_RISING_FALLING_EDGE = 3,
399 /// High level. Match (for this bit slice) occurs when there is a high level on the
400 HIGH_LEVEL = 4,
401 /// Low level. Match occurs when there is a low level on the specified input.
402 LowLevelMatchOccursWhenThereIsALowLevelOnTheSpecifiedInput = 5,
403 /// Constant 0. This bit slice never contributes to a match (should be used to disab
404 CONSTANT_ZERO = 6,
405 /// Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when e
406 EVENT = 7
407 ],
408 /// Specifies the match contribution condition for bit slice 5.
409 CFG5 OFFSET(23) NUMBITS(3) [
410 /// Constant HIGH. This bit slice always contributes to a product term match.
411 ConstantHIGHThisBitSliceAlwaysContributesToAProductTermMatch = 0,
412 /// Sticky rising edge. Match occurs if a rising edge on the specified input has occ
413 STICKY_RISING_EDGE = 1,
414 /// Sticky falling edge. Match occurs if a falling edge on the specified input has o
415 STICKY_FALLING_EDGE = 2,
416 /// Sticky rising or falling edge. Match occurs if either a rising or falling edge o
417 STICKY_RISING_FALLING_EDGE = 3,
418 /// High level. Match (for this bit slice) occurs when there is a high level on the
419 HIGH_LEVEL = 4,
420 /// Low level. Match occurs when there is a low level on the specified input.
421 LowLevelMatchOccursWhenThereIsALowLevelOnTheSpecifiedInput = 5,
422 /// Constant 0. This bit slice never contributes to a match (should be used to disab
423 CONSTANT_ZERO = 6,
424 /// Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when e
425 EVENT = 7
426 ],
427 /// Specifies the match contribution condition for bit slice 6.
428 CFG6 OFFSET(26) NUMBITS(3) [
429 /// Constant HIGH. This bit slice always contributes to a product term match.
430 ConstantHIGHThisBitSliceAlwaysContributesToAProductTermMatch = 0,
431 /// Sticky rising edge. Match occurs if a rising edge on the specified input has occ
432 STICKY_RISING_EDGE = 1,
433 /// Sticky falling edge. Match occurs if a falling edge on the specified input has o
434 STICKY_FALLING_EDGE = 2,
435 /// Sticky rising or falling edge. Match occurs if either a rising or falling edge o
436 STICKY_RISING_FALLING_EDGE = 3,
437 /// High level. Match (for this bit slice) occurs when there is a high level on the
438 HIGH_LEVEL = 4,
439 /// Low level. Match occurs when there is a low level on the specified input.
440 LowLevelMatchOccursWhenThereIsALowLevelOnTheSpecifiedInput = 5,
441 /// Constant 0. This bit slice never contributes to a match (should be used to disab
442 CONSTANT_ZERO = 6,
443 /// Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when e
444 EVENT = 7
445 ],
446 /// Specifies the match contribution condition for bit slice 7.
447 CFG7 OFFSET(29) NUMBITS(3) [
448 /// Constant HIGH. This bit slice always contributes to a product term match.
449 ConstantHIGHThisBitSliceAlwaysContributesToAProductTermMatch = 0,
450 /// Sticky rising edge. Match occurs if a rising edge on the specified input has occ
451 STICKY_RISING_EDGE = 1,
452 /// Sticky falling edge. Match occurs if a falling edge on the specified input has o
453 STICKY_FALLING_EDGE = 2,
454 /// Sticky rising or falling edge. Match occurs if either a rising or falling edge o
455 STICKY_RISING_FALLING_EDGE = 3,
456 /// High level. Match (for this bit slice) occurs when there is a high level on the
457 HIGH_LEVEL = 4,
458 /// Low level. Match occurs when there is a low level on the specified input.
459 LowLevelMatchOccursWhenThereIsALowLevelOnTheSpecifiedInput = 5,
460 /// Constant 0. This bit slice never contributes to a match (should be used to disab
461 CONSTANT_ZERO = 6,
462 /// Event. Non-sticky rising or falling edge. Match occurs on an event - i.e. when e
463 EVENT = 7
464 ]
465]
466];
467pub(crate) const PINT_BASE: StaticRef<PintRegisters> =
468 unsafe { StaticRef::new(0x50004000 as *const PintRegisters) };
469
470#[derive(Clone, Copy)]
471pub enum Edge {
472 Rising,
473 Falling,
474 Both,
475}
476
477pub struct Pint<'a> {
478 registers: StaticRef<PintRegisters>,
479 clients: [OptionalCell<&'a dyn kernel::hil::gpio::Client>; 8],
480}
481
482impl<'a> Pint<'a> {
483 pub const fn new() -> Self {
484 Self {
485 registers: PINT_BASE,
486 clients: [
487 OptionalCell::empty(),
488 OptionalCell::empty(),
489 OptionalCell::empty(),
490 OptionalCell::empty(),
491 OptionalCell::empty(),
492 OptionalCell::empty(),
493 OptionalCell::empty(),
494 OptionalCell::empty(),
495 ],
496 }
497 }
498
499 pub fn set_client(&self, channel: u8, client: &'a dyn kernel::hil::gpio::Client) {
500 if channel < 8 {
501 self.clients[channel as usize].replace(client);
502 }
503 }
504
505 pub fn configure_interrupt(&self, channel: usize, edge: Edge) {
506 if channel < 8 {
507 let mask = 1 << channel;
508
509 self.registers.isel.modify(ISEL::PMODE.val(!mask));
510
511 match edge {
512 Edge::Rising => {
513 self.registers.sienr.write(SIENR::SETENRL.val(mask));
514 self.registers.cienf.write(CIENF::CENAF.val(mask));
515 }
516 Edge::Falling => {
517 self.registers.sienf.write(SIENF::SETENAF.val(mask));
518 self.registers.cienr.write(CIENR::CENRL.val(mask));
519 }
520 Edge::Both => {
521 self.registers.sienr.write(SIENR::SETENRL.val(mask));
522 self.registers.sienf.write(SIENF::SETENAF.val(mask));
523 }
524 }
525 }
526 }
527
528 pub fn handle_interrupt(&self) {
529 let status = self.registers.ist.get();
530
531 self.registers.rise.write(RISE::RDET.val(status));
532 self.registers.fall.write(FALL::FDET.val(status));
533
534 for i in 0..8 {
535 if (status & (1 << i)) != 0 {
536 self.registers.ist.write(IST::PSTAT.val(1 << i));
537 self.clients[i].map(|client| client.fired());
538 }
539 }
540 }
541
542 pub fn disable_interrupt(&self, channel: usize) {
543 if channel < 8 {
544 let mask = 1 << channel;
545
546 self.registers.cienr.write(CIENR::CENRL.val(mask));
547 self.registers.cienf.write(CIENF::CENAF.val(mask));
548 }
549 }
550
551 pub fn read_interrupt(&self) -> u32 {
552 self.registers.rise.get()
553 }
554
555 /// Returns true if the given channel has a pending interrupt.
556 pub fn is_pending(&self, channel: usize) -> bool {
557 let status = self.registers.ist.get();
558 (status & (1 << channel)) != 0
559 }
560
561 /// Clears the pending interrupt for the given channel.
562 pub fn clear_pending(&self, channel: usize) {
563 // Writing a 1 clears the bit
564 self.registers.ist.set(1 << channel);
565 }
566}