1use core::marker::PhantomData;
3
4use crate::pac;
5
6pub trait GlbExt {
8 fn split(self) -> Parts;
10}
11
12#[derive(Copy, Clone)]
13pub enum Event {
14 NegativePulse = 0,
16 PositivePulse = 1,
18 NegativeLevel = 2,
20 HighLevel = 3,
22}
23
24pub trait InterruptPin {
26 fn trigger_on_event(&mut self, event: Event);
29 fn control_asynchronous(&mut self);
30 fn control_synchronous(&mut self);
31 fn enable_interrupt(&mut self);
32 fn disable_interrupt(&mut self);
33 fn clear_interrupt_pending_bit(&mut self);
34 fn check_interrupt(&self) -> bool;
35}
36
37pub use uart_sig::*;
38
39pub mod uart_sig {
41 use core::marker::PhantomData;
42
43 use crate::pac;
44
45 pub struct Uart0Rts;
47
48 pub struct Uart0Cts;
50
51 pub struct Uart0Tx;
53
54 pub struct Uart0Rx;
56
57 pub struct Uart1Rx;
59
60 pub struct Uart1Rts;
62
63 pub struct Uart1Cts;
65
66 pub struct Uart1Tx;
68
69 macro_rules! impl_uart_sig {
70 ($UartSigi: ident, $doc1: expr, $sigi:ident, $UartMuxi: ident, $doc2: expr) => {
71 #[doc = $doc1]
72 pub struct $UartSigi;
73
74 #[doc = $doc2]
75 pub struct $UartMuxi<MODE> {
76 pub(crate) _mode: PhantomData<MODE>,
77 }
78
79 impl<MODE> $UartMuxi<MODE> {
80 pub fn into_uart0_rts(self) -> $UartMuxi<Uart0Rts> {
82 self.into_uart_mode(0)
83 }
84
85 pub fn into_uart0_cts(self) -> $UartMuxi<Uart0Cts> {
87 self.into_uart_mode(1)
88 }
89
90 pub fn into_uart0_tx(self) -> $UartMuxi<Uart0Tx> {
92 self.into_uart_mode(2)
93 }
94
95 pub fn into_uart0_rx(self) -> $UartMuxi<Uart0Rx> {
97 self.into_uart_mode(3)
98 }
99
100 pub fn into_uart1_rts(self) -> $UartMuxi<Uart1Rts> {
102 self.into_uart_mode(4)
103 }
104
105 pub fn into_uart1_cts(self) -> $UartMuxi<Uart1Cts> {
107 self.into_uart_mode(5)
108 }
109
110 pub fn into_uart1_tx(self) -> $UartMuxi<Uart1Tx> {
112 self.into_uart_mode(6)
113 }
114
115 pub fn into_uart1_rx(self) -> $UartMuxi<Uart1Rx> {
117 self.into_uart_mode(7)
118 }
119
120 paste::paste! {
121 #[inline]
122 fn into_uart_mode<T>(self, mode: u8) -> $UartMuxi<T> {
123 let glb = unsafe { &*pac::GLB::ptr() };
124
125 glb.uart_sig_sel_0.modify(|_r, w| unsafe { w
126 .[<uart_ $sigi _sel>]().bits(mode)
127 });
128
129 $UartMuxi { _mode: PhantomData }
130 }
131 }
132 }
133 };
134 }
135
136 impl_uart_sig!(
137 UartSig0,
138 "UART signal 0 (type state)",
139 sig_0,
140 UartMux0,
141 "UART multiplexer peripherals for signal 0"
142 );
143
144 impl_uart_sig!(
145 UartSig1,
146 "UART signal 1 (type state)",
147 sig_1,
148 UartMux1,
149 "UART multiplexer peripherals for signal 1"
150 );
151
152 impl_uart_sig!(
153 UartSig2,
154 "UART signal 2 (type state)",
155 sig_2,
156 UartMux2,
157 "UART multiplexer peripherals for signal 2"
158 );
159
160 impl_uart_sig!(
161 UartSig3,
162 "UART signal 3 (type state)",
163 sig_3,
164 UartMux3,
165 "UART multiplexer peripherals for signal 3"
166 );
167
168 impl_uart_sig!(
169 UartSig4,
170 "UART signal 4 (type state)",
171 sig_4,
172 UartMux4,
173 "UART multiplexer peripherals for signal 4"
174 );
175
176 impl_uart_sig!(
177 UartSig5,
178 "UART signal 5 (type state)",
179 sig_5,
180 UartMux5,
181 "UART multiplexer peripherals for signal 5"
182 );
183
184 impl_uart_sig!(
185 UartSig6,
186 "UART signal 6 (type state)",
187 sig_6,
188 UartMux6,
189 "UART multiplexer peripherals for signal 6"
190 );
191
192 impl_uart_sig!(
193 UartSig7,
194 "UART signal 7 (type state)",
195 sig_7,
196 UartMux7,
197 "UART multiplexer peripherals for signal 7"
198 );
199}
200
201pub struct ClkCfg {
203 pub(crate) _ownership: (),
204}
205
206pub struct Floating;
215pub struct PullDown;
217pub struct PullUp;
219
220pub struct Input<MODE> {
222 _mode: PhantomData<MODE>,
223}
224
225pub struct Output<MODE> {
227 _mode: PhantomData<MODE>,
228}
229
230pub struct Uart;
232
233pub struct Spi;
235
236pub struct I2c;
238
239#[doc(hidden)]
240pub trait UartPin<SIG> {}
241
242pub use self::pin::*;
245
246macro_rules! impl_glb {
247 ($($Pini: ident: ($pini: ident, $gpio_cfgctli: ident, $UartSigi: ident, $sigi: ident, $spi_kind: ident, $i2c_kind: ident, $gpio_i: ident, $gpio_int_mode_seti: ident, $pin_id: literal) ,)+) => {
248 impl GlbExt for pac::GLB {
249 fn split(self) -> Parts {
250 Parts {
251 $( $pini: $Pini { _mode: PhantomData }, )+
252 uart_mux0: UartMux0 { _mode: PhantomData },
253 uart_mux1: UartMux1 { _mode: PhantomData },
254 uart_mux2: UartMux2 { _mode: PhantomData },
255 uart_mux3: UartMux3 { _mode: PhantomData },
256 uart_mux4: UartMux4 { _mode: PhantomData },
257 uart_mux5: UartMux5 { _mode: PhantomData },
258 uart_mux6: UartMux6 { _mode: PhantomData },
259 uart_mux7: UartMux7 { _mode: PhantomData },
260 clk_cfg: ClkCfg { _ownership: () },
261 }
262 }
263 }
264
265 pub struct Parts {
267 $( pub $pini: $Pini<Input<Floating>>, )+
268 pub uart_mux0: UartMux0<Uart0Cts>,
269 pub uart_mux1: UartMux1<Uart0Cts>,
270 pub uart_mux2: UartMux2<Uart0Cts>,
271 pub uart_mux3: UartMux3<Uart0Cts>,
272 pub uart_mux4: UartMux4<Uart0Cts>,
273 pub uart_mux5: UartMux5<Uart0Cts>,
274 pub uart_mux6: UartMux6<Uart0Cts>,
275 pub uart_mux7: UartMux7<Uart0Cts>,
276 pub clk_cfg: ClkCfg,
277 }
278
279 pub mod pin {
281 use core::marker::PhantomData;
282 use core::convert::Infallible;
283 use embedded_hal::digital::blocking::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
284 use embedded_hal_zero::digital::v2::{
285 InputPin as InputPinZero,
286 OutputPin as OutputPinZero,
287 StatefulOutputPin as StatefulOutputPinZero,
288 ToggleableOutputPin as ToggleableOutputPinZero
289 };
290 use crate::pac;
291 use super::*;
292
293 trait InternalInputPinImpl {
295 fn is_high_inner(&self) -> bool;
296 fn is_low_inner(&self) -> bool;
297 }
298
299 trait InternalOutputPinImp {
301 fn set_high_inner(&self);
302 fn set_low_inner(&self);
303 }
304
305 trait InternalStatefulOutputImp {
307 fn is_output_high_inner(&self) -> bool;
308 fn is_output_low_inner(&self) -> bool;
309 }
310
311 $(
312 pub struct $Pini<MODE> {
314 pub(crate) _mode: PhantomData<MODE>,
315 }
316
317 impl<MODE> $Pini<MODE> {
318 pub fn into_floating_output(self) -> $Pini<Output<Floating>> {
321 self.into_pin_with_mode(11, false, false, false)
322 }
323
324 pub fn into_pull_up_output(self) -> $Pini<Output<PullUp>> {
326 self.into_pin_with_mode(11, true, false, false)
327 }
328
329 pub fn into_pull_down_output(self) -> $Pini<Output<PullDown>> {
331 self.into_pin_with_mode(11, false, true, false)
332 }
333
334 pub fn into_floating_input(self) -> $Pini<Input<Floating>> {
336 self.into_pin_with_mode(11, false, false, true)
337 }
338
339 pub fn into_pull_up_input(self) -> $Pini<Input<PullUp>> {
341 self.into_pin_with_mode(11, true, false, true)
342 }
343
344 pub fn into_pull_down_input(self) -> $Pini<Input<PullDown>> {
346 self.into_pin_with_mode(11, false, true, true)
347 }
348
349 paste::paste! {
350 #[inline]
351 fn into_pin_with_mode<T>(self, mode: u8, pu: bool, pd: bool, ie: bool) -> $Pini<T> {
352 let glb = unsafe { &*pac::GLB::ptr() };
353
354 glb.$gpio_cfgctli.modify(|_r, w| unsafe { w
355 .[<reg_ $gpio_i _func_sel>]().bits(mode)
356 .[<reg_ $gpio_i _ie>]().bit(ie) .[<reg_ $gpio_i _pu>]().bit(pu)
358 .[<reg_ $gpio_i _pd>]().bit(pd)
359 .[<reg_ $gpio_i _drv>]().bits(0) .[<reg_ $gpio_i _smt>]().clear_bit()
361 });
362
363 glb.gpio_cfgctl34.modify(|_, w| w.[<reg_ $gpio_i _oe>]().bit(!ie));
365
366 $Pini { _mode: PhantomData }
367 }
368 }
369 }
370
371 impl<MODE> $Pini<Input<MODE>> {
372 paste::paste! {
373 pub fn enable_smitter(&mut self) {
375 let glb = unsafe { &*pac::GLB::ptr() };
376
377 glb.$gpio_cfgctli.modify(|_, w| w.[<reg_ $gpio_i _smt>]().set_bit());
378 }
379
380 pub fn disable_smitter(&mut self) {
382 let glb = unsafe { &*pac::GLB::ptr() };
383
384 glb.$gpio_cfgctli.modify(|_, w| w.[<reg_ $gpio_i _smt>]().clear_bit());
385 }
386 }
387 }
388
389 impl<MODE> $Pini<MODE> {
390 paste::paste! {
391 pub fn [<into_uart_ $sigi>](self) -> $Pini<Uart> {
393 self.into_pin_with_mode(7, true, false, true)
395 }
396
397 pub fn [<into_spi_ $spi_kind>](self) -> $Pini<Spi> {
399 self.into_pin_with_mode(4, true, false, true)
401 }
402
403 pub fn [<into_i2c_ $i2c_kind>](self) -> $Pini<I2c> {
405 self.into_pin_with_mode(6, true, false, true)
407 }
408 }
409 }
410
411 impl UartPin<$UartSigi> for $Pini<Uart> {}
412
413 impl<MODE> InternalInputPinImpl for $Pini<Input<MODE>> {
414 paste::paste! {
415 fn is_high_inner(&self) -> bool {
416 let glb = unsafe { &*pac::GLB::ptr() };
417 glb.gpio_cfgctl30.read().[<reg_ $gpio_i _i>]().bit_is_set()
418 }
419 }
420 paste::paste! {
421 fn is_low_inner(&self) -> bool {
422 let glb = unsafe { &*pac::GLB::ptr() };
423 glb.gpio_cfgctl30.read().[<reg_ $gpio_i _i>]().bit_is_clear()
424 }
425 }
426 }
427
428 impl<MODE> InternalOutputPinImp for $Pini<Output<MODE>> {
429 paste::paste! {
430 fn set_high_inner(&self) {
431 let glb = unsafe { &*pac::GLB::ptr() };
432 glb.gpio_cfgctl32.modify(|_, w| w.[<reg_ $gpio_i _o>]().set_bit())
433 }
434 }
435 paste::paste! {
436 fn set_low_inner(&self) {
437 let glb = unsafe { &*pac::GLB::ptr() };
438 glb.gpio_cfgctl32.modify(|_, w| w.[<reg_ $gpio_i _o>]().clear_bit())
439 }
440 }
441 }
442
443 impl<MODE> InternalStatefulOutputImp for $Pini<Output<MODE>> {
444 paste::paste! {
445 fn is_output_high_inner(&self) -> bool {
446 let glb = unsafe { &*pac::GLB::ptr() };
447 glb.gpio_cfgctl32.read().[<reg_ $gpio_i _o>]().bit_is_set()
448 }
449
450 fn is_output_low_inner(& self) -> bool {
451 let glb = unsafe { &*pac::GLB::ptr() };
452 glb.gpio_cfgctl32.read().[<reg_ $gpio_i _o>]().bit_is_clear()
453 }
454 }
455 }
456
457
458 impl<MODE> InputPin for $Pini<Input<MODE>> {
459 type Error = Infallible;
460
461 fn is_high(&self) -> Result<bool, Self::Error> {
462 Ok(self.is_high_inner())
463 }
464
465 fn is_low(&self) -> Result<bool, Self::Error> {
466 Ok(self.is_low_inner())
467 }
468 }
469
470 impl<MODE> InputPinZero for $Pini<Input<MODE>> {
471 type Error = Infallible;
472
473 fn is_high(&self) -> Result<bool, Self::Error> {
474 Ok(self.is_high_inner())
475 }
476
477 fn is_low(&self) -> Result<bool, Self::Error> {
478 Ok(self.is_low_inner())
479 }
480 }
481
482 impl<MODE> InterruptPin for $Pini<Input<MODE>> {
483
484 paste::paste! {
485 fn trigger_on_event(&mut self, event: Event) {
486 let glb = unsafe { &*pac::GLB::ptr() };
487 let pin_id = $pin_id % 10;
489 let offset = pin_id * 3;
491 let event = (0b11 & event as u32) << offset;
493 glb.$gpio_int_mode_seti.modify(|r,w| {
495 let mask = 0b11 << offset;
497 let prev = r.bits() & ! mask;
498 unsafe {w.bits(prev | event)}
499 });
500 }
501
502 fn control_asynchronous(&mut self) {
503 let glb = unsafe { &*pac::GLB::ptr() };
504 let pin_id = $pin_id % 10;
505 let offset = pin_id * 3;
506 glb.$gpio_int_mode_seti.modify(|r,w| {
507 let mask = 0b100 << offset;
508 unsafe {w.bits(r.bits() | mask)}
509 });
510 }
511
512 fn control_synchronous(&mut self) {
513 let glb = unsafe { &*pac::GLB::ptr() };
514 let pin_id = $pin_id % 10;
515 let offset = pin_id * 3;
517 glb.gpio_int_mode_set1.modify(|r,w| {
518 let mask = 0b100 << offset;
519 unsafe {w.bits(r.bits() & !mask)}
520 });
521 }
522
523 fn enable_interrupt(&mut self) {
524 let glb = unsafe { &*pac::GLB::ptr() };
525
526 glb.gpio_int_mask1.modify(|r,w| {
527 unsafe {
528 w.bits(r.bits() | (1 << $pin_id))
529 }
530 });
531 }
532
533 fn disable_interrupt(&mut self) {
534 let glb = unsafe { &*pac::GLB::ptr() };
535
536 glb.gpio_int_mask1.modify(|r, w| {
537 unsafe {
538 w.bits(r.bits() & (0xFFFF_FFFF - (1 << $pin_id)))
539 }
540 });
541 }
542
543 fn clear_interrupt_pending_bit(&mut self) {
544 let glb = unsafe { &*pac::GLB::ptr() };
545
546 glb.gpio_int_clr1.write(|w| {
547 unsafe {
548 w.bits(1 << $pin_id)
549 }
550 });
551 }
552
553 fn check_interrupt(&self) -> bool {
554 let glb = unsafe { &*pac::GLB::ptr() };
555 let intstat:u32 = glb.gpio_int_stat1.read().gpio_int_stat1().bits();
556 let int_masked:u32 = intstat | (1 << $pin_id);
557 0 != int_masked
558 }
559 }
560 }
561
562
563 impl<MODE> OutputPin for $Pini<Output<MODE>> {
564 type Error = Infallible;
565
566 fn set_high(&mut self) -> Result<(), Self::Error> {
567 self.set_high_inner();
568 Ok(())
569 }
570
571 fn set_low(&mut self) -> Result<(), Self::Error> {
572 self.set_low_inner();
573 Ok(())
574 }
575 }
576
577 impl<MODE> OutputPinZero for $Pini<Output<MODE>> {
578 type Error = Infallible;
579
580 fn set_high(&mut self) -> Result<(), Self::Error> {
581 self.set_high_inner();
582 Ok(())
583 }
584
585 fn set_low(&mut self) -> Result<(), Self::Error> {
586 self.set_low_inner();
587 Ok(())
588 }
589 }
590
591 impl<MODE> StatefulOutputPin for $Pini<Output<MODE>> {
592 fn is_set_high(&self) -> Result<bool, Self::Error> {
593 Ok(self.is_output_high_inner())
594 }
595
596 fn is_set_low(&self) -> Result<bool, Self::Error> {
597 Ok(self.is_output_low_inner())
598 }
599 }
600
601 impl<MODE> StatefulOutputPinZero for $Pini<Output<MODE>> {
602 fn is_set_high(&self) -> Result<bool, Self::Error> {
603 Ok(self.is_output_high_inner())
604 }
605
606 fn is_set_low(&self) -> Result<bool, Self::Error> {
607 Ok(self.is_output_low_inner())
608 }
609 }
610
611
612 impl<MODE> ToggleableOutputPin for $Pini<Output<MODE>> {
613 type Error = Infallible;
614
615 fn toggle(&mut self) -> Result<(), Self::Error> {
616 if self.is_output_high_inner() {
617 self.set_low_inner()
618 } else {
619 self.set_high_inner()
620 }
621 Ok(())
622 }
623 }
624
625 impl<MODE> ToggleableOutputPinZero for $Pini<Output<MODE>> {
626 type Error = Infallible;
627
628 fn toggle(&mut self) -> Result<(), Self::Error> {
629 if self.is_output_high_inner() {
630 self.set_low_inner()
631 } else {
632 self.set_high_inner()
633 }
634 Ok(())
635 }
636 }
637
638 )+
639 }
640 };
641}
642
643impl_glb! {
647 Pin0: (pin0, gpio_cfgctl0, UartSig0, sig0, miso, scl, gpio_0, gpio_int_mode_set1,0),
648 Pin1: (pin1, gpio_cfgctl0, UartSig1, sig1, mosi, sda, gpio_1, gpio_int_mode_set1,1),
649 Pin2: (pin2, gpio_cfgctl1, UartSig2, sig2, ss, scl, gpio_2, gpio_int_mode_set1,2),
650 Pin3: (pin3, gpio_cfgctl1, UartSig3, sig3, sclk, sda, gpio_3, gpio_int_mode_set1,3),
651 Pin4: (pin4, gpio_cfgctl2, UartSig4, sig4, miso, scl, gpio_4, gpio_int_mode_set1,4),
652 Pin5: (pin5, gpio_cfgctl2, UartSig5, sig5, mosi, sda, gpio_5, gpio_int_mode_set1,5),
653 Pin6: (pin6, gpio_cfgctl3, UartSig6, sig6, ss, scl, gpio_6, gpio_int_mode_set1,6),
654 Pin7: (pin7, gpio_cfgctl3, UartSig7, sig7, sclk, sda, gpio_7, gpio_int_mode_set1,7),
655 Pin8: (pin8, gpio_cfgctl4, UartSig0, sig0, miso, scl, gpio_8, gpio_int_mode_set1,8),
656 Pin9: (pin9, gpio_cfgctl4, UartSig1, sig1, mosi, sda, gpio_9, gpio_int_mode_set1,9),
657 Pin10: (pin10, gpio_cfgctl5, UartSig2, sig2, ss, scl, gpio_10, gpio_int_mode_set2,11),
658 Pin11: (pin11, gpio_cfgctl5, UartSig3, sig3, sclk, sda, gpio_11, gpio_int_mode_set2,12),
659 Pin12: (pin12, gpio_cfgctl6, UartSig4, sig4, miso, scl, gpio_12, gpio_int_mode_set2,13),
660 Pin13: (pin13, gpio_cfgctl6, UartSig5, sig5, mosi, sda, gpio_13, gpio_int_mode_set2,14),
661 Pin14: (pin14, gpio_cfgctl7, UartSig6, sig6, ss, scl, gpio_14, gpio_int_mode_set2,15),
662 Pin15: (pin15, gpio_cfgctl7, UartSig7, sig7, sclk, sda, gpio_15, gpio_int_mode_set2,16),
663 Pin16: (pin16, gpio_cfgctl8, UartSig0, sig0, miso, scl, gpio_16, gpio_int_mode_set2,17),
664 Pin17: (pin17, gpio_cfgctl8, UartSig1, sig1, mosi, sda, gpio_17, gpio_int_mode_set2,18),
665 Pin18: (pin18, gpio_cfgctl9, UartSig2, sig2, ss, scl, gpio_18, gpio_int_mode_set2,19),
666 Pin19: (pin19, gpio_cfgctl9, UartSig3, sig3, sclk, sda, gpio_19, gpio_int_mode_set2,20),
667 Pin20: (pin20, gpio_cfgctl10, UartSig4, sig4, miso, scl, gpio_20, gpio_int_mode_set3,21),
668 Pin21: (pin21, gpio_cfgctl10, UartSig5, sig5, mosi, sda, gpio_21, gpio_int_mode_set3,22),
669 Pin22: (pin22, gpio_cfgctl11, UartSig6, sig6, ss, scl, gpio_22, gpio_int_mode_set3,23),
670}