1use core::marker::PhantomData;
7
8use rcc::AHB;
9
10pub trait GpioExt {
12 type Parts;
14
15 fn split(self, ahb: &mut AHB) -> 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::OutputPin;
98 use stm32f30x::{$gpioy, $GPIOX};
99
100 use rcc::AHB;
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 AHB) -> Parts {
128 ahb.enr().modify(|_, w| w.$iopxenr().enabled());
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> OutputPin for $PXx<Output<MODE>> {
207 fn set_high(&mut self) {
208 unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << self.i)) }
210 }
211
212 fn set_low(&mut self) {
213 unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + self.i))) }
215 }
216 }
217
218 $(
219 pub struct $PXi<MODE> {
221 _mode: PhantomData<MODE>,
222 }
223
224 impl<MODE> $PXi<MODE> {
225 pub fn into_af4(
227 self,
228 moder: &mut MODER,
229 afr: &mut $AFR,
230 ) -> $PXi<AF4> {
231 let offset = 2 * $i;
232
233 let mode = 0b10;
235 moder.moder().modify(|r, w| unsafe {
236 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
237 });
238
239 let af = 4;
240 let offset = 4 * ($i % 8);
241 afr.afr().modify(|r, w| unsafe {
242 w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
243 });
244
245 $PXi { _mode: PhantomData }
246 }
247
248 pub fn into_af5(
250 self,
251 moder: &mut MODER,
252 afr: &mut $AFR,
253 ) -> $PXi<AF5> {
254 let offset = 2 * $i;
255
256 let mode = 0b10;
258 moder.moder().modify(|r, w| unsafe {
259 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
260 });
261
262 let af = 5;
263 let offset = 4 * ($i % 8);
264 afr.afr().modify(|r, w| unsafe {
265 w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
266 });
267
268 $PXi { _mode: PhantomData }
269 }
270
271 pub fn into_af6(
273 self,
274 moder: &mut MODER,
275 afr: &mut $AFR,
276 ) -> $PXi<AF6> {
277 let offset = 2 * $i;
278
279 let mode = 0b10;
281 moder.moder().modify(|r, w| unsafe {
282 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
283 });
284
285 let af = 6;
286 let offset = 4 * ($i % 8);
287 afr.afr().modify(|r, w| unsafe {
288 w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
289 });
290
291 $PXi { _mode: PhantomData }
292 }
293
294 pub fn into_af7(
296 self,
297 moder: &mut MODER,
298 afr: &mut $AFR,
299 ) -> $PXi<AF7> {
300 let offset = 2 * $i;
301
302 let mode = 0b10;
304 moder.moder().modify(|r, w| unsafe {
305 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
306 });
307
308 let af = 7;
309 let offset = 4 * ($i % 8);
310
311 afr.afr().modify(|r, w| unsafe {
312 w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
313 });
314
315 $PXi { _mode: PhantomData }
316 }
317
318 pub fn into_floating_input(
320 self,
321 moder: &mut MODER,
322 pupdr: &mut PUPDR,
323 ) -> $PXi<Input<Floating>> {
324 let offset = 2 * $i;
325
326 moder
328 .moder()
329 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
330
331 pupdr
333 .pupdr()
334 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
335
336 $PXi { _mode: PhantomData }
337 }
338
339 pub fn into_pull_down_input(
341 self,
342 moder: &mut MODER,
343 pupdr: &mut PUPDR,
344 ) -> $PXi<Input<PullDown>> {
345 let offset = 2 * $i;
346
347 moder
349 .moder()
350 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
351
352 pupdr.pupdr().modify(|r, w| unsafe {
354 w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset))
355 });
356
357 $PXi { _mode: PhantomData }
358 }
359
360 pub fn into_pull_up_input(
362 self,
363 moder: &mut MODER,
364 pupdr: &mut PUPDR,
365 ) -> $PXi<Input<PullUp>> {
366 let offset = 2 * $i;
367
368 moder
370 .moder()
371 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
372
373 pupdr.pupdr().modify(|r, w| unsafe {
375 w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
376 });
377
378 $PXi { _mode: PhantomData }
379 }
380
381 pub fn into_open_drain_output(
383 self,
384 moder: &mut MODER,
385 otyper: &mut OTYPER,
386 ) -> $PXi<Output<OpenDrain>> {
387 let offset = 2 * $i;
388
389 let mode = 0b01;
391 moder.moder().modify(|r, w| unsafe {
392 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
393 });
394
395 otyper
397 .otyper()
398 .modify(|r, w| unsafe { w.bits(r.bits() | (0b1 << $i)) });
399
400 $PXi { _mode: PhantomData }
401 }
402
403 pub fn into_push_pull_output(
405 self,
406 moder: &mut MODER,
407 otyper: &mut OTYPER,
408 ) -> $PXi<Output<PushPull>> {
409 let offset = 2 * $i;
410
411 let mode = 0b01;
413 moder.moder().modify(|r, w| unsafe {
414 w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
415 });
416
417 otyper
419 .otyper()
420 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b1 << $i)) });
421
422 $PXi { _mode: PhantomData }
423 }
424 }
425
426 impl $PXi<Output<OpenDrain>> {
427 pub fn internal_pull_up(&mut self, pupdr: &mut PUPDR, on: bool) {
429 let offset = 2 * $i;
430
431 pupdr.pupdr().modify(|r, w| unsafe {
432 w.bits(
433 (r.bits() & !(0b11 << offset)) | if on {
434 0b01 << offset
435 } else {
436 0
437 },
438 )
439 });
440 }
441 }
442
443 impl<MODE> $PXi<Output<MODE>> {
444 pub fn downgrade(self) -> $PXx<Output<MODE>> {
449 $PXx {
450 i: $i,
451 _mode: self._mode,
452 }
453 }
454 }
455
456 impl<MODE> OutputPin for $PXi<Output<MODE>> {
457 fn set_high(&mut self) {
458 unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) }
460 }
461
462 fn set_low(&mut self) {
463 unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) }
465 }
466 }
467 )+
468 }
469 }
470}
471
472gpio!(GPIOA, gpioa, gpioa, iopaen, ioparst, PAx, [
473 PA0: (pa0, 0, Input<Floating>, AFRL),
474 PA1: (pa1, 1, Input<Floating>, AFRL),
475 PA2: (pa2, 2, Input<Floating>, AFRL),
476 PA3: (pa3, 3, Input<Floating>, AFRL),
477 PA4: (pa4, 4, Input<Floating>, AFRL),
478 PA5: (pa5, 5, Input<Floating>, AFRL),
479 PA6: (pa6, 6, Input<Floating>, AFRL),
480 PA7: (pa7, 7, Input<Floating>, AFRL),
481 PA8: (pa8, 8, Input<Floating>, AFRH),
482 PA9: (pa9, 9, Input<Floating>, AFRH),
483 PA10: (pa10, 10, Input<Floating>, AFRH),
484 PA11: (pa11, 11, Input<Floating>, AFRH),
485 PA12: (pa12, 12, Input<Floating>, AFRH),
486 ]);
491
492gpio!(GPIOB, gpiob, gpiob, iopben, iopbrst, PBx, [
493 PB0: (pb0, 0, Input<Floating>, AFRL),
494 PB1: (pb1, 1, Input<Floating>, AFRL),
495 PB2: (pb2, 2, Input<Floating>, AFRL),
496 PB5: (pb5, 5, Input<Floating>, AFRL),
500 PB6: (pb6, 6, Input<Floating>, AFRL),
501 PB7: (pb7, 7, Input<Floating>, AFRL),
502 PB8: (pb8, 8, Input<Floating>, AFRH),
503 PB9: (pb9, 9, Input<Floating>, AFRH),
504 PB10: (pb10, 10, Input<Floating>, AFRH),
505 PB11: (pb11, 11, Input<Floating>, AFRH),
506 PB12: (pb12, 12, Input<Floating>, AFRH),
507 PB13: (pb13, 13, Input<Floating>, AFRH),
508 PB14: (pb14, 14, Input<Floating>, AFRH),
509 PB15: (pb15, 15, Input<Floating>, AFRH),
510]);
511
512gpio!(GPIOC, gpioc, gpioc, iopcen, iopcrst, PCx, [
513 PC0: (pc0, 0, Input<Floating>, AFRL),
514 PC1: (pc1, 1, Input<Floating>, AFRL),
515 PC2: (pc2, 2, Input<Floating>, AFRL),
516 PC3: (pc3, 3, Input<Floating>, AFRL),
517 PC4: (pc4, 4, Input<Floating>, AFRL),
518 PC5: (pc5, 5, Input<Floating>, AFRL),
519 PC6: (pc6, 6, Input<Floating>, AFRL),
520 PC7: (pc7, 7, Input<Floating>, AFRL),
521 PC8: (pc8, 8, Input<Floating>, AFRH),
522 PC9: (pc9, 9, Input<Floating>, AFRH),
523 PC10: (pc10, 10, Input<Floating>, AFRH),
524 PC11: (pc11, 11, Input<Floating>, AFRH),
525 PC12: (pc12, 12, Input<Floating>, AFRH),
526 PC13: (pc13, 13, Input<Floating>, AFRH),
527 PC14: (pc14, 14, Input<Floating>, AFRH),
528 PC15: (pc15, 15, Input<Floating>, AFRH),
529]);
530
531gpio!(GPIOD, gpiod, gpioc, iopden, iopdrst, PDx, [
532 PD0: (pd0, 0, Input<Floating>, AFRL),
533 PD1: (pd1, 1, Input<Floating>, AFRL),
534 PD2: (pd2, 2, Input<Floating>, AFRL),
535 PD3: (pd3, 3, Input<Floating>, AFRL),
536 PD4: (pd4, 4, Input<Floating>, AFRL),
537 PD5: (pd5, 5, Input<Floating>, AFRL),
538 PD6: (pd6, 6, Input<Floating>, AFRL),
539 PD7: (pd7, 7, Input<Floating>, AFRL),
540 PD8: (pd8, 8, Input<Floating>, AFRH),
541 PD9: (pd9, 9, Input<Floating>, AFRH),
542 PD10: (pd10, 10, Input<Floating>, AFRH),
543 PD11: (pd11, 11, Input<Floating>, AFRH),
544 PD12: (pd12, 12, Input<Floating>, AFRH),
545 PD13: (pd13, 13, Input<Floating>, AFRH),
546 PD14: (pd14, 14, Input<Floating>, AFRH),
547 PD15: (pd15, 15, Input<Floating>, AFRH),
548]);
549
550gpio!(GPIOE, gpioe, gpioc, iopeen, ioperst, PEx, [
551 PE0: (pe0, 0, Input<Floating>, AFRL),
552 PE1: (pe1, 1, Input<Floating>, AFRL),
553 PE2: (pe2, 2, Input<Floating>, AFRL),
554 PE3: (pe3, 3, Input<Floating>, AFRL),
555 PE4: (pe4, 4, Input<Floating>, AFRL),
556 PE5: (pe5, 5, Input<Floating>, AFRL),
557 PE6: (pe6, 6, Input<Floating>, AFRL),
558 PE7: (pe7, 7, Input<Floating>, AFRL),
559 PE8: (pe8, 8, Input<Floating>, AFRH),
560 PE9: (pe9, 9, Input<Floating>, AFRH),
561 PE10: (pe10, 10, Input<Floating>, AFRH),
562 PE11: (pe11, 11, Input<Floating>, AFRH),
563 PE12: (pe12, 12, Input<Floating>, AFRH),
564 PE13: (pe13, 13, Input<Floating>, AFRH),
565 PE14: (pe14, 14, Input<Floating>, AFRH),
566 PE15: (pe15, 15, Input<Floating>, AFRH),
567]);
568
569gpio!(GPIOF, gpiof, gpioc, iopfen, iopfrst, PFx, [
570 PF0: (pf0, 0, Input<Floating>, AFRL),
571 PF1: (pf1, 1, Input<Floating>, AFRL),
572 PF2: (pf2, 2, Input<Floating>, AFRL),
573 PF4: (pf3, 4, Input<Floating>, AFRL),
574 PF6: (pf6, 6, Input<Floating>, AFRL),
575 PF9: (pf9, 9, Input<Floating>, AFRH),
576 PF10: (pf10, 10, Input<Floating>, AFRH),
577]);