sam3_hal/pio/
peripheral.rs

1//! PIO peripheral configuration
2//!
3//! # Pin Multiplexing
4//!
5//! Each pin is configurable, according to product definition as either a general-purpose I/O line
6//! only, or as an I/O line multiplexed with one or two peripheral I/Os. As the multiplexing is
7//! hardware defined and thus product-dependent, the hardware designer and programmer must carefully
8//! determine the configuration of the PIO controllers required by their application. When an I/O
9//! line is general-purpose only, i.e. not multiplexed with any peripheral I/O, programming of the
10//! PIO Controller regarding the assignment to a peripheral has no effect and only the PIO
11//! Controller can control how the pin is driven by the product.
12//!
13//! Relevant manual sections:
14//! - SAM3A, SAM3X: [manual][ax], pages 622-624 (31.5.2, 31.5.3, 31.5.4, 31.5.5, 31.5.7)
15//! - SAM3N: [manual][n], pages 380-382 (27.5.2, 27.5.3, 27.5.4, 27.5.5, 27.5.7)
16//! - SAM3S1, SAM3S2, SAM3S4: [manual][n], pages 471-473 (29.5.2, 29.5.3, 29.5.4, 29.5.5, 29.5.7)
17//! - SAM3S8, SAM3SD8: [manual][sd8], pages 480-482 (28.5.2, 28.5.3, 28.5.4, 28.5.5, 28.5.7)
18//! - SAM3U: [manual][u], pages 498-499 (29.5.2, 29.5.3, 29.5.4, 29.5.5, 29.5.7)
19//!
20//! [ax]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf
21//! [n]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11011-32-bit-Cortex-M3-Microcontroller-SAM3N_Datasheet.pdf
22//! [s124]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6500-32-bit-Cortex-M3-Microcontroller-SAM3S4-SAM3S2-SAM3S1_Datasheet.pdf
23//! [sd8]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11090-32-bit%20Cortex-M3-Microcontroller-SAM-3S8-SD8_Datasheet.pdf
24//! [u]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6430-32-bit-Cortex-M3-Microcontroller-SAM3U4-SAM3U2-SAM3U1_Datasheet.pdf
25
26use crate::{
27    pio::{
28        filter::InputFilterCfg,
29        interrupt::InterruptCfg,
30        pin::{Configured, MultiDriverCfg, PadResistorCfg, Pin, PinId, Unconfigured},
31        structure::*,
32        PioError,
33    },
34    structure::*,
35    write_protect::*,
36};
37use core::marker::PhantomData;
38
39/// Marker trait for line control configuration options.
40pub trait PioControlCfg {}
41
42impl PioControlCfg for Unconfigured {}
43
44#[allow(clippy::module_name_repetitions)]
45/// Allow the peripheral to control this I/O line.
46pub struct PeripheralControlled<Psel: PeripheralSelectCfg> {
47    _psel: PhantomData<Psel>,
48}
49
50impl<Psel: PeripheralSelectCfg> PioControlCfg for PeripheralControlled<Psel> {}
51impl<Psel: PeripheralSelectCfg + Configured> Configured for PeripheralControlled<Psel> {}
52
53/// Allow the PIO controller to control this I/O.
54pub struct PioControlled<Otpt: OutputCfg> {
55    _otpt: PhantomData<Otpt>,
56}
57
58impl<Otpt: OutputCfg> PioControlCfg for PioControlled<Otpt> {}
59impl<Otpt: OutputCfg + Configured> Configured for PioControlled<Otpt> {}
60
61/// # I/O Line or Peripheral Function Selection
62///
63/// When a pin is multiplexed with one or two peripheral functions, the selection is controlled with
64/// the registers `PIO_PER` (PIO Enable Register) and `PIO_PDR` (PIO Disable Register). The register
65/// `PIO_PSR` (PIO Status Register) is the result of the set and clear registers and indicates
66/// whether the pin is controlled by the corresponding peripheral or by the PIO Controller. A value
67/// of 0 indicates the pin is controlled by the corresponding on-chip peripheral selected in the
68/// `PIO_ABSR` (AB Select Register). A value of 1 indicates the pin is controlled by the PIO
69/// controller.
70///
71/// If a pin is used as a general purpose I/O line (not multiplexed with an on-chip peripheral),
72/// `PIO_PER` and `PIO_PDR` have no effect and `PIO_PSR` returns 1 for the corresponding bit.
73///
74/// After reset, most generally, the I/O lines are controlled by the PIO controller, i.e. `PIO_PSR`
75/// resets at 1. Howeever, in some events, it is important that PIO lines are controlled by the
76/// peripheral (as in the case of memory chip seelect lines that must be driven inactive after reset
77/// or for address lines that must be driven low for booting out of an external memory). Thus, the
78/// reset value of `PIO_PSR` is defined at the product level, depending on the multiplexing of the
79/// device.
80pub trait ConfigurePioControl: Sized {
81    type Pio: ConfigurePioControl;
82    type Peripheral: ConfigurePioControl;
83
84    /// Enable PIO control of this pin. Waits for `PIO_PSR` to update accordingly.
85    ///
86    /// # Errors
87    ///
88    /// This function can fail if:
89    /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
90    ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
91    ///   controller.
92    /// - Write protection is enabled on the PIO controller. Write protection must first be
93    ///   disabled for any pins within the controller to have their configurations modified.
94    fn pio_controlled(self) -> Result<Self::Pio, (Self, PioError)>;
95    /// Enable PIO control of this pin without waiting for `PIO_PSR` to update.
96    ///
97    /// # Safety
98    ///
99    /// This function returns a type showing that this pin is PIO controlled, but this may be at
100    /// odds with the actual configuration state of the PIO controller. Writes to the configuration
101    /// may fail silently if the PIO line is locked or write protection is enabled.
102    unsafe fn pio_controlled_unchecked(self) -> Self::Pio;
103    /// Enable peripheral control of this pin. Waits for `PIO_PSR` to update accordingly.
104    ///
105    /// # Errors
106    ///
107    /// This function can fail if:
108    /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
109    ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
110    ///   controller.
111    /// - Write protection is enabled on the PIO controller. Write protection must first be
112    ///   disabled for any pins within the controller to have their configurations modified.
113    fn peripheral_controlled(self) -> Result<Self::Peripheral, (Self, PioError)>;
114    /// Enable peripheral control of this pin without waiting for `PIO_PSR` to update.
115    ///
116    /// # Safety
117    ///
118    /// This function returns a type showing that this pin is peripheral controlled, but this may be
119    /// at odds with the actual configuration state of the PIO controller. Writes to the
120    /// configuration may fail silently if the PIO line is locked or write protection is enabled.
121    unsafe fn peripheral_controlled_unchecked(self) -> Self::Peripheral;
122}
123
124// When the I/O line is controlled by the PIO controller, the pin can be configured to be driven.
125// This is done by writing `PIO_OER` (Output Enable Register) and `PIO_ODR` (Output Disable
126// Register). The results of these write operations are detected in `PIO_OSR` (Output Status
127// Register). When a bit in this register is at 0, the corresponding I/O line is used as an input
128// only. When the bit is at 1, the corresponding I/O line is driven by the PIO controller.
129
130#[allow(clippy::module_name_repetitions)]
131/// Marker trait for peripheral selection configuration options.
132pub trait PeripheralSelectCfg {}
133
134impl PeripheralSelectCfg for Unconfigured {}
135
136#[allow(clippy::module_name_repetitions)]
137/// Allow output from peripheral A to drive the I/O line.
138pub struct PeripheralA;
139
140impl PeripheralSelectCfg for PeripheralA {}
141impl Configured for PeripheralA {}
142
143#[allow(clippy::module_name_repetitions)]
144/// Allow output from peripheral B to drive the I/O line.
145pub struct PeripheralB;
146
147impl PeripheralSelectCfg for PeripheralB {}
148impl Configured for PeripheralB {}
149
150#[cfg(any(feature = "3fn", feature = "4fn"))]
151mod c {
152    #[allow(clippy::wildcard_imports)]
153    use super::*;
154
155    #[allow(clippy::module_name_repetitions)]
156    /// Allow output from peripheral C to drive the I/O line.
157    pub struct PeripheralC;
158
159    impl PeripheralSelectCfg for PeripheralC {}
160    impl Configured for PeripheralC {}
161}
162
163#[cfg(any(feature = "3fn", feature = "4fn"))]
164pub use c::PeripheralC;
165
166#[cfg(feature = "4fn")]
167mod d {
168    #[allow(clippy::wildcard_imports)]
169    use super::*;
170
171    #[allow(clippy::module_name_repetitions)]
172    /// Allow output from peripheral D to drive the I/O line.
173    pub struct PeripheralD;
174
175    impl PeripheralSelectCfg for PeripheralD {}
176    impl Configured for PeripheralD {}
177}
178
179#[cfg(feature = "4fn")]
180pub use d::PeripheralD;
181
182/// Marks whether a given peripheral exists for a given PIO + pin ID combination.
183pub trait PeripheralExistsFor<Pio: PioRegisters, Pid: PinId<Controller = Pio>>:
184    PeripheralSelectCfg
185{
186}
187
188/// Marks it possible to execute a given function selection and provides methods to do so.
189///
190/// This is the preferred way to execute a function selection, since it should only be callable
191/// on types that are able to be configured to a given peripheral.
192pub trait ExecFnSel<Psel>: ConfigureFunctionSelect
193where
194    Self: Sized,
195    Psel: PeripheralSelectCfg,
196{
197    type Configured;
198    /// Selects the given peripheral for this pin. Waits for the peripheral selection register(s)
199    /// to update.
200    ///
201    /// # Errors
202    ///
203    /// This function can fail if:
204    /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
205    ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
206    ///   controller.
207    /// - Write protection is enabled on the PIO controller. Write protection must first be
208    ///   disabled for any pins within the controller to have their configurations modified.
209    fn configure_function(self) -> Result<Self::Configured, (Self, PioError)>;
210    /// Executes a given function selection without checking `PIO_LOCKSR`, `PIO_WPMR`, or waiting
211    /// for the peripheral selection register(s) to update.
212    ///
213    /// # Safety
214    ///
215    /// This function returns a type showing that this pin has selected the chosen peripheral, but
216    /// this may be at odds with the actual configuration state of the PIO controller. Writes to the
217    /// configuration may fail silently if the PIO line is locked or write protection is enabled.
218    unsafe fn configure_function_unchecked(self) -> Self::Configured;
219}
220
221impl<Pio, Pid, Mdvr, Psel, Padr, Irpt, Filt> ExecFnSel<PeripheralA>
222    for Pin<Pio, Pid, Mdvr, PeripheralControlled<Psel>, Padr, Irpt, Filt>
223where
224    Self: ConfigureFunctionSelect,
225    PeripheralA: PeripheralExistsFor<Pio, Pid>,
226    Pio: PioRegisters,
227    Pio::Rb: WriteProtect,
228    Pid: PinId<Controller = Pio>,
229    Mdvr: MultiDriverCfg,
230    Psel: PeripheralSelectCfg,
231    Padr: PadResistorCfg,
232    Irpt: InterruptCfg,
233    Filt: InputFilterCfg,
234{
235    type Configured = <Self as ConfigureFunctionSelect>::A;
236
237    fn configure_function(self) -> Result<Self::Configured, (Self, PioError)> {
238        unsafe { self.peripheral_a() }
239    }
240
241    unsafe fn configure_function_unchecked(self) -> Self::Configured {
242        self.peripheral_a_unchecked()
243    }
244}
245
246impl<Pio, Pid, Mdvr, Psel, Padr, Irpt, Filt> ExecFnSel<PeripheralB>
247    for Pin<Pio, Pid, Mdvr, PeripheralControlled<Psel>, Padr, Irpt, Filt>
248where
249    Self: ConfigureFunctionSelect,
250    PeripheralB: PeripheralExistsFor<Pio, Pid>,
251    Pio: PioRegisters,
252    Pio::Rb: WriteProtect,
253    Pid: PinId<Controller = Pio>,
254    Mdvr: MultiDriverCfg,
255    Psel: PeripheralSelectCfg,
256    Padr: PadResistorCfg,
257    Irpt: InterruptCfg,
258    Filt: InputFilterCfg,
259{
260    type Configured = <Self as ConfigureFunctionSelect>::B;
261
262    fn configure_function(self) -> Result<Self::Configured, (Self, PioError)> {
263        unsafe { self.peripheral_b() }
264    }
265
266    unsafe fn configure_function_unchecked(self) -> Self::Configured {
267        self.peripheral_b_unchecked()
268    }
269}
270
271#[cfg(feature = "3fn")]
272impl<Pio, Pid, Mdvr, Psel, Padr, Irpt, Filt> ExecFnSel<PeripheralC>
273    for Pin<Pio, Pid, Mdvr, PeripheralControlled<Psel>, Padr, Irpt, Filt>
274where
275    Self: ConfigureFunctionSelect,
276    PeripheralC: PeripheralExistsFor<Pio, Pid>,
277    Pio: PioRegisters,
278    Pio::Rb: WriteProtect,
279    Pid: PinId<Controller = Pio>,
280    Mdvr: MultiDriverCfg,
281    Psel: PeripheralSelectCfg,
282    Padr: PadResistorCfg,
283    Irpt: InterruptCfg,
284    Filt: InputFilterCfg,
285{
286    type Configured = <Self as ConfigureFunctionSelect>::C;
287
288    fn configure_function(self) -> Result<Self::Configured, (Self, PioError)> {
289        unsafe { self.peripheral_c() }
290    }
291
292    unsafe fn configure_function_unchecked(self) -> Self::Configured {
293        self.peripheral_c_unchecked()
294    }
295}
296
297#[cfg(feature = "4fn")]
298impl<Pio, Pid, Mdvr, Psel, Padr, Irpt, Filt> ExecFnSel<PeripheralD>
299    for Pin<Pio, Pid, Mdvr, PeripheralControlled<Psel>, Padr, Irpt, Filt>
300where
301    Self: ConfigureFunctionSelect,
302    PeripheralD: PeripheralExistsFor<Pio, Pid>,
303    Pio: PioRegisters,
304    Pio::Rb: WriteProtect,
305    Pid: PinId<Controller = Pio>,
306    Mdvr: MultiDriverCfg,
307    Psel: PeripheralSelectCfg,
308    Padr: PadResistorCfg,
309    Irpt: InterruptCfg,
310    Filt: InputFilterCfg,
311{
312    type Configured = <Self as ConfigureFunctionSelect>::D;
313
314    fn configure_function(self) -> Result<Self::Configured, (Self, PioError)> {
315        unsafe { self.peripheral_d() }
316    }
317
318    unsafe fn configure_function_unchecked(self) -> Self::Configured {
319        self.peripheral_d_unchecked()
320    }
321}
322
323impl<Pio, Pid, Mdvr, Psel1, Padr, Irpt, Filt>
324    Pin<Pio, Pid, Mdvr, PeripheralControlled<Psel1>, Padr, Irpt, Filt>
325where
326    Self: ConfigureFunctionSelect,
327    Pio: PioRegisters,
328    Pio::Rb: WriteProtect,
329    Pid: PinId<Controller = Pio>,
330    Mdvr: MultiDriverCfg,
331    Psel1: PeripheralSelectCfg,
332    Padr: PadResistorCfg,
333    Irpt: InterruptCfg,
334    Filt: InputFilterCfg,
335{
336    /// A sort of equivalent to `ExecFnSel::configure_function`, except the generic is on the
337    /// function instead of the trait.
338    ///
339    /// # Errors
340    ///
341    /// This function can fail if:
342    /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
343    ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
344    ///   controller.
345    /// - Write protection is enabled on the PIO controller. Write protection must first be
346    ///   disabled for any pins within the controller to have their configurations modified.
347    pub fn select_peripheral<Psel2>(
348        self,
349    ) -> Result<<Self as ExecFnSel<Psel2>>::Configured, (Self, PioError)>
350    where
351        Self: ExecFnSel<Psel2>,
352        Psel2: PeripheralExistsFor<Pio, Pid>,
353    {
354        self.configure_function()
355    }
356
357    /// A sort of equivalent to `ExecFnSel::configure_function_unchecked`, except the generic is on
358    /// the function instead of the trait.
359    ///
360    /// # Safety
361    ///
362    /// This function returns a type showing that this pin selects peripheral A, but this may be
363    /// at odds with the actual configuration state of the PIO controller. Writes to the
364    /// configuration may fail silently if the PIO line is locked or write protection is
365    /// enabled.
366    pub unsafe fn select_peripheral_unchecked<Psel2>(self) -> <Self as ExecFnSel<Psel2>>::Configured
367    where
368        Self: ExecFnSel<Psel2>,
369        Psel2: PeripheralExistsFor<Pio, Pid>,
370    {
371        self.configure_function_unchecked()
372    }
373}
374
375impl<Pio, Pid, Mdvr, Psel, Padr, Irpt, Filt>
376    Pin<Pio, Pid, Mdvr, PeripheralControlled<Psel>, Padr, Irpt, Filt>
377where
378    Self: ConfigureFunctionSelect + ExecFnSel<PeripheralA>,
379    PeripheralA: PeripheralExistsFor<Pio, Pid>,
380    Pio: PioRegisters,
381    Pio::Rb: WriteProtect,
382    Pid: PinId<Controller = Pio>,
383    Mdvr: MultiDriverCfg,
384    Psel: PeripheralSelectCfg,
385    Padr: PadResistorCfg,
386    Irpt: InterruptCfg,
387    Filt: InputFilterCfg,
388{
389    /// Select peripheral A for this pin.
390    ///
391    /// # Errors
392    ///
393    /// This function can fail if:
394    /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
395    ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
396    ///   controller.
397    /// - Write protection is enabled on the PIO controller. Write protection must first be
398    ///   disabled for any pins within the controller to have their configurations modified.
399    pub fn select_peripheral_a(
400        self,
401    ) -> Result<<Self as ExecFnSel<PeripheralA>>::Configured, (Self, PioError)> {
402        self.configure_function()
403    }
404
405    /// Select peripheral A for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
406    ///
407    /// # Safety
408    ///
409    /// This function returns a type showing that this pin selects peripheral A, but this may be
410    /// at odds with the actual configuration state of the PIO controller. Writes to the
411    /// configuration may fail silently if the PIO line is locked or write protection is
412    /// enabled.
413    pub unsafe fn select_peripheral_a_unchecked(
414        self,
415    ) -> <Self as ExecFnSel<PeripheralA>>::Configured {
416        self.configure_function_unchecked()
417    }
418}
419
420impl<Pio, Pid, Mdvr, Psel, Padr, Irpt, Filt>
421    Pin<Pio, Pid, Mdvr, PeripheralControlled<Psel>, Padr, Irpt, Filt>
422where
423    Self: ConfigureFunctionSelect + ExecFnSel<PeripheralB>,
424    PeripheralB: PeripheralExistsFor<Pio, Pid>,
425    Pio: PioRegisters,
426    Pio::Rb: WriteProtect,
427    Pid: PinId<Controller = Pio>,
428    Mdvr: MultiDriverCfg,
429    Psel: PeripheralSelectCfg,
430    Padr: PadResistorCfg,
431    Irpt: InterruptCfg,
432    Filt: InputFilterCfg,
433{
434    /// Select peripheral B for this pin.
435    ///
436    /// # Errors
437    ///
438    /// This function can fail if:
439    /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
440    ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
441    ///   controller.
442    /// - Write protection is enabled on the PIO controller. Write protection must first be
443    ///   disabled for any pins within the controller to have their configurations modified.
444    pub fn select_peripheral_b(
445        self,
446    ) -> Result<<Self as ExecFnSel<PeripheralB>>::Configured, (Self, PioError)> {
447        self.configure_function()
448    }
449
450    /// Select peripheral B for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
451    ///
452    /// # Safety
453    ///
454    /// This function returns a type showing that this pin selects peripheral B, but this may be
455    /// at odds with the actual configuration state of the PIO controller. Writes to the
456    /// configuration may fail silently if the PIO line is locked or write protection is
457    /// enabled.
458    pub unsafe fn select_peripheral_b_unchecked(
459        self,
460    ) -> <Self as ExecFnSel<PeripheralB>>::Configured {
461        self.configure_function_unchecked()
462    }
463}
464
465#[cfg(feature = "3fn")]
466impl<Pio, Pid, Mdvr, Psel, Padr, Irpt, Filt>
467    Pin<Pio, Pid, Mdvr, PeripheralControlled<Psel>, Padr, Irpt, Filt>
468where
469    Self: ConfigureFunctionSelect + ExecFnSel<PeripheralC>,
470    PeripheralC: PeripheralExistsFor<Pio, Pid>,
471    Pio: PioRegisters,
472    Pio::Rb: WriteProtect,
473    Pid: PinId<Controller = Pio>,
474    Mdvr: MultiDriverCfg,
475    Psel: PeripheralSelectCfg,
476    Padr: PadResistorCfg,
477    Irpt: InterruptCfg,
478    Filt: InputFilterCfg,
479{
480    /// Select peripheral C for this pin.
481    ///
482    /// # Errors
483    ///
484    /// This function can fail if:
485    /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
486    ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
487    ///   controller.
488    /// - Write protection is enabled on the PIO controller. Write protection must first be
489    ///   disabled for any pins within the controller to have their configurations modified.
490    pub fn select_peripheral_c(
491        self,
492    ) -> Result<<Self as ExecFnSel<PeripheralC>>::Configured, (Self, PioError)> {
493        self.configure_function()
494    }
495
496    /// Select peripheral C for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
497    ///
498    /// # Safety
499    ///
500    /// This function returns a type showing that this pin selects peripheral C, but this may be
501    /// at odds with the actual configuration state of the PIO controller. Writes to the
502    /// configuration may fail silently if the PIO line is locked or write protection is
503    /// enabled.
504    pub unsafe fn select_peripheral_c_unchecked(
505        self,
506    ) -> <Self as ExecFnSel<PeripheralC>>::Configured {
507        self.configure_function_unchecked()
508    }
509}
510
511#[cfg(feature = "4fn")]
512impl<Pio, Pid, Mdvr, Psel, Padr, Irpt, Filt>
513    Pin<Pio, Pid, Mdvr, PeripheralControlled<Psel>, Padr, Irpt, Filt>
514where
515    Self: ConfigureFunctionSelect + ExecFnSel<PeripheralD>,
516    PeripheralD: PeripheralExistsFor<Pio, Pid>,
517    Pio: PioRegisters,
518    Pio::Rb: WriteProtect,
519    Pid: PinId<Controller = Pio>,
520    Mdvr: MultiDriverCfg,
521    Psel: PeripheralSelectCfg,
522    Padr: PadResistorCfg,
523    Irpt: InterruptCfg,
524    Filt: InputFilterCfg,
525{
526    /// Select peripheral D for this pin.
527    ///
528    /// # Errors
529    ///
530    /// This function can fail if:
531    /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
532    ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
533    ///   controller.
534    /// - Write protection is enabled on the PIO controller. Write protection must first be
535    ///   disabled for any pins within the controller to have their configurations modified.
536    pub fn select_peripheral_d(
537        self,
538    ) -> Result<<Self as ExecFnSel<PeripheralD>>::Configured, (Self, PioError)> {
539        self.configure_function()
540    }
541
542    /// Select peripheral D for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
543    ///
544    /// # Safety
545    ///
546    /// This function returns a type showing that this pin selects peripheral D, but this may be
547    /// at odds with the actual configuration state of the PIO controller. Writes to the
548    /// configuration may fail silently if the PIO line is locked or write protection is
549    /// enabled.
550    pub unsafe fn select_peripheral_d_unchecked(
551        self,
552    ) -> <Self as ExecFnSel<PeripheralD>>::Configured {
553        self.configure_function_unchecked()
554    }
555}
556
557#[cfg(feature = "2fn")]
558mod fn_ab {
559    use crate::pio::PioError;
560
561    /// # Peripheral A or B Selection
562    ///
563    /// The PIO Controller provides multiplexing of up to two peripheral functions on a single pin.
564    /// The selection is performed by writing `PIO_ABSR` (AB Select Register). For each pin, the
565    /// corresponding bit at level 0 means peripheral A is selected whereas the corresponding bit at
566    /// level 1 indicates that peripheral B is selected.
567    ///
568    /// Note that multiplexing of peripheral lines A and B only affects the output line. The
569    /// peripheral input lines are always connected to the pin input.
570    ///
571    /// After reset, `PIO_ABSR` is 0, thus indicating that all the PIO lines are configured on
572    /// peripheral A. However, peripheral A generally does not drive the pin as the PIO Controller
573    /// resets in I/O line mode.
574    ///
575    /// Writing in `PIO_ABSR` manages the multiplexing regardless of the configuration of the pin.
576    /// However, assignment of a pin to a peripheral function requires a write in the peripheral
577    /// selection register (`PIO_ABSR`) in addition to a write in `PIO_PDR`.
578    /// ([`ConfigurePioControl::peripheral_controlled`][pc],
579    /// [`ConfigurePioControl::peripheral_controlled_unchecked`][pcu]).
580    ///
581    /// [pc]: crate::pio::peripheral::ConfigurePioControl::peripheral_controlled
582    /// [pcu]: crate::pio::peripheral::ConfigurePioControl::peripheral_controlled_unchecked
583    pub trait ConfigureFunctionSelect2Fn: Sized {
584        type A: ConfigureFunctionSelect2Fn;
585        type B: ConfigureFunctionSelect2Fn;
586
587        /// Select peripheral A for this pin.
588        ///
589        /// # Errors
590        ///
591        /// This function can fail if:
592        /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
593        ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
594        ///   controller.
595        /// - Write protection is enabled on the PIO controller. Write protection must first be
596        ///   disabled for any pins within the controller to have their configurations modified.
597        ///
598        /// # Safety
599        ///
600        /// The device manuals do not specify what happens in the event that an unmapped peripheral
601        /// function is selected, and so this method is marked as unsafe. Please refer to
602        /// [`ExecFnSel`][efs] for a safe method to configure pins.
603        ///
604        /// [efs]: crate::pio::peripheral::ExecFnSel
605        unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)>;
606        /// Select peripheral A for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
607        ///
608        /// # Safety
609        ///
610        /// This function returns a type showing that this pin selects peripheral A, but this may be
611        /// at odds with the actual configuration state of the PIO controller. Writes to the
612        /// configuration may fail silently if the PIO line is locked or write protection is
613        /// enabled.
614        unsafe fn peripheral_a_unchecked(self) -> Self::A;
615        /// Enable select peripheral B for this pin.
616        ///
617        /// # Errors
618        ///
619        /// This function can fail if:
620        /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
621        ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
622        ///   controller.
623        /// - Write protection is enabled on the PIO controller. Write protection must first be
624        ///   disabled for any pins within the controller to have their configurations modified.
625        ///
626        /// # Safety
627        ///
628        /// The device manuals do not specify what happens in the event that an unmapped peripheral
629        /// function is selected, and so this method is marked as unsafe. Please refer to
630        /// [`ExecFnSel`][efs] for a safe method to configure pins.
631        ///
632        /// [efs]: crate::pio::peripheral::ExecFnSel
633        unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)>;
634        /// Select peripheral B for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
635        ///
636        /// # Safety
637        ///
638        /// This function returns a type showing that this pin selects peripheral B, but this may be
639        /// at odds with the actual configuration state of the PIO controller. Writes to the
640        /// configuration may fail silently if the PIO line is locked or write protection is
641        /// enabled.
642        unsafe fn peripheral_b_unchecked(self) -> Self::B;
643    }
644}
645
646#[cfg(feature = "2fn")]
647pub use fn_ab::ConfigureFunctionSelect2Fn as ConfigureFunctionSelect;
648
649#[cfg(all(feature = "3fn", not(feature = "4fn")))]
650mod fn_abc {
651    use crate::pio::PioError;
652
653    /// # Peripheral A or B or C Selection
654    ///
655    /// The PIO Controller provides multiplexing of up to three peripheral functions on a single
656    /// pin. The selection is performed by writing to `PIO_ABCDSR0` and `PIO_ABCDSR1` (ABCD select
657    /// registers).
658    ///
659    /// The following is a table denoting the peripheral selected for all the select register
660    /// combinations:
661    ///
662    /// `PIO_ABCDSR0` | `PIO_ABCDSR1` | Selected
663    /// --------------|---------------|------------
664    ///             0 |             0 |           A
665    ///             1 |             0 |           B
666    ///             0 |             1 |           C
667    ///             1 |             0 | Unspecified
668    ///
669    /// Note that multiplexing of peripheral lines A, B, and C only affects the output line. The
670    /// peripheral input lines are always connected to the pin input.
671    ///
672    /// After reset, `PIO_ABCDSR0` and `PIO_ABCDSR1` are 0, thus indicating that all the PIO lines
673    /// are configured on peripheral A. However, peripheral A generally does not drive the pin as
674    /// the PIO controller resets in I/O line mode.
675    ///
676    /// Writing in `PIO_ABCDSR0` and `PIO_ABCDSR1` manages the multiplexing regardless of the
677    /// configuration of the pin. However, an assigment of a pin to a peripheral function requires a
678    /// write in the peripheral selection registers (`PIO_ABCDSR0` and `PIO_ABCDSR1`) in addition to
679    /// a write in `PIO_PDR` ([`ConfigurePioControl::peripheral_controlled`][pc],
680    /// [`ConfigurePioControl::peripheral_controlled_unchecked`][pcu]).
681    ///
682    /// [pc]: crate::pio::peripheral::ConfigurePioControl::peripheral_controlled
683    /// [pcu]: crate::pio::peripheral::ConfigurePioControl::peripheral_controlled_unchecked
684    pub trait ConfigureFunctionSelect3Fn: Sized {
685        type A: ConfigureFunctionSelect3Fn;
686        type B: ConfigureFunctionSelect3Fn;
687        type C: ConfigureFunctionSelect3Fn;
688
689        /// Select peripheral A for this pin.
690        ///
691        /// # Errors
692        ///
693        /// This function can fail if:
694        /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
695        ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
696        ///   controller.
697        /// - Write protection is enabled on the PIO controller. Write protection must first be
698        ///   disabled for any pins within the controller to have their configurations modified.
699        ///
700        /// # Safety
701        ///
702        /// The device manuals do not specify what happens in the event that an unmapped peripheral
703        /// function is selected, and so this method is marked as unsafe. Please refer to
704        /// [`ExecFnSel`][efs] for a safe method to configure pins.
705        ///
706        /// [efs]: crate::pio::peripheral::ExecFnSel
707        unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)>;
708        /// Select peripheral A for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
709        ///
710        /// # Safety
711        ///
712        /// This function returns a type showing that this pin selects peripheral A, but this may be
713        /// at odds with the actual configuration state of the PIO controller. Writes to the
714        /// configuration may fail silently if the PIO line is locked or write protection is
715        /// enabled.
716        unsafe fn peripheral_a_unchecked(self) -> Self::A;
717        /// Select peripheral B for this pin.
718        ///
719        /// # Errors
720        ///
721        /// This function can fail if:
722        /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
723        ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
724        ///   controller.
725        /// - Write protection is enabled on the PIO controller. Write protection must first be
726        ///   disabled for any pins within the controller to have their configurations modified.
727        ///
728        /// # Safety
729        ///
730        /// The device manuals do not specify what happens in the event that an unmapped peripheral
731        /// function is selected, and so this method is marked as unsafe. Please refer to
732        /// [`ExecFnSel`][efs] for a safe method to configure pins.
733        ///
734        /// [efs]: crate::pio::peripheral::ExecFnSel
735        unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)>;
736        /// Select peripheral B for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
737        ///
738        /// # Safety
739        ///
740        /// This function returns a type showing that this pin selects peripheral B, but this may be
741        /// at odds with the actual configuration state of the PIO controller. Writes to the
742        /// configuration may fail silently if the PIO line is locked or write protection is
743        /// enabled.
744        unsafe fn peripheral_b_unchecked(self) -> Self::B;
745        /// Select peripheral C for this pin.
746        ///
747        /// # Errors
748        ///
749        /// This function can fail if:
750        /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
751        ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
752        ///   controller.
753        /// - Write protection is enabled on the PIO controller. Write protection must first be
754        ///   disabled for any pins within the controller to have their configurations modified.
755        ///
756        /// # Safety
757        ///
758        /// The device manuals do not specify what happens in the event that an unmapped peripheral
759        /// function is selected, and so this method is marked as unsafe. Please refer to
760        /// [`ExecFnSel`][efs] for a safe method to configure pins.
761        ///
762        /// [efs]: crate::pio::peripheral::ExecFnSel
763        unsafe fn peripheral_c(self) -> Result<Self::C, (Self, PioError)>;
764        /// Select peripheral C for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
765        ///
766        /// # Safety
767        ///
768        /// This function returns a type showing that this pin selects peripheral C, but this may be
769        /// at odds with the actual configuration state of the PIO controller. Writes to the
770        /// configuration may fail silently if the PIO line is locked or write protection is
771        /// enabled.
772        unsafe fn peripheral_c_unchecked(self) -> Self::C;
773    }
774}
775
776#[cfg(all(feature = "3fn", not(feature = "4fn")))]
777pub use fn_abc::ConfigureFunctionSelect3Fn as ConfigureFunctionSelect;
778
779#[cfg(feature = "4fn")]
780mod fn_abcd {
781    use crate::pio::PioError;
782
783    /// # Peripheral A or B or C or D Selection
784    ///
785    /// The PIO Controller provides multiplexing of up to three peripheral functions on a single
786    /// pin. The selection is performed by writing to `PIO_ABCDSR0` and `PIO_ABCDSR1` (ABCD select
787    /// registers).
788    ///
789    /// The following is a table denoting the peripheral selected for all the select register
790    /// combinations:
791    ///
792    /// `PIO_ABCDSR0` | `PIO_ABCDSR1` | Selected
793    /// --------------|---------------|------------
794    ///             0 |             0 |           A
795    ///             1 |             0 |           B
796    ///             0 |             1 |           C
797    ///             1 |             0 |           D
798    ///
799    /// Note that multiplexing of peripheral lines A, B, C, and D only affects the output line. The
800    /// peripheral input lines are always connected to the pin input.
801    ///
802    /// After reset, `PIO_ABCDSR0` and `PIO_ABCDSR1` are 0, thus indicating that all the PIO lines
803    /// are configured on peripheral A. However, peripheral A generally does not drive the pin as
804    /// the PIO controller resets in I/O line mode.
805    ///
806    /// Writing in `PIO_ABCDSR0` and `PIO_ABCDSR1` manages the multiplexing regardless of the
807    /// configuration of the pin. However, an assigment of a pin to a peripheral function requires a
808    /// write in the peripheral selection registers (`PIO_ABCDSR0` and `PIO_ABCDSR1`) in addition to
809    /// a write in `PIO_PDR` ([`ConfigurePioControl::peripheral_controlled`],
810    /// [`ConfigurePioControl::peripheral_controlled_unchecked`][pcu]).
811    ///
812    /// [pc]: crate::pio::peripheral::ConfigurePioControl::peripheral_controlled
813    /// [pcu]: crate::pio::peripheral::ConfigurePioControl::peripheral_controlled_unchecked
814    pub trait ConfigureFunctionSelect4Fn: Sized {
815        type A: ConfigureFunctionSelect4Fn;
816        type B: ConfigureFunctionSelect4Fn;
817        type C: ConfigureFunctionSelect4Fn;
818        type D: ConfigureFunctionSelect4Fn;
819
820        /// Select peripheral A for this pin.
821        ///
822        /// # Errors
823        ///
824        /// This function can fail if:
825        /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
826        ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
827        ///   controller.
828        /// - Write protection is enabled on the PIO controller. Write protection must first be
829        ///   disabled for any pins within the controller to have their configurations modified.
830        ///
831        /// # Safety
832        ///
833        /// The device manuals do not specify what happens in the event that an unmapped peripheral
834        /// function is selected, and so this method is marked as unsafe. Please refer to
835        /// [`ExecFnSel`][efs] for a safe method to configure pins.
836        ///
837        /// [efs]: crate::pio::peripheral::ExecFnSel
838        unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)>;
839        /// Select peripheral A for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
840        ///
841        /// # Safety
842        ///
843        /// This function returns a type showing that this pin selects peripheral A, but this may be
844        /// at odds with the actual configuration state of the PIO controller. Writes to the
845        /// configuration may fail silently if the PIO line is locked or write protection is
846        /// enabled.
847        unsafe fn peripheral_a_unchecked(self) -> Self::A;
848        /// Select peripheral B for this pin.
849        ///
850        /// # Errors
851        ///
852        /// This function can fail if:
853        /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
854        ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
855        ///   controller.
856        /// - Write protection is enabled on the PIO controller. Write protection must first be
857        ///   disabled for any pins within the controller to have their configurations modified.
858        ///
859        /// # Safety
860        ///
861        /// The device manuals do not specify what happens in the event that an unmapped peripheral
862        /// function is selected, and so this method is marked as unsafe. Please refer to
863        /// [`ExecFnSel`][efs] for a safe method to configure pins.
864        ///
865        /// [efs]: crate::pio::peripheral::ExecFnSel
866        unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)>;
867        /// Select peripheral B for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
868        ///
869        /// # Safety
870        ///
871        /// This function returns a type showing that this pin selects peripheral B, but this may be
872        /// at odds with the actual configuration state of the PIO controller. Writes to the
873        /// configuration may fail silently if the PIO line is locked or write protection is
874        /// enabled.
875        unsafe fn peripheral_b_unchecked(self) -> Self::B;
876        /// Select peripheral C for this pin.
877        ///
878        /// # Errors
879        ///
880        /// This function can fail if:
881        /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
882        ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
883        ///   controller.
884        /// - Write protection is enabled on the PIO controller. Write protection must first be
885        ///   disabled for any pins within the controller to have their configurations modified.
886        ///
887        /// # Safety
888        ///
889        /// The device manuals do not specify what happens in the event that an unmapped peripheral
890        /// function is selected, and so this method is marked as unsafe. Please refer to
891        /// [`ExecFnSel`][efs] for a safe method to configure pins.
892        ///
893        /// [efs]: crate::pio::peripheral::ExecFnSel
894        unsafe fn peripheral_c(self) -> Result<Self::C, (Self, PioError)>;
895        /// Select peripheral C for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
896        ///
897        /// # Safety
898        ///
899        /// This function returns a type showing that this pin selects peripheral C, but this may be
900        /// at odds with the actual configuration state of the PIO controller. Writes to the
901        /// configuration may fail silently if the PIO line is locked or write protection is
902        /// enabled.
903        unsafe fn peripheral_c_unchecked(self) -> Self::C;
904        /// Select peripheral D for this pin.
905        ///
906        /// # Errors
907        ///
908        /// This function can fail if:
909        /// - This pin's bit is set in `PIO_LOCKSR`, denoting that a peripheral has locked its
910        ///   configuration, and it cannot be changed until a hardware reset is given to the PIO
911        ///   controller.
912        /// - Write protection is enabled on the PIO controller. Write protection must first be
913        ///   disabled for any pins within the controller to have their configurations modified.
914        ///
915        /// # Safety
916        ///
917        /// The device manuals do not specify what happens in the event that an unmapped peripheral
918        /// function is selected, and so this method is marked as unsafe. Please refer to
919        /// [`ExecFnSel`][efs] for a safe method to configure pins.
920        ///
921        /// [efs]: crate::pio::peripheral::ExecFnSel
922        unsafe fn peripheral_d(self) -> Result<Self::D, (Self, PioError)>;
923        /// Select peripheral D for this pin without checking `PIO_LOCKSR` or `PIO_WPMR`.
924        ///
925        /// # Safety
926        ///
927        /// This function returns a type showing that this pin selects peripheral D, but this may be
928        /// at odds with the actual configuration state of the PIO controller. Writes to the
929        /// configuration may fail silently if the PIO line is locked or write protection is
930        /// enabled.
931        unsafe fn peripheral_d_unchecked(self) -> Self::D;
932    }
933}
934
935#[cfg(feature = "4fn")]
936pub use fn_abcd::ConfigureFunctionSelect4Fn as ConfigureFunctionSelect;
937
938/// Marker trait for PIO output control configuration options.
939pub trait OutputCfg {}
940
941impl OutputCfg for Unconfigured {}
942
943#[cfg(not(feature = "schmitt"))]
944/// Disable PIO control of the output.
945pub struct OutputDisabled;
946
947#[cfg(feature = "schmitt")]
948/// Disable PIO control of the output.
949pub struct OutputDisabled<Schm: SchmittTriggerCfg> {
950    _schm: PhantomData<Schm>,
951}
952
953#[cfg(not(feature = "schmitt"))]
954impl OutputCfg for OutputDisabled {}
955#[cfg(feature = "schmitt")]
956impl<Schm: SchmittTriggerCfg> OutputCfg for OutputDisabled<Schm> {}
957
958#[cfg(not(feature = "schmitt"))]
959impl Configured for OutputDisabled {}
960#[cfg(feature = "schmitt")]
961impl<Schm: SchmittTriggerCfg + Configured> Configured for OutputDisabled<Schm> {}
962
963/// Enable PIO control of the output.
964pub struct OutputEnabled<Sync: OutputSyncWriteCfg, Outw: OutputWriteCfg> {
965    _sync: PhantomData<Sync>,
966    _outw: PhantomData<Outw>,
967}
968
969impl<Sync: OutputSyncWriteCfg, Outw: OutputWriteCfg> OutputCfg for OutputEnabled<Sync, Outw> {}
970impl<Sync: OutputSyncWriteCfg + Configured, Outw: OutputWriteCfg + Configured> Configured
971    for OutputEnabled<Sync, Outw>
972{
973}
974
975/// # Output Control (enable/disable PIO driving output)
976///
977/// When the I/O line is assigned to a peripheral function, i.e. the corresponding bit in `PIO_PSR`
978/// is at 0, the drive of the I/O line is controlled by the peripheral. Peripheral A or B depending
979/// on the value in `PIO_ABSR` (AB Select Register) determines whether the pin is driven or not.
980///
981/// When the I/O line is controlled by the PIO controller, the pin can be configured to be driven.
982/// This is done by writing `PIO_OER` (Output Enable Register) and `PIO_ODR` (Output Disable
983/// Register). The results of these write operations are detected in `PIO_OSR` (Output Status
984/// Register). When a bit in this register is at 0, the corresponding I/O line is used as an input
985/// only. When the bit is at 1, the corresponding I/O line is driven by the PIO controller.
986pub trait ConfigurePioOutput: Sized {
987    type Enabled: ConfigurePioOutput;
988    type Disabled: ConfigurePioOutput;
989
990    /// Enables PIO output for this pin. Waits for `PIO_OSR` to update accordingly.
991    ///
992    /// # Errors
993    ///
994    /// This function can fail if write protection is enabled on the PIO controller. Write
995    /// protection must first be disabled for any pins within the controller to have their
996    /// configurations modified.
997    fn enable_pio_output(self) -> Result<Self::Enabled, (Self, PioError)>;
998    /// Enables PIO output for this pin without waiting for `PIO_OSR` to update.
999    ///
1000    /// # Safety
1001    ///
1002    /// This function returns a type showing that this pin has PIO output enabled, but this may be
1003    /// at odds with the actual configuration state of the PIO controller. Writes to the
1004    /// configuration may fail silently if write protection is enabled.
1005    unsafe fn enable_pio_output_unchecked(self) -> Self::Enabled;
1006    /// Disables PIO output for this pin. Waits for `PIO_OSR` to update accordingly.
1007    ///
1008    /// # Errors
1009    ///
1010    /// This function can fail if write protection is enabled on the PIO controller. Write
1011    /// protection must first be disabled for any pins within the controller to have their
1012    /// configurations modified.
1013    fn disable_pio_output(self) -> Result<Self::Disabled, (Self, PioError)>;
1014    /// Disables PIO output for this pin without waiting for `PIO_OSR` to update.
1015    ///
1016    /// # Safety
1017    ///
1018    /// This function returns a type showing that this pin has PIO output disabled, but this may be
1019    /// at odds with the actual configuration state of the PIO controller. Writes to the
1020    /// configuration may fail silently if write protection is enabled.
1021    unsafe fn disable_pio_output_unchecked(self) -> Self::Disabled;
1022}
1023
1024/// Marker trait for synchronous output writing configuration options.
1025pub trait OutputSyncWriteCfg {}
1026
1027impl OutputSyncWriteCfg for Unconfigured {}
1028
1029/// Allow the output of this PIO line to be set or cleared synchronously with other PIO lines
1030/// by writing to `PIO_ODSR`.
1031pub struct SyncOutputEnabled;
1032
1033impl OutputSyncWriteCfg for SyncOutputEnabled {}
1034impl Configured for SyncOutputEnabled {}
1035
1036/// Disable synchronously setting the output of this PIO line with others.
1037pub struct SyncOutputDisabled;
1038
1039impl OutputSyncWriteCfg for SyncOutputDisabled {}
1040impl Configured for SyncOutputDisabled {}
1041
1042/// # Synchronous Data Output
1043///
1044/// Clearing one (or more) PIO line(s) and setting another one (or more) PIO line(s) synchronously
1045/// cannot be done by using `PIO_SODR` and `PIO_CODR` registers. It requires two successive write
1046/// operations into two different registers. To overcome this, the PIO Controller offers a direct
1047/// control of PIO outputs by single write access to `PIO_ODSR` (Output Data Status Register). Only
1048/// bits unmasked by `PIO_OWSR` (Output Write Status Register) are written. The mask bits in
1049/// `PIO_OWSR` are set by writing to `PIO_OWER` (Output Write Enable Register) and cleared by
1050/// writing to `PIO_OWDR` (Output Write Disable Register).
1051///
1052/// After reset, the synchronous data output is disabled on all the I/O lines as `PIO_OWSR` resets
1053/// at `0x0`.
1054pub trait ConfigureOutputSyncWrite: Sized {
1055    type Enabled: ConfigureOutputSyncWrite;
1056    type Disabled: ConfigureOutputSyncWrite;
1057
1058    /// Enables synchronous data output writing for this pin. Waits for `PIO_OWSR` to update
1059    /// accordingly.
1060    ///
1061    /// # Errors
1062    ///
1063    /// This function will fail unless write protection is disabled on the PIO controller. Write
1064    /// protection must be disabled for any pins within the controller to have their configurations
1065    /// modified.
1066    ///
1067    /// # Safety
1068    ///
1069    /// This function allows external control of this pin's output, and for that reason, it's marked
1070    /// `unsafe`. Mutable access to either this pin or the PIO controller driving it will allow
1071    /// modification of the output.
1072    unsafe fn enable_output_sync_write(self) -> Result<Self::Enabled, (Self, PioError)>;
1073    /// Enables synchronous data output writing for this pin without waiting for `PIO_OWSR` to
1074    /// update.
1075    ///
1076    /// # Safety
1077    ///
1078    /// This function returns a type showing that this pin has synchronous output writing enabled,
1079    /// but this may be at odds with the actual configuration state of the PIO controller. Writes to
1080    /// the configuration may fail silently if write protection is enabled. Furthermore, this is
1081    /// opting into having two owners of the same data (pin output), as mentioned in
1082    /// [`enable_output_sync_write`](ConfigureOutputSyncWrite::enable_output_sync_write).
1083    unsafe fn enable_output_sync_write_unchecked(self) -> Self::Enabled;
1084    /// Disables synchronous data output writing for this pin. Waits for `PIO_OWSR` to update
1085    /// accordingly.
1086    ///
1087    /// # Errors
1088    ///
1089    /// This function will fail unless write protection is disabled on the PIO controller. Write
1090    /// protection must be disabled for any pins within the controller to have their configurations
1091    /// modified.
1092    fn disable_output_sync_write(self) -> Result<Self::Disabled, (Self, PioError)>;
1093    /// Disables synchronous data output writing for this pin without waiting for `PIO_OWSR` to
1094    /// update.
1095    ///
1096    /// # Safety
1097    ///
1098    /// This function returns a type showing that this pin has synchronous output writing disabled,
1099    /// but this may be at odds with the actual configuration state of the PIO controller. Writes to
1100    /// the configuration may fail silently if write protection is enabled.
1101    unsafe fn disable_output_sync_write_unchecked(self) -> Self::Disabled;
1102}
1103
1104/// Marker trait for PIO output configurations.
1105pub trait OutputWriteCfg {}
1106
1107impl OutputWriteCfg for Unconfigured {}
1108
1109/// Drive the output of an I/O line high.
1110pub struct SetOutput;
1111
1112impl OutputWriteCfg for SetOutput {}
1113impl Configured for SetOutput {}
1114
1115/// Pull the output of an I/O line low.
1116pub struct ClearOutput;
1117
1118impl OutputWriteCfg for ClearOutput {}
1119impl Configured for ClearOutput {}
1120
1121/// # Output Control (Set/Clear Output Data)
1122///
1123/// The level driven on an I/O line can be determined by writing in `PIO_SODR` (Set Output Data
1124/// Register) and `PIO_CODR` (Clear Output Data Register). These write operations respectively set
1125/// and clear `PIO_ODSR` (Output Data Status Register), which represents the data driven on the I/O
1126/// lines. Writing in `PIO_OER` and `PIO_ODR` manages `PIO_OSR` whether the pin is configured to be
1127/// controlled by the PIO controller or assigned to a peripheral function. This enables
1128/// configuration of the I/O line prior to setting it to be managed by the PIO Controller.
1129///
1130/// Similarly, writing in `PIO_SODR` and `PIO_CODR` affects `PIO_ODSR`. This is important as it
1131/// defines the first level driven on the I/O line.
1132pub trait ConfigureOutputWrite {
1133    type Set: ConfigureOutputWrite;
1134    type Clear: ConfigureOutputWrite;
1135
1136    /// Set 1 as the first driven level for this pin I/O line. Waits for `PIO_ODSR` to update
1137    /// accordingly.
1138    fn set_output(self) -> Self::Set;
1139    /// Set 1 as the first driven level for this pin I/O line without waiting for `PIO_ODSR` to
1140    /// update.
1141    ///
1142    /// # Safety
1143    ///
1144    /// This function returns a type showing that this pin has set 1 as its first driven level, but
1145    /// the first driven level won't be set to 1 until the corresponding bit in `PIO_ODSR` is set.
1146    unsafe fn set_output_unchecked(self) -> Self::Set;
1147    /// Set 0 as the first driven level for this pin I/O line. Waits for `PIO_ODSR` to update
1148    /// accordingly.
1149    fn clear_output(self) -> Self::Clear;
1150    /// Set 0 as the first driven level for this pin I/O line without waiting for `PIO_ODSR` to
1151    /// update.
1152    ///
1153    /// # Safety
1154    ///
1155    /// This function returns a type showing that this pin has 0 set as its first driven level, but
1156    /// the first driven level won't be set to 0 until the corresponding bit in `PIO_ODSR` is
1157    /// cleared.
1158    unsafe fn clear_output_unchecked(self) -> Self::Clear;
1159}
1160
1161#[cfg(feature = "schmitt")]
1162/// Marker trait for Schmitt input trigger configuration options.
1163pub trait SchmittTriggerCfg {}
1164
1165#[cfg(feature = "schmitt")]
1166impl SchmittTriggerCfg for Unconfigured {}
1167
1168#[cfg(feature = "schmitt")]
1169/// Disables the Schmitt input trigger for this pin.
1170pub struct SchmittDisabled;
1171
1172#[cfg(feature = "schmitt")]
1173impl SchmittTriggerCfg for SchmittDisabled {}
1174
1175#[cfg(feature = "schmitt")]
1176/// Enables the Schmitt input trigger for this pin.
1177pub struct SchmittEnabled;
1178
1179#[cfg(feature = "schmitt")]
1180impl SchmittTriggerCfg for SchmittEnabled {}
1181
1182#[cfg(feature = "schmitt")]
1183/// # Programmable Schmitt Trigger
1184///
1185/// It is possible to configure each input for the Schmitt Trigger. By default the Schmitt trigger
1186/// is active.
1187///
1188/// (Yes, this is actually all of the information given about this functionality in the manuals,
1189/// sorry about that.)
1190pub trait ConfigureSchmittTrigger {
1191    type Disabled;
1192    type Enabled;
1193
1194    /// Disable the Schmitt trigger on this I/O line. Waits for `PIO_SCHMITT` to update accordingly.
1195    fn disable_schmitt_trigger(self) -> Self::Disabled;
1196    /// Disable the Schmitt trigger on this I/O line without waiting for `PIO_SCHMITT` to update.
1197    ///
1198    /// # Safety
1199    ///
1200    /// This function returns a type showing that this pin has the Schmitt trigger disabled, but the
1201    /// trigger won't be disabled until the corresponding bit in `PIO_SCHMITT` is set.
1202    unsafe fn disable_schmitt_trigger_unchecked(self) -> Self::Disabled;
1203    /// Enable the Schmitt trigger on this I/O line. Waits for `PIO_SCHMITT` to update accordingly.
1204    fn enable_schmitt_trigger(self) -> Self::Enabled;
1205    /// Enable the Schmitt trigger on this I/O line without waiting for `PIO_SCHMITT` to update.
1206    ///
1207    /// # Safety
1208    ///
1209    /// This function returns a type showing that this pin has the Schmitt trigger enabled, but the
1210    /// trigger won't be enabled until the corresponding bit in `PIO_SCHMITT` is clear.
1211    unsafe fn enable_schmitt_trigger_unchecked(self) -> Self::Enabled;
1212}
1213
1214impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigurePioControl
1215    for Pin<Pio, Pid, Mdvr, Unconfigured, Padr, Irpt, Filt>
1216where
1217    Pio: PioRegisters,
1218    Pio::Rb: WriteProtect,
1219    Pid: PinId<Controller = Pio>,
1220    Mdvr: MultiDriverCfg,
1221    Padr: PadResistorCfg,
1222    Irpt: InterruptCfg,
1223    Filt: InputFilterCfg,
1224{
1225    type Peripheral = Pin<Pio, Pid, Mdvr, PeripheralControlled<Unconfigured>, Padr, Irpt, Filt>;
1226    type Pio = Pin<Pio, Pid, Mdvr, PioControlled<Unconfigured>, Padr, Irpt, Filt>;
1227
1228    fn peripheral_controlled(self) -> Result<Self::Peripheral, (Self, PioError)> {
1229        unsafe {
1230            let pioreg = &*Pio::PTR;
1231            if Pio::Rb::writeprotect_enabled(pioreg) {
1232                return Err((self, PioError::WriteProtected));
1233            }
1234            if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1235                return Err((self, PioError::LineLocked));
1236            }
1237            if pioreg._psr().read().bits() & Pid::MASK != 0 {
1238                let _ = self.peripheral_controlled_unchecked();
1239                while pioreg._psr().read().bits() & Pid::MASK != 0 {}
1240            }
1241            Ok(Pin::new())
1242        }
1243    }
1244
1245    unsafe fn peripheral_controlled_unchecked(self) -> Self::Peripheral {
1246        let pioreg = &*Pio::PTR;
1247        pioreg._pdr().write_with_zero(|w| w.bits(Pid::MASK));
1248        Pin::new()
1249    }
1250
1251    fn pio_controlled(self) -> Result<Self::Pio, (Self, PioError)> {
1252        unsafe {
1253            let pioreg = &*Pio::PTR;
1254            if Pio::Rb::writeprotect_enabled(pioreg) {
1255                return Err((self, PioError::WriteProtected));
1256            }
1257            if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1258                return Err((self, PioError::LineLocked));
1259            }
1260            if pioreg._psr().read().bits() & Pid::MASK == 0 {
1261                let _ = self.pio_controlled_unchecked();
1262                while pioreg._psr().read().bits() & Pid::MASK == 0 {}
1263            }
1264            Ok(Pin::new())
1265        }
1266    }
1267
1268    unsafe fn pio_controlled_unchecked(self) -> Self::Pio {
1269        let pioreg = &*Pio::PTR;
1270        pioreg._per().write_with_zero(|w| w.bits(Pid::MASK));
1271        Pin::new()
1272    }
1273}
1274
1275impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigurePioControl
1276    for Pin<Pio, Pid, Mdvr, PeripheralControlled<Unconfigured>, Padr, Irpt, Filt>
1277where
1278    Pio: PioRegisters,
1279    Pio::Rb: WriteProtect,
1280    Pid: PinId<Controller = Pio>,
1281    Mdvr: MultiDriverCfg,
1282    Padr: PadResistorCfg,
1283    Irpt: InterruptCfg,
1284    Filt: InputFilterCfg,
1285{
1286    type Peripheral = Self;
1287    type Pio = Pin<Pio, Pid, Mdvr, PioControlled<Unconfigured>, Padr, Irpt, Filt>;
1288
1289    fn peripheral_controlled(self) -> Result<Self::Peripheral, (Self, PioError)> {
1290        Ok(self)
1291    }
1292
1293    unsafe fn peripheral_controlled_unchecked(self) -> Self::Peripheral {
1294        self
1295    }
1296
1297    fn pio_controlled(self) -> Result<Self::Pio, (Self, PioError)> {
1298        unsafe {
1299            let pioreg = &*Pio::PTR;
1300            if Pio::Rb::writeprotect_enabled(pioreg) {
1301                return Err((self, PioError::WriteProtected));
1302            }
1303            if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1304                return Err((self, PioError::LineLocked));
1305            }
1306            let _ = self.pio_controlled_unchecked();
1307            while pioreg._psr().read().bits() & Pid::MASK == 0 {}
1308            Ok(Pin::new())
1309        }
1310    }
1311
1312    unsafe fn pio_controlled_unchecked(self) -> Self::Pio {
1313        let pioreg = &*Pio::PTR;
1314        pioreg._per().write_with_zero(|w| w.bits(Pid::MASK));
1315        Pin::new()
1316    }
1317}
1318
1319impl<Pio, Pid, Mdvr, Otpt, Padr, Irpt, Filt> ConfigurePioControl
1320    for Pin<Pio, Pid, Mdvr, PioControlled<Otpt>, Padr, Irpt, Filt>
1321where
1322    Pio: PioRegisters,
1323    Pio::Rb: WriteProtect,
1324    Pid: PinId<Controller = Pio>,
1325    Mdvr: MultiDriverCfg,
1326    Otpt: OutputCfg,
1327    Padr: PadResistorCfg,
1328    Irpt: InterruptCfg,
1329    Filt: InputFilterCfg,
1330{
1331    type Peripheral = Pin<Pio, Pid, Mdvr, PeripheralControlled<Unconfigured>, Padr, Irpt, Filt>;
1332    type Pio = Self;
1333
1334    fn peripheral_controlled(self) -> Result<Self::Peripheral, (Self, PioError)> {
1335        unsafe {
1336            let pioreg = &*Pio::PTR;
1337            if Pio::Rb::writeprotect_enabled(pioreg) {
1338                return Err((self, PioError::WriteProtected));
1339            }
1340            if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1341                return Err((self, PioError::LineLocked));
1342            }
1343            let _ = self.peripheral_controlled_unchecked();
1344            while pioreg._psr().read().bits() & Pid::MASK != 0 {}
1345            Ok(Pin::new())
1346        }
1347    }
1348
1349    unsafe fn peripheral_controlled_unchecked(self) -> Self::Peripheral {
1350        let pioreg = &*Pio::PTR;
1351        pioreg._pdr().write_with_zero(|w| w.bits(Pid::MASK));
1352        Pin::new()
1353    }
1354
1355    fn pio_controlled(self) -> Result<Self::Pio, (Self, PioError)> {
1356        Ok(self)
1357    }
1358
1359    unsafe fn pio_controlled_unchecked(self) -> Self::Pio {
1360        self
1361    }
1362}
1363
1364impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigureFunctionSelect
1365    for Pin<Pio, Pid, Mdvr, PeripheralControlled<Unconfigured>, Padr, Irpt, Filt>
1366where
1367    Pio: PioRegisters,
1368    Pio::Rb: WriteProtect,
1369    Pid: PinId<Controller = Pio>,
1370    Mdvr: MultiDriverCfg,
1371    Padr: PadResistorCfg,
1372    Irpt: InterruptCfg,
1373    Filt: InputFilterCfg,
1374{
1375    type A = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralA>, Padr, Irpt, Filt>;
1376    type B = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralB>, Padr, Irpt, Filt>;
1377    #[cfg(feature = "3fn")]
1378    type C = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralC>, Padr, Irpt, Filt>;
1379    #[cfg(feature = "4fn")]
1380    type D = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralD>, Padr, Irpt, Filt>;
1381
1382    #[cfg(feature = "2fn")]
1383    unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)> {
1384        let pioreg = &*Pio::PTR;
1385        if Pio::Rb::writeprotect_enabled(pioreg) {
1386            return Err((self, PioError::WriteProtected));
1387        }
1388        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1389            return Err((self, PioError::LineLocked));
1390        }
1391        Ok(self.peripheral_a_unchecked())
1392    }
1393
1394    #[cfg(feature = "2fn")]
1395    unsafe fn peripheral_a_unchecked(self) -> Self::A {
1396        let pioreg = &*Pio::PTR;
1397        pioreg._absr().modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1398        Pin::new()
1399    }
1400
1401    #[cfg(feature = "2fn")]
1402    unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)> {
1403        let pioreg = &*Pio::PTR;
1404        if Pio::Rb::writeprotect_enabled(pioreg) {
1405            return Err((self, PioError::WriteProtected));
1406        }
1407        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1408            return Err((self, PioError::LineLocked));
1409        }
1410        Ok(self.peripheral_b_unchecked())
1411    }
1412
1413    #[cfg(feature = "2fn")]
1414    unsafe fn peripheral_b_unchecked(self) -> Self::B {
1415        let pioreg = &*Pio::PTR;
1416        pioreg._absr().modify(|r, w| w.bits(r.bits() | Pid::MASK));
1417        Pin::new()
1418    }
1419
1420    #[cfg(any(feature = "3fn", feature = "4fn"))]
1421    unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)> {
1422        let pioreg = &*Pio::PTR;
1423        if Pio::Rb::writeprotect_enabled(pioreg) {
1424            return Err((self, PioError::WriteProtected));
1425        }
1426        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1427            return Err((self, PioError::LineLocked));
1428        }
1429        Ok(self.peripheral_a_unchecked())
1430    }
1431
1432    #[cfg(any(feature = "3fn", feature = "4fn"))]
1433    unsafe fn peripheral_a_unchecked(self) -> Self::A {
1434        let pioreg = &*Pio::PTR;
1435        pioreg
1436            ._abcdsr0()
1437            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1438        pioreg
1439            ._abcdsr1()
1440            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1441        Pin::new()
1442    }
1443
1444    #[cfg(any(feature = "3fn", feature = "4fn"))]
1445    unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)> {
1446        let pioreg = &*Pio::PTR;
1447        if Pio::Rb::writeprotect_enabled(pioreg) {
1448            return Err((self, PioError::WriteProtected));
1449        }
1450        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1451            return Err((self, PioError::LineLocked));
1452        }
1453        Ok(self.peripheral_b_unchecked())
1454    }
1455
1456    #[cfg(any(feature = "3fn", feature = "4fn"))]
1457    unsafe fn peripheral_b_unchecked(self) -> Self::B {
1458        let pioreg = &*Pio::PTR;
1459        pioreg
1460            ._abcdsr0()
1461            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1462        pioreg
1463            ._abcdsr1()
1464            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1465        Pin::new()
1466    }
1467
1468    #[cfg(any(feature = "3fn", feature = "4fn"))]
1469    unsafe fn peripheral_c(self) -> Result<Self::C, (Self, PioError)> {
1470        let pioreg = &*Pio::PTR;
1471        if Pio::Rb::writeprotect_enabled(pioreg) {
1472            return Err((self, PioError::WriteProtected));
1473        }
1474        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1475            return Err((self, PioError::LineLocked));
1476        }
1477        Ok(self.peripheral_c_unchecked())
1478    }
1479
1480    #[cfg(any(feature = "3fn", feature = "4fn"))]
1481    unsafe fn peripheral_c_unchecked(self) -> Self::C {
1482        let pioreg = &*Pio::PTR;
1483        pioreg
1484            ._abcdsr0()
1485            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1486        pioreg
1487            ._abcdsr1()
1488            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1489        Pin::new()
1490    }
1491
1492    #[cfg(feature = "4fn")]
1493    unsafe fn peripheral_d(self) -> Result<Self::D, (Self, PioError)> {
1494        let pioreg = &*Pio::PTR;
1495        if Pio::Rb::writeprotect_enabled(pioreg) {
1496            return Err((self, PioError::WriteProtected));
1497        }
1498        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1499            return Err((self, PioError::LineLocked));
1500        }
1501        Ok(self.peripheral_d_unchecked())
1502    }
1503
1504    #[cfg(feature = "4fn")]
1505    unsafe fn peripheral_d_unchecked(self) -> Self::D {
1506        let pioreg = &*Pio::PTR;
1507        pioreg
1508            ._abcdsr0()
1509            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1510        pioreg
1511            ._abcdsr1()
1512            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1513        Pin::new()
1514    }
1515}
1516
1517impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigureFunctionSelect
1518    for Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralA>, Padr, Irpt, Filt>
1519where
1520    Pio: PioRegisters,
1521    Pio::Rb: WriteProtect,
1522    Pid: PinId<Controller = Pio>,
1523    Mdvr: MultiDriverCfg,
1524    Padr: PadResistorCfg,
1525    Irpt: InterruptCfg,
1526    Filt: InputFilterCfg,
1527{
1528    type A = Self;
1529    type B = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralB>, Padr, Irpt, Filt>;
1530    #[cfg(feature = "3fn")]
1531    type C = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralC>, Padr, Irpt, Filt>;
1532    #[cfg(feature = "4fn")]
1533    type D = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralD>, Padr, Irpt, Filt>;
1534
1535    unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)> {
1536        Ok(self)
1537    }
1538
1539    unsafe fn peripheral_a_unchecked(self) -> Self::A {
1540        self
1541    }
1542
1543    #[cfg(feature = "2fn")]
1544    unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)> {
1545        let pioreg = &*Pio::PTR;
1546        if Pio::Rb::writeprotect_enabled(pioreg) {
1547            return Err((self, PioError::WriteProtected));
1548        }
1549        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1550            return Err((self, PioError::LineLocked));
1551        }
1552        Ok(self.peripheral_b_unchecked())
1553    }
1554
1555    #[cfg(feature = "2fn")]
1556    unsafe fn peripheral_b_unchecked(self) -> Self::B {
1557        let pioreg = &*Pio::PTR;
1558        pioreg._absr().modify(|r, w| w.bits(r.bits() | Pid::MASK));
1559        Pin::new()
1560    }
1561
1562    #[cfg(any(feature = "3fn", feature = "4fn"))]
1563    unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)> {
1564        let pioreg = &*Pio::PTR;
1565        if Pio::Rb::writeprotect_enabled(pioreg) {
1566            return Err((self, PioError::WriteProtected));
1567        }
1568        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1569            return Err((self, PioError::LineLocked));
1570        }
1571        Ok(self.peripheral_b_unchecked())
1572    }
1573
1574    #[cfg(any(feature = "3fn", feature = "4fn"))]
1575    unsafe fn peripheral_b_unchecked(self) -> Self::B {
1576        let pioreg = &*Pio::PTR;
1577        pioreg
1578            ._abcdsr0()
1579            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1580        pioreg
1581            ._abcdsr1()
1582            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1583        Pin::new()
1584    }
1585
1586    #[cfg(any(feature = "3fn", feature = "4fn"))]
1587    unsafe fn peripheral_c(self) -> Result<Self::C, (Self, PioError)> {
1588        let pioreg = &*Pio::PTR;
1589        if Pio::Rb::writeprotect_enabled(pioreg) {
1590            return Err((self, PioError::WriteProtected));
1591        }
1592        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1593            return Err((self, PioError::LineLocked));
1594        }
1595        Ok(self.peripheral_c_unchecked())
1596    }
1597
1598    #[cfg(any(feature = "3fn", feature = "4fn"))]
1599    unsafe fn peripheral_c_unchecked(self) -> Self::C {
1600        let pioreg = &*Pio::PTR;
1601        pioreg
1602            ._abcdsr0()
1603            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1604        pioreg
1605            ._abcdsr1()
1606            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1607        Pin::new()
1608    }
1609
1610    #[cfg(feature = "4fn")]
1611    unsafe fn peripheral_d(self) -> Result<Self::D, (Self, PioError)> {
1612        let pioreg = &*Pio::PTR;
1613        if Pio::Rb::writeprotect_enabled(pioreg) {
1614            return Err((self, PioError::WriteProtected));
1615        }
1616        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1617            return Err((self, PioError::LineLocked));
1618        }
1619        Ok(self.peripheral_d_unchecked())
1620    }
1621
1622    #[cfg(feature = "4fn")]
1623    unsafe fn peripheral_d_unchecked(self) -> Self::D {
1624        let pioreg = &*Pio::PTR;
1625        pioreg
1626            ._abcdsr0()
1627            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1628        pioreg
1629            ._abcdsr1()
1630            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1631        Pin::new()
1632    }
1633}
1634
1635impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigureFunctionSelect
1636    for Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralB>, Padr, Irpt, Filt>
1637where
1638    Pio: PioRegisters,
1639    Pio::Rb: WriteProtect,
1640    Pid: PinId<Controller = Pio>,
1641    Mdvr: MultiDriverCfg,
1642    Padr: PadResistorCfg,
1643    Irpt: InterruptCfg,
1644    Filt: InputFilterCfg,
1645{
1646    type A = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralA>, Padr, Irpt, Filt>;
1647    type B = Self;
1648    #[cfg(any(feature = "3fn", feature = "4fn"))]
1649    type C = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralC>, Padr, Irpt, Filt>;
1650    #[cfg(feature = "4fn")]
1651    type D = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralD>, Padr, Irpt, Filt>;
1652
1653    #[cfg(feature = "2fn")]
1654    unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)> {
1655        let pioreg = &*Pio::PTR;
1656        if Pio::Rb::writeprotect_enabled(pioreg) {
1657            return Err((self, PioError::WriteProtected));
1658        }
1659        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1660            return Err((self, PioError::LineLocked));
1661        }
1662        Ok(self.peripheral_a_unchecked())
1663    }
1664
1665    #[cfg(feature = "2fn")]
1666    unsafe fn peripheral_a_unchecked(self) -> Self::A {
1667        let pioreg = &*Pio::PTR;
1668        pioreg._absr().modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1669        Pin::new()
1670    }
1671
1672    unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)> {
1673        Ok(self)
1674    }
1675
1676    unsafe fn peripheral_b_unchecked(self) -> Self::B {
1677        self
1678    }
1679
1680    #[cfg(any(feature = "3fn", feature = "4fn"))]
1681    unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)> {
1682        let pioreg = &*Pio::PTR;
1683        if Pio::Rb::writeprotect_enabled(pioreg) {
1684            return Err((self, PioError::WriteProtected));
1685        }
1686        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1687            return Err((self, PioError::LineLocked));
1688        }
1689        Ok(self.peripheral_a_unchecked())
1690    }
1691
1692    #[cfg(any(feature = "3fn", feature = "4fn"))]
1693    unsafe fn peripheral_a_unchecked(self) -> Self::A {
1694        let pioreg = &*Pio::PTR;
1695        pioreg
1696            ._abcdsr0()
1697            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1698        pioreg
1699            ._abcdsr1()
1700            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1701        Pin::new()
1702    }
1703
1704    #[cfg(any(feature = "3fn", feature = "4fn"))]
1705    unsafe fn peripheral_c(self) -> Result<Self::C, (Self, PioError)> {
1706        let pioreg = &*Pio::PTR;
1707        if Pio::Rb::writeprotect_enabled(pioreg) {
1708            return Err((self, PioError::WriteProtected));
1709        }
1710        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1711            return Err((self, PioError::LineLocked));
1712        }
1713        Ok(self.peripheral_c_unchecked())
1714    }
1715
1716    #[cfg(any(feature = "3fn", feature = "4fn"))]
1717    unsafe fn peripheral_c_unchecked(self) -> Self::C {
1718        let pioreg = &*Pio::PTR;
1719        pioreg
1720            ._abcdsr0()
1721            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1722        pioreg
1723            ._abcdsr1()
1724            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1725        Pin::new()
1726    }
1727
1728    #[cfg(feature = "4fn")]
1729    unsafe fn peripheral_d(self) -> Result<Self::D, (Self, PioError)> {
1730        let pioreg = &*Pio::PTR;
1731        if Pio::Rb::writeprotect_enabled(pioreg) {
1732            return Err((self, PioError::WriteProtected));
1733        }
1734        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1735            return Err((self, PioError::LineLocked));
1736        }
1737        Ok(self.peripheral_d_unchecked())
1738    }
1739
1740    #[cfg(feature = "4fn")]
1741    unsafe fn peripheral_d_unchecked(self) -> Self::D {
1742        let pioreg = &*Pio::PTR;
1743        pioreg
1744            ._abcdsr0()
1745            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1746        pioreg
1747            ._abcdsr1()
1748            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1749        Pin::new()
1750    }
1751}
1752
1753#[cfg(feature = "3fn")]
1754impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigureFunctionSelect
1755    for Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralC>, Padr, Irpt, Filt>
1756where
1757    Pio: PioRegisters,
1758    Pio::Rb: WriteProtect,
1759    Pid: PinId<Controller = Pio>,
1760    Mdvr: MultiDriverCfg,
1761    Padr: PadResistorCfg,
1762    Irpt: InterruptCfg,
1763    Filt: InputFilterCfg,
1764{
1765    type A = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralA>, Padr, Irpt, Filt>;
1766    type B = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralB>, Padr, Irpt, Filt>;
1767    type C = Self;
1768    #[cfg(feature = "4fn")]
1769    type D = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralD>, Padr, Irpt, Filt>;
1770
1771    unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)> {
1772        let pioreg = &*Pio::PTR;
1773        if Pio::Rb::writeprotect_enabled(pioreg) {
1774            return Err((self, PioError::WriteProtected));
1775        }
1776        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1777            return Err((self, PioError::LineLocked));
1778        }
1779        Ok(self.peripheral_a_unchecked())
1780    }
1781
1782    unsafe fn peripheral_a_unchecked(self) -> Self::A {
1783        let pioreg = &*Pio::PTR;
1784        pioreg
1785            ._abcdsr0()
1786            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1787        pioreg
1788            ._abcdsr1()
1789            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1790        Pin::new()
1791    }
1792
1793    unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)> {
1794        let pioreg = &*Pio::PTR;
1795        if Pio::Rb::writeprotect_enabled(pioreg) {
1796            return Err((self, PioError::WriteProtected));
1797        }
1798        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1799            return Err((self, PioError::LineLocked));
1800        }
1801        Ok(self.peripheral_b_unchecked())
1802    }
1803
1804    unsafe fn peripheral_b_unchecked(self) -> Self::B {
1805        let pioreg = &*Pio::PTR;
1806        pioreg
1807            ._abcdsr0()
1808            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1809        pioreg
1810            ._abcdsr1()
1811            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1812        Pin::new()
1813    }
1814
1815    unsafe fn peripheral_c(self) -> Result<Self::C, (Self, PioError)> {
1816        Ok(self)
1817    }
1818
1819    unsafe fn peripheral_c_unchecked(self) -> Self::C {
1820        self
1821    }
1822
1823    #[cfg(feature = "4fn")]
1824    unsafe fn peripheral_d(self) -> Result<Self::D, (Self, PioError)> {
1825        let pioreg = &*Pio::PTR;
1826        if Pio::Rb::writeprotect_enabled(pioreg) {
1827            return Err((self, PioError::WriteProtected));
1828        }
1829        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1830            return Err((self, PioError::LineLocked));
1831        }
1832        Ok(self.peripheral_d_unchecked())
1833    }
1834
1835    #[cfg(feature = "4fn")]
1836    unsafe fn peripheral_d_unchecked(self) -> Self::D {
1837        let pioreg = &*Pio::PTR;
1838        pioreg
1839            ._abcdsr0()
1840            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1841        pioreg
1842            ._abcdsr1()
1843            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1844        Pin::new()
1845    }
1846}
1847
1848#[cfg(feature = "4fn")]
1849impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigureFunctionSelect
1850    for Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralD>, Padr, Irpt, Filt>
1851where
1852    Pio: PioRegisters,
1853    Pio::Rb: WriteProtect,
1854    Pid: PinId<Controller = Pio>,
1855    Mdvr: MultiDriverCfg,
1856    Padr: PadResistorCfg,
1857    Irpt: InterruptCfg,
1858    Filt: InputFilterCfg,
1859{
1860    type A = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralA>, Padr, Irpt, Filt>;
1861    type B = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralB>, Padr, Irpt, Filt>;
1862    type C = Pin<Pio, Pid, Mdvr, PeripheralControlled<PeripheralC>, Padr, Irpt, Filt>;
1863    type D = Self;
1864
1865    unsafe fn peripheral_a(self) -> Result<Self::A, (Self, PioError)> {
1866        let pioreg = &*Pio::PTR;
1867        if Pio::Rb::writeprotect_enabled(pioreg) {
1868            return Err((self, PioError::WriteProtected));
1869        }
1870        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1871            return Err((self, PioError::LineLocked));
1872        }
1873        Ok(self.peripheral_a_unchecked())
1874    }
1875
1876    unsafe fn peripheral_a_unchecked(self) -> Self::A {
1877        let pioreg = &*Pio::PTR;
1878        pioreg
1879            ._abcdsr0()
1880            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1881        pioreg
1882            ._abcdsr1()
1883            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1884        Pin::new()
1885    }
1886
1887    unsafe fn peripheral_b(self) -> Result<Self::B, (Self, PioError)> {
1888        let pioreg = &*Pio::PTR;
1889        if Pio::Rb::writeprotect_enabled(pioreg) {
1890            return Err((self, PioError::WriteProtected));
1891        }
1892        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1893            return Err((self, PioError::LineLocked));
1894        }
1895        Ok(self.peripheral_b_unchecked())
1896    }
1897
1898    unsafe fn peripheral_b_unchecked(self) -> Self::B {
1899        let pioreg = &*Pio::PTR;
1900        pioreg
1901            ._abcdsr0()
1902            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1903        pioreg
1904            ._abcdsr1()
1905            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1906        Pin::new()
1907    }
1908
1909    unsafe fn peripheral_c(self) -> Result<Self::C, (Self, PioError)> {
1910        let pioreg = &*Pio::PTR;
1911        if Pio::Rb::writeprotect_enabled(pioreg) {
1912            return Err((self, PioError::WriteProtected));
1913        }
1914        if pioreg._locksr().read().bits() & Pid::MASK == 0 {
1915            return Err((self, PioError::LineLocked));
1916        }
1917        Ok(self.peripheral_c_unchecked())
1918    }
1919
1920    unsafe fn peripheral_c_unchecked(self) -> Self::C {
1921        let pioreg = &*Pio::PTR;
1922        pioreg
1923            ._abcdsr0()
1924            .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
1925        pioreg
1926            ._abcdsr1()
1927            .modify(|r, w| w.bits(r.bits() | Pid::MASK));
1928        Pin::new()
1929    }
1930
1931    unsafe fn peripheral_d(self) -> Result<Self::D, (Self, PioError)> {
1932        Ok(self)
1933    }
1934
1935    unsafe fn peripheral_d_unchecked(self) -> Self::D {
1936        self
1937    }
1938}
1939
1940#[cfg(not(feature = "schmitt"))]
1941const _: () = {
1942    impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigurePioOutput
1943        for Pin<Pio, Pid, Mdvr, PioControlled<Unconfigured>, Padr, Irpt, Filt>
1944    where
1945        Pio: PioRegisters,
1946        Pio::Rb: WriteProtect,
1947        Pid: PinId<Controller = Pio>,
1948        Mdvr: MultiDriverCfg,
1949        Padr: PadResistorCfg,
1950        Irpt: InterruptCfg,
1951        Filt: InputFilterCfg,
1952    {
1953        type Disabled = Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled>, Padr, Irpt, Filt>;
1954        type Enabled = Pin<
1955            Pio,
1956            Pid,
1957            Mdvr,
1958            PioControlled<OutputEnabled<Unconfigured, Unconfigured>>,
1959            Padr,
1960            Irpt,
1961            Filt,
1962        >;
1963
1964        fn disable_pio_output(self) -> Result<Self::Disabled, (Self, PioError)> {
1965            unsafe {
1966                let pioreg = &*Pio::PTR;
1967                if Pio::Rb::writeprotect_enabled(pioreg) {
1968                    return Err((self, PioError::WriteProtected));
1969                }
1970                if pioreg._osr().read().bits() & Pid::MASK != 0 {
1971                    let _ = self.disable_pio_output_unchecked();
1972                    while pioreg._osr().read().bits() & Pid::MASK != 0 {}
1973                }
1974                Ok(Pin::new())
1975            }
1976        }
1977
1978        unsafe fn disable_pio_output_unchecked(self) -> Self::Disabled {
1979            let pioreg = &*Pio::PTR;
1980            pioreg._odr().write_with_zero(|w| w.bits(Pid::MASK));
1981            Pin::new()
1982        }
1983
1984        fn enable_pio_output(self) -> Result<Self::Enabled, (Self, PioError)> {
1985            unsafe {
1986                let pioreg = &*Pio::PTR;
1987                if Pio::Rb::writeprotect_enabled(pioreg) {
1988                    return Err((self, PioError::WriteProtected));
1989                }
1990                if pioreg._osr().read().bits() & Pid::MASK == 0 {
1991                    let _ = self.enable_pio_output_unchecked();
1992                    while pioreg._osr().read().bits() & Pid::MASK == 0 {}
1993                }
1994                Ok(Pin::new())
1995            }
1996        }
1997
1998        unsafe fn enable_pio_output_unchecked(self) -> Self::Enabled {
1999            let pioreg = &*Pio::PTR;
2000            pioreg._oer().write_with_zero(|w| w.bits(Pid::MASK));
2001            Pin::new()
2002        }
2003    }
2004
2005    impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigurePioOutput
2006        for Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled>, Padr, Irpt, Filt>
2007    where
2008        Pio: PioRegisters,
2009        Pio::Rb: WriteProtect,
2010        Pid: PinId<Controller = Pio>,
2011        Mdvr: MultiDriverCfg,
2012        Padr: PadResistorCfg,
2013        Irpt: InterruptCfg,
2014        Filt: InputFilterCfg,
2015    {
2016        type Disabled = Self;
2017        type Enabled = Pin<
2018            Pio,
2019            Pid,
2020            Mdvr,
2021            PioControlled<OutputEnabled<Unconfigured, Unconfigured>>,
2022            Padr,
2023            Irpt,
2024            Filt,
2025        >;
2026
2027        fn disable_pio_output(self) -> Result<Self::Disabled, (Self, PioError)> {
2028            Ok(self)
2029        }
2030
2031        unsafe fn disable_pio_output_unchecked(self) -> Self::Disabled {
2032            self
2033        }
2034
2035        fn enable_pio_output(self) -> Result<Self::Enabled, (Self, PioError)> {
2036            unsafe {
2037                let pioreg = &*Pio::PTR;
2038                if Pio::Rb::writeprotect_enabled(pioreg) {
2039                    return Err((self, PioError::WriteProtected));
2040                }
2041                let _ = self.enable_pio_output_unchecked();
2042                while pioreg._osr().read().bits() & Pid::MASK == 0 {}
2043                Ok(Pin::new())
2044            }
2045        }
2046
2047        unsafe fn enable_pio_output_unchecked(self) -> Self::Enabled {
2048            let pioreg = &*Pio::PTR;
2049            pioreg._oer().write_with_zero(|w| w.bits(Pid::MASK));
2050            Pin::new()
2051        }
2052    }
2053
2054    impl<Pio, Pid, Mdvr, Sync, Outw, Padr, Irpt, Filt> ConfigurePioOutput
2055        for Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Sync, Outw>>, Padr, Irpt, Filt>
2056    where
2057        Pio: PioRegisters,
2058        Pio::Rb: WriteProtect,
2059        Pid: PinId<Controller = Pio>,
2060        Mdvr: MultiDriverCfg,
2061        Sync: OutputSyncWriteCfg,
2062        Outw: OutputWriteCfg,
2063        Padr: PadResistorCfg,
2064        Irpt: InterruptCfg,
2065        Filt: InputFilterCfg,
2066    {
2067        type Disabled = Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled>, Padr, Irpt, Filt>;
2068        type Enabled = Self;
2069
2070        fn disable_pio_output(self) -> Result<Self::Disabled, (Self, PioError)> {
2071            unsafe {
2072                let pioreg = &*Pio::PTR;
2073                if Pio::Rb::writeprotect_enabled(pioreg) {
2074                    return Err((self, PioError::WriteProtected));
2075                }
2076                let _ = self.disable_pio_output_unchecked();
2077                while pioreg._osr().read().bits() & Pid::MASK != 0 {}
2078                Ok(Pin::new())
2079            }
2080        }
2081
2082        unsafe fn disable_pio_output_unchecked(self) -> Self::Disabled {
2083            let pioreg = &*Pio::PTR;
2084            pioreg._odr().write_with_zero(|w| w.bits(Pid::MASK));
2085            Pin::new()
2086        }
2087
2088        fn enable_pio_output(self) -> Result<Self::Enabled, (Self, PioError)> {
2089            Ok(self)
2090        }
2091
2092        unsafe fn enable_pio_output_unchecked(self) -> Self::Enabled {
2093            self
2094        }
2095    }
2096};
2097
2098#[cfg(feature = "schmitt")]
2099const _: () = {
2100    impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigurePioOutput
2101        for Pin<Pio, Pid, Mdvr, PioControlled<Unconfigured>, Padr, Irpt, Filt>
2102    where
2103        Pio: PioRegisters,
2104        Pio::Rb: WriteProtect,
2105        Pid: PinId<Controller = Pio>,
2106        Mdvr: MultiDriverCfg,
2107        Padr: PadResistorCfg,
2108        Irpt: InterruptCfg,
2109        Filt: InputFilterCfg,
2110    {
2111        type Disabled =
2112            Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<Unconfigured>>, Padr, Irpt, Filt>;
2113        type Enabled = Pin<
2114            Pio,
2115            Pid,
2116            Mdvr,
2117            PioControlled<OutputEnabled<Unconfigured, Unconfigured>>,
2118            Padr,
2119            Irpt,
2120            Filt,
2121        >;
2122
2123        fn disable_pio_output(self) -> Result<Self::Disabled, (Self, PioError)> {
2124            unsafe {
2125                let pioreg = &*Pio::PTR;
2126                if Pio::Rb::writeprotect_enabled(pioreg) {
2127                    return Err((self, PioError::WriteProtected));
2128                }
2129                if pioreg._osr().read().bits() & Pid::MASK != 0 {
2130                    let _ = self.disable_pio_output_unchecked();
2131                    while pioreg._osr().read().bits() & Pid::MASK != 0 {}
2132                }
2133                Ok(Pin::new())
2134            }
2135        }
2136
2137        unsafe fn disable_pio_output_unchecked(self) -> Self::Disabled {
2138            let pioreg = &*Pio::PTR;
2139            pioreg._odr().write_with_zero(|w| w.bits(Pid::MASK));
2140            Pin::new()
2141        }
2142
2143        fn enable_pio_output(self) -> Result<Self::Enabled, (Self, PioError)> {
2144            unsafe {
2145                let pioreg = &*Pio::PTR;
2146                if Pio::Rb::writeprotect_enabled(pioreg) {
2147                    return Err((self, PioError::WriteProtected));
2148                }
2149                if pioreg._osr().read().bits() & Pid::MASK == 0 {
2150                    let _ = self.enable_pio_output_unchecked();
2151                    while pioreg._osr().read().bits() & Pid::MASK == 0 {}
2152                }
2153                Ok(Pin::new())
2154            }
2155        }
2156
2157        unsafe fn enable_pio_output_unchecked(self) -> Self::Enabled {
2158            let pioreg = &*Pio::PTR;
2159            pioreg._oer().write_with_zero(|w| w.bits(Pid::MASK));
2160            Pin::new()
2161        }
2162    }
2163
2164    impl<Pio, Pid, Mdvr, Schm, Padr, Irpt, Filt> ConfigurePioOutput
2165        for Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<Schm>>, Padr, Irpt, Filt>
2166    where
2167        Pio: PioRegisters,
2168        Pio::Rb: WriteProtect,
2169        Pid: PinId<Controller = Pio>,
2170        Mdvr: MultiDriverCfg,
2171        Schm: SchmittTriggerCfg,
2172        Padr: PadResistorCfg,
2173        Irpt: InterruptCfg,
2174        Filt: InputFilterCfg,
2175    {
2176        type Disabled = Self;
2177        type Enabled = Pin<
2178            Pio,
2179            Pid,
2180            Mdvr,
2181            PioControlled<OutputEnabled<Unconfigured, Unconfigured>>,
2182            Padr,
2183            Irpt,
2184            Filt,
2185        >;
2186
2187        fn disable_pio_output(self) -> Result<Self::Disabled, (Self, PioError)> {
2188            Ok(self)
2189        }
2190
2191        unsafe fn disable_pio_output_unchecked(self) -> Self::Disabled {
2192            self
2193        }
2194
2195        fn enable_pio_output(self) -> Result<Self::Enabled, (Self, PioError)> {
2196            unsafe {
2197                let pioreg = &*Pio::PTR;
2198                if Pio::Rb::writeprotect_enabled(pioreg) {
2199                    return Err((self, PioError::WriteProtected));
2200                }
2201                let _ = self.enable_pio_output_unchecked();
2202                while pioreg._osr().read().bits() & Pid::MASK == 0 {}
2203                Ok(Pin::new())
2204            }
2205        }
2206
2207        unsafe fn enable_pio_output_unchecked(self) -> Self::Enabled {
2208            let pioreg = &*Pio::PTR;
2209            pioreg._oer().write_with_zero(|w| w.bits(Pid::MASK));
2210            Pin::new()
2211        }
2212    }
2213
2214    impl<Pio, Pid, Mdvr, Sync, Outw, Padr, Irpt, Filt> ConfigurePioOutput
2215        for Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Sync, Outw>>, Padr, Irpt, Filt>
2216    where
2217        Pio: PioRegisters,
2218        Pio::Rb: WriteProtect,
2219        Pid: PinId<Controller = Pio>,
2220        Mdvr: MultiDriverCfg,
2221        Sync: OutputSyncWriteCfg,
2222        Outw: OutputWriteCfg,
2223        Padr: PadResistorCfg,
2224        Irpt: InterruptCfg,
2225        Filt: InputFilterCfg,
2226    {
2227        type Disabled =
2228            Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<Unconfigured>>, Padr, Irpt, Filt>;
2229        type Enabled = Self;
2230
2231        fn disable_pio_output(self) -> Result<Self::Disabled, (Self, PioError)> {
2232            unsafe {
2233                let pioreg = &*Pio::PTR;
2234                if Pio::Rb::writeprotect_enabled(pioreg) {
2235                    return Err((self, PioError::WriteProtected));
2236                }
2237                let _ = self.disable_pio_output_unchecked();
2238                while pioreg._osr().read().bits() & Pid::MASK != 0 {}
2239                Ok(Pin::new())
2240            }
2241        }
2242
2243        unsafe fn disable_pio_output_unchecked(self) -> Self::Disabled {
2244            let pioreg = &*Pio::PTR;
2245            pioreg._odr().write_with_zero(|w| w.bits(Pid::MASK));
2246            Pin::new()
2247        }
2248
2249        fn enable_pio_output(self) -> Result<Self::Enabled, (Self, PioError)> {
2250            Ok(self)
2251        }
2252
2253        unsafe fn enable_pio_output_unchecked(self) -> Self::Enabled {
2254            self
2255        }
2256    }
2257
2258    impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigureSchmittTrigger
2259        for Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<Unconfigured>>, Padr, Irpt, Filt>
2260    where
2261        Pio: PioRegisters,
2262        Pid: PinId<Controller = Pio>,
2263        Mdvr: MultiDriverCfg,
2264        Padr: PadResistorCfg,
2265        Irpt: InterruptCfg,
2266        Filt: InputFilterCfg,
2267    {
2268        type Disabled =
2269            Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<SchmittDisabled>>, Padr, Irpt, Filt>;
2270        type Enabled =
2271            Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<SchmittEnabled>>, Padr, Irpt, Filt>;
2272
2273        fn disable_schmitt_trigger(self) -> Self::Disabled {
2274            unsafe {
2275                let pioreg = &*Pio::PTR;
2276                if pioreg._schmitt().read().bits() & Pid::MASK == 0 {
2277                    let _ = self.disable_schmitt_trigger_unchecked();
2278                    while pioreg._schmitt().read().bits() & Pid::MASK == 0 {}
2279                }
2280                Pin::new()
2281            }
2282        }
2283
2284        unsafe fn disable_schmitt_trigger_unchecked(self) -> Self::Disabled {
2285            let pioreg = &*Pio::PTR;
2286            pioreg
2287                ._schmitt()
2288                .modify(|r, w| w.bits(r.bits() | Pid::MASK));
2289            Pin::new()
2290        }
2291
2292        fn enable_schmitt_trigger(self) -> Self::Enabled {
2293            unsafe {
2294                let pioreg = &*Pio::PTR;
2295                if pioreg._schmitt().read().bits() & Pid::MASK != 0 {
2296                    let _ = self.enable_schmitt_trigger_unchecked();
2297                    while pioreg._schmitt().read().bits() & Pid::MASK != 0 {}
2298                }
2299                Pin::new()
2300            }
2301        }
2302
2303        unsafe fn enable_schmitt_trigger_unchecked(self) -> Self::Enabled {
2304            let pioreg = &*Pio::PTR;
2305            pioreg
2306                ._schmitt()
2307                .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
2308            Pin::new()
2309        }
2310    }
2311
2312    impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigureSchmittTrigger
2313        for Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<SchmittDisabled>>, Padr, Irpt, Filt>
2314    where
2315        Pio: PioRegisters,
2316        Pid: PinId<Controller = Pio>,
2317        Mdvr: MultiDriverCfg,
2318        Padr: PadResistorCfg,
2319        Irpt: InterruptCfg,
2320        Filt: InputFilterCfg,
2321    {
2322        type Disabled = Self;
2323        type Enabled =
2324            Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<SchmittEnabled>>, Padr, Irpt, Filt>;
2325
2326        fn disable_schmitt_trigger(self) -> Self::Disabled {
2327            self
2328        }
2329
2330        unsafe fn disable_schmitt_trigger_unchecked(self) -> Self::Disabled {
2331            self
2332        }
2333
2334        fn enable_schmitt_trigger(self) -> Self::Enabled {
2335            unsafe {
2336                let pioreg = &*Pio::PTR;
2337                let _ = self.enable_schmitt_trigger_unchecked();
2338                while pioreg._schmitt().read().bits() & Pid::MASK != 0 {}
2339                Pin::new()
2340            }
2341        }
2342
2343        unsafe fn enable_schmitt_trigger_unchecked(self) -> Self::Enabled {
2344            let pioreg = &*Pio::PTR;
2345            pioreg
2346                ._schmitt()
2347                .modify(|r, w| w.bits(r.bits() & !Pid::MASK));
2348            Pin::new()
2349        }
2350    }
2351
2352    impl<Pio, Pid, Mdvr, Padr, Irpt, Filt> ConfigureSchmittTrigger
2353        for Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<SchmittEnabled>>, Padr, Irpt, Filt>
2354    where
2355        Pio: PioRegisters,
2356        Pid: PinId<Controller = Pio>,
2357        Mdvr: MultiDriverCfg,
2358        Padr: PadResistorCfg,
2359        Irpt: InterruptCfg,
2360        Filt: InputFilterCfg,
2361    {
2362        type Disabled =
2363            Pin<Pio, Pid, Mdvr, PioControlled<OutputDisabled<SchmittDisabled>>, Padr, Irpt, Filt>;
2364        type Enabled = Self;
2365
2366        fn disable_schmitt_trigger(self) -> Self::Disabled {
2367            unsafe {
2368                let pioreg = &*Pio::PTR;
2369                let _ = self.disable_schmitt_trigger_unchecked();
2370                while pioreg._schmitt().read().bits() & Pid::MASK == 0 {}
2371                Pin::new()
2372            }
2373        }
2374
2375        unsafe fn disable_schmitt_trigger_unchecked(self) -> Self::Disabled {
2376            let pioreg = &*Pio::PTR;
2377            pioreg
2378                ._schmitt()
2379                .modify(|r, w| w.bits(r.bits() | Pid::MASK));
2380            Pin::new()
2381        }
2382
2383        fn enable_schmitt_trigger(self) -> Self::Enabled {
2384            self
2385        }
2386
2387        unsafe fn enable_schmitt_trigger_unchecked(self) -> Self::Enabled {
2388            self
2389        }
2390    }
2391};
2392
2393impl<Pio, Pid, Mdvr, Outw, Padr, Irpt, Filt> ConfigureOutputSyncWrite
2394    for Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Unconfigured, Outw>>, Padr, Irpt, Filt>
2395where
2396    Pio: PioRegisters,
2397    Pio::Rb: WriteProtect,
2398    Pid: PinId<Controller = Pio>,
2399    Mdvr: MultiDriverCfg,
2400    Outw: OutputWriteCfg,
2401    Padr: PadResistorCfg,
2402    Irpt: InterruptCfg,
2403    Filt: InputFilterCfg,
2404{
2405    type Disabled = Pin<
2406        Pio,
2407        Pid,
2408        Mdvr,
2409        PioControlled<OutputEnabled<SyncOutputDisabled, Outw>>,
2410        Padr,
2411        Irpt,
2412        Filt,
2413    >;
2414    type Enabled = Pin<
2415        Pio,
2416        Pid,
2417        Mdvr,
2418        PioControlled<OutputEnabled<SyncOutputEnabled, Outw>>,
2419        Padr,
2420        Irpt,
2421        Filt,
2422    >;
2423
2424    fn disable_output_sync_write(self) -> Result<Self::Disabled, (Self, PioError)> {
2425        unsafe {
2426            let pioreg = &*Pio::PTR;
2427            if Pio::Rb::writeprotect_enabled(pioreg) {
2428                return Err((self, PioError::WriteProtected));
2429            }
2430            if pioreg._owsr().read().bits() & Pid::MASK != 0 {
2431                let _ = self.disable_output_sync_write_unchecked();
2432                while pioreg._owsr().read().bits() & Pid::MASK != 0 {}
2433            }
2434            Ok(Pin::new())
2435        }
2436    }
2437
2438    unsafe fn disable_output_sync_write_unchecked(self) -> Self::Disabled {
2439        let pioreg = &*Pio::PTR;
2440        pioreg._owdr().write_with_zero(|w| w.bits(Pid::MASK));
2441        Pin::new()
2442    }
2443
2444    unsafe fn enable_output_sync_write(self) -> Result<Self::Enabled, (Self, PioError)> {
2445        let pioreg = &*Pio::PTR;
2446        if Pio::Rb::writeprotect_enabled(pioreg) {
2447            return Err((self, PioError::WriteProtected));
2448        }
2449        if pioreg._owsr().read().bits() & Pid::MASK == 0 {
2450            let _ = self.enable_output_sync_write_unchecked();
2451            while pioreg._owsr().read().bits() & Pid::MASK == 0 {}
2452        }
2453        Ok(Pin::new())
2454    }
2455
2456    unsafe fn enable_output_sync_write_unchecked(self) -> Self::Enabled {
2457        let pioreg = &*Pio::PTR;
2458        pioreg._ower().write_with_zero(|w| w.bits(Pid::MASK));
2459        Pin::new()
2460    }
2461}
2462
2463impl<Pio, Pid, Mdvr, Outw, Padr, Irpt, Filt> ConfigureOutputSyncWrite
2464    for Pin<
2465        Pio,
2466        Pid,
2467        Mdvr,
2468        PioControlled<OutputEnabled<SyncOutputDisabled, Outw>>,
2469        Padr,
2470        Irpt,
2471        Filt,
2472    >
2473where
2474    Pio: PioRegisters,
2475    Pio::Rb: WriteProtect,
2476    Pid: PinId<Controller = Pio>,
2477    Mdvr: MultiDriverCfg,
2478    Outw: OutputWriteCfg,
2479    Padr: PadResistorCfg,
2480    Irpt: InterruptCfg,
2481    Filt: InputFilterCfg,
2482{
2483    type Disabled = Self;
2484    type Enabled = Pin<
2485        Pio,
2486        Pid,
2487        Mdvr,
2488        PioControlled<OutputEnabled<SyncOutputEnabled, Outw>>,
2489        Padr,
2490        Irpt,
2491        Filt,
2492    >;
2493
2494    fn disable_output_sync_write(self) -> Result<Self::Disabled, (Self, PioError)> {
2495        Ok(self)
2496    }
2497
2498    unsafe fn disable_output_sync_write_unchecked(self) -> Self::Disabled {
2499        self
2500    }
2501
2502    unsafe fn enable_output_sync_write(self) -> Result<Self::Enabled, (Self, PioError)> {
2503        let pioreg = &*Pio::PTR;
2504        if Pio::Rb::writeprotect_enabled(pioreg) {
2505            return Err((self, PioError::WriteProtected));
2506        }
2507        let _ = self.enable_output_sync_write_unchecked();
2508        while pioreg._owsr().read().bits() & Pid::MASK == 0 {}
2509        Ok(Pin::new())
2510    }
2511
2512    unsafe fn enable_output_sync_write_unchecked(self) -> Self::Enabled {
2513        let pioreg = &*Pio::PTR;
2514        pioreg._ower().write_with_zero(|w| w.bits(Pid::MASK));
2515        Pin::new()
2516    }
2517}
2518
2519impl<Pio, Pid, Mdvr, Outw, Padr, Irpt, Filt> ConfigureOutputSyncWrite
2520    for Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<SyncOutputEnabled, Outw>>, Padr, Irpt, Filt>
2521where
2522    Pio: PioRegisters,
2523    Pio::Rb: WriteProtect,
2524    Pid: PinId<Controller = Pio>,
2525    Mdvr: MultiDriverCfg,
2526    Outw: OutputWriteCfg,
2527    Padr: PadResistorCfg,
2528    Irpt: InterruptCfg,
2529    Filt: InputFilterCfg,
2530{
2531    type Disabled = Pin<
2532        Pio,
2533        Pid,
2534        Mdvr,
2535        PioControlled<OutputEnabled<SyncOutputDisabled, Outw>>,
2536        Padr,
2537        Irpt,
2538        Filt,
2539    >;
2540    type Enabled = Self;
2541
2542    fn disable_output_sync_write(self) -> Result<Self::Disabled, (Self, PioError)> {
2543        unsafe {
2544            let pioreg = &*Pio::PTR;
2545            if Pio::Rb::writeprotect_enabled(pioreg) {
2546                return Err((self, PioError::WriteProtected));
2547            }
2548            let _ = self.disable_output_sync_write_unchecked();
2549            while pioreg._owsr().read().bits() & Pid::MASK != 0 {}
2550            Ok(Pin::new())
2551        }
2552    }
2553
2554    unsafe fn disable_output_sync_write_unchecked(self) -> Self::Disabled {
2555        let pioreg = &*Pio::PTR;
2556        pioreg._owdr().write_with_zero(|w| w.bits(Pid::MASK));
2557        Pin::new()
2558    }
2559
2560    unsafe fn enable_output_sync_write(self) -> Result<Self::Enabled, (Self, PioError)> {
2561        Ok(self)
2562    }
2563
2564    unsafe fn enable_output_sync_write_unchecked(self) -> Self::Enabled {
2565        self
2566    }
2567}
2568
2569impl<Pio, Pid, Mdvr, Sync, Padr, Irpt, Filt> ConfigureOutputWrite
2570    for Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Sync, Unconfigured>>, Padr, Irpt, Filt>
2571where
2572    Pio: PioRegisters,
2573    Pid: PinId<Controller = Pio>,
2574    Mdvr: MultiDriverCfg,
2575    Sync: OutputSyncWriteCfg,
2576    Padr: PadResistorCfg,
2577    Irpt: InterruptCfg,
2578    Filt: InputFilterCfg,
2579{
2580    type Clear =
2581        Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Sync, ClearOutput>>, Padr, Irpt, Filt>;
2582    type Set = Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Sync, SetOutput>>, Padr, Irpt, Filt>;
2583
2584    fn clear_output(self) -> Self::Clear {
2585        unsafe {
2586            let pioreg = &*Pio::PTR;
2587            if pioreg._odsr().read().bits() & Pid::MASK != 0 {
2588                let _ = self.clear_output_unchecked();
2589                while pioreg._odsr().read().bits() & Pid::MASK != 0 {}
2590            }
2591            Pin::new()
2592        }
2593    }
2594
2595    unsafe fn clear_output_unchecked(self) -> Self::Clear {
2596        let pioreg = &*Pio::PTR;
2597        pioreg._codr().write_with_zero(|w| w.bits(Pid::MASK));
2598        Pin::new()
2599    }
2600
2601    fn set_output(self) -> Self::Set {
2602        unsafe {
2603            let pioreg = &*Pio::PTR;
2604            if pioreg._odsr().read().bits() & Pid::MASK == 0 {
2605                let _ = self.set_output_unchecked();
2606                while pioreg._odsr().read().bits() & Pid::MASK == 0 {}
2607            }
2608            Pin::new()
2609        }
2610    }
2611
2612    unsafe fn set_output_unchecked(self) -> Self::Set {
2613        let pioreg = &*Pio::PTR;
2614        pioreg._sodr().write_with_zero(|w| w.bits(Pid::MASK));
2615        Pin::new()
2616    }
2617}
2618
2619impl<Pio, Pid, Mdvr, Sync, Padr, Irpt, Filt> ConfigureOutputWrite
2620    for Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Sync, ClearOutput>>, Padr, Irpt, Filt>
2621where
2622    Pio: PioRegisters,
2623    Pid: PinId<Controller = Pio>,
2624    Mdvr: MultiDriverCfg,
2625    Sync: OutputSyncWriteCfg,
2626    Padr: PadResistorCfg,
2627    Irpt: InterruptCfg,
2628    Filt: InputFilterCfg,
2629{
2630    type Clear = Self;
2631    type Set = Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Sync, SetOutput>>, Padr, Irpt, Filt>;
2632
2633    fn clear_output(self) -> Self::Clear {
2634        self
2635    }
2636
2637    unsafe fn clear_output_unchecked(self) -> Self::Clear {
2638        self
2639    }
2640
2641    fn set_output(self) -> Self::Set {
2642        unsafe {
2643            let pioreg = &*Pio::PTR;
2644            let _ = self.set_output_unchecked();
2645            while pioreg._odsr().read().bits() & Pid::MASK == 0 {}
2646            Pin::new()
2647        }
2648    }
2649
2650    unsafe fn set_output_unchecked(self) -> Self::Set {
2651        let pioreg = &*Pio::PTR;
2652        pioreg._sodr().write_with_zero(|w| w.bits(Pid::MASK));
2653        Pin::new()
2654    }
2655}
2656
2657impl<Pio, Pid, Mdvr, Sync, Padr, Irpt, Filt> ConfigureOutputWrite
2658    for Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Sync, SetOutput>>, Padr, Irpt, Filt>
2659where
2660    Pio: PioRegisters,
2661    Pid: PinId<Controller = Pio>,
2662    Mdvr: MultiDriverCfg,
2663    Sync: OutputSyncWriteCfg,
2664    Padr: PadResistorCfg,
2665    Irpt: InterruptCfg,
2666    Filt: InputFilterCfg,
2667{
2668    type Clear =
2669        Pin<Pio, Pid, Mdvr, PioControlled<OutputEnabled<Sync, ClearOutput>>, Padr, Irpt, Filt>;
2670    type Set = Self;
2671
2672    fn clear_output(self) -> Self::Clear {
2673        unsafe {
2674            let pioreg = &*Pio::PTR;
2675            let _ = self.clear_output_unchecked();
2676            while pioreg._odsr().read().bits() & Pid::MASK != 0 {}
2677            Pin::new()
2678        }
2679    }
2680
2681    unsafe fn clear_output_unchecked(self) -> Self::Clear {
2682        let pioreg = &*Pio::PTR;
2683        pioreg._codr().write_with_zero(|w| w.bits(Pid::MASK));
2684        Pin::new()
2685    }
2686
2687    fn set_output(self) -> Self::Set {
2688        self
2689    }
2690
2691    unsafe fn set_output_unchecked(self) -> Self::Set {
2692        self
2693    }
2694}