embedded_c_sdk_bind_hal/gpio/
fast_pin.rs1use super::PinNum;
2use crate::ll_api::{ll_cmd::*, GpioInitParam, PortNum};
3use core::marker::PhantomData;
4
5pub trait FastPinReg {
6 const PORT: PortNum;
8 const IDR: usize;
10 const ODR: usize;
12 const BSR: usize;
14 const BCR: usize;
16}
17
18pub trait FastPinNum {
19 const PIN: PinNum;
20}
21
22pub mod fast_pin_num {
24 use super::FastPinNum;
25 use crate::gpio::PinNum;
26 macro_rules! impl_fast_pin_num {
27 ($( $pin_num:expr ),*) => {
28 $(
29 paste::paste! {
30 pub struct [<FastPin $pin_num>];
31 impl FastPinNum for [<FastPin $pin_num>] {
32 const PIN: PinNum = PinNum::[<Pin $pin_num>];
33 }
34 }
35 )*
36 };
37 }
38
39 impl_fast_pin_num![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
40}
41
42#[derive(Clone, Copy, PartialEq, Eq, Debug)]
43pub enum FastPinModeInput {
44 InFloating,
46 InPullUp,
48 InPullDown,
50}
51
52impl FastPinModeInput {
53 fn to_flag(&self) -> u32 {
54 match self {
55 FastPinModeInput::InFloating => GpioInitParam::InFloating.param(),
56 FastPinModeInput::InPullUp => GpioInitParam::InPU.param(),
57 FastPinModeInput::InPullDown => GpioInitParam::InPD.param(),
58 }
59 }
60}
61
62pub enum FastPinModeOutput {
63 OutOD,
65 OutPP,
67}
68
69impl FastPinModeOutput {
70 fn to_flag(&self) -> u32 {
71 match self {
72 FastPinModeOutput::OutOD => GpioInitParam::OutOD.param(),
73 FastPinModeOutput::OutPP => GpioInitParam::OutPP.param(),
74 }
75 }
76}
77
78pub struct InputFastPin;
79pub struct OutputFastPin;
80
81#[derive(Clone, Copy, Debug)]
82pub struct FastPin<R, N, MODE> {
83 phantom: PhantomData<(R, N, MODE)>,
84}
85
86impl<R: FastPinReg, N: FastPinNum, MODE> FastPin<R, N, MODE> {
87 pub const fn new() -> Self {
89 FastPin {
90 phantom: PhantomData,
91 }
92 }
93
94 pub fn into_input(&self, mode: FastPinModeInput) -> FastPin<R, N, InputFastPin> {
96 ll_invoke_inner!(INVOKE_ID_GPIO_INIT, R::PORT, N::PIN, mode.to_flag());
97
98 FastPin {
99 phantom: PhantomData,
100 }
101 }
102
103 pub fn into_output(&self, mode: FastPinModeOutput) -> FastPin<R, N, OutputFastPin> {
105 ll_invoke_inner!(INVOKE_ID_GPIO_INIT, R::PORT, N::PIN, mode.to_flag());
106
107 FastPin {
108 phantom: PhantomData,
109 }
110 }
111}
112
113impl<R: FastPinReg, N: FastPinNum> FastPin<R, N, InputFastPin> {
114 #[inline]
116 pub fn is_input_high(&self) -> bool {
117 (unsafe { core::ptr::read_volatile(R::IDR as *const u16) } & (1 << N::PIN as u8)) != 0
118 }
119
120 #[inline]
122 pub fn is_input_low(&self) -> bool {
123 (unsafe { core::ptr::read_volatile(R::IDR as *const u16) } & (1 << N::PIN as u8)) == 0
124 }
125}
126
127impl<R: FastPinReg, N: FastPinNum> FastPin<R, N, OutputFastPin> {
128 #[inline]
130 pub fn output_high(&self) {
131 unsafe { core::ptr::write_volatile(R::BSR as *mut u16, 1 << N::PIN as u8) };
132 }
133
134 #[inline]
136 pub fn output_low(&self) {
137 unsafe { core::ptr::write_volatile(R::BCR as *mut u16, 1 << N::PIN as u8) };
138 }
139
140 #[inline]
142 pub fn is_output_high(&self) -> bool {
143 (unsafe { core::ptr::read_volatile(R::ODR as *const u16) } & (1 << N::PIN as u8)) != 0
144 }
145
146 #[inline]
148 pub fn is_output_low(&self) -> bool {
149 (unsafe { core::ptr::read_volatile(R::ODR as *const u16) } & (1 << N::PIN as u8)) == 0
150 }
151
152 #[inline]
154 pub fn is_input_high(&self) -> bool {
155 (unsafe { core::ptr::read_volatile(R::IDR as *const u16) } & (1 << N::PIN as u8)) != 0
156 }
157
158 #[inline]
160 pub fn is_input_low(&self) -> bool {
161 (unsafe { core::ptr::read_volatile(R::IDR as *const u16) } & (1 << N::PIN as u8)) == 0
162 }
163}
164
165impl<R: FastPinReg, N: FastPinNum, MODE> embedded_hal::digital::ErrorType for FastPin<R, N, MODE> {
166 type Error = core::convert::Infallible;
167}
168
169impl<R: FastPinReg, N: FastPinNum> embedded_hal::digital::OutputPin
170 for FastPin<R, N, OutputFastPin>
171{
172 #[inline(always)]
173 fn set_high(&mut self) -> Result<(), Self::Error> {
174 self.output_high();
175 Ok(())
176 }
177
178 #[inline(always)]
179 fn set_low(&mut self) -> Result<(), Self::Error> {
180 self.output_low();
181 Ok(())
182 }
183
184 fn set_state(&mut self, state: embedded_hal::digital::PinState) -> Result<(), Self::Error> {
185 match state {
186 embedded_hal::digital::PinState::Low => self.set_low(),
187 embedded_hal::digital::PinState::High => self.set_high(),
188 }
189 }
190}
191
192impl<R: FastPinReg, N: FastPinNum> embedded_hal::digital::StatefulOutputPin
193 for FastPin<R, N, OutputFastPin>
194{
195 #[inline(always)]
196 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
197 Ok(self.is_output_high())
198 }
199
200 #[inline(always)]
201 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
202 Ok(self.is_output_low())
203 }
204}
205
206impl<R: FastPinReg, N: FastPinNum> embedded_hal::digital::InputPin for FastPin<R, N, InputFastPin> {
207 #[inline(always)]
208 fn is_high(&mut self) -> Result<bool, Self::Error> {
209 Ok(self.is_input_high())
210 }
211
212 #[inline(always)]
213 fn is_low(&mut self) -> Result<bool, Self::Error> {
214 Ok(self.is_input_low())
215 }
216}
217
218impl<R: FastPinReg, N: FastPinNum> embedded_hal::digital::InputPin
219 for FastPin<R, N, OutputFastPin>
220{
221 #[inline(always)]
222 fn is_high(&mut self) -> Result<bool, Self::Error> {
223 Ok(self.is_input_high())
224 }
225
226 #[inline(always)]
227 fn is_low(&mut self) -> Result<bool, Self::Error> {
228 Ok(self.is_input_low())
229 }
230}