1use crate::peripherals::UlpGpio;
11use core::marker::PhantomData;
12
13pub struct Input;
15pub struct Output;
16
17pub struct UlpGpioPin<'d, MODE> {
19 bit: u8,
20 _mode: PhantomData<&'d MODE>,
21}
22
23fn regs() -> &'static ws63_pac::gpio0::RegisterBlock {
24 unsafe { &*UlpGpio::ptr() }
26}
27
28impl<MODE> UlpGpioPin<'_, MODE> {
29 pub fn number(&self) -> u8 {
31 107 + self.bit
32 }
33}
34
35impl UlpGpioPin<'_, Output> {
36 pub fn set_high(&mut self) {
38 unsafe { regs().gpio_data_set().write(|w| w.bits(1 << self.bit)) };
39 }
40
41 pub fn set_low(&mut self) {
43 unsafe { regs().gpio_data_clr().write(|w| w.bits(1 << self.bit)) };
44 }
45
46 pub fn toggle(&mut self) {
48 let val = regs().gpio_sw_out().read().bits();
49 if val & (1 << self.bit) != 0 {
50 unsafe { regs().gpio_data_clr().write(|w| w.bits(1 << self.bit)) };
51 } else {
52 unsafe { regs().gpio_data_set().write(|w| w.bits(1 << self.bit)) };
53 }
54 }
55
56 pub fn is_set_high(&self) -> bool {
58 (regs().gpio_sw_out().read().bits() >> self.bit) & 1 != 0
59 }
60
61 pub fn into_input(self) -> UlpGpioPin<'static, Input> {
63 regs().gpio_sw_oen().modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.bit)) });
64 UlpGpioPin { bit: self.bit, _mode: PhantomData }
65 }
66}
67
68impl UlpGpioPin<'_, Input> {
69 pub fn is_high(&self) -> bool {
71 (regs().gpio_sw_out().read().bits() >> self.bit) & 1 != 0
72 }
73
74 pub fn is_low(&self) -> bool {
76 !self.is_high()
77 }
78
79 pub fn enable_interrupt(&self) {
81 regs().gpio_int_en().modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.bit)) });
82 }
83
84 pub fn disable_interrupt(&self) {
86 regs().gpio_int_en().modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.bit)) });
87 }
88
89 pub fn clear_interrupt(&self) {
91 unsafe { regs().gpio_int_eoi().write(|w| w.bits(1 << self.bit)) };
92 }
93
94 pub fn interrupt_pending(&self) -> bool {
96 (regs().gpio_int_raw().read().bits() >> self.bit) & 1 != 0
97 }
98
99 pub fn into_output(self) -> UlpGpioPin<'static, Output> {
101 regs().gpio_sw_oen().modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.bit)) });
102 UlpGpioPin { bit: self.bit, _mode: PhantomData }
103 }
104}
105
106impl embedded_hal::digital::ErrorType for UlpGpioPin<'_, Output> {
109 type Error = core::convert::Infallible;
110}
111impl embedded_hal::digital::OutputPin for UlpGpioPin<'_, Output> {
112 fn set_low(&mut self) -> Result<(), Self::Error> {
113 UlpGpioPin::set_low(self);
114 Ok(())
115 }
116 fn set_high(&mut self) -> Result<(), Self::Error> {
117 UlpGpioPin::set_high(self);
118 Ok(())
119 }
120}
121impl embedded_hal::digital::StatefulOutputPin for UlpGpioPin<'_, Output> {
122 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
123 Ok(UlpGpioPin::is_set_high(self))
124 }
125 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
126 Ok(!UlpGpioPin::is_set_high(self))
127 }
128}
129impl embedded_hal::digital::ErrorType for UlpGpioPin<'_, Input> {
130 type Error = core::convert::Infallible;
131}
132impl embedded_hal::digital::InputPin for UlpGpioPin<'_, Input> {
133 fn is_high(&mut self) -> Result<bool, Self::Error> {
134 Ok(UlpGpioPin::is_high(self))
135 }
136 fn is_low(&mut self) -> Result<bool, Self::Error> {
137 Ok(!UlpGpioPin::is_high(self))
138 }
139}
140
141pub fn create_input_pin(pin: u8) -> UlpGpioPin<'static, Input> {
143 let bit = pin - 107;
144 assert!(bit < 8, "ULP GPIO pin must be 107-114");
145 regs().gpio_sw_oen().modify(|r, w| unsafe { w.bits(r.bits() | (1 << bit)) });
146 UlpGpioPin { bit, _mode: PhantomData }
147}
148
149pub fn create_output_pin(pin: u8) -> UlpGpioPin<'static, Output> {
151 let bit = pin - 107;
152 assert!(bit < 8, "ULP GPIO pin must be 107-114");
153 regs().gpio_sw_oen().modify(|r, w| unsafe { w.bits(r.bits() & !(1 << bit)) });
154 UlpGpioPin { bit, _mode: PhantomData }
155}