1use kernel::hil::gpio::{Configuration, Configure, Input, Interrupt, Output};
6use kernel::utilities::cells::OptionalCell;
7use kernel::utilities::registers::{
8 interfaces::{ReadWriteable, Readable},
9 register_bitfields, register_structs, ReadOnly, ReadWrite,
10};
11use kernel::utilities::StaticRef;
12
13#[repr(C)]
14struct GpioPort {
15 prt_out: ReadWrite<u32, PRT_OUT::Register>,
16 prt_out_clr: ReadWrite<u32, PRT_OUT::Register>,
17 prt_out_set: ReadWrite<u32, PRT_OUT::Register>,
18 prt_out_inv: ReadWrite<u32, PRT_OUT::Register>,
19 prt_in: ReadOnly<u32, PRT_IN::Register>,
20 prt_intr: ReadWrite<u32, PRT_INTR::Register>,
21 prt_intr_mask: ReadWrite<u32, PRT_INTR::Register>,
22 prt_intr_masked: ReadOnly<u32, PRT_INTR::Register>,
23 prt_intr_set: ReadWrite<u32, PRT_INTR::Register>,
24 _reserved0: [u32; 7],
25 prt_intr_cfg: ReadWrite<u32, PRT_INTR_CFG::Register>,
26 prt_cfg: ReadWrite<u32, PRT_CFG::Register>,
27 prt_cfg_in: ReadWrite<u32, PRT_CFG_IN::Register>,
28 prt_cfg_out: ReadWrite<u32, PRT_CFG_OUT::Register>,
29 _reserved1: [u32; 12],
30}
31
32register_structs! {
33 GpioRegisters {
35 (0x000 => ports: [GpioPort; 15]),
36 (0x780 => _reserved0),
37 (0x4000 => intr_cause0: ReadOnly<u32>),
39 (0x4004 => intr_cause1: ReadOnly<u32>),
41 (0x4008 => intr_cause2: ReadOnly<u32>),
43 (0x400C => intr_cause3: ReadOnly<u32>),
45 (0x4010 => vdd_active: ReadOnly<u32, VDD_ACTIVE::Register>),
47 (0x4014 => vdd_intr: ReadWrite<u32, VDD_INTR::Register>),
49 (0x4018 => vdd_intr_mask: ReadWrite<u32, VDD_INTR_MASK::Register>),
51 (0x401C => vdd_intr_masked: ReadOnly<u32, VDD_INTR_MASKED::Register>),
53 (0x4020 => vdd_intr_set: ReadWrite<u32, VDD_INTR_SET::Register>),
55 (0x4024 => @END),
56 }
57}
58register_bitfields![u32,
59PRT_OUT [
60 OUT0 OFFSET(0) NUMBITS(1) [],
61 OUT1 OFFSET(1) NUMBITS(1) [],
62 OUT2 OFFSET(2) NUMBITS(1) [],
63 OUT3 OFFSET(3) NUMBITS(1) [],
64 OUT4 OFFSET(4) NUMBITS(1) [],
65 OUT5 OFFSET(5) NUMBITS(1) [],
66 OUT6 OFFSET(6) NUMBITS(1) [],
67 OUT7 OFFSET(7) NUMBITS(1) [],
68],
69PRT_IN [
70 IN0 OFFSET(0) NUMBITS(1) [],
71 IN1 OFFSET(1) NUMBITS(1) [],
72 IN2 OFFSET(2) NUMBITS(1) [],
73 IN3 OFFSET(3) NUMBITS(1) [],
74 IN4 OFFSET(4) NUMBITS(1) [],
75 IN5 OFFSET(5) NUMBITS(1) [],
76 IN6 OFFSET(6) NUMBITS(1) [],
77 IN7 OFFSET(7) NUMBITS(1) [],
78 FLT_IN OFFSET(8) NUMBITS(1) [],
79],
80PRT_INTR [
81 EDGE0 OFFSET(0) NUMBITS(1) [],
82 EDGE1 OFFSET(1) NUMBITS(1) [],
83 EDGE2 OFFSET(2) NUMBITS(1) [],
84 EDGE3 OFFSET(3) NUMBITS(1) [],
85 EDGE4 OFFSET(4) NUMBITS(1) [],
86 EDGE5 OFFSET(5) NUMBITS(1) [],
87 EDGE6 OFFSET(6) NUMBITS(1) [],
88 EDGE7 OFFSET(7) NUMBITS(1) [],
89 FLT_EDGE OFFSET(8) NUMBITS(1) [],
90 IN_IN OFFSET(16) NUMBITS(8) [],
91 FLT_IN_IN OFFSET(24) NUMBITS(1) [],
92],
93PRT_INTR_CFG [
94 EDGE_SEL0 OFFSET(0) NUMBITS(2) [],
95 EDGE_SEL1 OFFSET(2) NUMBITS(2) [],
96 EDGE_SEL2 OFFSET(4) NUMBITS(2) [],
97 EDGE_SEL3 OFFSET(6) NUMBITS(2) [],
98 EDGE_SEL4 OFFSET(8) NUMBITS(2) [],
99 EDGE_SEL5 OFFSET(10) NUMBITS(2) [],
100 EDGE_SEL6 OFFSET(12) NUMBITS(2) [],
101 EDGE_SEL7 OFFSET(14) NUMBITS(2) [],
102 FLT_EDGE_SEL OFFSET(16) NUMBITS(2) [],
103 FLT_SEL OFFSET(18) NUMBITS(3) [],
104],
105PRT_CFG [
106 DRIVE_MODE0 OFFSET(0) NUMBITS(3) [
107 HIGHZ = 0,
108 PULL_UP = 2,
109 PULL_DOWN = 3,
110 OD_DRIVESLOW = 4,
111 OD_DRIVESHIGH = 5,
112 STRONG = 6,
113 PULLUP_DOWN = 7,
114 ],
115 IN_EN0 OFFSET(3) NUMBITS(1) [],
116 DRIVE_MODE1 OFFSET(4) NUMBITS(3) [
117 HIGHZ = 0,
118 PULL_UP = 2,
119 PULL_DOWN = 3,
120 OD_DRIVESLOW = 4,
121 OD_DRIVESHIGH = 5,
122 STRONG = 6,
123 PULLUP_DOWN = 7,
124 ],
125 IN_EN1 OFFSET(7) NUMBITS(1) [],
126 DRIVE_MODE2 OFFSET(8) NUMBITS(3) [
127 HIGHZ = 0,
128 PULL_UP = 2,
129 PULL_DOWN = 3,
130 OD_DRIVESLOW = 4,
131 OD_DRIVESHIGH = 5,
132 STRONG = 6,
133 PULLUP_DOWN = 7,
134 ],
135 IN_EN2 OFFSET(11) NUMBITS(1) [],
136 DRIVE_MODE3 OFFSET(12) NUMBITS(3) [
137 HIGHZ = 0,
138 PULL_UP = 2,
139 PULL_DOWN = 3,
140 OD_DRIVESLOW = 4,
141 OD_DRIVESHIGH = 5,
142 STRONG = 6,
143 PULLUP_DOWN = 7,
144 ],
145 IN_EN3 OFFSET(15) NUMBITS(1) [],
146 DRIVE_MODE4 OFFSET(16) NUMBITS(3) [
147 HIGHZ = 0,
148 PULL_UP = 2,
149 PULL_DOWN = 3,
150 OD_DRIVESLOW = 4,
151 OD_DRIVESHIGH = 5,
152 STRONG = 6,
153 PULLUP_DOWN = 7,
154 ],
155 IN_EN4 OFFSET(19) NUMBITS(1) [],
156 DRIVE_MODE5 OFFSET(20) NUMBITS(3) [
157 HIGHZ = 0,
158 PULL_UP = 2,
159 PULL_DOWN = 3,
160 OD_DRIVESLOW = 4,
161 OD_DRIVESHIGH = 5,
162 STRONG = 6,
163 PULLUP_DOWN = 7,
164 ],
165 IN_EN5 OFFSET(23) NUMBITS(1) [],
166 DRIVE_MODE6 OFFSET(24) NUMBITS(3) [
167 HIGHZ = 0,
168 PULL_UP = 2,
169 PULL_DOWN = 3,
170 OD_DRIVESLOW = 4,
171 OD_DRIVESHIGH = 5,
172 STRONG = 6,
173 PULLUP_DOWN = 7,
174 ],
175 IN_EN6 OFFSET(27) NUMBITS(1) [],
176 DRIVE_MODE7 OFFSET(28) NUMBITS(3) [
177 HIGHZ = 0,
178 PULL_UP = 2,
179 PULL_DOWN = 3,
180 OD_DRIVESLOW = 4,
181 OD_DRIVESHIGH = 5,
182 STRONG = 6,
183 PULLUP_DOWN = 7,
184 ],
185 IN_EN7 OFFSET(31) NUMBITS(1) [],
186],
187PRT_CFG_IN [
188 VTRIP_VTRIP_SEL_0 OFFSET(0) NUMBITS(1) [],
189 VTRIP_VTRIP_SEL_1 OFFSET(1) NUMBITS(1) [],
190 VTRIP_VTRIP_SEL_2 OFFSET(2) NUMBITS(1) [],
191 VTRIP_VTRIP_SEL_3 OFFSET(3) NUMBITS(1) [],
192 VTRIP_VTRIP_SEL_4 OFFSET(4) NUMBITS(1) [],
193 VTRIP_VTRIP_SEL_5 OFFSET(5) NUMBITS(1) [],
194 VTRIP_VTRIP_SEL_6 OFFSET(6) NUMBITS(1) [],
195 VTRIP_VTRIP_SEL_7 OFFSET(7) NUMBITS(1) [],
196],
197PRT_CFG_OUT [
198 SLOW0 OFFSET(0) NUMBITS(1) [],
199 SLOW1 OFFSET(0) NUMBITS(1) [],
200 SLOW2 OFFSET(0) NUMBITS(1) [],
201 SLOW3 OFFSET(0) NUMBITS(1) [],
202 SLOW4 OFFSET(0) NUMBITS(1) [],
203 SLOW5 OFFSET(0) NUMBITS(1) [],
204 SLOW6 OFFSET(0) NUMBITS(1) [],
205 SLOW7 OFFSET(0) NUMBITS(1) [],
206 DRIVE_SEL0 OFFSET(16) NUMBITS(2) [],
207 DRIVE_SEL1 OFFSET(18) NUMBITS(2) [],
208 DRIVE_SEL2 OFFSET(20) NUMBITS(2) [],
209 DRIVE_SEL3 OFFSET(22) NUMBITS(2) [],
210 DRIVE_SEL4 OFFSET(24) NUMBITS(2) [],
211 DRIVE_SEL5 OFFSET(26) NUMBITS(2) [],
212 DRIVE_SEL6 OFFSET(28) NUMBITS(2) [],
213 DRIVE_SEL7 OFFSET(30) NUMBITS(2) [],
214],
215INTR_CAUSE0 [
216 PORT_INT OFFSET(0) NUMBITS(32) []
217],
218INTR_CAUSE1 [
219 PORT_INT OFFSET(0) NUMBITS(32) []
220],
221INTR_CAUSE2 [
222 PORT_INT OFFSET(0) NUMBITS(32) []
223],
224INTR_CAUSE3 [
225 PORT_INT OFFSET(0) NUMBITS(32) []
226],
227VDD_ACTIVE [
228 VDDIO_ACTIVE OFFSET(0) NUMBITS(16) [],
229 VDDA_ACTIVE OFFSET(30) NUMBITS(1) [],
230 VDDD_ACTIVE OFFSET(31) NUMBITS(1) []
231],
232VDD_INTR [
233 VDDIO_ACTIVE OFFSET(0) NUMBITS(16) [],
234 VDDA_ACTIVE OFFSET(30) NUMBITS(1) [],
235 VDDD_ACTIVE OFFSET(31) NUMBITS(1) []
236],
237VDD_INTR_MASK [
238 VDDIO_ACTIVE OFFSET(0) NUMBITS(16) [],
239 VDDA_ACTIVE OFFSET(30) NUMBITS(1) [],
240 VDDD_ACTIVE OFFSET(31) NUMBITS(1) []
241],
242VDD_INTR_MASKED [
243 VDDIO_ACTIVE OFFSET(0) NUMBITS(16) [],
244 VDDA_ACTIVE OFFSET(30) NUMBITS(1) [],
245 VDDD_ACTIVE OFFSET(31) NUMBITS(1) []
246],
247VDD_INTR_SET [
248 VDDIO_ACTIVE OFFSET(0) NUMBITS(16) [],
249 VDDA_ACTIVE OFFSET(30) NUMBITS(1) [],
250 VDDD_ACTIVE OFFSET(31) NUMBITS(1) []
251]
252];
253const GPIO_BASE: StaticRef<GpioRegisters> =
254 unsafe { StaticRef::new(0x40310000 as *const GpioRegisters) };
255
256const HIGHZ: u32 = 0;
257const PULL_UP: u32 = 2;
258const PULL_DOWN: u32 = 3;
259
260#[derive(Clone, Copy, Debug)]
261pub enum PsocPin {
262 P0_0 = 0,
263 P0_1 = 1,
264 P0_2 = 2,
265 P0_3 = 3,
266 P0_4 = 4,
267 P0_5 = 5,
268 P1_0 = 8,
269 P1_1 = 9,
270 P1_2 = 10,
271 P1_3 = 11,
272 P1_4 = 12,
273 P1_5 = 13,
274 P2_0 = 16,
275 P2_1 = 17,
276 P2_2 = 18,
277 P2_3 = 19,
278 P2_4 = 20,
279 P2_5 = 21,
280 P2_6 = 22,
281 P2_7 = 23,
282 P3_0 = 24,
283 P3_1 = 25,
284 P3_2 = 26,
285 P3_3 = 27,
286 P3_4 = 28,
287 P3_5 = 29,
288 P4_0 = 32,
289 P4_1 = 33,
290 P4_2 = 34,
291 P4_3 = 35,
292 P5_0 = 40,
293 P5_1 = 41,
294 P5_2 = 42,
295 P5_3 = 43,
296 P5_4 = 44,
297 P5_5 = 45,
298 P5_6 = 46,
299 P5_7 = 47,
300 P6_0 = 48,
301 P6_1 = 49,
302 P6_2 = 50,
303 P6_3 = 51,
304 P6_4 = 52,
305 P6_5 = 53,
306 P6_6 = 54,
307 P6_7 = 55,
308 P7_0 = 56,
309 P7_1 = 57,
310 P7_2 = 58,
311 P7_3 = 59,
312 P7_4 = 60,
313 P7_5 = 61,
314 P7_6 = 62,
315 P7_7 = 63,
316 P8_0 = 64,
317 P8_1 = 65,
318 P8_2 = 66,
319 P8_3 = 67,
320 P8_4 = 68,
321 P8_5 = 69,
322 P8_6 = 70,
323 P8_7 = 71,
324 P9_0 = 72,
325 P9_1 = 73,
326 P9_2 = 74,
327 P9_3 = 75,
328 P9_4 = 76,
329 P9_5 = 77,
330 P9_6 = 78,
331 P9_7 = 79,
332 P10_0 = 80,
333 P10_1 = 81,
334 P10_2 = 82,
335 P10_3 = 83,
336 P10_4 = 84,
337 P10_5 = 85,
338 P10_6 = 86,
339 P10_7 = 87,
340 P11_0 = 88,
341 P11_1 = 89,
342 P11_2 = 90,
343 P11_3 = 91,
344 P11_4 = 92,
345 P11_5 = 93,
346 P11_6 = 94,
347 P11_7 = 95,
348 P12_0 = 96,
349 P12_1 = 97,
350 P12_2 = 98,
351 P12_3 = 99,
352 P12_4 = 100,
353 P12_5 = 101,
354 P12_6 = 102,
355 P12_7 = 103,
356 P13_0 = 104,
357 P13_1 = 105,
358 P13_2 = 106,
359 P13_3 = 107,
360 P13_4 = 108,
361 P13_5 = 109,
362 P13_6 = 110,
363 P13_7 = 111,
364}
365
366pub struct PsocPins<'a> {
367 pub pins: [Option<GpioPin<'a>>; 112],
368}
369
370impl<'a> PsocPins<'a> {
371 pub const fn new() -> Self {
372 Self {
373 pins: [
374 Some(GpioPin::new(PsocPin::P0_0)),
375 Some(GpioPin::new(PsocPin::P0_1)),
376 Some(GpioPin::new(PsocPin::P0_2)),
377 Some(GpioPin::new(PsocPin::P0_3)),
378 Some(GpioPin::new(PsocPin::P0_4)),
379 Some(GpioPin::new(PsocPin::P0_5)),
380 None,
381 None,
382 Some(GpioPin::new(PsocPin::P1_0)),
383 Some(GpioPin::new(PsocPin::P1_1)),
384 Some(GpioPin::new(PsocPin::P1_2)),
385 Some(GpioPin::new(PsocPin::P1_3)),
386 Some(GpioPin::new(PsocPin::P1_4)),
387 Some(GpioPin::new(PsocPin::P1_5)),
388 None,
389 None,
390 Some(GpioPin::new(PsocPin::P2_0)),
391 Some(GpioPin::new(PsocPin::P2_1)),
392 Some(GpioPin::new(PsocPin::P2_2)),
393 Some(GpioPin::new(PsocPin::P2_3)),
394 Some(GpioPin::new(PsocPin::P2_4)),
395 Some(GpioPin::new(PsocPin::P2_5)),
396 Some(GpioPin::new(PsocPin::P2_6)),
397 Some(GpioPin::new(PsocPin::P2_7)),
398 Some(GpioPin::new(PsocPin::P3_0)),
399 Some(GpioPin::new(PsocPin::P3_1)),
400 Some(GpioPin::new(PsocPin::P3_2)),
401 Some(GpioPin::new(PsocPin::P3_3)),
402 Some(GpioPin::new(PsocPin::P3_4)),
403 Some(GpioPin::new(PsocPin::P3_5)),
404 None,
405 None,
406 Some(GpioPin::new(PsocPin::P4_0)),
407 Some(GpioPin::new(PsocPin::P4_1)),
408 Some(GpioPin::new(PsocPin::P4_2)),
409 Some(GpioPin::new(PsocPin::P4_3)),
410 None,
411 None,
412 None,
413 None,
414 Some(GpioPin::new(PsocPin::P5_0)),
415 Some(GpioPin::new(PsocPin::P5_1)),
416 Some(GpioPin::new(PsocPin::P5_2)),
417 Some(GpioPin::new(PsocPin::P5_3)),
418 Some(GpioPin::new(PsocPin::P5_4)),
419 Some(GpioPin::new(PsocPin::P5_5)),
420 Some(GpioPin::new(PsocPin::P5_6)),
421 Some(GpioPin::new(PsocPin::P5_7)),
422 Some(GpioPin::new(PsocPin::P6_0)),
423 Some(GpioPin::new(PsocPin::P6_1)),
424 Some(GpioPin::new(PsocPin::P6_2)),
425 Some(GpioPin::new(PsocPin::P6_3)),
426 Some(GpioPin::new(PsocPin::P6_4)),
427 Some(GpioPin::new(PsocPin::P6_5)),
428 Some(GpioPin::new(PsocPin::P6_6)),
429 Some(GpioPin::new(PsocPin::P6_7)),
430 Some(GpioPin::new(PsocPin::P7_0)),
431 Some(GpioPin::new(PsocPin::P7_1)),
432 Some(GpioPin::new(PsocPin::P7_2)),
433 Some(GpioPin::new(PsocPin::P7_3)),
434 Some(GpioPin::new(PsocPin::P7_4)),
435 Some(GpioPin::new(PsocPin::P7_5)),
436 Some(GpioPin::new(PsocPin::P7_6)),
437 Some(GpioPin::new(PsocPin::P7_7)),
438 Some(GpioPin::new(PsocPin::P8_0)),
439 Some(GpioPin::new(PsocPin::P8_1)),
440 Some(GpioPin::new(PsocPin::P8_2)),
441 Some(GpioPin::new(PsocPin::P8_3)),
442 Some(GpioPin::new(PsocPin::P8_4)),
443 Some(GpioPin::new(PsocPin::P8_5)),
444 Some(GpioPin::new(PsocPin::P8_6)),
445 Some(GpioPin::new(PsocPin::P8_7)),
446 Some(GpioPin::new(PsocPin::P9_0)),
447 Some(GpioPin::new(PsocPin::P9_1)),
448 Some(GpioPin::new(PsocPin::P9_2)),
449 Some(GpioPin::new(PsocPin::P9_3)),
450 Some(GpioPin::new(PsocPin::P9_4)),
451 Some(GpioPin::new(PsocPin::P9_5)),
452 Some(GpioPin::new(PsocPin::P9_6)),
453 Some(GpioPin::new(PsocPin::P9_7)),
454 Some(GpioPin::new(PsocPin::P10_0)),
455 Some(GpioPin::new(PsocPin::P10_1)),
456 Some(GpioPin::new(PsocPin::P10_2)),
457 Some(GpioPin::new(PsocPin::P10_3)),
458 Some(GpioPin::new(PsocPin::P10_4)),
459 Some(GpioPin::new(PsocPin::P10_5)),
460 Some(GpioPin::new(PsocPin::P10_6)),
461 Some(GpioPin::new(PsocPin::P10_7)),
462 Some(GpioPin::new(PsocPin::P11_0)),
463 Some(GpioPin::new(PsocPin::P11_1)),
464 Some(GpioPin::new(PsocPin::P11_2)),
465 Some(GpioPin::new(PsocPin::P11_3)),
466 Some(GpioPin::new(PsocPin::P11_4)),
467 Some(GpioPin::new(PsocPin::P11_5)),
468 Some(GpioPin::new(PsocPin::P11_6)),
469 Some(GpioPin::new(PsocPin::P11_7)),
470 Some(GpioPin::new(PsocPin::P12_0)),
471 Some(GpioPin::new(PsocPin::P12_1)),
472 Some(GpioPin::new(PsocPin::P12_2)),
473 Some(GpioPin::new(PsocPin::P12_3)),
474 Some(GpioPin::new(PsocPin::P12_4)),
475 Some(GpioPin::new(PsocPin::P12_5)),
476 Some(GpioPin::new(PsocPin::P12_6)),
477 Some(GpioPin::new(PsocPin::P12_7)),
478 Some(GpioPin::new(PsocPin::P13_0)),
479 Some(GpioPin::new(PsocPin::P13_1)),
480 Some(GpioPin::new(PsocPin::P13_2)),
481 Some(GpioPin::new(PsocPin::P13_3)),
482 Some(GpioPin::new(PsocPin::P13_4)),
483 Some(GpioPin::new(PsocPin::P13_5)),
484 Some(GpioPin::new(PsocPin::P13_6)),
485 Some(GpioPin::new(PsocPin::P13_7)),
486 ],
487 }
488 }
489
490 pub fn get_pin(&self, searched_pin: PsocPin) -> &'a GpioPin {
491 self.pins[searched_pin as usize].as_ref().unwrap()
492 }
493
494 pub fn handle_interrupt(&self) {
495 for pin in self.pins.iter() {
496 pin.as_ref().inspect(|pin| pin.handle_interrupt());
497 }
498 }
499}
500
501pub enum DriveMode {
502 HighZ = 0,
503 PullUp = 2,
505 PullDown = 3,
506 OpenDrainLow = 4,
507 OpenDrainHigh = 5,
508 Strong = 6,
509 PullUpDown = 7,
510}
511
512pub struct GpioPin<'a> {
513 registers: StaticRef<GpioRegisters>,
514 pin: usize,
515 port: usize,
516
517 client: OptionalCell<&'a dyn kernel::hil::gpio::Client>,
518}
519
520impl GpioPin<'_> {
521 pub const fn new(id: PsocPin) -> Self {
522 Self {
523 registers: GPIO_BASE,
524 pin: (id as usize) % 8,
525 port: (id as usize) / 8,
526 client: OptionalCell::empty(),
527 }
528 }
529
530 pub fn get_configuration(&self) -> Configuration {
531 let (input_buffer, high_impedance) = if self.pin == 0 {
532 (
533 self.registers.ports[self.port]
534 .prt_cfg
535 .is_set(PRT_CFG::IN_EN0),
536 self.registers.ports[self.port]
537 .prt_cfg
538 .read(PRT_CFG::DRIVE_MODE0)
539 == HIGHZ,
540 )
541 } else if self.pin == 1 {
542 (
543 self.registers.ports[self.port]
544 .prt_cfg
545 .is_set(PRT_CFG::IN_EN1),
546 self.registers.ports[self.port]
547 .prt_cfg
548 .read(PRT_CFG::DRIVE_MODE1)
549 == HIGHZ,
550 )
551 } else if self.pin == 2 {
552 (
553 self.registers.ports[self.port]
554 .prt_cfg
555 .is_set(PRT_CFG::IN_EN2),
556 self.registers.ports[self.port]
557 .prt_cfg
558 .read(PRT_CFG::DRIVE_MODE2)
559 == HIGHZ,
560 )
561 } else if self.pin == 3 {
562 (
563 self.registers.ports[self.port]
564 .prt_cfg
565 .is_set(PRT_CFG::IN_EN3),
566 self.registers.ports[self.port]
567 .prt_cfg
568 .read(PRT_CFG::DRIVE_MODE3)
569 == HIGHZ,
570 )
571 } else if self.pin == 4 {
572 (
573 self.registers.ports[self.port]
574 .prt_cfg
575 .is_set(PRT_CFG::IN_EN4),
576 self.registers.ports[self.port]
577 .prt_cfg
578 .read(PRT_CFG::DRIVE_MODE4)
579 == HIGHZ,
580 )
581 } else if self.pin == 5 {
582 (
583 self.registers.ports[self.port]
584 .prt_cfg
585 .is_set(PRT_CFG::IN_EN5),
586 self.registers.ports[self.port]
587 .prt_cfg
588 .read(PRT_CFG::DRIVE_MODE5)
589 == HIGHZ,
590 )
591 } else if self.pin == 6 {
592 (
593 self.registers.ports[self.port]
594 .prt_cfg
595 .is_set(PRT_CFG::IN_EN6),
596 self.registers.ports[self.port]
597 .prt_cfg
598 .read(PRT_CFG::DRIVE_MODE6)
599 == HIGHZ,
600 )
601 } else {
602 (
603 self.registers.ports[self.port]
604 .prt_cfg
605 .is_set(PRT_CFG::IN_EN7),
606 self.registers.ports[self.port]
607 .prt_cfg
608 .read(PRT_CFG::DRIVE_MODE7)
609 == HIGHZ,
610 )
611 };
612 match (input_buffer, high_impedance) {
613 (false, false) => Configuration::Output,
614 (false, true) => Configuration::LowPower,
615 (true, true) => Configuration::Input,
616 (true, false) => Configuration::InputOutput,
617 }
618 }
619
620 pub fn configure_drive_mode(&self, drive_mode: DriveMode) {
621 if self.pin == 0 {
622 self.registers.ports[self.port]
623 .prt_cfg
624 .modify(PRT_CFG::DRIVE_MODE0.val(drive_mode as u32));
625 } else if self.pin == 1 {
626 self.registers.ports[self.port]
627 .prt_cfg
628 .modify(PRT_CFG::DRIVE_MODE1.val(drive_mode as u32));
629 } else if self.pin == 2 {
630 self.registers.ports[self.port]
631 .prt_cfg
632 .modify(PRT_CFG::DRIVE_MODE2.val(drive_mode as u32));
633 } else if self.pin == 3 {
634 self.registers.ports[self.port]
635 .prt_cfg
636 .modify(PRT_CFG::DRIVE_MODE3.val(drive_mode as u32));
637 } else if self.pin == 4 {
638 self.registers.ports[self.port]
639 .prt_cfg
640 .modify(PRT_CFG::DRIVE_MODE4.val(drive_mode as u32));
641 } else if self.pin == 5 {
642 self.registers.ports[self.port]
643 .prt_cfg
644 .modify(PRT_CFG::DRIVE_MODE5.val(drive_mode as u32));
645 } else if self.pin == 6 {
646 self.registers.ports[self.port]
647 .prt_cfg
648 .modify(PRT_CFG::DRIVE_MODE6.val(drive_mode as u32));
649 } else {
650 self.registers.ports[self.port]
651 .prt_cfg
652 .modify(PRT_CFG::DRIVE_MODE7.val(drive_mode as u32));
653 }
654 }
655
656 pub fn configure_input(&self, input_enable: bool) {
657 if self.pin == 0 {
658 self.registers.ports[self.port]
659 .prt_cfg
660 .modify(PRT_CFG::IN_EN0.val(input_enable as u32));
661 } else if self.pin == 1 {
662 self.registers.ports[self.port]
663 .prt_cfg
664 .modify(PRT_CFG::IN_EN1.val(input_enable as u32));
665 } else if self.pin == 2 {
666 self.registers.ports[self.port]
667 .prt_cfg
668 .modify(PRT_CFG::IN_EN2.val(input_enable as u32));
669 } else if self.pin == 3 {
670 self.registers.ports[self.port]
671 .prt_cfg
672 .modify(PRT_CFG::IN_EN3.val(input_enable as u32));
673 } else if self.pin == 4 {
674 self.registers.ports[self.port]
675 .prt_cfg
676 .modify(PRT_CFG::IN_EN4.val(input_enable as u32));
677 } else if self.pin == 5 {
678 self.registers.ports[self.port]
679 .prt_cfg
680 .modify(PRT_CFG::IN_EN5.val(input_enable as u32));
681 } else if self.pin == 6 {
682 self.registers.ports[self.port]
683 .prt_cfg
684 .modify(PRT_CFG::IN_EN6.val(input_enable as u32));
685 } else {
686 self.registers.ports[self.port]
687 .prt_cfg
688 .modify(PRT_CFG::IN_EN7.val(input_enable as u32));
689 }
690 }
691
692 pub fn handle_interrupt(&self) {
693 if self.is_pending() {
694 let bitfield = match self.pin {
695 0 => PRT_INTR::EDGE0,
696 1 => PRT_INTR::EDGE1,
697 2 => PRT_INTR::EDGE2,
698 3 => PRT_INTR::EDGE3,
699 4 => PRT_INTR::EDGE4,
700 5 => PRT_INTR::EDGE5,
701 6 => PRT_INTR::EDGE6,
702 _ => PRT_INTR::EDGE7,
703 };
704 self.registers.ports[self.port]
705 .prt_intr
706 .modify(bitfield.val(1));
707 self.client.map(|client| client.fired());
708 }
709 }
710}
711
712impl Input for GpioPin<'_> {
713 fn read(&self) -> bool {
714 match self.get_configuration() {
715 Configuration::Input => {
716 let bitfield = match self.pin {
717 0 => PRT_IN::IN0,
718 1 => PRT_IN::IN1,
719 2 => PRT_IN::IN2,
720 3 => PRT_IN::IN3,
721 4 => PRT_IN::IN4,
722 5 => PRT_IN::IN5,
723 6 => PRT_IN::IN6,
724 _ => PRT_IN::IN7,
725 };
726 self.registers.ports[self.port].prt_in.is_set(bitfield)
727 }
728 Configuration::Output => {
729 let bitfield = match self.pin {
730 0 => PRT_OUT::OUT0,
731 1 => PRT_OUT::OUT1,
732 2 => PRT_OUT::OUT2,
733 3 => PRT_OUT::OUT3,
734 4 => PRT_OUT::OUT4,
735 5 => PRT_OUT::OUT5,
736 6 => PRT_OUT::OUT6,
737 _ => PRT_OUT::OUT7,
738 };
739 self.registers.ports[self.port].prt_out.is_set(bitfield)
740 }
741 _ => false,
742 }
743 }
744}
745
746impl Output for GpioPin<'_> {
747 fn set(&self) {
748 match self.get_configuration() {
749 Configuration::Output | Configuration::InputOutput => {
750 let bitfield = match self.pin {
751 0 => PRT_OUT::OUT0,
752 1 => PRT_OUT::OUT1,
753 2 => PRT_OUT::OUT2,
754 3 => PRT_OUT::OUT3,
755 4 => PRT_OUT::OUT4,
756 5 => PRT_OUT::OUT5,
757 6 => PRT_OUT::OUT6,
758 _ => PRT_OUT::OUT7,
759 };
760 self.registers.ports[self.port]
761 .prt_out
762 .modify(bitfield.val(1));
763 }
764 _ => (),
765 }
766 }
767
768 fn clear(&self) {
769 match self.get_configuration() {
770 Configuration::Output | Configuration::InputOutput => {
771 let bitfield = match self.pin {
772 0 => PRT_OUT::OUT0,
773 1 => PRT_OUT::OUT1,
774 2 => PRT_OUT::OUT2,
775 3 => PRT_OUT::OUT3,
776 4 => PRT_OUT::OUT4,
777 5 => PRT_OUT::OUT5,
778 6 => PRT_OUT::OUT6,
779 _ => PRT_OUT::OUT7,
780 };
781 self.registers.ports[self.port]
782 .prt_out
783 .modify(bitfield.val(0));
784 }
785 _ => (),
786 }
787 }
788
789 fn toggle(&self) -> bool {
790 if self.read() {
791 self.clear();
792 false
793 } else {
794 self.set();
795 true
796 }
797 }
798}
799
800impl Configure for GpioPin<'_> {
801 fn configuration(&self) -> Configuration {
802 self.get_configuration()
803 }
804
805 fn make_input(&self) -> Configuration {
806 self.configure_input(true);
807 self.get_configuration()
808 }
809
810 fn disable_input(&self) -> Configuration {
811 self.configure_input(false);
812 self.get_configuration()
813 }
814
815 fn make_output(&self) -> Configuration {
816 self.configure_drive_mode(DriveMode::Strong);
817 self.get_configuration()
818 }
819
820 fn disable_output(&self) -> Configuration {
821 self.configure_drive_mode(DriveMode::HighZ);
822 self.get_configuration()
823 }
824
825 fn set_floating_state(&self, state: kernel::hil::gpio::FloatingState) {
826 match state {
827 kernel::hil::gpio::FloatingState::PullUp => {
828 self.configure_drive_mode(DriveMode::PullUp);
829 self.set();
830 }
831 kernel::hil::gpio::FloatingState::PullDown => {
832 self.configure_drive_mode(DriveMode::PullDown);
833 self.clear();
834 }
835 kernel::hil::gpio::FloatingState::PullNone => {
836 self.configure_drive_mode(DriveMode::HighZ)
837 }
838 }
839 }
840
841 fn deactivate_to_low_power(&self) {
842 self.configure_drive_mode(DriveMode::HighZ);
843 self.configure_input(false);
844 }
845
846 fn floating_state(&self) -> kernel::hil::gpio::FloatingState {
847 let drive_mode = if self.pin == 0 {
848 self.registers.ports[self.port]
849 .prt_cfg
850 .read(PRT_CFG::DRIVE_MODE0)
851 } else if self.pin == 1 {
852 self.registers.ports[self.port]
853 .prt_cfg
854 .read(PRT_CFG::DRIVE_MODE1)
855 } else if self.pin == 2 {
856 self.registers.ports[self.port]
857 .prt_cfg
858 .read(PRT_CFG::DRIVE_MODE2)
859 } else if self.pin == 3 {
860 self.registers.ports[self.port]
861 .prt_cfg
862 .read(PRT_CFG::DRIVE_MODE3)
863 } else if self.pin == 4 {
864 self.registers.ports[self.port]
865 .prt_cfg
866 .read(PRT_CFG::DRIVE_MODE4)
867 } else if self.pin == 5 {
868 self.registers.ports[self.port]
869 .prt_cfg
870 .read(PRT_CFG::DRIVE_MODE5)
871 } else if self.pin == 6 {
872 self.registers.ports[self.port]
873 .prt_cfg
874 .read(PRT_CFG::DRIVE_MODE6)
875 } else {
876 self.registers.ports[self.port]
877 .prt_cfg
878 .read(PRT_CFG::DRIVE_MODE7)
879 };
880 if drive_mode == PULL_UP {
881 kernel::hil::gpio::FloatingState::PullUp
882 } else if drive_mode == PULL_DOWN {
883 kernel::hil::gpio::FloatingState::PullDown
884 } else {
885 kernel::hil::gpio::FloatingState::PullNone
886 }
887 }
888}
889
890impl<'a> Interrupt<'a> for GpioPin<'a> {
891 fn set_client(&self, client: &'a dyn kernel::hil::gpio::Client) {
892 self.client.set(client);
893 }
894
895 fn enable_interrupts(&self, mode: kernel::hil::gpio::InterruptEdge) {
896 let edge_value = match mode {
897 kernel::hil::gpio::InterruptEdge::RisingEdge => 1,
898 kernel::hil::gpio::InterruptEdge::FallingEdge => 2,
899 kernel::hil::gpio::InterruptEdge::EitherEdge => 3,
900 };
901 if self.pin == 0 {
902 self.registers.ports[self.port]
903 .prt_intr_cfg
904 .modify(PRT_INTR_CFG::EDGE_SEL0.val(edge_value));
905 } else if self.pin == 1 {
906 self.registers.ports[self.port]
907 .prt_intr_cfg
908 .modify(PRT_INTR_CFG::EDGE_SEL1.val(edge_value));
909 } else if self.pin == 2 {
910 self.registers.ports[self.port]
911 .prt_intr_cfg
912 .modify(PRT_INTR_CFG::EDGE_SEL2.val(edge_value));
913 } else if self.pin == 3 {
914 self.registers.ports[self.port]
915 .prt_intr_cfg
916 .modify(PRT_INTR_CFG::EDGE_SEL3.val(edge_value));
917 } else if self.pin == 4 {
918 self.registers.ports[self.port]
919 .prt_intr_cfg
920 .modify(PRT_INTR_CFG::EDGE_SEL4.val(edge_value));
921 } else if self.pin == 5 {
922 self.registers.ports[self.port]
923 .prt_intr_cfg
924 .modify(PRT_INTR_CFG::EDGE_SEL5.val(edge_value));
925 } else if self.pin == 6 {
926 self.registers.ports[self.port]
927 .prt_intr_cfg
928 .modify(PRT_INTR_CFG::EDGE_SEL6.val(edge_value));
929 } else {
930 self.registers.ports[self.port]
931 .prt_intr_cfg
932 .modify(PRT_INTR_CFG::EDGE_SEL7.val(edge_value));
933 }
934 let bitfield = match self.pin {
935 0 => PRT_INTR::EDGE0,
936 1 => PRT_INTR::EDGE1,
937 2 => PRT_INTR::EDGE2,
938 3 => PRT_INTR::EDGE3,
939 4 => PRT_INTR::EDGE4,
940 5 => PRT_INTR::EDGE5,
941 6 => PRT_INTR::EDGE6,
942 _ => PRT_INTR::EDGE7,
943 };
944 self.registers.ports[self.port]
945 .prt_intr_mask
946 .modify(bitfield.val(1));
947 }
948
949 fn disable_interrupts(&self) {
950 let bitfield = match self.pin {
951 0 => PRT_INTR::EDGE0,
952 1 => PRT_INTR::EDGE1,
953 2 => PRT_INTR::EDGE2,
954 3 => PRT_INTR::EDGE3,
955 4 => PRT_INTR::EDGE4,
956 5 => PRT_INTR::EDGE5,
957 6 => PRT_INTR::EDGE6,
958 _ => PRT_INTR::EDGE7,
959 };
960 self.registers.ports[self.port]
961 .prt_intr_mask
962 .modify(bitfield.val(0));
963 }
964
965 fn is_pending(&self) -> bool {
966 let bitfield = match self.pin {
967 0 => PRT_INTR::EDGE0,
968 1 => PRT_INTR::EDGE1,
969 2 => PRT_INTR::EDGE2,
970 3 => PRT_INTR::EDGE3,
971 4 => PRT_INTR::EDGE4,
972 5 => PRT_INTR::EDGE5,
973 6 => PRT_INTR::EDGE6,
974 _ => PRT_INTR::EDGE7,
975 };
976 self.registers.ports[self.port].prt_intr.is_set(bitfield)
977 }
978}