1use core::marker::PhantomData;
7
8use rcc::AHB1;
9
10pub trait GpioExt {
12 type Parts;
14
15 fn split(self, ahb: &mut AHB1) -> Self::Parts;
17}
18
19pub struct Input<MODE> {
21 _mode: PhantomData<MODE>,
22}
23
24pub struct Floating;
26pub struct PullDown;
28pub struct PullUp;
30
31pub struct Output<MODE> {
33 _mode: PhantomData<MODE>,
34}
35
36pub struct PushPull;
38pub struct OpenDrain;
40
41pub struct AF0;
43
44pub struct AF1;
46
47pub struct AF2;
49
50pub struct AF3;
52
53pub struct AF4;
55
56pub struct AF5;
58
59pub struct AF6;
61
62pub struct AF7;
64
65pub struct AF8;
67
68pub struct AF9;
70
71pub struct AF10;
73
74pub struct AF11;
76
77pub struct AF12;
79
80pub struct AF13;
82
83pub struct AF14;
85
86pub struct AF15;
88
89macro_rules! gpio {
90 ($GPIOX:ident, $gpiox:ident, $gpioy:ident, $iopxenr:ident, $iopxrst:ident, $PXx:ident, [
91 $($PXi:ident: ($pxi:ident, $i:expr, $MODE:ty, $AFR:ident),)+
92 ]) => {
93 pub mod $gpiox {
95 use core::marker::PhantomData;
96
97 use hal::digital::{InputPin, OutputPin};
98 use stm32f429::{$gpioy, $GPIOX};
99
100 use rcc::AHB1;
101 use super::{
102 AF4, AF5, AF6, AF7, Floating, GpioExt, Input, OpenDrain, Output,
103 PullDown, PullUp, PushPull,
104 };
105
106 pub struct Parts {
108 pub afrh: AFRH,
110 pub afrl: AFRL,
112 pub moder: MODER,
114 pub otyper: OTYPER,
116 pub pupdr: PUPDR,
118 $(
119 pub $pxi: $PXi<$MODE>,
121 )+
122 }
123
124 impl GpioExt for $GPIOX {
125 type Parts = Parts;
126
127 fn split(self, ahb: &mut AHB1) -> Parts {
128 ahb.enr().modify(|_, w| w.$iopxenr().set_bit());
129 ahb.rstr().modify(|_, w| w.$iopxrst().set_bit());
130 ahb.rstr().modify(|_, w| w.$iopxrst().clear_bit());
131
132 Parts {
133 afrh: AFRH { _0: () },
134 afrl: AFRL { _0: () },
135 moder: MODER { _0: () },
136 otyper: OTYPER { _0: () },
137 pupdr: PUPDR { _0: () },
138 $(
139 $pxi: $PXi { _mode: PhantomData },
140 )+
141 }
142 }
143 }
144
145 pub struct AFRL {
147 _0: (),
148 }
149
150 impl AFRL {
151 pub(crate) fn afr(&mut self) -> &$gpioy::AFRL {
152 unsafe { &(*$GPIOX::ptr()).afrl }
153 }
154 }
155
156 pub struct AFRH {
158 _0: (),
159 }
160
161 impl AFRH {
162 pub(crate) fn afr(&mut self) -> &$gpioy::AFRH {
163 unsafe { &(*$GPIOX::ptr()).afrh }
164 }
165 }
166
167 pub struct MODER {
169 _0: (),
170 }
171
172 impl MODER {
173 pub(crate) fn moder(&mut self) -> &$gpioy::MODER {
174 unsafe { &(*$GPIOX::ptr()).moder }
175 }
176 }
177
178 pub struct OTYPER {
180 _0: (),
181 }
182
183 impl OTYPER {
184 pub(crate) fn otyper(&mut self) -> &$gpioy::OTYPER {
185 unsafe { &(*$GPIOX::ptr()).otyper }
186 }
187 }
188
189 pub struct PUPDR {
191 _0: (),
192 }
193
194 impl PUPDR {
195 pub(crate) fn pupdr(&mut self) -> &$gpioy::PUPDR {
196 unsafe { &(*$GPIOX::ptr()).pupdr }
197 }
198 }
199
200 pub struct $PXx<MODE> {
202 i: u8,
203 _mode: PhantomData<MODE>,
204 }
205
206 impl<MODE> InputPin for $PXx<Input<MODE>> {
207 fn is_high(&self) -> bool {
208 !self.is_low()
209 }
210
211 fn is_low(&self) -> bool {
212 unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << self.i) == 0 }
214 }
215 }
216
217 impl<MODE> OutputPin for $PXx<Output<MODE>> {
218 fn set_high(&mut self) {
219 unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << self.i)) }
221 }
222
223 fn set_low(&mut self) {
224 unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + self.i))) }
226 }
227 }
228
229 $(
230 pub struct $PXi<MODE> {
232 _mode: PhantomData<MODE>,
233 }
234
235 impl<MODE> $PXi<MODE> {
236 pub fn into_af4(
238 self,
239 moder: &mut MODER,
240 afr: &mut $AFR,
241 ) -> $PXi<AF4> {
242 let offset = 2 * $i;
243
244 let mode = 0b10;
246 moder.moder().modify(|r, w| unsafe {
247 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
248 });
249
250 let af = 4;
251 let offset = 4 * ($i % 8);
252 afr.afr().modify(|r, w| unsafe {
253 w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
254 });
255
256 $PXi { _mode: PhantomData }
257 }
258
259 pub fn into_af5(
261 self,
262 moder: &mut MODER,
263 afr: &mut $AFR,
264 ) -> $PXi<AF5> {
265 let offset = 2 * $i;
266
267 let mode = 0b10;
269 moder.moder().modify(|r, w| unsafe {
270 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
271 });
272
273 let af = 5;
274 let offset = 4 * ($i % 8);
275 afr.afr().modify(|r, w| unsafe {
276 w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
277 });
278
279 $PXi { _mode: PhantomData }
280 }
281
282 pub fn into_af6(
284 self,
285 moder: &mut MODER,
286 afr: &mut $AFR,
287 ) -> $PXi<AF6> {
288 let offset = 2 * $i;
289
290 let mode = 0b10;
292 moder.moder().modify(|r, w| unsafe {
293 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
294 });
295
296 let af = 6;
297 let offset = 4 * ($i % 8);
298 afr.afr().modify(|r, w| unsafe {
299 w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
300 });
301
302 $PXi { _mode: PhantomData }
303 }
304
305 pub fn into_af7(
307 self,
308 moder: &mut MODER,
309 afr: &mut $AFR,
310 ) -> $PXi<AF7> {
311 let offset = 2 * $i;
312
313 let mode = 0b10;
315 moder.moder().modify(|r, w| unsafe {
316 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
317 });
318
319 let af = 7;
320 let offset = 4 * ($i % 8);
321
322 afr.afr().modify(|r, w| unsafe {
323 w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
324 });
325
326 $PXi { _mode: PhantomData }
327 }
328
329 pub fn into_floating_input(
331 self,
332 moder: &mut MODER,
333 pupdr: &mut PUPDR,
334 ) -> $PXi<Input<Floating>> {
335 let offset = 2 * $i;
336
337 moder
339 .moder()
340 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
341
342 pupdr
344 .pupdr()
345 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
346
347 $PXi { _mode: PhantomData }
348 }
349
350 pub fn into_pull_down_input(
352 self,
353 moder: &mut MODER,
354 pupdr: &mut PUPDR,
355 ) -> $PXi<Input<PullDown>> {
356 let offset = 2 * $i;
357
358 moder
360 .moder()
361 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
362
363 pupdr.pupdr().modify(|r, w| unsafe {
365 w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset))
366 });
367
368 $PXi { _mode: PhantomData }
369 }
370
371 pub fn into_pull_up_input(
373 self,
374 moder: &mut MODER,
375 pupdr: &mut PUPDR,
376 ) -> $PXi<Input<PullUp>> {
377 let offset = 2 * $i;
378
379 moder
381 .moder()
382 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
383
384 pupdr.pupdr().modify(|r, w| unsafe {
386 w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
387 });
388
389 $PXi { _mode: PhantomData }
390 }
391
392 pub fn into_open_drain_output(
394 self,
395 moder: &mut MODER,
396 otyper: &mut OTYPER,
397 ) -> $PXi<Output<OpenDrain>> {
398 let offset = 2 * $i;
399
400 let mode = 0b01;
402 moder.moder().modify(|r, w| unsafe {
403 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
404 });
405
406 otyper
408 .otyper()
409 .modify(|r, w| unsafe { w.bits(r.bits() | (0b1 << $i)) });
410
411 $PXi { _mode: PhantomData }
412 }
413
414 pub fn into_push_pull_output(
416 self,
417 moder: &mut MODER,
418 otyper: &mut OTYPER,
419 ) -> $PXi<Output<PushPull>> {
420 let offset = 2 * $i;
421
422 let mode = 0b01;
424 moder.moder().modify(|r, w| unsafe {
425 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
426 });
427
428 otyper
430 .otyper()
431 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b1 << $i)) });
432
433 $PXi { _mode: PhantomData }
434 }
435 }
436
437 impl $PXi<Output<OpenDrain>> {
438 pub fn internal_pull_up(&mut self, pupdr: &mut PUPDR, on: bool) {
440 let offset = 2 * $i;
441
442 pupdr.pupdr().modify(|r, w| unsafe {
443 w.bits(
444 (r.bits() & !(0b11 << offset)) | if on {
445 0b01 << offset
446 } else {
447 0
448 },
449 )
450 });
451 }
452 }
453
454 impl<MODE> $PXi<Output<MODE>> {
455 pub fn downgrade(self) -> $PXx<Output<MODE>> {
460 $PXx {
461 i: $i,
462 _mode: self._mode,
463 }
464 }
465 }
466
467 impl<MODE> InputPin for $PXi<Input<MODE>> {
468 fn is_high(&self) -> bool {
469 !self.is_low()
470 }
471
472 fn is_low(&self) -> bool {
473 unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 }
475 }
476 }
477
478 impl<MODE> OutputPin for $PXi<Output<MODE>> {
479 fn set_high(&mut self) {
480 unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) }
482 }
483
484 fn set_low(&mut self) {
485 unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) }
487 }
488 }
489 )+
490 }
491 }
492}
493
494gpio!(GPIOA, gpioa, gpioa, gpioaen, gpioarst, PAx, [
495 PA0: (pa0, 0, Input<Floating>, AFRL),
496 PA1: (pa1, 1, Input<Floating>, AFRL),
497 PA2: (pa2, 2, Input<Floating>, AFRL),
498 PA3: (pa3, 3, Input<Floating>, AFRL),
499 PA4: (pa4, 4, Input<Floating>, AFRL),
500 PA5: (pa5, 5, Input<Floating>, AFRL),
501 PA6: (pa6, 6, Input<Floating>, AFRL),
502 PA7: (pa7, 7, Input<Floating>, AFRL),
503 PA8: (pa8, 8, Input<Floating>, AFRH),
504 PA9: (pa9, 9, Input<Floating>, AFRH),
505 PA10: (pa10, 10, Input<Floating>, AFRH),
506 PA11: (pa11, 11, Input<Floating>, AFRH),
507 PA12: (pa12, 12, Input<Floating>, AFRH),
508 ]);
513
514gpio!(GPIOB, gpiob, gpiob, gpioben, gpiobrst, PBx, [
515 PB0: (pb0, 0, Input<Floating>, AFRL),
516 PB1: (pb1, 1, Input<Floating>, AFRL),
517 PB2: (pb2, 2, Input<Floating>, AFRL),
518 PB5: (pb5, 5, Input<Floating>, AFRL),
522 PB6: (pb6, 6, Input<Floating>, AFRL),
523 PB7: (pb7, 7, Input<Floating>, AFRL),
524 PB8: (pb8, 8, Input<Floating>, AFRH),
525 PB9: (pb9, 9, Input<Floating>, AFRH),
526 PB10: (pb10, 10, Input<Floating>, AFRH),
527 PB11: (pb11, 11, Input<Floating>, AFRH),
528 PB12: (pb12, 12, Input<Floating>, AFRH),
529 PB13: (pb13, 13, Input<Floating>, AFRH),
530 PB14: (pb14, 14, Input<Floating>, AFRH),
531 PB15: (pb15, 15, Input<Floating>, AFRH),
532]);
533
534gpio!(GPIOC, gpioc, gpiok, gpiocen, gpiocrst, PCx, [
535 PC0: (pc0, 0, Input<Floating>, AFRL),
536 PC1: (pc1, 1, Input<Floating>, AFRL),
537 PC2: (pc2, 2, Input<Floating>, AFRL),
538 PC3: (pc3, 3, Input<Floating>, AFRL),
539 PC4: (pc4, 4, Input<Floating>, AFRL),
540 PC5: (pc5, 5, Input<Floating>, AFRL),
541 PC6: (pc6, 6, Input<Floating>, AFRL),
542 PC7: (pc7, 7, Input<Floating>, AFRL),
543 PC8: (pc8, 8, Input<Floating>, AFRH),
544 PC9: (pc9, 9, Input<Floating>, AFRH),
545 PC10: (pc10, 10, Input<Floating>, AFRH),
546 PC11: (pc11, 11, Input<Floating>, AFRH),
547 PC12: (pc12, 12, Input<Floating>, AFRH),
548 PC13: (pc13, 13, Input<Floating>, AFRH),
549 PC14: (pc14, 14, Input<Floating>, AFRH),
550 PC15: (pc15, 15, Input<Floating>, AFRH),
551]);
552
553gpio!(GPIOD, gpiod, gpiok, gpioden, gpiodrst, PDx, [
554 PD0: (pd0, 0, Input<Floating>, AFRL),
555 PD1: (pd1, 1, Input<Floating>, AFRL),
556 PD2: (pd2, 2, Input<Floating>, AFRL),
557 PD3: (pd3, 3, Input<Floating>, AFRL),
558 PD4: (pd4, 4, Input<Floating>, AFRL),
559 PD5: (pd5, 5, Input<Floating>, AFRL),
560 PD6: (pd6, 6, Input<Floating>, AFRL),
561 PD7: (pd7, 7, Input<Floating>, AFRL),
562 PD8: (pd8, 8, Input<Floating>, AFRH),
563 PD9: (pd9, 9, Input<Floating>, AFRH),
564 PD10: (pd10, 10, Input<Floating>, AFRH),
565 PD11: (pd11, 11, Input<Floating>, AFRH),
566 PD12: (pd12, 12, Input<Floating>, AFRH),
567 PD13: (pd13, 13, Input<Floating>, AFRH),
568 PD14: (pd14, 14, Input<Floating>, AFRH),
569 PD15: (pd15, 15, Input<Floating>, AFRH),
570]);
571
572gpio!(GPIOE, gpioe, gpiok, gpioeen, gpioerst, PEx, [
573 PE0: (pe0, 0, Input<Floating>, AFRL),
574 PE1: (pe1, 1, Input<Floating>, AFRL),
575 PE2: (pe2, 2, Input<Floating>, AFRL),
576 PE3: (pe3, 3, Input<Floating>, AFRL),
577 PE4: (pe4, 4, Input<Floating>, AFRL),
578 PE5: (pe5, 5, Input<Floating>, AFRL),
579 PE6: (pe6, 6, Input<Floating>, AFRL),
580 PE7: (pe7, 7, Input<Floating>, AFRL),
581 PE8: (pe8, 8, Input<Floating>, AFRH),
582 PE9: (pe9, 9, Input<Floating>, AFRH),
583 PE10: (pe10, 10, Input<Floating>, AFRH),
584 PE11: (pe11, 11, Input<Floating>, AFRH),
585 PE12: (pe12, 12, Input<Floating>, AFRH),
586 PE13: (pe13, 13, Input<Floating>, AFRH),
587 PE14: (pe14, 14, Input<Floating>, AFRH),
588 PE15: (pe15, 15, Input<Floating>, AFRH),
589]);
590
591gpio!(GPIOF, gpiof, gpiok, gpiofen, gpiofrst, PFx, [
592 PF0: (pf0, 0, Input<Floating>, AFRL),
593 PF1: (pf1, 1, Input<Floating>, AFRL),
594 PF2: (pf2, 2, Input<Floating>, AFRL),
595 PF3: (pf3, 3, Input<Floating>, AFRL),
596 PF4: (pf4, 4, Input<Floating>, AFRL),
597 PF5: (pf5, 5, Input<Floating>, AFRL),
598 PF6: (pf6, 6, Input<Floating>, AFRL),
599 PF7: (pf7, 7, Input<Floating>, AFRL),
600 PF8: (pf8, 8, Input<Floating>, AFRL),
601 PF9: (pf9, 9, Input<Floating>, AFRH),
602 PF10: (pf10, 10, Input<Floating>, AFRH),
603 PF11: (pf11, 11, Input<Floating>, AFRH),
604 PF12: (pf12, 12, Input<Floating>, AFRH),
605 PF13: (pf13, 13, Input<Floating>, AFRH),
606 PF14: (pf14, 14, Input<Floating>, AFRH),
607 PF15: (pf15, 15, Input<Floating>, AFRH),
608]);
609
610gpio!(GPIOG, gpiog, gpiok, gpiogen, gpiogrst, PGx, [
611 PG0: (pg0, 0, Input<Floating>, AFRL),
612 PG1: (pg1, 1, Input<Floating>, AFRL),
613 PG2: (pg2, 2, Input<Floating>, AFRL),
614 PG3: (pg3, 3, Input<Floating>, AFRL),
615 PG4: (pg4, 4, Input<Floating>, AFRL),
616 PG5: (pg5, 5, Input<Floating>, AFRL),
617 PG6: (pg6, 6, Input<Floating>, AFRL),
618 PG7: (pg7, 7, Input<Floating>, AFRL),
619 PG8: (pg8, 8, Input<Floating>, AFRL),
620 PG9: (pg9, 9, Input<Floating>, AFRH),
621 PG10: (pg10, 10, Input<Floating>, AFRH),
622 PG11: (pg11, 11, Input<Floating>, AFRH),
623 PG12: (pg12, 12, Input<Floating>, AFRH),
624 PG13: (pg13, 13, Input<Floating>, AFRH),
625 PG14: (pg14, 14, Input<Floating>, AFRH),
626 PG15: (pg15, 15, Input<Floating>, AFRH),
627]);
628
629gpio!(GPIOH, gpioh, gpiok, gpiohen, gpiohrst, PHx, [
630 PH0: (ph0, 0, Input<Floating>, AFRL),
631 PH1: (ph1, 1, Input<Floating>, AFRL),
632 PH2: (ph2, 2, Input<Floating>, AFRL),
633 PH3: (ph3, 3, Input<Floating>, AFRL),
634 PH4: (ph4, 4, Input<Floating>, AFRL),
635 PH5: (ph5, 5, Input<Floating>, AFRL),
636 PH6: (ph6, 6, Input<Floating>, AFRL),
637 PH7: (ph7, 7, Input<Floating>, AFRL),
638 PH8: (ph8, 8, Input<Floating>, AFRL),
639 PH9: (ph9, 9, Input<Floating>, AFRH),
640 PH10: (ph10, 10, Input<Floating>, AFRH),
641 PH11: (ph11, 11, Input<Floating>, AFRH),
642 PH12: (ph12, 12, Input<Floating>, AFRH),
643 PH13: (ph13, 13, Input<Floating>, AFRH),
644 PH14: (ph14, 14, Input<Floating>, AFRH),
645 PH15: (ph15, 15, Input<Floating>, AFRH),
646]);
647
648gpio!(GPIOI, gpioi, gpiok, gpioien, gpioirst, PIx, [
649 PI0: (pi0, 0, Input<Floating>, AFRL),
650 PI1: (pi1, 1, Input<Floating>, AFRL),
651 PI2: (pi2, 2, Input<Floating>, AFRL),
652 PI3: (pi3, 3, Input<Floating>, AFRL),
653 PI4: (pi4, 4, Input<Floating>, AFRL),
654 PI5: (pi5, 5, Input<Floating>, AFRL),
655 PI6: (pi6, 6, Input<Floating>, AFRL),
656 PI7: (pi7, 7, Input<Floating>, AFRL),
657 PI8: (pi8, 8, Input<Floating>, AFRL),
658 PI9: (pi9, 9, Input<Floating>, AFRH),
659 PI10: (pi10, 10, Input<Floating>, AFRH),
660 PI11: (pi11, 11, Input<Floating>, AFRH),
661 PI12: (pi12, 12, Input<Floating>, AFRH),
662 PI13: (pi13, 13, Input<Floating>, AFRH),
663 PI14: (pi14, 14, Input<Floating>, AFRH),
664 PI15: (pi15, 15, Input<Floating>, AFRH),
665]);
666
667