1use core::ops::{Index, IndexMut};
8use enum_primitive::cast::FromPrimitive;
9use enum_primitive::enum_from_primitive;
10use kernel::hil::gpio;
11use kernel::utilities::cells::OptionalCell;
12use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
13use kernel::utilities::registers::{register_bitfields, register_structs, ReadWrite};
14use kernel::utilities::StaticRef;
15
16pub const GPIO_BASE_RAW: usize = 0x4001_0000; const GPIO_BASE: StaticRef<GpioRegisters> =
19 unsafe { StaticRef::new(GPIO_BASE_RAW as *const GpioRegisters) };
20
21pub struct Port<'a> {
22 pins: [GpioPin<'a>; 50],
23}
24
25impl Port<'_> {
26 pub const fn new() -> Self {
27 Self {
28 pins: [
29 GpioPin::new(GPIO_BASE, Pin::Pin00),
30 GpioPin::new(GPIO_BASE, Pin::Pin01),
31 GpioPin::new(GPIO_BASE, Pin::Pin02),
32 GpioPin::new(GPIO_BASE, Pin::Pin03),
33 GpioPin::new(GPIO_BASE, Pin::Pin04),
34 GpioPin::new(GPIO_BASE, Pin::Pin05),
35 GpioPin::new(GPIO_BASE, Pin::Pin06),
36 GpioPin::new(GPIO_BASE, Pin::Pin07),
37 GpioPin::new(GPIO_BASE, Pin::Pin08),
38 GpioPin::new(GPIO_BASE, Pin::Pin09),
39 GpioPin::new(GPIO_BASE, Pin::Pin10),
40 GpioPin::new(GPIO_BASE, Pin::Pin11),
41 GpioPin::new(GPIO_BASE, Pin::Pin12),
42 GpioPin::new(GPIO_BASE, Pin::Pin13),
43 GpioPin::new(GPIO_BASE, Pin::Pin14),
44 GpioPin::new(GPIO_BASE, Pin::Pin15),
45 GpioPin::new(GPIO_BASE, Pin::Pin16),
46 GpioPin::new(GPIO_BASE, Pin::Pin17),
47 GpioPin::new(GPIO_BASE, Pin::Pin18),
48 GpioPin::new(GPIO_BASE, Pin::Pin19),
49 GpioPin::new(GPIO_BASE, Pin::Pin20),
50 GpioPin::new(GPIO_BASE, Pin::Pin21),
51 GpioPin::new(GPIO_BASE, Pin::Pin22),
52 GpioPin::new(GPIO_BASE, Pin::Pin23),
53 GpioPin::new(GPIO_BASE, Pin::Pin24),
54 GpioPin::new(GPIO_BASE, Pin::Pin25),
55 GpioPin::new(GPIO_BASE, Pin::Pin26),
56 GpioPin::new(GPIO_BASE, Pin::Pin27),
57 GpioPin::new(GPIO_BASE, Pin::Pin28),
58 GpioPin::new(GPIO_BASE, Pin::Pin29),
59 GpioPin::new(GPIO_BASE, Pin::Pin30),
60 GpioPin::new(GPIO_BASE, Pin::Pin31),
61 GpioPin::new(GPIO_BASE, Pin::Pin32),
62 GpioPin::new(GPIO_BASE, Pin::Pin33),
63 GpioPin::new(GPIO_BASE, Pin::Pin34),
64 GpioPin::new(GPIO_BASE, Pin::Pin35),
65 GpioPin::new(GPIO_BASE, Pin::Pin36),
66 GpioPin::new(GPIO_BASE, Pin::Pin37),
67 GpioPin::new(GPIO_BASE, Pin::Pin38),
68 GpioPin::new(GPIO_BASE, Pin::Pin39),
69 GpioPin::new(GPIO_BASE, Pin::Pin40),
70 GpioPin::new(GPIO_BASE, Pin::Pin41),
71 GpioPin::new(GPIO_BASE, Pin::Pin42),
72 GpioPin::new(GPIO_BASE, Pin::Pin43),
73 GpioPin::new(GPIO_BASE, Pin::Pin44),
74 GpioPin::new(GPIO_BASE, Pin::Pin45),
75 GpioPin::new(GPIO_BASE, Pin::Pin46),
76 GpioPin::new(GPIO_BASE, Pin::Pin47),
77 GpioPin::new(GPIO_BASE, Pin::Pin48),
78 GpioPin::new(GPIO_BASE, Pin::Pin49),
79 ],
80 }
81 }
82}
83
84impl<'a> Index<usize> for Port<'a> {
85 type Output = GpioPin<'a>;
86
87 fn index(&self, index: usize) -> &GpioPin<'a> {
88 &self.pins[index]
89 }
90}
91
92impl<'a> IndexMut<usize> for Port<'a> {
93 fn index_mut(&mut self, index: usize) -> &mut GpioPin<'a> {
94 &mut self.pins[index]
95 }
96}
97
98impl Port<'_> {
99 pub fn handle_interrupt(&self) {
100 let regs = GPIO_BASE;
101 let mut irqs = regs.int0stat.get();
102 regs.int0clr.set(irqs);
103
104 let mut count = 0;
105 while irqs != 0 && count < self.pins.len() {
106 if (irqs & 0b1) != 0 {
107 self.pins[count].handle_interrupt();
108 }
109 count += 1;
110 irqs >>= 1;
111 }
112
113 let mut irqs = regs.int1stat.get();
114 regs.int1clr.set(irqs);
115
116 let mut count = 0;
117 while irqs != 0 && count < self.pins.len() {
118 if (irqs & 0b1) != 0 {
119 self.pins[count + 32].handle_interrupt();
122 }
123 count += 1;
124 irqs >>= 1;
125 }
126 }
127
128 pub fn enable_uart(&self, tx_pin: &GpioPin, rx_pin: &GpioPin) {
129 let regs = GPIO_BASE;
130
131 match tx_pin.pin as usize {
132 48 => {
133 regs.padkey.set(115);
134 regs.padreg[12].set(regs.padreg[12].get() & 0xffffff00);
135 regs.cfg[6].modify(CFG::GPIO0INTD.val(0x00) + CFG::GPIO0OUTCFG.val(0x00));
136 regs.altpadcfgm
137 .modify(ALTPADCFG::PAD0_DS1::CLEAR + ALTPADCFG::PAD0_SR::CLEAR);
138 regs.padkey.set(0x00);
139 }
140 _ => {
141 panic!("tx_pin not supported");
142 }
143 }
144
145 match rx_pin.pin as usize {
146 49 => {
147 regs.padkey.set(115);
148 regs.padreg[12].modify(
149 PADREG::PAD1PULL::CLEAR
150 + PADREG::PAD1INPEN::SET
151 + PADREG::PAD1STRNG::CLEAR
152 + PADREG::PAD1FNCSEL::CLEAR
153 + PADREG::PAD1RSEL::CLEAR,
154 );
155 regs.cfg[6].modify(
156 CFG::GPIO1INCFG::CLEAR + CFG::GPIO1INTD.val(0x00) + CFG::GPIO1OUTCFG.val(0x00),
157 );
158 regs.altpadcfgm
159 .modify(ALTPADCFG::PAD1_DS1::CLEAR + ALTPADCFG::PAD1_SR::CLEAR);
160 regs.padkey.set(0x00);
161 }
162 _ => {
163 panic!("rx_pin not supported");
164 }
165 }
166 }
167
168 pub fn enable_sx1262_radio_pins(&self) {
188 let regs = GPIO_BASE;
189
190 regs.padkey.set(115);
191
192 regs.padreg[9].modify(
194 PADREG::PAD0PULL::CLEAR + PADREG::PAD0INPEN::CLEAR + PADREG::PAD0FNCSEL.val(0x1),
195 );
196 regs.cfg[4].modify(CFG::GPIO4INCFG.val(0x00) + CFG::GPIO4OUTCFG.val(0x00));
197 regs.altpadcfgj
198 .modify(ALTPADCFG::PAD0_DS1::CLEAR + ALTPADCFG::PAD0_SR::CLEAR);
199
200 regs.padreg[9].modify(
202 PADREG::PAD3INPEN::SET
203 + PADREG::PAD3STRNG::CLEAR
204 + PADREG::PAD3FNCSEL.val(0x3)
205 + PADREG::PAD3RSEL.val(0x0),
206 );
207 regs.cfg[4].modify(
208 CFG::GPIO7INCFG.val(0x00) + CFG::GPIO7OUTCFG.val(0x00) + CFG::GPIO7INTD.val(0x00),
209 );
210 regs.altpadcfgj
211 .modify(ALTPADCFG::PAD3_DS1::CLEAR + ALTPADCFG::PAD3_SR::CLEAR);
212
213 regs.padreg[10].modify(
215 PADREG::PAD0PULL::CLEAR
216 + PADREG::PAD0INPEN::SET
217 + PADREG::PAD0STRING::CLEAR
218 + PADREG::PAD0FNCSEL.val(0x3)
219 + PADREG::PAD0RSEL.val(0x0),
220 );
221 regs.cfg[5].modify(
222 CFG::GPIO0INCFG.val(0x00) + CFG::GPIO0OUTCFG.val(0x00) + CFG::GPIO0INTD.val(0x00),
223 );
224 regs.altpadcfgk
225 .modify(ALTPADCFG::PAD0_DS1::CLEAR + ALTPADCFG::PAD0_SR::CLEAR);
226
227 regs.padreg[11].modify(
229 PADREG::PAD3PULL::CLEAR
230 + PADREG::PAD3INPEN::SET
231 + PADREG::PAD3STRNG::CLEAR
232 + PADREG::PAD3FNCSEL.val(0x3)
233 + PADREG::PAD3RSEL.val(0x0),
234 );
235 regs.cfg[5].modify(
236 CFG::GPIO7INCFG.val(0x00) + CFG::GPIO7OUTCFG.val(0x00) + CFG::GPIO7INTD.val(0x00),
237 );
238 regs.altpadcfgl
239 .modify(ALTPADCFG::PAD3_DS1::CLEAR + ALTPADCFG::PAD3_SR::CLEAR);
240
241 regs.padreg[11].modify(
243 PADREG::PAD0PULL::CLEAR
244 + PADREG::PAD0INPEN::CLEAR
245 + PADREG::PAD0STRING::CLEAR
246 + PADREG::PAD0FNCSEL.val(0x3)
247 + PADREG::PAD0RSEL.val(0x0),
248 );
249 regs.cfg[5].modify(
250 CFG::GPIO4INCFG.val(0x00) + CFG::GPIO4OUTCFG.val(0x00) + CFG::GPIO4INTD.val(0x00),
251 );
252 regs.altpadcfgl
253 .modify(ALTPADCFG::PAD0_DS1::CLEAR + ALTPADCFG::PAD0_SR::CLEAR);
254
255 regs.padkey.set(0x00);
256 }
257
258 pub fn enable_i2c(&self, sda: &GpioPin, scl: &GpioPin) {
259 let regs = GPIO_BASE;
260
261 match sda.pin as usize {
262 40 => {
263 regs.padkey.set(115);
264 regs.padreg[10].modify(
265 PADREG::PAD0PULL::SET
266 + PADREG::PAD0INPEN::SET
267 + PADREG::PAD0STRING::SET
268 + PADREG::PAD0FNCSEL.val(0x4)
269 + PADREG::PAD0RSEL.val(0x00),
270 );
271 regs.cfg[5].modify(CFG::GPIO0INCFG.val(0x00) + CFG::GPIO0OUTCFG.val(0x02));
272 regs.altpadcfgk
273 .modify(ALTPADCFG::PAD0_DS1::SET + ALTPADCFG::PAD0_DS1::CLEAR);
274 regs.padkey.set(0x00);
275 }
276 25 => {
277 regs.padkey.set(115);
278 regs.padreg[6].modify(
279 PADREG::PAD1PULL::SET
280 + PADREG::PAD1INPEN::SET
281 + PADREG::PAD1STRNG::SET
282 + PADREG::PAD1FNCSEL.val(0x4),
283 );
284 regs.cfg[3].modify(CFG::GPIO1INTD.val(0x00) + CFG::GPIO1OUTCFG.val(0x02));
285 regs.altpadcfgg
286 .modify(ALTPADCFG::PAD1_DS1::CLEAR + ALTPADCFG::PAD1_SR::CLEAR);
287 regs.padkey.set(0x00);
288 }
289 6 => {
290 regs.padkey.set(115);
291 regs.padreg[1].modify(
292 PADREG::PAD2PULL::SET
293 + PADREG::PAD2INPEN::SET
294 + PADREG::PAD2STRNG::SET
295 + PADREG::PAD2FNCSEL.val(0x00),
296 );
297 regs.cfg[0].modify(CFG::GPIO6OUTCFG.val(0x03) + CFG::GPIO6OUTCFG.val(0x00));
298 regs.altpadcfgb
299 .modify(ALTPADCFG::PAD2_DS1::SET + ALTPADCFG::PAD2_SR::CLEAR);
300 regs.padkey.set(0x00);
301 }
302 _ => {
303 panic!("sda not supported");
304 }
305 }
306
307 match scl.pin as usize {
308 39 => {
309 regs.padkey.set(115);
310 regs.padreg[9].modify(
311 PADREG::PAD3PULL::SET
312 + PADREG::PAD3INPEN::SET
313 + PADREG::PAD3STRNG::SET
314 + PADREG::PAD3FNCSEL.val(0x4)
315 + PADREG::PAD3RSEL.val(0x00),
316 );
317 regs.cfg[4].modify(CFG::GPIO7INTD.val(0x00) + CFG::GPIO7OUTCFG.val(0x02));
318 regs.altpadcfgj
319 .modify(ALTPADCFG::PAD3_DS1::SET + ALTPADCFG::PAD3_SR::CLEAR);
320 regs.padkey.set(0x00);
321 }
322 27 => {
323 regs.padkey.set(115);
324 regs.padreg[6].modify(
325 PADREG::PAD3PULL::SET
326 + PADREG::PAD3INPEN::SET
327 + PADREG::PAD3STRNG::SET
328 + PADREG::PAD3FNCSEL.val(0x4),
329 );
330 regs.cfg[3].modify(CFG::GPIO3INTD.val(0x00) + CFG::GPIO3OUTCFG.val(0x02));
331 regs.altpadcfgg
332 .modify(ALTPADCFG::PAD3_DS1::CLEAR + ALTPADCFG::PAD3_SR::CLEAR);
333 regs.padkey.set(0x00);
334 }
335 5 => {
336 regs.padkey.set(115);
337 regs.padreg[1].modify(
338 PADREG::PAD1PULL::SET
339 + PADREG::PAD1INPEN::SET
340 + PADREG::PAD1STRNG::SET
341 + PADREG::PAD1FNCSEL.val(0x00)
342 + PADREG::PAD1RSEL.val(0x00),
343 );
344 regs.cfg[0].modify(CFG::GPIO5OUTCFG.val(0x03) + CFG::GPIO1OUTCFG.val(0x00));
345 regs.altpadcfgb
346 .modify(ALTPADCFG::PAD1_DS1::SET + ALTPADCFG::PAD1_SR::CLEAR);
347 regs.padkey.set(0x00);
348 }
349 _ => {
350 panic!("scl not supported");
351 }
352 }
353 }
354
355 pub fn enable_i2c_slave(&self, sda: &GpioPin, scl: &GpioPin) {
356 let regs = GPIO_BASE;
357
358 match sda.pin as usize {
359 1 => {
360 regs.padkey.set(115);
361 regs.padreg[0].modify(
362 PADREG::PAD1PULL::SET
363 + PADREG::PAD1INPEN::SET
364 + PADREG::PAD1STRNG::CLEAR
365 + PADREG::PAD1FNCSEL.val(0x00)
366 + PADREG::PAD1RSEL.val(0x00),
367 );
368 regs.cfg[0].modify(
369 CFG::GPIO1INCFG::CLEAR + CFG::GPIO1OUTCFG.val(0x02) + CFG::GPIO1INTD::CLEAR,
370 );
371 regs.altpadcfga
372 .modify(ALTPADCFG::PAD1_DS1::CLEAR + ALTPADCFG::PAD1_SR::CLEAR);
373 regs.padkey.set(0x00);
374 }
375 _ => {
376 panic!("sda not supported");
377 }
378 }
379
380 match scl.pin as usize {
381 0 => {
382 regs.padkey.set(115);
383 regs.padreg[0].modify(
384 PADREG::PAD0PULL::CLEAR
385 + PADREG::PAD0INPEN::SET
386 + PADREG::PAD0STRING::CLEAR
387 + PADREG::PAD0FNCSEL.val(0x0)
388 + PADREG::PAD0RSEL.val(0x0),
389 );
390 regs.cfg[0].modify(
391 CFG::GPIO0INCFG::CLEAR + CFG::GPIO0OUTCFG.val(0x0) + CFG::GPIO0INTD::CLEAR,
392 );
393 regs.altpadcfga
394 .modify(ALTPADCFG::PAD0_DS1::CLEAR + ALTPADCFG::PAD0_SR::CLEAR);
395 regs.padkey.set(0x00);
396 }
397 _ => {
398 panic!("scl not supported");
399 }
400 }
401 }
402
403 pub fn enable_spi(&self, sck: &GpioPin, mosi: &GpioPin, miso: &GpioPin) {
404 let regs = GPIO_BASE;
405
406 match sck.pin as usize {
407 5 => {
408 regs.padkey.set(115);
409 regs.padreg[1].modify(
410 PADREG::PAD1PULL::CLEAR
411 + PADREG::PAD1INPEN::SET
412 + PADREG::PAD1STRNG::SET
413 + PADREG::PAD1FNCSEL.val(0x1)
414 + PADREG::PAD1RSEL.val(0x00),
415 );
416 regs.cfg[0].modify(
417 CFG::GPIO1INCFG.val(0x00)
418 + CFG::GPIO1OUTCFG.val(0x000)
419 + CFG::GPIO1INTD.val(0x00),
420 );
421 regs.altpadcfgb
422 .modify(ALTPADCFG::PAD1_DS1::SET + ALTPADCFG::PAD1_SR::CLEAR);
423 regs.padkey.set(0x00);
424 }
425 18 => {
426 regs.padkey.set(115);
427 regs.padreg[4].modify(
428 PADREG::PAD2PULL::CLEAR
429 + PADREG::PAD2INPEN::CLEAR
430 + PADREG::PAD2STRNG::SET
431 + PADREG::PAD2FNCSEL.val(0x5),
432 );
433 regs.cfg[2].modify(
434 CFG::GPIO2INCFG.val(0x00)
435 + CFG::GPIO2OUTCFG.val(0x000)
436 + CFG::GPIO2INTD.val(0x00),
437 );
438 regs.altpadcfge
439 .modify(ALTPADCFG::PAD2_DS1::SET + ALTPADCFG::PAD2_SR::CLEAR);
440 regs.padkey.set(0x00);
441 }
442 27 => {
443 regs.padkey.set(115);
444 regs.padreg[6].modify(
445 PADREG::PAD3PULL::CLEAR
446 + PADREG::PAD3INPEN::SET
447 + PADREG::PAD3STRNG::SET
448 + PADREG::PAD3FNCSEL.val(0x5)
449 + PADREG::PAD3RSEL.val(0x00),
450 );
451 regs.cfg[3].modify(
452 CFG::GPIO3INCFG.val(0x00)
453 + CFG::GPIO3OUTCFG.val(0x000)
454 + CFG::GPIO3INTD.val(0x00),
455 );
456 regs.altpadcfgg
457 .modify(ALTPADCFG::PAD3_DS1::SET + ALTPADCFG::PAD3_SR::CLEAR);
458 regs.padkey.set(0x00);
459 }
460 42 => {
461 regs.padkey.set(115);
462 regs.padreg[10].modify(
463 PADREG::PAD2PULL::CLEAR
464 + PADREG::PAD2INPEN::SET
465 + PADREG::PAD2STRNG::SET
466 + PADREG::PAD2FNCSEL.val(0x5),
467 );
468 regs.cfg[5].modify(
469 CFG::GPIO2INCFG.val(0x00)
470 + CFG::GPIO2OUTCFG.val(0x000)
471 + CFG::GPIO2INTD.val(0x00),
472 );
473 regs.altpadcfgk
474 .modify(ALTPADCFG::PAD2_DS1::SET + ALTPADCFG::PAD2_SR::CLEAR);
475 regs.padkey.set(0x00);
476 }
477 _ => {
478 panic!("sck not supported");
479 }
480 }
481
482 match mosi.pin as usize {
483 7 => {
484 regs.padkey.set(115);
485 regs.padreg[1].modify(
486 PADREG::PAD3PULL::CLEAR
487 + PADREG::PAD3INPEN::CLEAR
488 + PADREG::PAD3STRNG::SET
489 + PADREG::PAD3FNCSEL.val(0x1)
490 + PADREG::PAD3RSEL.val(0x00),
491 );
492 regs.cfg[0].modify(
493 CFG::GPIO4INCFG.val(0x00)
494 + CFG::GPIO4OUTCFG.val(0x000)
495 + CFG::GPIO4INTD.val(0x00),
496 );
497 regs.altpadcfgb
498 .modify(ALTPADCFG::PAD3_DS1::SET + ALTPADCFG::PAD3_SR::CLEAR);
499 regs.padkey.set(0x00);
500 }
501 17 => {
502 regs.padkey.set(115);
503 regs.padreg[4].modify(
504 PADREG::PAD2PULL::CLEAR
505 + PADREG::PAD2INPEN::SET
506 + PADREG::PAD2STRNG::CLEAR
507 + PADREG::PAD2FNCSEL.val(0x5),
508 );
509 regs.cfg[2].modify(
510 CFG::GPIO1INCFG.val(0x00)
511 + CFG::GPIO1OUTCFG.val(0x000)
512 + CFG::GPIO1INTD.val(0x00),
513 );
514 regs.altpadcfge
515 .modify(ALTPADCFG::PAD1_DS1::SET + ALTPADCFG::PAD1_SR::CLEAR);
516 regs.padkey.set(0x00);
517 }
518 28 => {
519 regs.padkey.set(115);
520 regs.padreg[7].modify(
521 PADREG::PAD0PULL::CLEAR
522 + PADREG::PAD0INPEN::CLEAR
523 + PADREG::PAD0STRING::SET
524 + PADREG::PAD0FNCSEL.val(0x5)
525 + PADREG::PAD0RSEL.val(0x00),
526 );
527 regs.cfg[3].modify(
528 CFG::GPIO4INCFG.val(0x00)
529 + CFG::GPIO4OUTCFG.val(0x000)
530 + CFG::GPIO4INTD.val(0x00),
531 );
532 regs.altpadcfgh
533 .modify(ALTPADCFG::PAD0_DS1::SET + ALTPADCFG::PAD0_SR::CLEAR);
534 regs.padkey.set(0x00);
535 }
536 38 => {
537 regs.padkey.set(115);
538 regs.padreg[9].modify(
539 PADREG::PAD2PULL::CLEAR
540 + PADREG::PAD2INPEN::CLEAR
541 + PADREG::PAD2STRNG::CLEAR
542 + PADREG::PAD2FNCSEL.val(0x5),
543 );
544 regs.cfg[4].modify(
545 CFG::GPIO6INCFG.val(0x00)
546 + CFG::GPIO6OUTCFG.val(0x000)
547 + CFG::GPIO6INTD.val(0x00),
548 );
549 regs.altpadcfgj
550 .modify(ALTPADCFG::PAD2_DS1::CLEAR + ALTPADCFG::PAD2_SR::CLEAR);
551 regs.padkey.set(0x00);
552 }
553 _ => {
554 panic!("mosi not supported");
555 }
556 }
557
558 match miso.pin as usize {
559 6 => {
560 regs.padkey.set(115);
561 regs.padreg[1].modify(
562 PADREG::PAD2PULL::CLEAR
563 + PADREG::PAD2INPEN::SET
564 + PADREG::PAD2STRNG::CLEAR
565 + PADREG::PAD2FNCSEL.val(0x1),
566 );
567 regs.cfg[0].modify(
568 CFG::GPIO3INCFG.val(0x00)
569 + CFG::GPIO3OUTCFG.val(0x000)
570 + CFG::GPIO3INTD.val(0x00),
571 );
572 regs.altpadcfgb
573 .modify(ALTPADCFG::PAD2_DS1::CLEAR + ALTPADCFG::PAD2_SR::CLEAR);
574 regs.padkey.set(0x00);
575 }
576 25 => {
577 regs.padkey.set(115);
578 regs.padreg[6].modify(
579 PADREG::PAD1PULL::CLEAR
580 + PADREG::PAD1INPEN::SET
581 + PADREG::PAD1STRNG::CLEAR
582 + PADREG::PAD1FNCSEL.val(0x5)
583 + PADREG::PAD1RSEL.val(0x00),
584 );
585 regs.cfg[3].modify(
586 CFG::GPIO1INCFG.val(0x00)
587 + CFG::GPIO1OUTCFG.val(0x000)
588 + CFG::GPIO1INTD.val(0x00),
589 );
590 regs.altpadcfgg
591 .modify(ALTPADCFG::PAD1_DS1::CLEAR + ALTPADCFG::PAD1_SR::CLEAR);
592 regs.padkey.set(0x00);
593 }
594 26 => {
595 regs.padkey.set(115);
596 regs.padreg[6].modify(
597 PADREG::PAD2PULL::CLEAR
598 + PADREG::PAD2INPEN::SET
599 + PADREG::PAD2STRNG::CLEAR
600 + PADREG::PAD2FNCSEL.val(0x5),
601 );
602 regs.cfg[3].modify(
603 CFG::GPIO2INCFG.val(0x00)
604 + CFG::GPIO2OUTCFG.val(0x000)
605 + CFG::GPIO2INTD.val(0x00),
606 );
607 regs.altpadcfgg
608 .modify(ALTPADCFG::PAD2_DS1::CLEAR + ALTPADCFG::PAD2_SR::CLEAR);
609 regs.padkey.set(0x00);
610 }
611 43 => {
612 regs.padkey.set(115);
613 regs.padreg[10].modify(
614 PADREG::PAD3PULL::CLEAR
615 + PADREG::PAD3INPEN::SET
616 + PADREG::PAD3STRNG::CLEAR
617 + PADREG::PAD3FNCSEL.val(0x5),
618 );
619 regs.cfg[5].modify(
620 CFG::GPIO3INCFG.val(0x00)
621 + CFG::GPIO3OUTCFG.val(0x000)
622 + CFG::GPIO3INTD.val(0x00),
623 );
624 regs.altpadcfgk
625 .modify(ALTPADCFG::PAD3_DS1::CLEAR + ALTPADCFG::PAD3_SR::CLEAR);
626 regs.padkey.set(0x00);
627 }
628 _ => {
629 panic!("miso not supported");
630 }
631 }
632 }
633}
634
635enum_from_primitive! {
636 #[derive(Copy, Clone, Debug, PartialEq)]
637 pub enum Pin {
638 Pin00, Pin01, Pin02, Pin03, Pin04, Pin05, Pin06, Pin07,
639 Pin08, Pin09, Pin10, Pin11, Pin12, Pin13, Pin14, Pin15,
640 Pin16, Pin17, Pin18, Pin19, Pin20, Pin21, Pin22, Pin23,
641 Pin24, Pin25, Pin26, Pin27, Pin28, Pin29, Pin30, Pin31,
642 Pin32, Pin33, Pin34, Pin35, Pin36, Pin37, Pin38, Pin39,
643 Pin40, Pin41, Pin42, Pin43, Pin44, Pin45, Pin46, Pin47,
644 Pin48, Pin49,
645 }
646}
647
648register_structs! {
649 pub GpioRegisters {
650 (0x00 => padreg: [ReadWrite<u32, PADREG::Register>; 13]),
651 (0x34 => _reserved0),
652 (0x40 => cfg: [ReadWrite<u32, CFG::Register>; 7]),
653 (0x5C => _reserved1),
654 (0x60 => padkey: ReadWrite<u32, PADKEY::Register>),
655 (0x64 => _reserved2),
656 (0x80 => rda: ReadWrite<u32, RDA::Register>),
657 (0x84 => rdb: ReadWrite<u32, RDB::Register>),
658 (0x88 => wta: ReadWrite<u32, WTA::Register>),
659 (0x8C => wtb: ReadWrite<u32, WTB::Register>),
660 (0x90 => wtsa: ReadWrite<u32, WTSA::Register>),
661 (0x94 => wtsb: ReadWrite<u32, WTSB::Register>),
662 (0x98 => wtca: ReadWrite<u32, WTCA::Register>),
663 (0x9c => wtcb: ReadWrite<u32, WTCB::Register>),
664 (0xA0 => ena: ReadWrite<u32, ENA::Register>),
665 (0xA4 => enb: ReadWrite<u32, ENB::Register>),
666 (0xA8 => ensa: ReadWrite<u32, ENSA::Register>),
667 (0xAC => ensb: ReadWrite<u32, ENSB::Register>),
668 (0xB0 => _reserved3),
669 (0xB4 => enca: ReadWrite<u32, ENCA::Register>),
670 (0xB8 => encb: ReadWrite<u32, ENCB::Register>),
671 (0xBC => stmrcap: ReadWrite<u32, STMRCAP::Register>),
672 (0xC0 => iom0irq: ReadWrite<u32, IOMIRQ::Register>),
673 (0xC4 => iom1irq: ReadWrite<u32, IOMIRQ::Register>),
674 (0xC8 => iom2irq: ReadWrite<u32, IOMIRQ::Register>),
675 (0xCC => iom3irq: ReadWrite<u32, IOMIRQ::Register>),
676 (0xD0 => iom4irq: ReadWrite<u32, IOMIRQ::Register>),
677 (0xD4 => iom5irq: ReadWrite<u32, IOMIRQ::Register>),
678 (0xD8 => bleif5irq: ReadWrite<u32, IOMIRQ::Register>),
679 (0xDC => gpioobs: ReadWrite<u32, GPIOOBS::Register>),
680 (0xE0 => altpadcfga: ReadWrite<u32, ALTPADCFG::Register>),
681 (0xE4 => altpadcfgb: ReadWrite<u32, ALTPADCFG::Register>),
682 (0xE8 => altpadcfgc: ReadWrite<u32, ALTPADCFG::Register>),
683 (0xEC => altpadcfgd: ReadWrite<u32, ALTPADCFG::Register>),
684 (0xF0 => altpadcfge: ReadWrite<u32, ALTPADCFG::Register>),
685 (0xF4 => altpadcfgf: ReadWrite<u32, ALTPADCFG::Register>),
686 (0xF8 => altpadcfgg: ReadWrite<u32, ALTPADCFG::Register>),
687 (0xFC => altpadcfgh: ReadWrite<u32, ALTPADCFG::Register>),
688 (0x100 => altpadcfgi: ReadWrite<u32, ALTPADCFG::Register>),
689 (0x104 => altpadcfgj: ReadWrite<u32, ALTPADCFG::Register>),
690 (0x108 => altpadcfgk: ReadWrite<u32, ALTPADCFG::Register>),
691 (0x10C => altpadcfgl: ReadWrite<u32, ALTPADCFG::Register>),
692 (0x110 => altpadcfgm: ReadWrite<u32, ALTPADCFG::Register>),
693 (0x114 => scdet: ReadWrite<u32, SCDET::Register>),
694 (0x118 => ctencfg: ReadWrite<u32, CTENCFG::Register>),
695 (0x11C => _reserved4),
696 (0x200 => int0en: ReadWrite<u32, INT0::Register>),
697 (0x204 => int0stat: ReadWrite<u32, INT0::Register>),
698 (0x208 => int0clr: ReadWrite<u32, INT0::Register>),
699 (0x20C => int0set: ReadWrite<u32, INT0::Register>),
700 (0x210 => int1en: ReadWrite<u32, INT1::Register>),
701 (0x214 => int1stat: ReadWrite<u32, INT1::Register>),
702 (0x218 => int1clr: ReadWrite<u32, INT1::Register>),
703 (0x21C => int1set: ReadWrite<u32, INT1::Register>),
704 (0x220 => @END),
705 }
706}
707
708register_bitfields![u32,
709 PADREG [
710 PAD0PULL OFFSET(0) NUMBITS(1) [],
711 PAD0INPEN OFFSET(1) NUMBITS(1) [],
712 PAD0STRING OFFSET(2) NUMBITS(1) [],
713 PAD0FNCSEL OFFSET(3) NUMBITS(3) [],
714 PAD0RSEL OFFSET(6) NUMBITS(2) [],
715 PAD1PULL OFFSET(8) NUMBITS(1) [],
716 PAD1INPEN OFFSET(9) NUMBITS(1) [],
717 PAD1STRNG OFFSET(10) NUMBITS(1) [],
718 PAD1FNCSEL OFFSET(11) NUMBITS(3) [],
719 PAD1RSEL OFFSET(14) NUMBITS(2) [],
720 PAD2PULL OFFSET(16) NUMBITS(1) [],
721 PAD2INPEN OFFSET(17) NUMBITS(1) [],
722 PAD2STRNG OFFSET(18) NUMBITS(1) [],
723 PAD2FNCSEL OFFSET(19) NUMBITS(3) [],
724 PAD3PULL OFFSET(24) NUMBITS(1) [],
725 PAD3INPEN OFFSET(25) NUMBITS(1) [],
726 PAD3STRNG OFFSET(26) NUMBITS(1) [],
727 PAD3FNCSEL OFFSET(27) NUMBITS(3) [],
728 PAD3RSEL OFFSET(30) NUMBITS(2) []
729 ],
730 CFG [
731 GPIO0INCFG OFFSET(0) NUMBITS(1) [],
732 GPIO0OUTCFG OFFSET(1) NUMBITS(2) [],
733 GPIO0INTD OFFSET(3) NUMBITS(1) [],
734 GPIO1INCFG OFFSET(4) NUMBITS(1) [],
735 GPIO1OUTCFG OFFSET(5) NUMBITS(2) [],
736 GPIO1INTD OFFSET(7) NUMBITS(1) [],
737 GPIO2INCFG OFFSET(8) NUMBITS(1) [],
738 GPIO2OUTCFG OFFSET(9) NUMBITS(2) [],
739 GPIO2INTD OFFSET(11) NUMBITS(1) [],
740 GPIO3INCFG OFFSET(12) NUMBITS(1) [],
741 GPIO3OUTCFG OFFSET(13) NUMBITS(2) [],
742 GPIO3INTD OFFSET(15) NUMBITS(1) [],
743 GPIO4INCFG OFFSET(16) NUMBITS(1) [],
744 GPIO4OUTCFG OFFSET(17) NUMBITS(2) [],
745 GPIO4INTD OFFSET(19) NUMBITS(1) [],
746 GPIO5INCFG OFFSET(20) NUMBITS(1) [],
747 GPIO5OUTCFG OFFSET(21) NUMBITS(2) [],
748 GPIO5INTD OFFSET(23) NUMBITS(1) [],
749 GPIO6INCFG OFFSET(24) NUMBITS(1) [],
750 GPIO6OUTCFG OFFSET(25) NUMBITS(2) [],
751 GPIO6INTD OFFSET(27) NUMBITS(1) [],
752 GPIO7INCFG OFFSET(28) NUMBITS(1) [],
753 GPIO7OUTCFG OFFSET(29) NUMBITS(2) [],
754 GPIO7INTD OFFSET(31) NUMBITS(1) []
755 ],
756 PADKEY [
757 PADKEY OFFSET(0) NUMBITS(31) []
758 ],
759 RDA [
760 RDA OFFSET(0) NUMBITS(31) []
761 ],
762 RDB [
763 RDB OFFSET(0) NUMBITS(17) []
764 ],
765 WTA [
766 WTA OFFSET(0) NUMBITS(31) []
767 ],
768 WTB [
769 WTB OFFSET(0) NUMBITS(17) []
770 ],
771 WTSA [
772 WTSA OFFSET(0) NUMBITS(31) []
773 ],
774 WTSB [
775 WTSB OFFSET(0) NUMBITS(17) []
776 ],
777 WTCA [
778 WTCA OFFSET(0) NUMBITS(31) []
779 ],
780 WTCB [
781 WTCB OFFSET(0) NUMBITS(17) []
782 ],
783 ENA [
784 ENA OFFSET(0) NUMBITS(31) []
785 ],
786 ENB [
787 ENB OFFSET(0) NUMBITS(17) []
788 ],
789 ENSA [
790 ENSA OFFSET(0) NUMBITS(31) []
791 ],
792 ENSB [
793 ENSB OFFSET(0) NUMBITS(17) []
794 ],
795 ENCA [
796 ENCA OFFSET(0) NUMBITS(31) []
797 ],
798 ENCB [
799 ENCB OFFSET(0) NUMBITS(17) []
800 ],
801 STMRCAP [
802 STSEL0 OFFSET(0) NUMBITS(5) [],
803 STPOL0 OFFSET(6) NUMBITS(1) [],
804 STSEL1 OFFSET(8) NUMBITS(5) [],
805 STPOL1 OFFSET(14) NUMBITS(1) [],
806 STSEL2 OFFSET(16) NUMBITS(5) [],
807 STPOL2 OFFSET(2) NUMBITS(1) [],
808 STSEL3 OFFSET(24) NUMBITS(5) [],
809 STPOL3 OFFSET(30) NUMBITS(1) []
810 ],
811 IOMIRQ [
812 IOMIRQ OFFSET(0) NUMBITS(5) []
813 ],
814 GPIOOBS [
815 OBS_DATA OFFSET(0) NUMBITS(15) []
816 ],
817 ALTPADCFG [
818 PAD0_DS1 OFFSET(0) NUMBITS(1) [],
819 PAD0_SR OFFSET(4) NUMBITS(1) [],
820 PAD1_DS1 OFFSET(8) NUMBITS(1) [],
821 PAD1_SR OFFSET(12) NUMBITS(1) [],
822 PAD2_DS1 OFFSET(16) NUMBITS(1) [],
823 PAD2_SR OFFSET(20) NUMBITS(1) [],
824 PAD3_DS1 OFFSET(24) NUMBITS(1) [],
825 PAD3_SR OFFSET(28) NUMBITS(1) []
826 ],
827 SCDET [
828 SCDET OFFSET(0) NUMBITS(5) []
829 ],
830 CTENCFG [
831 EN0 OFFSET(0) NUMBITS(1) [],
832 EN1 OFFSET(1) NUMBITS(1) [],
833 EN2 OFFSET(2) NUMBITS(1) [],
834 EN3 OFFSET(3) NUMBITS(1) [],
835 EN4 OFFSET(4) NUMBITS(1) [],
836 EN5 OFFSET(5) NUMBITS(1) [],
837 EN6 OFFSET(6) NUMBITS(1) [],
838 EN7 OFFSET(7) NUMBITS(1) [],
839 EN8 OFFSET(8) NUMBITS(1) [],
840 EN9 OFFSET(9) NUMBITS(1) [],
841 EN10 OFFSET(10) NUMBITS(1) [],
842 EN11 OFFSET(11) NUMBITS(1) [],
843 EN12 OFFSET(12) NUMBITS(1) [],
844 EN13 OFFSET(13) NUMBITS(1) [],
845 EN14 OFFSET(14) NUMBITS(1) [],
846 EN15 OFFSET(15) NUMBITS(1) [],
847 EN16 OFFSET(16) NUMBITS(1) [],
848 EN17 OFFSET(17) NUMBITS(1) [],
849 EN18 OFFSET(18) NUMBITS(1) [],
850 EN19 OFFSET(19) NUMBITS(1) [],
851 EN20 OFFSET(20) NUMBITS(1) [],
852 EN21 OFFSET(21) NUMBITS(1) [],
853 EN22 OFFSET(22) NUMBITS(1) [],
854 EN23 OFFSET(23) NUMBITS(1) [],
855 EN24 OFFSET(24) NUMBITS(1) [],
856 EN25 OFFSET(25) NUMBITS(1) [],
857 EN26 OFFSET(26) NUMBITS(1) [],
858 EN27 OFFSET(27) NUMBITS(1) [],
859 EN28 OFFSET(28) NUMBITS(1) [],
860 EN29 OFFSET(29) NUMBITS(1) [],
861 EN30 OFFSET(30) NUMBITS(1) [],
862 EN31 OFFSET(31) NUMBITS(1) []
863 ],
864 INT0 [
865 GPIO0 OFFSET(0) NUMBITS(1) [],
866 GPIO1 OFFSET(1) NUMBITS(1) [],
867 GPIO2 OFFSET(2) NUMBITS(1) [],
868 GPIO3 OFFSET(3) NUMBITS(1) [],
869 GPIO4 OFFSET(4) NUMBITS(1) [],
870 GPIO5 OFFSET(5) NUMBITS(1) [],
871 GPIO6 OFFSET(6) NUMBITS(1) [],
872 GPIO7 OFFSET(7) NUMBITS(1) [],
873 GPIO8 OFFSET(8) NUMBITS(1) [],
874 GPIO9 OFFSET(9) NUMBITS(1) [],
875 GPIO10 OFFSET(10) NUMBITS(1) [],
876 GPIO11 OFFSET(11) NUMBITS(1) [],
877 GPIO12 OFFSET(12) NUMBITS(1) [],
878 GPIO13 OFFSET(13) NUMBITS(1) [],
879 GPIO14 OFFSET(14) NUMBITS(1) [],
880 GPIO15 OFFSET(15) NUMBITS(1) [],
881 GPIO16 OFFSET(16) NUMBITS(1) [],
882 GPIO17 OFFSET(17) NUMBITS(1) [],
883 GPIO18 OFFSET(18) NUMBITS(1) [],
884 GPIO19 OFFSET(19) NUMBITS(1) [],
885 GPIO20 OFFSET(20) NUMBITS(1) [],
886 GPIO21 OFFSET(21) NUMBITS(1) [],
887 GPIO22 OFFSET(22) NUMBITS(1) [],
888 GPIO23 OFFSET(23) NUMBITS(1) [],
889 GPIO24 OFFSET(24) NUMBITS(1) [],
890 GPIO25 OFFSET(25) NUMBITS(1) [],
891 GPIO26 OFFSET(26) NUMBITS(1) [],
892 GPIO27 OFFSET(27) NUMBITS(1) [],
893 GPIO28 OFFSET(28) NUMBITS(1) [],
894 GPIO29 OFFSET(29) NUMBITS(1) [],
895 GPIO30 OFFSET(30) NUMBITS(1) [],
896 GPIO31 OFFSET(31) NUMBITS(1) []
897 ],
898 INT1 [
899 GPIO32 OFFSET(0) NUMBITS(1) [],
900 GPIO33 OFFSET(1) NUMBITS(1) [],
901 GPIO34 OFFSET(2) NUMBITS(1) [],
902 GPIO35 OFFSET(3) NUMBITS(1) [],
903 GPIO36 OFFSET(4) NUMBITS(1) [],
904 GPIO37 OFFSET(5) NUMBITS(1) [],
905 GPIO38 OFFSET(6) NUMBITS(1) [],
906 GPIO39 OFFSET(7) NUMBITS(1) [],
907 GPIO40 OFFSET(8) NUMBITS(1) [],
908 GPIO41 OFFSET(9) NUMBITS(1) [],
909 GPIO42 OFFSET(10) NUMBITS(1) [],
910 GPIO43 OFFSET(11) NUMBITS(1) [],
911 GPIO44 OFFSET(12) NUMBITS(1) [],
912 GPIO45 OFFSET(13) NUMBITS(1) [],
913 GPIO46 OFFSET(14) NUMBITS(1) [],
914 GPIO47 OFFSET(15) NUMBITS(1) [],
915 GPIO48 OFFSET(16) NUMBITS(1) [],
916 GPIO49 OFFSET(17) NUMBITS(1) []
917 ]
918];
919
920pub struct GpioPin<'a> {
921 registers: StaticRef<GpioRegisters>,
922 pin: Pin,
923 client: OptionalCell<&'a dyn gpio::Client>,
924}
925
926impl<'a> GpioPin<'a> {
927 pub const fn new(base: StaticRef<GpioRegisters>, pin: Pin) -> GpioPin<'a> {
928 GpioPin {
929 registers: base,
930 pin,
931 client: OptionalCell::empty(),
932 }
933 }
934
935 pub fn handle_interrupt(&self) {
936 self.client.map(|client| {
938 client.fired();
939 });
940 }
941}
942
943impl gpio::Configure for GpioPin<'_> {
944 fn configuration(&self) -> gpio::Configuration {
945 unimplemented!();
946 }
947
948 fn set_floating_state(&self, mode: gpio::FloatingState) {
949 self.registers.padkey.set(115);
951
952 let pagreg_offset = self.pin as usize / 4;
954 let pagreg_value = match self.pin as usize % 4 {
955 0 => PADREG::PAD0FNCSEL.val(0x3),
956 1 => PADREG::PAD1FNCSEL.val(0x3),
957 2 => PADREG::PAD2FNCSEL.val(0x3),
958 3 => PADREG::PAD3FNCSEL.val(0x3),
959 _ => unreachable!(),
960 };
961 self.registers.padreg[pagreg_offset].modify(pagreg_value);
962
963 match mode {
964 gpio::FloatingState::PullUp => {
965 let cfgreg_offset = self.pin as usize / 8;
966 let cfgreg_value = match self.pin as usize % 8 {
967 0 => CFG::GPIO0OUTCFG.val(0x1),
968 1 => CFG::GPIO1OUTCFG.val(0x1),
969 2 => CFG::GPIO2OUTCFG.val(0x1),
970 3 => CFG::GPIO3OUTCFG.val(0x1),
971 4 => CFG::GPIO4OUTCFG.val(0x1),
972 5 => CFG::GPIO5OUTCFG.val(0x1),
973 6 => CFG::GPIO6OUTCFG.val(0x1),
974 7 => CFG::GPIO7OUTCFG.val(0x1),
975 _ => unreachable!(),
976 };
977 self.registers.cfg[cfgreg_offset].modify(cfgreg_value);
978
979 let pagreg_value = match self.pin as usize % 4 {
980 0 => PADREG::PAD0PULL.val(0x1),
981 1 => PADREG::PAD1PULL.val(0x1),
982 2 => PADREG::PAD2PULL.val(0x1),
983 3 => PADREG::PAD3PULL.val(0x1),
984 _ => unreachable!(),
985 };
986 self.registers.padreg[pagreg_offset].modify(pagreg_value);
987 }
988 gpio::FloatingState::PullDown => {
989 let cfgreg_offset = self.pin as usize / 8;
990 let cfgreg_value = match self.pin as usize % 8 {
991 0 => CFG::GPIO0OUTCFG.val(0x2),
992 1 => CFG::GPIO1OUTCFG.val(0x2),
993 2 => CFG::GPIO2OUTCFG.val(0x2),
994 3 => CFG::GPIO3OUTCFG.val(0x2),
995 4 => CFG::GPIO4OUTCFG.val(0x2),
996 5 => CFG::GPIO5OUTCFG.val(0x2),
997 6 => CFG::GPIO6OUTCFG.val(0x2),
998 7 => CFG::GPIO7OUTCFG.val(0x2),
999 _ => unreachable!(),
1000 };
1001 self.registers.cfg[cfgreg_offset].modify(cfgreg_value);
1002 }
1003 gpio::FloatingState::PullNone => {
1004 let cfgreg_offset = self.pin as usize / 8;
1005 let cfgreg_value = match self.pin as usize % 8 {
1006 0 => CFG::GPIO0OUTCFG.val(0x3),
1007 1 => CFG::GPIO1OUTCFG.val(0x3),
1008 2 => CFG::GPIO2OUTCFG.val(0x3),
1009 3 => CFG::GPIO3OUTCFG.val(0x3),
1010 4 => CFG::GPIO4OUTCFG.val(0x3),
1011 5 => CFG::GPIO5OUTCFG.val(0x3),
1012 6 => CFG::GPIO6OUTCFG.val(0x3),
1013 7 => CFG::GPIO7OUTCFG.val(0x3),
1014 _ => unreachable!(),
1015 };
1016 self.registers.cfg[cfgreg_offset].modify(cfgreg_value);
1017
1018 let pagreg_value = match self.pin as usize % 4 {
1019 0 => PADREG::PAD0PULL.val(0x0),
1020 1 => PADREG::PAD1PULL.val(0x0),
1021 2 => PADREG::PAD2PULL.val(0x0),
1022 3 => PADREG::PAD3PULL.val(0x0),
1023 _ => unreachable!(),
1024 };
1025 self.registers.padreg[pagreg_offset].modify(pagreg_value);
1026 }
1027 }
1028
1029 self.registers.padkey.set(0x00);
1031 }
1032
1033 fn floating_state(&self) -> gpio::FloatingState {
1034 unimplemented!();
1035 }
1036
1037 fn deactivate_to_low_power(&self) {
1038 self.disable_input();
1039 self.disable_output();
1040 }
1041
1042 fn make_output(&self) -> gpio::Configuration {
1043 let regs = self.registers;
1044
1045 regs.padkey.set(115);
1047
1048 let pagreg_offset = self.pin as usize / 4;
1050 let pagreg_value = match self.pin as usize % 4 {
1051 0 => PADREG::PAD0FNCSEL.val(0x3),
1052 1 => PADREG::PAD1FNCSEL.val(0x3),
1053 2 => PADREG::PAD2FNCSEL.val(0x3),
1054 3 => PADREG::PAD3FNCSEL.val(0x3),
1055 _ => unreachable!(),
1056 };
1057 regs.padreg[pagreg_offset].modify(pagreg_value);
1058
1059 let cfgreg_offset = self.pin as usize / 8;
1061 let cfgreg_value = match self.pin as usize % 8 {
1062 0 => CFG::GPIO0OUTCFG.val(0x1),
1063 1 => CFG::GPIO1OUTCFG.val(0x1),
1064 2 => CFG::GPIO2OUTCFG.val(0x1),
1065 3 => CFG::GPIO3OUTCFG.val(0x1),
1066 4 => CFG::GPIO4OUTCFG.val(0x1),
1067 5 => CFG::GPIO5OUTCFG.val(0x1),
1068 6 => CFG::GPIO6OUTCFG.val(0x1),
1069 7 => CFG::GPIO7OUTCFG.val(0x1),
1070 _ => unreachable!(),
1071 };
1072 regs.cfg[cfgreg_offset].modify(cfgreg_value);
1073
1074 regs.padkey.set(0x00);
1076
1077 gpio::Configuration::Output
1078 }
1079
1080 fn disable_output(&self) -> gpio::Configuration {
1081 let regs = self.registers;
1082
1083 regs.padkey.set(115);
1085
1086 let pagreg_offset = self.pin as usize / 4;
1088 let pagreg_value = match self.pin as usize % 4 {
1089 0 => PADREG::PAD0FNCSEL.val(0x3),
1090 1 => PADREG::PAD1FNCSEL.val(0x3),
1091 2 => PADREG::PAD2FNCSEL.val(0x3),
1092 3 => PADREG::PAD3FNCSEL.val(0x3),
1093 _ => unreachable!(),
1094 };
1095 regs.padreg[pagreg_offset].modify(pagreg_value);
1096
1097 let cfgreg_offset = self.pin as usize / 8;
1099 let cfgreg_value = match self.pin as usize % 8 {
1100 0 => CFG::GPIO0OUTCFG.val(0x00),
1101 1 => CFG::GPIO1OUTCFG.val(0x00),
1102 2 => CFG::GPIO2OUTCFG.val(0x00),
1103 3 => CFG::GPIO3OUTCFG.val(0x00),
1104 4 => CFG::GPIO4OUTCFG.val(0x00),
1105 5 => CFG::GPIO5OUTCFG.val(0x00),
1106 6 => CFG::GPIO6OUTCFG.val(0x00),
1107 7 => CFG::GPIO7OUTCFG.val(0x00),
1108 _ => unreachable!(),
1109 };
1110 regs.cfg[cfgreg_offset].modify(cfgreg_value);
1111
1112 regs.padkey.set(0x00);
1114
1115 gpio::Configuration::LowPower
1116 }
1117
1118 fn make_input(&self) -> gpio::Configuration {
1119 let regs = self.registers;
1120
1121 regs.padkey.set(115);
1123
1124 let pagreg_offset = self.pin as usize / 4;
1126 let pagreg_value = match self.pin as usize % 4 {
1127 0 => PADREG::PAD0FNCSEL.val(0x3) + PADREG::PAD0INPEN.val(0x1),
1128 1 => PADREG::PAD1FNCSEL.val(0x3) + PADREG::PAD1INPEN.val(0x1),
1129 2 => PADREG::PAD2FNCSEL.val(0x3) + PADREG::PAD2INPEN.val(0x1),
1130 3 => PADREG::PAD3FNCSEL.val(0x3) + PADREG::PAD3INPEN.val(0x1),
1131 _ => unreachable!(),
1132 };
1133 regs.padreg[pagreg_offset].modify(pagreg_value);
1134
1135 regs.padkey.set(0x00);
1137
1138 gpio::Configuration::Input
1139 }
1140
1141 fn disable_input(&self) -> gpio::Configuration {
1142 let regs = self.registers;
1143
1144 regs.padkey.set(115);
1146
1147 let pagreg_offset = self.pin as usize / 4;
1149 let pagreg_value = match self.pin as usize % 4 {
1150 0 => PADREG::PAD0INPEN.val(0x0),
1151 1 => PADREG::PAD1INPEN.val(0x0),
1152 2 => PADREG::PAD2INPEN.val(0x0),
1153 3 => PADREG::PAD3INPEN.val(0x0),
1154 _ => unreachable!(),
1155 };
1156 regs.padreg[pagreg_offset].modify(pagreg_value);
1157
1158 regs.padkey.set(0x00);
1160
1161 gpio::Configuration::Output
1162 }
1163}
1164
1165impl gpio::Input for GpioPin<'_> {
1166 fn read(&self) -> bool {
1167 let regs = self.registers;
1168
1169 if (self.pin as usize) < 32 {
1170 regs.rda.get() & (1 << self.pin as usize) != 0
1171 } else {
1172 regs.rdb.get() & (1 << (self.pin as usize - 32)) != 0
1173 }
1174 }
1175}
1176
1177impl gpio::Output for GpioPin<'_> {
1178 fn toggle(&self) -> bool {
1179 let regs = self.registers;
1180 let cur_value;
1181
1182 if (self.pin as usize) < 32 {
1183 cur_value = (regs.wtsa.get() & 1 << self.pin as usize) != 0;
1184 if cur_value {
1185 regs.wta.set(1 << self.pin as usize | regs.wtsa.get());
1186 } else {
1187 regs.wta.set(0 << self.pin as usize | regs.wtsa.get());
1188 }
1189 } else {
1190 cur_value = (regs.wtsb.get() & 1 << self.pin as usize) != 0;
1191 if cur_value {
1192 regs.wtb
1193 .set(1 << (self.pin as usize - 32) | regs.wtsb.get());
1194 } else {
1195 regs.wtb
1196 .set(0 << (self.pin as usize - 32) | regs.wtsb.get());
1197 }
1198 }
1199
1200 cur_value
1201 }
1202
1203 fn set(&self) {
1204 let regs = self.registers;
1205
1206 if (self.pin as usize) < 32 {
1207 regs.wtsa.set(1 << self.pin as usize);
1208 } else {
1209 regs.wtsb.set(1 << (self.pin as usize - 32));
1210 }
1211 }
1212
1213 fn clear(&self) {
1214 let regs = self.registers;
1215
1216 if (self.pin as usize) < 32 {
1217 regs.wtca.set(1 << self.pin as usize);
1218 } else {
1219 regs.wtcb.set(1 << (self.pin as usize - 32));
1220 }
1221 }
1222}
1223
1224impl<'a> gpio::Interrupt<'a> for GpioPin<'a> {
1225 fn set_client(&self, client: &'a dyn gpio::Client) {
1226 self.client.set(client);
1227 }
1228
1229 fn enable_interrupts(&self, mode: gpio::InterruptEdge) {
1230 let regs = self.registers;
1231
1232 regs.padkey.set(115);
1234
1235 let pagreg_offset = self.pin as usize / 4;
1237 let pagreg_value = match self.pin as usize % 4 {
1238 0 => PADREG::PAD0FNCSEL.val(0x3),
1239 1 => PADREG::PAD1FNCSEL.val(0x3),
1240 2 => PADREG::PAD2FNCSEL.val(0x3),
1241 3 => PADREG::PAD2FNCSEL.val(0x3),
1242 _ => unreachable!(),
1243 };
1244 regs.padreg[pagreg_offset].modify(pagreg_value);
1245
1246 let cfgreg_offset = self.pin as usize / 8;
1248 match mode {
1249 gpio::InterruptEdge::RisingEdge => {
1250 let cfgreg_value = match self.pin as usize % 8 {
1251 0 => CFG::GPIO0INTD::CLEAR + CFG::GPIO0INCFG::CLEAR,
1252 1 => CFG::GPIO1INTD::CLEAR + CFG::GPIO1INCFG::CLEAR,
1253 2 => CFG::GPIO2INTD::CLEAR + CFG::GPIO2INCFG::CLEAR,
1254 3 => CFG::GPIO3INTD::CLEAR + CFG::GPIO3INCFG::CLEAR,
1255 4 => CFG::GPIO4INTD::CLEAR + CFG::GPIO4INCFG::CLEAR,
1256 5 => CFG::GPIO5INTD::CLEAR + CFG::GPIO5INCFG::CLEAR,
1257 6 => CFG::GPIO6INTD::CLEAR + CFG::GPIO6INCFG::CLEAR,
1258 7 => CFG::GPIO7INTD::CLEAR + CFG::GPIO7INCFG::CLEAR,
1259 _ => unreachable!(),
1260 };
1261 regs.cfg[cfgreg_offset].modify(cfgreg_value);
1262 }
1263 gpio::InterruptEdge::FallingEdge => {
1264 let cfgreg_value = match self.pin as usize % 8 {
1265 0 => CFG::GPIO0INTD::SET + CFG::GPIO0INCFG::CLEAR,
1266 1 => CFG::GPIO1INTD::SET + CFG::GPIO1INCFG::CLEAR,
1267 2 => CFG::GPIO2INTD::SET + CFG::GPIO2INCFG::CLEAR,
1268 3 => CFG::GPIO3INTD::SET + CFG::GPIO3INCFG::CLEAR,
1269 4 => CFG::GPIO4INTD::SET + CFG::GPIO4INCFG::CLEAR,
1270 5 => CFG::GPIO5INTD::SET + CFG::GPIO5INCFG::CLEAR,
1271 6 => CFG::GPIO6INTD::SET + CFG::GPIO6INCFG::CLEAR,
1272 7 => CFG::GPIO7INTD::SET + CFG::GPIO7INCFG::CLEAR,
1273 _ => unreachable!(),
1274 };
1275 regs.cfg[cfgreg_offset].modify(cfgreg_value);
1276 }
1277 gpio::InterruptEdge::EitherEdge => {
1278 let cfgreg_value = match self.pin as usize % 8 {
1279 0 => CFG::GPIO0INTD::SET + CFG::GPIO0INCFG::SET,
1280 1 => CFG::GPIO1INTD::SET + CFG::GPIO1INCFG::SET,
1281 2 => CFG::GPIO2INTD::SET + CFG::GPIO2INCFG::SET,
1282 3 => CFG::GPIO3INTD::SET + CFG::GPIO3INCFG::SET,
1283 4 => CFG::GPIO4INTD::SET + CFG::GPIO4INCFG::SET,
1284 5 => CFG::GPIO5INTD::SET + CFG::GPIO5INCFG::SET,
1285 6 => CFG::GPIO6INTD::SET + CFG::GPIO6INCFG::SET,
1286 7 => CFG::GPIO7INTD::SET + CFG::GPIO7INCFG::SET,
1287 _ => unreachable!(),
1288 };
1289 regs.cfg[cfgreg_offset].modify(cfgreg_value);
1290 }
1291 }
1292
1293 if (self.pin as usize) < 32 {
1295 regs.int0en.set(1 << self.pin as usize | regs.int0en.get());
1296 } else {
1297 regs.int1en
1298 .set(1 << (self.pin as usize - 32) | regs.int1en.get());
1299 }
1300
1301 regs.padkey.set(0x00);
1303 }
1304
1305 fn disable_interrupts(&self) {
1306 let regs = self.registers;
1307
1308 if (self.pin as usize) < 32 {
1310 regs.int0en
1311 .set(!(1 << self.pin as usize) & regs.int0en.get());
1312 } else {
1313 regs.int1en
1314 .set(!(1 << (self.pin as usize - 32)) & regs.int1en.get());
1315 }
1316
1317 if (self.pin as usize) < 32 {
1319 regs.int0clr.set(1 << self.pin as usize);
1320 } else {
1321 regs.int1clr.set(1 << (self.pin as usize - 32));
1322 }
1323 }
1324
1325 fn is_pending(&self) -> bool {
1326 let regs = self.registers;
1327
1328 regs.int0stat.get() | regs.int1stat.get() != 0
1329 }
1330}