1use core::convert::Infallible;
4use core::marker::PhantomData;
5
6use crate::rcc::Rcc;
7
8pub trait GpioExt {
10 type Parts;
12
13 fn split(self, rcc: &mut Rcc) -> Self::Parts;
15}
16
17trait GpioRegExt {
18 fn is_low(&self, pos: u8) -> bool;
19 fn is_set_low(&self, pos: u8) -> bool;
20 fn set_high(&self, pos: u8);
21 fn set_low(&self, pos: u8);
22}
23
24pub struct AF0;
26pub struct AF1;
28pub struct AF2;
30pub struct AF3;
32pub struct AF4;
34pub struct AF5;
36pub struct AF6;
38pub struct AF7;
40
41pub struct Alternate<AF> {
43 _mode: PhantomData<AF>,
44}
45
46pub struct Input<MODE> {
48 _mode: PhantomData<MODE>,
49}
50
51pub struct Floating;
53
54pub struct PullDown;
56
57pub struct PullUp;
59
60pub struct OpenDrain;
62
63pub struct Analog;
65
66pub struct Output<MODE> {
68 _mode: PhantomData<MODE>,
69}
70
71pub struct PushPull;
73
74use embedded_hal::digital::v2::{toggleable, InputPin, OutputPin, StatefulOutputPin};
75
76pub struct Pin<MODE> {
78 i: u8,
79 port: *const dyn GpioRegExt,
80 _mode: PhantomData<MODE>,
81}
82
83unsafe impl<MODE> Sync for Pin<MODE> {}
85unsafe impl<MODE> Send for Pin<MODE> {}
88
89impl<MODE> StatefulOutputPin for Pin<Output<MODE>> {
90 #[inline(always)]
91 fn is_set_high(&self) -> Result<bool, Self::Error> {
92 self.is_set_low().map(|v| !v)
93 }
94
95 #[inline(always)]
96 fn is_set_low(&self) -> Result<bool, Self::Error> {
97 Ok(unsafe { (*self.port).is_set_low(self.i) })
98 }
99}
100
101impl<MODE> OutputPin for Pin<Output<MODE>> {
102 type Error = Infallible;
103
104 #[inline(always)]
105 fn set_high(&mut self) -> Result<(), Self::Error> {
106 unsafe { (*self.port).set_high(self.i) };
107 Ok(())
108 }
109
110 #[inline(always)]
111 fn set_low(&mut self) -> Result<(), Self::Error> {
112 unsafe { (*self.port).set_low(self.i) }
113 Ok(())
114 }
115}
116
117impl<MODE> toggleable::Default for Pin<Output<MODE>> {}
118
119impl InputPin for Pin<Output<OpenDrain>> {
120 type Error = Infallible;
121
122 #[inline(always)]
123 fn is_high(&self) -> Result<bool, Self::Error> {
124 self.is_low().map(|v| !v)
125 }
126
127 #[inline(always)]
128 fn is_low(&self) -> Result<bool, Self::Error> {
129 Ok(unsafe { (*self.port).is_low(self.i) })
130 }
131}
132
133impl<MODE> InputPin for Pin<Input<MODE>> {
134 type Error = Infallible;
135
136 #[inline(always)]
137 fn is_high(&self) -> Result<bool, Self::Error> {
138 self.is_low().map(|v| !v)
139 }
140
141 #[inline(always)]
142 fn is_low(&self) -> Result<bool, Self::Error> {
143 Ok(unsafe { (*self.port).is_low(self.i) })
144 }
145}
146
147macro_rules! gpio_trait {
148 ($gpiox:ident) => {
149 impl GpioRegExt for crate::pac::$gpiox::RegisterBlock {
150 fn is_low(&self, pos: u8) -> bool {
151 self.idr.read().bits() & (1 << pos) == 0
153 }
154
155 fn is_set_low(&self, pos: u8) -> bool {
156 self.odr.read().bits() & (1 << pos) == 0
158 }
159
160 fn set_high(&self, pos: u8) {
161 unsafe { self.bsrr.write(|w| w.bits(1 << pos)) }
163 }
164
165 fn set_low(&self, pos: u8) {
166 unsafe { self.bsrr.write(|w| w.bits(1 << (pos + 16))) }
168 }
169 }
170 };
171}
172
173gpio_trait!(gpioa);
174gpio_trait!(gpiof);
175
176macro_rules! gpio {
177 ([$($GPIOX:ident, $gpiox:ident, $iopxenr:ident, $PXx:ident, $gate:meta => [
178 $($PXi:ident: ($pxi:ident, $i:expr, $MODE:ty),)+
179 ]),+]) => {
180 $(
181 #[cfg($gate)]
183 pub mod $gpiox {
184 use core::marker::PhantomData;
185 use core::convert::Infallible;
186
187 use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, toggleable};
188 use crate::{
189 rcc::Rcc,
190 pac::$GPIOX
191 };
192
193 use cortex_m::interrupt::CriticalSection;
194
195 use super::{
196 Alternate, Analog, Floating, GpioExt, Input, OpenDrain, Output,
197 PullDown, PullUp, PushPull, AF0, AF1, AF2, AF3, AF4, AF5, AF6, AF7,
198 Pin, GpioRegExt,
199 };
200
201 pub struct Parts {
203 $(
204 pub $pxi: $PXi<$MODE>,
206 )+
207 }
208
209 impl GpioExt for $GPIOX {
210 type Parts = Parts;
211
212 fn split(self, rcc: &mut Rcc) -> Parts {
213 rcc.regs.ahbenr.modify(|_, w| w.$iopxenr().set_bit());
214
215 Parts {
216 $(
217 $pxi: $PXi { _mode: PhantomData },
218 )+
219 }
220 }
221 }
222
223 fn _set_alternate_mode (index:usize, mode: u32)
224 {
225 let offset = 2 * index;
226 let offset2 = 4 * index;
227 unsafe {
228 let reg = &(*$GPIOX::ptr());
229 if offset2 < 32 {
230 reg.afrl.modify(|r, w| {
231 w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2))
232 });
233 } else {
234 let offset2 = offset2 - 32;
235 reg.afrh.modify(|r, w| {
236 w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2))
237 });
238 }
239 reg.moder.modify(|r, w| {
240 w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset))
241 });
242 }
243 }
244
245 $(
246 pub struct $PXi<MODE> {
248 _mode: PhantomData<MODE>,
249 }
250
251 impl<MODE> $PXi<MODE> {
252 pub fn into_alternate_af0(
254 self, _cs: &CriticalSection
255 ) -> $PXi<Alternate<AF0>> {
256 _set_alternate_mode($i, 0);
257 $PXi { _mode: PhantomData }
258 }
259
260 pub fn into_alternate_af1(
262 self, _cs: &CriticalSection
263 ) -> $PXi<Alternate<AF1>> {
264 _set_alternate_mode($i, 1);
265 $PXi { _mode: PhantomData }
266 }
267
268 pub fn into_alternate_af2(
270 self, _cs: &CriticalSection
271 ) -> $PXi<Alternate<AF2>> {
272 _set_alternate_mode($i, 2);
273 $PXi { _mode: PhantomData }
274 }
275
276 pub fn into_alternate_af3(
278 self, _cs: &CriticalSection
279 ) -> $PXi<Alternate<AF3>> {
280 _set_alternate_mode($i, 3);
281 $PXi { _mode: PhantomData }
282 }
283
284 pub fn into_alternate_af4(
286 self, _cs: &CriticalSection
287 ) -> $PXi<Alternate<AF4>> {
288 _set_alternate_mode($i, 4);
289 $PXi { _mode: PhantomData }
290 }
291
292 pub fn into_alternate_af5(
294 self, _cs: &CriticalSection
295 ) -> $PXi<Alternate<AF5>> {
296 _set_alternate_mode($i, 5);
297 $PXi { _mode: PhantomData }
298 }
299
300 pub fn into_alternate_af6(
302 self, _cs: &CriticalSection
303 ) -> $PXi<Alternate<AF6>> {
304 _set_alternate_mode($i, 6);
305 $PXi { _mode: PhantomData }
306 }
307
308 pub fn into_alternate_af7(
310 self, _cs: &CriticalSection
311 ) -> $PXi<Alternate<AF7>> {
312 _set_alternate_mode($i, 7);
313 $PXi { _mode: PhantomData }
314 }
315
316 pub fn into_floating_input(
318 self, _cs: &CriticalSection
319 ) -> $PXi<Input<Floating>> {
320 let offset = 2 * $i;
321 unsafe {
322 let reg = &(*$GPIOX::ptr());
323 reg.pupdr.modify(|r, w| {
324 w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
325 });
326 reg.moder.modify(|r, w| {
327 w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
328 });
329 }
330 $PXi { _mode: PhantomData }
331 }
332
333 pub fn into_pull_down_input(
335 self, _cs: &CriticalSection
336 ) -> $PXi<Input<PullDown>> {
337 let offset = 2 * $i;
338 unsafe {
339 let reg = &(*$GPIOX::ptr());
340 reg.pupdr.modify(|r, w| {
341 w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset))
342 });
343 reg.moder.modify(|r, w| {
344 w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
345 });
346 }
347 $PXi { _mode: PhantomData }
348 }
349
350 pub fn into_pull_up_input(
352 self, _cs: &CriticalSection
353 ) -> $PXi<Input<PullUp>> {
354 let offset = 2 * $i;
355 unsafe {
356 let reg = &(*$GPIOX::ptr());
357 reg.pupdr.modify(|r, w| {
358 w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
359 });
360 reg.moder.modify(|r, w| {
361 w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
362 });
363 }
364 $PXi { _mode: PhantomData }
365 }
366
367 pub fn into_analog(
369 self, _cs: &CriticalSection
370 ) -> $PXi<Analog> {
371 let offset = 2 * $i;
372 unsafe {
373 let reg = &(*$GPIOX::ptr());
374 reg.pupdr.modify(|r, w| {
375 w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
376 });
377 reg.moder.modify(|r, w| {
378 w.bits((r.bits() & !(0b11 << offset)) | (0b11 << offset))
379 });
380 }
381 $PXi { _mode: PhantomData }
382 }
383
384 pub fn into_open_drain_output(
386 self, _cs: &CriticalSection
387 ) -> $PXi<Output<OpenDrain>> {
388 let offset = 2 * $i;
389 unsafe {
390 let reg = &(*$GPIOX::ptr());
391 reg.pupdr.modify(|r, w| {
392 w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
393 });
394 reg.otyper.modify(|r, w| {
395 w.bits(r.bits() | (0b1 << $i))
396 });
397 reg.moder.modify(|r, w| {
398 w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
399 });
400 }
401 $PXi { _mode: PhantomData }
402 }
403
404 pub fn into_push_pull_output(
406 self, _cs: &CriticalSection
407 ) -> $PXi<Output<PushPull>> {
408 let offset = 2 * $i;
409 unsafe {
410 let reg = &(*$GPIOX::ptr());
411 reg.pupdr.modify(|r, w| {
412 w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
413 });
414 reg.otyper.modify(|r, w| {
415 w.bits(r.bits() & !(0b1 << $i))
416 });
417 reg.moder.modify(|r, w| {
418 w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
419 });
420 }
421 $PXi { _mode: PhantomData }
422 }
423
424 pub fn into_push_pull_output_hs(
427 self, _cs: &CriticalSection
428 ) -> $PXi<Output<PushPull>> {
429 let offset = 2 * $i;
430 unsafe {
431 let reg = &(*$GPIOX::ptr());
432 reg.pupdr.modify(|r, w| {
433 w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
434 });
435 reg.otyper.modify(|r, w| {
436 w.bits(r.bits() & !(0b1 << $i))
437 });
438 reg.ospeedr.modify(|r, w| {
439 w.bits(r.bits() & !(0b1 << $i))
440 });
441 reg.moder.modify(|r, w| {
442 w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
443 });
444 }
445 $PXi { _mode: PhantomData }
446 }
447 }
448
449 impl $PXi<Output<OpenDrain>> {
450 pub fn internal_pull_up(&mut self, _cs: &CriticalSection, on: bool) {
452 let offset = 2 * $i;
453 let value = if on { 0b01 } else { 0b00 };
454 unsafe {
455 let reg = &(*$GPIOX::ptr());
456 reg.pupdr.modify(|r, w| {
457 w.bits((r.bits() & !(0b11 << offset)) | (value << offset))
458 });
459 }
460 }
461 }
462
463 impl<AF> $PXi<Alternate<AF>> {
464 pub fn internal_pull_up(self, _cs: &CriticalSection, on: bool) -> Self {
466 let offset = 2 * $i;
467 let value = if on { 0b01 } else { 0b00 };
468 unsafe {
469 let reg = &(*$GPIOX::ptr());
470 reg.pupdr.modify(|r, w| {
471 w.bits((r.bits() & !(0b11 << offset)) | (value << offset))
472 });
473 }
474 self
475 }
476 }
477
478 impl<AF> $PXi<Alternate<AF>> {
479 pub fn set_open_drain(self, _cs: &CriticalSection) -> Self {
481 let offset = $i;
482 unsafe {
483 let reg = &(*$GPIOX::ptr());
484 reg.otyper.modify(|r, w| {
485 w.bits(r.bits() | (1 << offset))
486 });
487 }
488 self
489 }
490 }
491
492 impl<MODE> $PXi<Output<MODE>> {
493 pub fn downgrade(self) -> Pin<Output<MODE>> {
498 Pin {
499 i: $i,
500 port: $GPIOX::ptr() as *const dyn GpioRegExt,
501 _mode: self._mode,
502 }
503 }
504 }
505
506 impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
507 fn is_set_high(&self) -> Result<bool, Self::Error> {
508 self.is_set_low().map(|v| !v)
509 }
510
511 fn is_set_low(&self) -> Result<bool, Self::Error> {
512 Ok(unsafe { (*$GPIOX::ptr()).is_set_low($i) })
513 }
514 }
515
516 impl<MODE> OutputPin for $PXi<Output<MODE>> {
517 type Error = Infallible;
518
519 fn set_high(&mut self) -> Result<(), Self::Error> {
520 Ok(unsafe { (*$GPIOX::ptr()).set_high($i) })
521 }
522
523 fn set_low(&mut self) -> Result<(), Self::Error> {
524 Ok(unsafe { (*$GPIOX::ptr()).set_low($i) })
525 }
526 }
527
528 impl<MODE> toggleable::Default for $PXi<Output<MODE>> {}
529
530 impl InputPin for $PXi<Output<OpenDrain>> {
531 type Error = Infallible;
532
533 fn is_high(&self) -> Result<bool, Self::Error> {
534 self.is_low().map(|v| !v)
535 }
536
537 fn is_low(&self) -> Result<bool, Self::Error> {
538 Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
539 }
540 }
541
542 impl<MODE> $PXi<Input<MODE>> {
543 pub fn downgrade(self) -> Pin<Input<MODE>> {
548 Pin {
549 i: $i,
550 port: $GPIOX::ptr() as *const dyn GpioRegExt,
551 _mode: self._mode,
552 }
553 }
554 }
555
556 impl<MODE> InputPin for $PXi<Input<MODE>> {
557 type Error = Infallible;
558
559 fn is_high(&self) -> Result<bool, Self::Error> {
560 self.is_low().map(|v| !v)
561 }
562
563 fn is_low(&self) -> Result<bool, Self::Error> {
564 Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
565 }
566 }
567 )+
568 }
569 )+
570 }
571}
572
573gpio!([
574 GPIOA, gpioa, iopaen, PA, any(
575 feature = "device-selected"
576 ) => [
577 PA0: (pa0, 0, Input<Floating>),
578 PA1: (pa1, 1, Input<Floating>),
579 PA2: (pa2, 2, Input<Floating>),
580 PA3: (pa3, 3, Input<Floating>),
581 PA4: (pa4, 4, Input<Floating>),
582 PA5: (pa5, 5, Input<Floating>),
583 PA6: (pa6, 6, Input<Floating>),
584 PA7: (pa7, 7, Input<Floating>),
585 PA8: (pa8, 8, Input<Floating>),
586 PA9: (pa9, 9, Input<Floating>),
587 PA10: (pa10, 10, Input<Floating>),
588 PA11: (pa11, 11, Input<Floating>),
589 PA12: (pa12, 12, Input<Floating>),
590 PA13: (pa13, 13, Input<Floating>),
591 PA14: (pa14, 14, Input<Floating>),
592 PA15: (pa15, 15, Input<Floating>),
593 ],
594 GPIOB, gpiob, iopben, PB, any(
595 feature = "device-selected"
596 ) => [
597 PB0: (pb0, 0, Input<Floating>),
598 PB1: (pb1, 1, Input<Floating>),
599 PB2: (pb2, 2, Input<Floating>),
600 PB3: (pb3, 3, Input<Floating>),
601 PB4: (pb4, 4, Input<Floating>),
602 PB5: (pb5, 5, Input<Floating>),
603 PB6: (pb6, 6, Input<Floating>),
604 PB7: (pb7, 7, Input<Floating>),
605 PB8: (pb8, 8, Input<Floating>),
606 PB9: (pb9, 9, Input<Floating>),
607 PB10: (pb10, 10, Input<Floating>),
608 PB11: (pb11, 11, Input<Floating>),
609 PB12: (pb12, 12, Input<Floating>),
610 PB13: (pb13, 13, Input<Floating>),
611 PB14: (pb14, 14, Input<Floating>),
612 PB15: (pb15, 15, Input<Floating>),
613 ],
614 GPIOC, gpioc, iopcen, PC, any(
615 feature = "stm32f031",
616 feature = "stm32f038",
617 feature = "stm32f042",
618 feature = "stm32f048"
619 ) => [
620 PC13: (pc13, 13, Input<Floating>),
621 PC14: (pc14, 14, Input<Floating>),
622 PC15: (pc15, 15, Input<Floating>),
623 ],
624 GPIOC, gpioc, iopcen, PC, any(
625 feature = "stm32f030",
626 feature = "stm32f051",
627 feature = "stm32f058",
628 feature = "stm32f070",
629 feature = "stm32f071",
630 feature = "stm32f072",
631 feature = "stm32f078",
632 feature = "stm32f091",
633 feature = "stm32f098"
634 ) => [
635 PC0: (pc0, 0, Input<Floating>),
636 PC1: (pc1, 1, Input<Floating>),
637 PC2: (pc2, 2, Input<Floating>),
638 PC3: (pc3, 3, Input<Floating>),
639 PC4: (pc4, 4, Input<Floating>),
640 PC5: (pc5, 5, Input<Floating>),
641 PC6: (pc6, 6, Input<Floating>),
642 PC7: (pc7, 7, Input<Floating>),
643 PC8: (pc8, 8, Input<Floating>),
644 PC9: (pc9, 9, Input<Floating>),
645 PC10: (pc10, 10, Input<Floating>),
646 PC11: (pc11, 11, Input<Floating>),
647 PC12: (pc12, 12, Input<Floating>),
648 PC13: (pc13, 13, Input<Floating>),
649 PC14: (pc14, 14, Input<Floating>),
650 PC15: (pc15, 15, Input<Floating>),
651 ],
652 GPIOD, gpiod, iopden, PD, any(
653 feature = "stm32f030",
654 feature = "stm32f051",
655 feature = "stm32f058",
656 feature = "stm32f070"
657 ) => [
658 PD2: (pd2, 2, Input<Floating>),
659 ],
660 GPIOD, gpiod, iopden, PD, any(
661 feature = "stm32f071",
662 feature = "stm32f072",
663 feature = "stm32f078",
664 feature = "stm32f091",
665 feature = "stm32f098"
666 ) => [
667 PD0: (pd0, 0, Input<Floating>),
668 PD1: (pd1, 1, Input<Floating>),
669 PD2: (pd2, 2, Input<Floating>),
670 PD3: (pd3, 3, Input<Floating>),
671 PD4: (pd4, 4, Input<Floating>),
672 PD5: (pd5, 5, Input<Floating>),
673 PD6: (pd6, 6, Input<Floating>),
674 PD7: (pd7, 7, Input<Floating>),
675 PD8: (pd8, 8, Input<Floating>),
676 PD9: (pd9, 9, Input<Floating>),
677 PD10: (pd10, 10, Input<Floating>),
678 PD11: (pd11, 11, Input<Floating>),
679 PD12: (pd12, 12, Input<Floating>),
680 PD13: (pd13, 13, Input<Floating>),
681 PD14: (pd14, 14, Input<Floating>),
682 PD15: (pd15, 15, Input<Floating>),
683 ],
684 GPIOE, gpioe, iopeen, PE, any(
685 feature = "stm32f071",
686 feature = "stm32f072",
687 feature = "stm32f078",
688 feature = "stm32f091",
689 feature = "stm32f098"
690 ) => [
691 PE0: (pe0, 0, Input<Floating>),
692 PE1: (pe1, 1, Input<Floating>),
693 PE2: (pe2, 2, Input<Floating>),
694 PE3: (pe3, 3, Input<Floating>),
695 PE4: (pe4, 4, Input<Floating>),
696 PE5: (pe5, 5, Input<Floating>),
697 PE6: (pe6, 6, Input<Floating>),
698 PE7: (pe7, 7, Input<Floating>),
699 PE8: (pe8, 8, Input<Floating>),
700 PE9: (pe9, 9, Input<Floating>),
701 PE10: (pe10, 10, Input<Floating>),
702 PE11: (pe11, 11, Input<Floating>),
703 PE12: (pe12, 12, Input<Floating>),
704 PE13: (pe13, 13, Input<Floating>),
705 PE14: (pe14, 14, Input<Floating>),
706 PE15: (pe15, 15, Input<Floating>),
707 ],
708 GPIOF, gpiof, iopfen, PF, any(
709 feature = "stm32f030x4",
710 feature = "stm32f030x6",
711 feature = "stm32f030x8",
712 feature = "stm32f051",
713 feature = "stm32f058",
714 ) => [
715 PF0: (pf0, 0, Input<Floating>),
716 PF1: (pf1, 1, Input<Floating>),
717 PF4: (pf4, 4, Input<Floating>),
718 PF5: (pf5, 5, Input<Floating>),
719 PF6: (pf6, 6, Input<Floating>),
720 PF7: (pf7, 7, Input<Floating>),
721 ],
722 GPIOF, gpiof, iopfen, PF, any(
723 feature = "stm32f030xc",
724 feature = "stm32f070"
725 ) => [
726 PF0: (pf0, 0, Input<Floating>),
727 PF1: (pf1, 1, Input<Floating>),
728 ],
729 GPIOF, gpiof, iopfen, PF, any(
730 feature = "stm32f031",
731 feature = "stm32f038"
732 ) => [
733 PF0: (pf0, 0, Input<Floating>),
734 PF1: (pf1, 1, Input<Floating>),
735 PF6: (pf6, 6, Input<Floating>),
736 PF7: (pf7, 7, Input<Floating>),
737 ],
738 GPIOF, gpiof, iopfen, PF, any(
739 feature = "stm32f042",
740 feature = "stm32f048"
741 ) => [
742 PF0: (pf0, 0, Input<Floating>),
743 PF1: (pf1, 1, Input<Floating>),
744 PF11: (pf11, 11, Input<Floating>),
745 ],
746 GPIOF, gpiof, iopfen, PF, any(
747 feature = "stm32f071",
748 feature = "stm32f072",
749 feature = "stm32f078",
750 feature = "stm32f091",
751 feature = "stm32f098",
752 ) => [
753 PF0: (pf0, 0, Input<Floating>),
754 PF1: (pf1, 1, Input<Floating>),
755 PF2: (pf2, 2, Input<Floating>),
756 PF3: (pf3, 3, Input<Floating>),
757 PF6: (pf6, 6, Input<Floating>),
758 PF9: (pf9, 9, Input<Floating>),
759 PF10: (pf10, 10, Input<Floating>),
760 ]
761 ]);