Skip to content

Commit 5d40b14

Browse files
committed
Consolidate PinPortIncompatibleError pattern
Return the pin object so the users could try again. We should be able to share this error return pattern.
1 parent ea55636 commit 5d40b14

4 files changed

Lines changed: 61 additions & 26 deletions

File tree

src/chip/drivers/adc.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,7 @@ pub enum ResolutionBits {
105105
Res12,
106106
}
107107

108-
/// Error returned when a pin is not compatible with an ADC port.
109-
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
110-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
111-
pub struct PinPortIncompatibleError(());
108+
pub use crate::PinPortIncompatibleError;
112109

113110
/// A pin representing an analog input for an ADC.
114111
///
@@ -192,13 +189,16 @@ impl Adc {
192189
///
193190
/// The pin is consumed to ensure it's properly configured as an
194191
/// ADC input. If the pin isn't compatible with this ADC bank,
195-
/// the return is `None`.
196-
pub fn input<P, const N: u8>(&self, mut pin: P) -> Result<AnalogInput, PinPortIncompatibleError>
192+
/// the pin is returned inside the error so you can recover it.
193+
pub fn input<P, const N: u8>(
194+
&self,
195+
mut pin: P,
196+
) -> Result<AnalogInput, PinPortIncompatibleError<P>>
197197
where
198198
P: Pin<N>,
199199
{
200200
if self.instance() != N {
201-
return Err(PinPortIncompatibleError(()));
201+
return Err(PinPortIncompatibleError(pin));
202202
}
203203
prepare(&mut pin);
204204
Ok(AnalogInput { channel: P::INPUT })

src/chip/drivers/gpio.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,11 @@
3434
3535
use crate::{iomuxc, ral};
3636

37+
pub use crate::PinPortIncompatibleError;
38+
3739
/// Any GPIO instance.
3840
type AnyInstance = crate::AnyInstance<ral::gpio::RegisterBlock>;
3941

40-
/// Error returned when a pin is not compatible with a GPIO port.
41-
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
42-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43-
pub struct PinPortIncompatibleError(());
44-
4542
/// GPIO ports.
4643
pub struct Port {
4744
gpio: AnyInstance,
@@ -68,12 +65,16 @@ impl Port {
6865
///
6966
/// Returns an error if the pin is not compatible with this GPIO port
7067
/// (i.e., the pin's GPIO module number does not match the port's instance).
71-
pub fn output<P, const N: u8>(&mut self, mut pin: P) -> Result<Output, PinPortIncompatibleError>
68+
/// The pin is returned inside the error so you can recover it.
69+
pub fn output<P, const N: u8>(
70+
&mut self,
71+
mut pin: P,
72+
) -> Result<Output, PinPortIncompatibleError<P>>
7273
where
7374
P: iomuxc::gpio::Pin<N>,
7475
{
7576
if N != self.instance() {
76-
return Err(PinPortIncompatibleError(()));
77+
return Err(PinPortIncompatibleError(pin));
7778
}
7879
iomuxc::gpio::prepare(&mut pin);
7980
Ok(Output::new(self.duplicate_instance(), P::OFFSET))
@@ -83,12 +84,16 @@ impl Port {
8384
///
8485
/// Returns an error if the pin is not compatible with this GPIO port
8586
/// (i.e., the pin's GPIO module number does not match the port's instance).
86-
pub fn input<P, const N: u8>(&mut self, mut pin: P) -> Result<Input, PinPortIncompatibleError>
87+
/// The pin is returned inside the error so you can recover it.
88+
pub fn input<P, const N: u8>(
89+
&mut self,
90+
mut pin: P,
91+
) -> Result<Input, PinPortIncompatibleError<P>>
8792
where
8893
P: iomuxc::gpio::Pin<N>,
8994
{
9095
if N != self.instance() {
91-
return Err(PinPortIncompatibleError(()));
96+
return Err(PinPortIncompatibleError(pin));
9297
}
9398
iomuxc::gpio::prepare(&mut pin);
9499
Ok(Input::new(self.duplicate_instance(), P::OFFSET))
@@ -107,7 +112,7 @@ impl Port {
107112
&mut self,
108113
input: &Input,
109114
trigger: Option<Trigger>,
110-
) -> Result<(), PinPortIncompatibleError> {
115+
) -> Result<(), PinPortIncompatibleError<()>> {
111116
if !crate::is_same_instance(&self.gpio, &input.gpio) {
112117
return Err(PinPortIncompatibleError(()));
113118
}

src/chip/drivers/rgpio.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,11 @@
3131
3232
use crate::{iomuxc, ral};
3333

34+
pub use crate::PinPortIncompatibleError;
35+
3436
/// Any RGPIO instance.
3537
type AnyInstance = crate::AnyInstance<ral::rgpio::RegisterBlock>;
3638

37-
/// Error returned when a pin is not compatible with a GPIO port.
38-
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
39-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40-
pub struct PinPortIncompatibleError(());
41-
4239
/// GPIO ports.
4340
pub struct Port {
4441
gpio: AnyInstance,
@@ -65,12 +62,16 @@ impl Port {
6562
///
6663
/// Returns an error if the pin is not compatible with this GPIO port
6764
/// (i.e., the pin's GPIO module number does not match the port's instance).
68-
pub fn output<P, const N: u8>(&mut self, mut pin: P) -> Result<Output, PinPortIncompatibleError>
65+
/// The pin is returned inside the error so you can recover it.
66+
pub fn output<P, const N: u8>(
67+
&mut self,
68+
mut pin: P,
69+
) -> Result<Output, PinPortIncompatibleError<P>>
6970
where
7071
P: iomuxc::gpio::Pin<N>,
7172
{
7273
if N != self.instance() {
73-
return Err(PinPortIncompatibleError(()));
74+
return Err(PinPortIncompatibleError(pin));
7475
}
7576
iomuxc::gpio::prepare(&mut pin);
7677
Ok(Output::new(self.duplicate_instance(), P::OFFSET))
@@ -80,12 +81,16 @@ impl Port {
8081
///
8182
/// Returns an error if the pin is not compatible with this GPIO port
8283
/// (i.e., the pin's GPIO module number does not match the port's instance).
83-
pub fn input<P, const N: u8>(&mut self, mut pin: P) -> Result<Input, PinPortIncompatibleError>
84+
/// The pin is returned inside the error so you can recover it.
85+
pub fn input<P, const N: u8>(
86+
&mut self,
87+
mut pin: P,
88+
) -> Result<Input, PinPortIncompatibleError<P>>
8489
where
8590
P: iomuxc::gpio::Pin<N>,
8691
{
8792
if N != self.instance() {
88-
return Err(PinPortIncompatibleError(()));
93+
return Err(PinPortIncompatibleError(pin));
8994
}
9095
iomuxc::gpio::prepare(&mut pin);
9196
Ok(Input::new(self.duplicate_instance(), P::OFFSET))

src/lib.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,31 @@ fn spin_on<F: core::future::Future>(future: F) -> F::Output {
317317
}
318318
}
319319

320+
/// The wrapped pin is not compatible with this peripheral instance.
321+
///
322+
/// If `P` is `()`, it indicates that the caller's pin was incompatible with the
323+
/// peripheral, but the method did not take ownership of a pin.
324+
pub struct PinPortIncompatibleError<P>(P);
325+
impl<P> PinPortIncompatibleError<P> {
326+
/// Acquire the pin from this error.
327+
pub fn pin(self) -> P {
328+
self.0
329+
}
330+
}
331+
332+
impl<P> core::fmt::Debug for PinPortIncompatibleError<P> {
333+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
334+
f.write_str("PinPortIncompatibleError")
335+
}
336+
}
337+
338+
#[cfg(feature = "defmt")]
339+
impl<P> defmt::Format for PinPortIncompatibleError<P> {
340+
fn format(&self, f: defmt::Formatter) {
341+
defmt::write!(f, "PinPortIncompatibleError")
342+
}
343+
}
344+
320345
/// The peripheral instance for when we don't care.
321346
const HAL_INST: u8 = 0xff;
322347

0 commit comments

Comments
 (0)