Don't require interconnect signals to be Peripheral impls (#3302)

* Fix unsoundness around DerefMut

* Don't require interconnect signals to be Peripheral impls

* Remove Peripheral impl from pin drivers

* Changelog

* Yeet Level and NoPin impls

* Re-add missing Sealed impl for mutable references

* Relax
This commit is contained in:
Dániel Buga 2025-03-28 15:52:05 +01:00 committed by GitHub
parent 873f033089
commit f6b467402a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 925 additions and 850 deletions

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support for `rand_core` 0.9 (#3211)
- `ESP_HAL_CONFIG_STACK_GUARD_OFFSET` and `ESP_HAL_CONFIG_STACK_GUARD_VALUE` to configure Rust's [Stack smashing protection](https://doc.rust-lang.org/rustc/exploit-mitigations.html#stack-smashing-protection) (#3203)
- Experimental metadata in the output `.elf` (#3276)
- `PeripheralInput::connect_input_to_peripheral` and `PeripheralOuptut::{connect_peripheral_to_output, disconnect_from_peripheral_output}` (#3302)
### Changed
@ -20,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `esp_hal::i2c::master::AnyI2c` has been moved to `esp_hal::i2c::AnyI2c` (#3226)
- `SpiDmaBus` no longer adjusts the DMA buffer length for each transfer (#3263)
- `gpio::interconnect` types now have a lifetime associated with them (#3302)
### Fixed
- RMT now uses correct max filter threshold of 255 instead of 127 (#3192)
@ -37,6 +40,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed
- `gpio::{Level, NoPin, Input, Output, Flex}` no longer implement `Peripheral` (#3302)
## v1.0.0-beta.0
### Added

View File

@ -0,0 +1,23 @@
# Migration Guide from v1.0.0-beta.0 to ?
## GPIO changes
### Interconnect types now have a lifetime
The GPIO interconnect types now have a lifetime. This lifetime prevents them to be live for longer
than the GPIO that was used to create them.
The affected types in the `gpio::interconnect` module are:
- `InputSignal`
- `OutputSignal`
- `InputConnection`
- `OutputConnection`
### Pin drivers no longer implement `Peripheral`
Peripheral drivers now take `impl PeripheralInput` and `impl PeripheralOutput` directly. These
traits are now implemented for GPIO pins (stably) and driver structs (unstably) alike.
This change means it's no longer possible to pass a reference to a GPIO driver to a peripheral
driver. For example, it's no longer possible to pass an `&mut Input` to `Spi::with_miso`.

View File

@ -29,7 +29,7 @@ use crate::{
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct AnyGdmaChannel(u8);
impl Peripheral for AnyGdmaChannel {
unsafe impl Peripheral for AnyGdmaChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
@ -52,7 +52,7 @@ impl DmaChannel for AnyGdmaChannel {
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct AnyGdmaRxChannel(u8);
impl Peripheral for AnyGdmaRxChannel {
unsafe impl Peripheral for AnyGdmaRxChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
@ -71,7 +71,7 @@ impl DmaChannelConvert<AnyGdmaRxChannel> for AnyGdmaRxChannel {
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct AnyGdmaTxChannel(u8);
impl Peripheral for AnyGdmaTxChannel {
unsafe impl Peripheral for AnyGdmaTxChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
@ -602,7 +602,7 @@ macro_rules! impl_channel {
impl $crate::private::Sealed for [<DmaChannel $num>] {}
impl Peripheral for [<DmaChannel $num>] {
unsafe impl Peripheral for [<DmaChannel $num>] {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {

View File

@ -23,7 +23,7 @@ impl CryptoDmaRxChannel {
impl crate::private::Sealed for CryptoDmaRxChannel {}
impl DmaRxChannel for CryptoDmaRxChannel {}
impl Peripheral for CryptoDmaRxChannel {
unsafe impl Peripheral for CryptoDmaRxChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
@ -44,7 +44,7 @@ impl CryptoDmaTxChannel {
impl crate::private::Sealed for CryptoDmaTxChannel {}
impl DmaTxChannel for CryptoDmaTxChannel {}
impl Peripheral for CryptoDmaTxChannel {
unsafe impl Peripheral for CryptoDmaTxChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
@ -438,7 +438,7 @@ pub struct CryptoDmaChannel {}
impl crate::private::Sealed for CryptoDmaChannel {}
impl Peripheral for CryptoDmaChannel {
unsafe impl Peripheral for CryptoDmaChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
Self::steal()

View File

@ -17,7 +17,7 @@ impl AnyI2sDmaRxChannel {
impl crate::private::Sealed for AnyI2sDmaRxChannel {}
impl DmaRxChannel for AnyI2sDmaRxChannel {}
impl Peripheral for AnyI2sDmaRxChannel {
unsafe impl Peripheral for AnyI2sDmaRxChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
@ -38,7 +38,7 @@ impl AnyI2sDmaTxChannel {
impl crate::private::Sealed for AnyI2sDmaTxChannel {}
impl DmaTxChannel for AnyI2sDmaTxChannel {}
impl Peripheral for AnyI2sDmaTxChannel {
unsafe impl Peripheral for AnyI2sDmaTxChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {

View File

@ -59,7 +59,7 @@ macro_rules! impl_pdma_channel {
impl $crate::private::Sealed for [<$instance DmaChannel>] {}
impl Peripheral for [<$instance DmaChannel>] {
unsafe impl Peripheral for [<$instance DmaChannel>] {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {

View File

@ -17,7 +17,7 @@ impl AnySpiDmaRxChannel {
impl crate::private::Sealed for AnySpiDmaRxChannel {}
impl DmaRxChannel for AnySpiDmaRxChannel {}
impl Peripheral for AnySpiDmaRxChannel {
unsafe impl Peripheral for AnySpiDmaRxChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
@ -38,7 +38,7 @@ impl AnySpiDmaTxChannel {
impl crate::private::Sealed for AnySpiDmaTxChannel {}
impl DmaTxChannel for AnySpiDmaTxChannel {}
impl Peripheral for AnySpiDmaTxChannel {
unsafe impl Peripheral for AnySpiDmaTxChannel {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {

View File

@ -150,7 +150,7 @@ impl<const C: u8> EventChannel<C> {
/// Trigger at rising edge
pub fn rising_edge<'d>(
self,
pin: impl Peripheral<P = impl Into<InputSignal>> + 'd,
pin: impl Into<InputSignal<'d>>,
pin_config: InputConfig,
) -> Event<'d> {
self.into_event(pin, pin_config, EventKind::Rising)
@ -159,7 +159,7 @@ impl<const C: u8> EventChannel<C> {
/// Trigger at falling edge
pub fn falling_edge<'d>(
self,
pin: impl Peripheral<P = impl Into<InputSignal>> + 'd,
pin: impl Into<InputSignal<'d>>,
pin_config: InputConfig,
) -> Event<'d> {
self.into_event(pin, pin_config, EventKind::Falling)
@ -168,7 +168,7 @@ impl<const C: u8> EventChannel<C> {
/// Trigger at any edge
pub fn any_edge<'d>(
self,
pin: impl Peripheral<P = impl Into<InputSignal>> + 'd,
pin: impl Into<InputSignal<'d>>,
pin_config: InputConfig,
) -> Event<'d> {
self.into_event(pin, pin_config, EventKind::Any)
@ -176,11 +176,11 @@ impl<const C: u8> EventChannel<C> {
fn into_event<'d>(
self,
pin: impl Peripheral<P = impl Into<InputSignal>> + 'd,
pin: impl Into<InputSignal<'d>>,
pin_config: InputConfig,
kind: EventKind,
) -> Event<'d> {
crate::into_mapped_ref!(pin);
let pin = pin.into();
pin.init_input(pin_config.pull);
@ -256,27 +256,19 @@ impl<const C: u8> TaskChannel<C> {
// number is the pin-count
/// Task to set a high level
pub fn set<'d>(
self,
pin: impl Peripheral<P = impl Into<OutputSignal>> + 'd,
pin_config: OutputConfig,
) -> Task<'d> {
pub fn set<'d>(self, pin: impl Into<OutputSignal<'d>>, pin_config: OutputConfig) -> Task<'d> {
self.into_task(pin, pin_config, TaskKind::Set)
}
/// Task to set a low level
pub fn clear<'d>(
self,
pin: impl Peripheral<P = impl Into<OutputSignal>> + 'd,
pin_config: OutputConfig,
) -> Task<'d> {
pub fn clear<'d>(self, pin: impl Into<OutputSignal<'d>>, pin_config: OutputConfig) -> Task<'d> {
self.into_task(pin, pin_config, TaskKind::Clear)
}
/// Task to toggle the level
pub fn toggle<'d>(
self,
pin: impl Peripheral<P = impl Into<OutputSignal>> + 'd,
pin: impl Into<OutputSignal<'d>>,
pin_config: OutputConfig,
) -> Task<'d> {
self.into_task(pin, pin_config, TaskKind::Toggle)
@ -284,11 +276,11 @@ impl<const C: u8> TaskChannel<C> {
fn into_task<'d>(
self,
pin: impl Peripheral<P = impl Into<OutputSignal>> + 'd,
pin: impl Into<OutputSignal<'d>>,
pin_config: OutputConfig,
kind: TaskKind,
) -> Task<'d> {
crate::into_mapped_ref!(pin);
let pin = pin.into();
pin.set_output_high(pin_config.initial_state.into());
if pin_config.open_drain {

View File

@ -7,6 +7,10 @@
// interconnect module we allow multiple handles, which means possible RMW
// operations on the pin registers cause data races.
use core::marker::PhantomData;
#[cfg(feature = "unstable")]
use crate::gpio::{Input, Output};
use crate::{
gpio::{
self,
@ -27,7 +31,7 @@ use crate::{
INPUT_SIGNAL_MAX,
OUTPUT_SIGNAL_MAX,
},
peripheral::Peripheral,
peripheral::{Peripheral, PeripheralRef},
peripherals::GPIO,
private::{self, Sealed},
};
@ -40,7 +44,10 @@ use crate::{
private_bounds,
reason = "InputConnection is unstable, but the trait needs to be public"
)]
pub trait PeripheralInput: Into<InputConnection> + 'static + crate::private::Sealed {}
pub trait PeripheralInput<'d>: Into<InputConnection<'d>> + crate::private::Sealed {
/// Connects the peripheral input to an input signal source.
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal);
}
/// A signal that can be connected to a peripheral input and/or output.
///
@ -50,32 +57,186 @@ pub trait PeripheralInput: Into<InputConnection> + 'static + crate::private::Sea
private_bounds,
reason = "OutputConnection is unstable, but the trait needs to be public"
)]
pub trait PeripheralOutput: Into<OutputConnection> + 'static + crate::private::Sealed {}
pub trait PeripheralOutput<'d>: Into<OutputConnection<'d>> + crate::private::Sealed {
/// Connects the peripheral output to an output signal target.
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal);
/// Disconnects the peripheral output from an output signal target.
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal);
}
// Pins
impl<P: InputPin> PeripheralInput for P {}
impl<P: OutputPin> PeripheralOutput for P {}
impl<P, IP> PeripheralInput<'_> for P
where
P: Peripheral<P = IP> + crate::private::Sealed,
IP: InputPin,
{
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
let this = PeripheralRef::new(unsafe { self.clone_unchecked() });
let pin = unsafe { AnyPin::steal(this.number()) };
DirectInputSignal::new(pin).connect_input_to_peripheral(signal);
}
}
impl<P, OP> PeripheralOutput<'_> for P
where
P: Peripheral<P = OP> + crate::private::Sealed,
OP: OutputPin,
{
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
let this = PeripheralRef::new(unsafe { self.clone_unchecked() });
let pin = unsafe { AnyPin::steal(this.number()) };
DirectOutputSignal::new(pin).connect_peripheral_to_output(signal);
}
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
let this = PeripheralRef::new(unsafe { self.clone_unchecked() });
let pin = unsafe { AnyPin::steal(this.number()) };
DirectOutputSignal::new(pin).disconnect_from_peripheral_output(signal);
}
}
// Pin drivers
impl PeripheralInput for Flex<'static> {}
impl PeripheralOutput for Flex<'static> {}
impl<'d> PeripheralInput<'d> for Flex<'d> {
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
let pin = unsafe { AnyPin::steal(self.pin.number()) };
InputSignal::new(pin).connect_input_to_peripheral(signal);
}
}
#[instability::unstable]
impl<'d> PeripheralInput<'d> for Input<'d> {
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
// Delegate to Flex
self.pin.connect_input_to_peripheral(signal);
}
}
impl<'d> PeripheralOutput<'d> for Flex<'d> {
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
let pin = unsafe { AnyPin::steal(self.pin.number()) };
OutputSignal::new(pin).connect_peripheral_to_output(signal);
}
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
let pin = unsafe { AnyPin::steal(self.pin.number()) };
OutputSignal::new(pin).disconnect_from_peripheral_output(signal);
}
}
#[instability::unstable]
impl<'d> PeripheralOutput<'d> for Output<'d> {
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
// Delegate to Flex
self.pin.connect_peripheral_to_output(signal);
}
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
// Delegate to Flex
self.pin.disconnect_from_peripheral_output(signal);
}
}
// Placeholders
impl PeripheralInput for NoPin {}
impl PeripheralOutput for NoPin {}
impl PeripheralInput<'_> for NoPin {
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
// Arbitrary choice but we need to overwrite a previous signal input
// association.
Level::Low.connect_input_to_peripheral(signal);
}
}
impl PeripheralOutput<'_> for NoPin {
fn connect_peripheral_to_output(&self, _: gpio::OutputSignal) {
// A peripheral's outputs may be connected to any number of GPIOs.
// Connecting to, and disconnecting from a NoPin is therefore a
// no-op, as we are adding and removing nothing from that list of
// connections.
}
fn disconnect_from_peripheral_output(&self, _: gpio::OutputSignal) {
// A peripheral's outputs may be connected to any number of GPIOs.
// Connecting to, and disconnecting from a NoPin is therefore a
// no-op, as we are adding and removing nothing from that list of
// connections.
}
}
impl PeripheralInput for Level {}
impl PeripheralOutput for Level {}
impl PeripheralInput<'_> for Level {
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
let value = match self {
Level::High => gpio::ONE_INPUT,
Level::Low => gpio::ZERO_INPUT,
};
connect_input_signal(signal, value, false, true);
}
}
impl PeripheralOutput<'_> for Level {
fn connect_peripheral_to_output(&self, _: gpio::OutputSignal) {
// There is no such thing as a constant-high level peripheral output,
// the implementation just exists for convenience.
}
fn disconnect_from_peripheral_output(&self, _: gpio::OutputSignal) {
// There is no such thing as a constant-high level peripheral output,
// the implementation just exists for convenience.
}
}
// Split signals
impl PeripheralInput for InputSignal {}
impl PeripheralInput for OutputSignal {}
impl PeripheralOutput for OutputSignal {}
impl<'d> PeripheralInput<'d> for InputSignal<'d> {
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
// Since there can only be one input signal connected to a peripheral
// at a time, this function will disconnect any previously
// connected input signals.
connect_pin_to_input_signal(&self.pin, signal, self.is_inverted, true);
}
}
impl<'d> PeripheralInput<'d> for OutputSignal<'d> {
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
connect_pin_to_input_signal(&self.pin, signal, self.is_inverted, true);
}
}
impl<'d> PeripheralOutput<'d> for OutputSignal<'d> {
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
connect_peripheral_to_output(&self.pin, signal, self.is_inverted, true, true, false);
}
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
// Clears the entry in the GPIO matrix / Io mux that associates this output
// pin with a previously connected [signal](`gpio::OutputSignal`). Any
// other outputs connected to the peripheral remain intact.
disconnect_peripheral_output_from_pin(&self.pin, signal);
}
}
// Type-erased signals
impl PeripheralInput for InputConnection {}
impl PeripheralInput for OutputConnection {}
impl PeripheralOutput for OutputConnection {}
impl<'d> PeripheralInput<'d> for InputConnection<'d> {
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
self.connect_input_to_peripheral(signal);
}
}
impl<'d> PeripheralInput<'d> for OutputConnection<'d> {
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
match &self.0 {
OutputConnectionInner::Output(pin) => pin.connect_input_to_peripheral(signal),
OutputConnectionInner::DirectOutput(pin) => pin.connect_input_to_peripheral(signal),
OutputConnectionInner::Constant(level) => level.connect_input_to_peripheral(signal),
}
}
}
impl<'d> PeripheralOutput<'d> for OutputConnection<'d> {
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
match &self.0 {
OutputConnectionInner::Output(pin) => pin.connect_peripheral_to_output(signal),
OutputConnectionInner::DirectOutput(pin) => pin.connect_peripheral_to_output(signal),
OutputConnectionInner::Constant(level) => level.connect_peripheral_to_output(signal),
}
}
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
match &self.0 {
OutputConnectionInner::Output(pin) => pin.disconnect_from_peripheral_output(signal),
OutputConnectionInner::DirectOutput(pin) => {
pin.disconnect_from_peripheral_output(signal)
}
OutputConnectionInner::Constant(level) => {
level.disconnect_from_peripheral_output(signal)
}
}
}
}
impl gpio::InputSignal {
fn can_use_gpio_matrix(self) -> bool {
@ -91,9 +252,7 @@ impl gpio::InputSignal {
/// so if you want to disconnect it from GPIOs, you should connect it to a
/// constant level.
#[inline]
pub fn connect_to(self, pin: impl Peripheral<P = impl PeripheralInput>) {
crate::into_mapped_ref!(pin);
pub fn connect_to<'d>(self, pin: &impl PeripheralInput<'d>) {
pin.connect_input_to_peripheral(self);
}
}
@ -111,17 +270,13 @@ impl gpio::OutputSignal {
/// Also note that it is possible to connect a peripheral output signal to
/// multiple GPIOs, and old connections will not be cleared automatically.
#[inline]
pub fn connect_to(self, pin: impl Peripheral<P = impl PeripheralOutput>) {
crate::into_mapped_ref!(pin);
pub fn connect_to<'d>(self, pin: &impl PeripheralOutput<'d>) {
pin.connect_peripheral_to_output(self);
}
/// Disconnects a peripheral output signal from a GPIO.
#[inline]
pub fn disconnect_from(self, pin: impl Peripheral<P = impl PeripheralOutput>) {
crate::into_mapped_ref!(pin);
pub fn disconnect_from<'d>(self, pin: &impl PeripheralOutput<'d>) {
pin.disconnect_from_peripheral_output(self);
}
}
@ -229,53 +384,66 @@ fn disconnect_peripheral_output_from_pin(pin: &AnyPin, signal: gpio::OutputSigna
///
/// Multiple input signals can be connected to one pin.
#[instability::unstable]
pub struct InputSignal {
pub struct InputSignal<'d> {
pin: AnyPin,
is_inverted: bool,
_lifetime: PhantomData<&'d mut ()>,
}
impl<P> From<P> for InputSignal
where
P: InputPin,
{
fn from(input: P) -> Self {
Self::new(input.degrade())
}
}
impl Sealed for InputSignal<'_> {}
impl From<Flex<'static>> for InputSignal {
fn from(input: Flex<'static>) -> Self {
Self::new(unsafe { AnyPin::steal(input.pin.number()) })
}
}
impl Clone for InputSignal {
impl Clone for InputSignal<'_> {
fn clone(&self) -> Self {
Self {
pin: unsafe { self.pin.clone_unchecked() },
is_inverted: self.is_inverted,
_lifetime: PhantomData,
}
}
}
impl Peripheral for InputSignal {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
self.clone()
impl<'d, P, OP> From<P> for InputSignal<'d>
where
P: Peripheral<P = OP> + 'd,
OP: InputPin,
{
fn from(output: P) -> Self {
crate::into_ref!(output);
InputSignal::new(unsafe { AnyPin::steal(output.number()) })
}
}
impl Sealed for InputSignal {}
impl<'d> From<Flex<'d>> for InputSignal<'d> {
fn from(input: Flex<'d>) -> Self {
InputSignal::new(unsafe { AnyPin::steal(input.pin.number()) })
}
}
impl InputSignal {
#[instability::unstable]
impl<'d> From<Input<'d>> for InputSignal<'d> {
fn from(input: Input<'d>) -> Self {
input.pin.into()
}
}
#[instability::unstable]
impl<'d> From<Output<'d>> for InputSignal<'d> {
fn from(output: Output<'d>) -> Self {
output.pin.into()
}
}
impl InputSignal<'static> {
pub(crate) fn new(pin: AnyPin) -> Self {
Self {
pin,
is_inverted: false,
_lifetime: PhantomData,
}
}
}
impl InputSignal<'_> {
/// Returns the GPIO number of the underlying pin.
pub fn number(&self) -> u8 {
self.pin.number()
@ -302,15 +470,6 @@ impl InputSignal {
self
}
/// Connect the pin to a peripheral input signal.
///
/// Since there can only be one input signal connected to a peripheral at a
/// time, this function will disconnect any previously connected input
/// signals.
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
connect_pin_to_input_signal(&self.pin, signal, self.is_inverted, true);
}
delegate::delegate! {
#[doc(hidden)]
to self.pin {
@ -365,47 +524,49 @@ impl DirectInputSignal {
///
/// Multiple pins can be connected to one output signal.
#[instability::unstable]
pub struct OutputSignal {
pub struct OutputSignal<'d> {
pin: AnyPin,
is_inverted: bool,
_lifetime: PhantomData<&'d mut ()>,
}
impl<P> From<P> for OutputSignal
impl Sealed for OutputSignal<'_> {}
impl<'d, P, OP> From<P> for OutputSignal<'d>
where
P: OutputPin,
P: Peripheral<P = OP> + 'd,
OP: OutputPin,
{
fn from(output: P) -> Self {
Self::new(output.degrade())
crate::into_ref!(output);
OutputSignal::new(unsafe { AnyPin::steal(output.number()) })
}
}
impl From<Flex<'static>> for OutputSignal {
fn from(output: Flex<'static>) -> Self {
Self::new(unsafe { AnyPin::steal(output.pin.number()) })
impl<'d> From<Flex<'d>> for OutputSignal<'d> {
fn from(output: Flex<'d>) -> Self {
OutputSignal::new(unsafe { AnyPin::steal(output.pin.number()) })
}
}
impl Peripheral for OutputSignal {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
Self {
pin: self.pin.clone_unchecked(),
is_inverted: self.is_inverted,
}
#[instability::unstable]
impl<'d> From<Output<'d>> for OutputSignal<'d> {
fn from(output: Output<'d>) -> Self {
output.pin.into()
}
}
impl Sealed for OutputSignal {}
impl OutputSignal {
impl OutputSignal<'static> {
pub(crate) fn new(pin: AnyPin) -> Self {
Self {
pin,
is_inverted: false,
_lifetime: PhantomData,
}
}
}
impl OutputSignal<'_> {
/// Returns the GPIO number of the underlying pin.
pub fn number(&self) -> u8 {
self.pin.number()
@ -427,20 +588,6 @@ impl OutputSignal {
self
}
/// Connect the pin to a peripheral output signal.
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
connect_peripheral_to_output(&self.pin, signal, self.is_inverted, true, true, false);
}
/// Remove this output pin from a connected [signal](`gpio::OutputSignal`).
///
/// Clears the entry in the GPIO matrix / Io mux that associates this output
/// pin with a previously connected [signal](`gpio::OutputSignal`). Any
/// other outputs connected to the peripheral remain intact.
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
disconnect_peripheral_output_from_pin(&self.pin, signal);
}
delegate::delegate! {
#[instability::unstable]
to self.pin {
@ -474,6 +621,11 @@ impl DirectOutputSignal {
Self { pin }
}
/// Connect the pin to a peripheral input signal.
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
connect_pin_to_input_signal(&self.pin, signal, false, false);
}
/// Connect the pin to a peripheral output signal.
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
connect_peripheral_to_output(&self.pin, signal, false, false, true, false);
@ -509,8 +661,8 @@ impl DirectOutputSignal {
}
#[derive(Clone)]
enum InputConnectionInner {
Input(InputSignal),
enum InputConnectionInner<'d> {
Input(InputSignal<'d>),
DirectInput(DirectInputSignal),
Constant(Level),
}
@ -521,62 +673,64 @@ enum InputConnectionInner {
/// peripherals within the MCU without external hardware.
#[derive(Clone)]
#[instability::unstable]
pub struct InputConnection(InputConnectionInner);
pub struct InputConnection<'d>(InputConnectionInner<'d>);
impl Sealed for InputConnection<'_> {}
impl Peripheral for InputConnection {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
self.clone()
}
}
impl From<InputSignal> for InputConnection {
fn from(input: InputSignal) -> Self {
impl<'d> From<InputSignal<'d>> for InputConnection<'d> {
fn from(input: InputSignal<'d>) -> Self {
Self(InputConnectionInner::Input(input))
}
}
impl From<Level> for InputConnection {
impl From<Level> for InputConnection<'_> {
fn from(level: Level) -> Self {
Self(InputConnectionInner::Constant(level))
}
}
impl From<NoPin> for InputConnection {
impl From<NoPin> for InputConnection<'_> {
fn from(_pin: NoPin) -> Self {
Self(InputConnectionInner::Constant(Level::Low))
}
}
impl<P> From<P> for InputConnection
impl<P, GPIO> From<P> for InputConnection<'_>
where
P: InputPin,
P: Peripheral<P = GPIO> + crate::private::Sealed,
GPIO: Pin,
{
fn from(input: P) -> Self {
Self(InputConnectionInner::Input(InputSignal::from(input)))
}
}
impl From<OutputSignal> for InputConnection {
fn from(output_signal: OutputSignal) -> Self {
Self(InputConnectionInner::Input(InputSignal {
pin: output_signal.pin,
is_inverted: output_signal.is_inverted,
crate::into_ref!(input);
InputConnection::from(DirectInputSignal::new(unsafe {
AnyPin::steal(input.number())
}))
}
}
impl From<DirectOutputSignal> for InputConnection {
fn from(output_signal: DirectOutputSignal) -> Self {
Self(InputConnectionInner::DirectInput(DirectInputSignal::new(
output_signal.pin,
)))
impl<'d> From<OutputSignal<'d>> for InputConnection<'d> {
fn from(output_signal: OutputSignal<'d>) -> Self {
InputConnection::from(InputSignal {
pin: output_signal.pin,
is_inverted: output_signal.is_inverted,
_lifetime: PhantomData,
})
}
}
impl From<OutputConnection> for InputConnection {
fn from(conn: OutputConnection) -> Self {
impl From<DirectInputSignal> for InputConnection<'static> {
fn from(input_signal: DirectInputSignal) -> Self {
InputConnection(InputConnectionInner::DirectInput(input_signal))
}
}
impl From<DirectOutputSignal> for InputConnection<'static> {
fn from(output_signal: DirectOutputSignal) -> Self {
InputConnection::from(DirectInputSignal::new(output_signal.pin))
}
}
impl<'d> From<OutputConnection<'d>> for InputConnection<'d> {
fn from(conn: OutputConnection<'d>) -> Self {
match conn.0 {
OutputConnectionInner::Output(inner) => inner.into(),
OutputConnectionInner::DirectOutput(inner) => inner.into(),
@ -585,15 +739,27 @@ impl From<OutputConnection> for InputConnection {
}
}
impl From<Flex<'static>> for InputConnection {
fn from(pin: Flex<'static>) -> Self {
impl<'d> From<Flex<'d>> for InputConnection<'d> {
fn from(pin: Flex<'d>) -> Self {
pin.peripheral_input().into()
}
}
impl Sealed for InputConnection {}
#[instability::unstable]
impl<'d> From<Input<'d>> for InputConnection<'d> {
fn from(pin: Input<'d>) -> Self {
pin.pin.into()
}
}
impl InputConnection {
#[instability::unstable]
impl<'d> From<Output<'d>> for InputConnection<'d> {
fn from(pin: Output<'d>) -> Self {
pin.pin.into()
}
}
impl InputConnection<'_> {
delegate::delegate! {
#[instability::unstable]
to match &self.0 {
@ -613,8 +779,8 @@ impl InputConnection {
}
}
enum OutputConnectionInner {
Output(OutputSignal),
enum OutputConnectionInner<'d> {
Output(OutputSignal<'d>),
DirectOutput(DirectOutputSignal),
Constant(Level),
}
@ -624,64 +790,60 @@ enum OutputConnectionInner {
/// This is mainly intended for internal use, but it can be used to connect
/// peripherals within the MCU without external hardware.
#[instability::unstable]
pub struct OutputConnection(OutputConnectionInner);
pub struct OutputConnection<'d>(OutputConnectionInner<'d>);
impl Sealed for OutputConnection<'_> {}
impl Sealed for OutputConnection {}
impl Peripheral for OutputConnection {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
match self {
Self(OutputConnectionInner::Output(signal)) => Self::from(signal.clone_unchecked()),
Self(OutputConnectionInner::DirectOutput(signal)) => {
Self::from(DirectOutputSignal::new(signal.pin.clone_unchecked()))
}
Self(OutputConnectionInner::Constant(level)) => Self::from(*level),
}
impl<'d> From<OutputSignal<'d>> for OutputConnection<'d> {
fn from(signal: OutputSignal<'d>) -> Self {
Self(OutputConnectionInner::Output(signal))
}
}
impl From<NoPin> for OutputConnection {
impl From<NoPin> for OutputConnection<'_> {
fn from(_pin: NoPin) -> Self {
Self(OutputConnectionInner::Constant(Level::Low))
}
}
impl From<Level> for OutputConnection {
impl From<Level> for OutputConnection<'_> {
fn from(level: Level) -> Self {
Self(OutputConnectionInner::Constant(level))
}
}
impl<P> From<P> for OutputConnection
impl<P, OP> From<P> for OutputConnection<'_>
where
P: OutputPin,
P: Peripheral<P = OP> + crate::private::Sealed,
OP: OutputPin,
{
fn from(input: P) -> Self {
Self(OutputConnectionInner::Output(OutputSignal::from(input)))
fn from(output: P) -> Self {
crate::into_ref!(output);
OutputConnection::from(DirectOutputSignal::new(unsafe {
AnyPin::steal(output.number())
}))
}
}
impl From<OutputSignal> for OutputConnection {
fn from(signal: OutputSignal) -> Self {
Self(OutputConnectionInner::Output(signal))
}
}
impl From<Flex<'static>> for OutputConnection {
fn from(pin: Flex<'static>) -> Self {
impl<'d> From<Flex<'d>> for OutputConnection<'d> {
fn from(pin: Flex<'d>) -> Self {
pin.into_peripheral_output().into()
}
}
impl From<DirectOutputSignal> for OutputConnection {
#[instability::unstable]
impl<'d> From<Output<'d>> for OutputConnection<'d> {
fn from(pin: Output<'d>) -> Self {
pin.pin.into()
}
}
impl From<DirectOutputSignal> for OutputConnection<'static> {
fn from(signal: DirectOutputSignal) -> Self {
Self(OutputConnectionInner::DirectOutput(signal))
}
}
impl OutputConnection {
impl OutputConnection<'_> {
delegate::delegate! {
#[instability::unstable]
to match &self.0 {
@ -704,25 +866,13 @@ impl OutputConnection {
pub fn set_output_high(&self, on: bool);
pub fn set_drive_strength(&self, strength: gpio::DriveStrength);
pub fn enable_open_drain(&self, on: bool);
// These don't need to be public, the intended way is `connect_to` and `disconnect_from`
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal);
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal);
}
}
pub(crate) fn connect_with_guard(
this: impl Peripheral<P = impl PeripheralOutput>,
signal: crate::gpio::OutputSignal,
) -> PinGuard {
crate::into_mapped_ref!(this);
match &this.0 {
OutputConnectionInner::Output(pin) => {
PinGuard::new(unsafe { pin.pin.clone_unchecked() }, signal)
}
OutputConnectionInner::DirectOutput(pin) => {
PinGuard::new(unsafe { pin.pin.clone_unchecked() }, signal)
}
pub(crate) fn connect_with_guard(self, signal: crate::gpio::OutputSignal) -> PinGuard {
match self.0 {
OutputConnectionInner::Output(pin) => PinGuard::new(pin.pin, signal),
OutputConnectionInner::DirectOutput(pin) => PinGuard::new(pin.pin, signal),
OutputConnectionInner::Constant(_) => PinGuard::new_unconnected(signal),
}
}

View File

@ -132,22 +132,13 @@ pub(crate) struct PinGuard {
}
impl crate::private::Sealed for PinGuard {}
impl Peripheral for PinGuard {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
Self {
pin: self.pin,
signal: self.signal,
}
}
}
impl PinGuard {
pub(crate) fn new(mut pin: AnyPin, signal: OutputSignal) -> Self {
signal.connect_to(&mut pin);
pub(crate) fn new(pin: AnyPin, signal: OutputSignal) -> Self {
let number = pin.number();
signal.connect_to(&pin.into_ref());
Self {
pin: pin.number(),
pin: number,
signal,
}
}
@ -163,8 +154,8 @@ impl PinGuard {
impl Drop for PinGuard {
fn drop(&mut self) {
if self.pin != u8::MAX {
let mut pin = unsafe { AnyPin::steal(self.pin) };
self.signal.disconnect_from(&mut pin);
let pin = unsafe { AnyPin::steal(self.pin) };
self.signal.disconnect_from(&pin.into_ref());
}
}
}
@ -650,7 +641,12 @@ where
/// # }
/// ```
#[instability::unstable]
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
pub fn split(
self,
) -> (
interconnect::InputSignal<'static>,
interconnect::OutputSignal<'static>,
) {
// FIXME: we should implement this in the gpio macro for output pins, but we
// should also have an input-only alternative for pins that can't be used as
// outputs.
@ -689,7 +685,7 @@ fn disable_usb_pads(gpionum: u8) {
}
}
impl<const GPIONUM: u8> Peripheral for GpioPin<GPIONUM>
unsafe impl<const GPIONUM: u8> Peripheral for GpioPin<GPIONUM>
where
Self: Pin,
{
@ -963,7 +959,7 @@ macro_rules! gpio {
}
)+
impl $crate::peripheral::Peripheral for $crate::gpio::AnyPin {
unsafe impl $crate::peripheral::Peripheral for $crate::gpio::AnyPin {
type P = $crate::gpio::AnyPin;
unsafe fn clone_unchecked(&self) -> Self {
Self(self.0)
@ -1150,13 +1146,6 @@ pub struct Output<'d> {
impl private::Sealed for Output<'_> {}
impl<'d> Peripheral for Output<'d> {
type P = Flex<'d>;
unsafe fn clone_unchecked(&self) -> Self::P {
self.pin.clone_unchecked()
}
}
impl<'d> Output<'d> {
/// Creates a new GPIO output driver.
///
@ -1222,7 +1211,12 @@ impl<'d> Output<'d> {
/// ```
#[inline]
#[instability::unstable]
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
pub fn split(
self,
) -> (
interconnect::InputSignal<'d>,
interconnect::OutputSignal<'d>,
) {
self.pin.split()
}
@ -1242,7 +1236,7 @@ impl<'d> Output<'d> {
/// ```
#[inline]
#[instability::unstable]
pub fn peripheral_input(&self) -> interconnect::InputSignal {
pub fn peripheral_input(&self) -> interconnect::InputSignal<'d> {
self.pin.peripheral_input()
}
@ -1262,7 +1256,7 @@ impl<'d> Output<'d> {
/// ```
#[inline]
#[instability::unstable]
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
pub fn into_peripheral_output(self) -> interconnect::OutputSignal<'d> {
self.pin.into_peripheral_output()
}
@ -1361,13 +1355,6 @@ pub struct Input<'d> {
impl private::Sealed for Input<'_> {}
impl<'d> Peripheral for Input<'d> {
type P = Flex<'d>;
unsafe fn clone_unchecked(&self) -> Self::P {
self.pin.clone_unchecked()
}
}
impl<'d> Input<'d> {
/// Creates a new GPIO input.
///
@ -1432,7 +1419,7 @@ impl<'d> Input<'d> {
/// ```
#[inline]
#[instability::unstable]
pub fn peripheral_input(&self) -> interconnect::InputSignal {
pub fn peripheral_input(&self) -> interconnect::InputSignal<'d> {
self.pin.peripheral_input()
}
@ -1586,7 +1573,12 @@ impl<'d> Input<'d> {
/// ```
#[inline]
#[instability::unstable]
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
pub fn split(
self,
) -> (
interconnect::InputSignal<'d>,
interconnect::OutputSignal<'d>,
) {
self.pin.split()
}
@ -1607,7 +1599,7 @@ impl<'d> Input<'d> {
/// ```
#[inline]
#[instability::unstable]
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
pub fn into_peripheral_output(self) -> interconnect::OutputSignal<'d> {
self.pin.into_peripheral_output()
}
@ -1630,15 +1622,6 @@ pub struct Flex<'d> {
impl private::Sealed for Flex<'_> {}
impl Peripheral for Flex<'_> {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
Self {
pin: PeripheralRef::new(AnyPin(self.pin.number())),
}
}
}
impl<'d> Flex<'d> {
/// Create flexible pin driver for a [Pin].
/// No mode change happens.
@ -1683,7 +1666,7 @@ impl<'d> Flex<'d> {
/// ```
#[inline]
#[instability::unstable]
pub fn peripheral_input(&self) -> interconnect::InputSignal {
pub fn peripheral_input(&self) -> interconnect::InputSignal<'d> {
unsafe { AnyPin::steal(self.number()) }.split().0
}
@ -1919,7 +1902,12 @@ impl<'d> Flex<'d> {
/// ```
#[inline]
#[instability::unstable]
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
pub fn split(
self,
) -> (
interconnect::InputSignal<'d>,
interconnect::OutputSignal<'d>,
) {
assert!(self.pin.is_output());
unsafe { AnyPin::steal(self.number()) }.split()
}
@ -1940,7 +1928,7 @@ impl<'d> Flex<'d> {
/// ```
#[inline]
#[instability::unstable]
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
pub fn into_peripheral_output(self) -> interconnect::OutputSignal<'d> {
self.split().1
}
}
@ -1986,7 +1974,12 @@ impl AnyPin {
/// ```
#[inline]
#[instability::unstable]
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
pub fn split(
self,
) -> (
interconnect::InputSignal<'static>,
interconnect::OutputSignal<'static>,
) {
assert!(self.is_output());
(
interconnect::InputSignal::new(Self(self.0)),

View File

@ -6,15 +6,6 @@
// polluting the main module.
use super::*;
use crate::gpio::interconnect::connect_input_signal;
impl crate::peripheral::Peripheral for Level {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
*self
}
}
impl Level {
pub(crate) fn pull_direction(&self, _pull: Pull) {}
@ -34,15 +25,6 @@ impl Level {
*self == Level::High
}
pub(crate) fn connect_input_to_peripheral(&self, signal: InputSignal) {
let value = match self {
Level::High => ONE_INPUT,
Level::Low => ZERO_INPUT,
};
connect_input_signal(signal, value, false, true);
}
pub(crate) fn set_to_open_drain_output(&self) {}
pub(crate) fn set_to_push_pull_output(&self) {}
pub(crate) fn enable_output(&self, _on: bool) {}
@ -60,10 +42,6 @@ impl Level {
) -> &'static [(AlternateFunction, OutputSignal)] {
&[]
}
pub(crate) fn connect_peripheral_to_output(&self, _signal: OutputSignal) {}
pub(crate) fn disconnect_from_peripheral_output(&self, _signal: OutputSignal) {}
}
/// Placeholder pin, used when no pin is required when using a peripheral.
@ -72,14 +50,6 @@ impl Level {
#[derive(Default, Clone, Copy)]
pub struct NoPin;
impl crate::peripheral::Peripheral for NoPin {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
Self
}
}
impl private::Sealed for NoPin {}
impl embedded_hal::digital::ErrorType for NoPin {

View File

@ -917,7 +917,7 @@ where
/// Connect a pin to the I2C SDA signal.
///
/// This will replace previous pin assignments for this signal.
pub fn with_sda(mut self, sda: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
pub fn with_sda(mut self, sda: impl PeripheralOutput<'d>) -> Self {
let info = self.driver().info;
let input = info.sda_input;
let output = info.sda_output;
@ -929,7 +929,7 @@ where
/// Connect a pin to the I2C SCL signal.
///
/// This will replace previous pin assignments for this signal.
pub fn with_scl(mut self, scl: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
pub fn with_scl(mut self, scl: impl PeripheralOutput<'d>) -> Self {
let info = self.driver().info;
let input = info.scl_input;
let output = info.scl_output;
@ -939,12 +939,12 @@ where
}
fn connect_pin(
pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin: impl PeripheralOutput<'d>,
input: InputSignal,
output: OutputSignal,
guard: &mut PinGuard,
) {
crate::into_mapped_ref!(pin);
let pin = pin.into();
// avoid the pin going low during configuration
pin.set_output_high(true);
@ -952,7 +952,7 @@ where
pin.enable_input(true);
pin.pull_direction(Pull::Up);
input.connect_to(pin.reborrow());
input.connect_to(&pin);
*guard = OutputConnection::connect_with_guard(pin, output);
}

View File

@ -403,10 +403,10 @@ where
Dm: DriverMode,
{
/// Configures the I2S peripheral to use a master clock (MCLK) output pin.
pub fn with_mclk<P: PeripheralOutput>(self, pin: impl Peripheral<P = P> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pin.set_to_push_pull_output();
self.i2s_tx.i2s.mclk_signal().connect_to(pin);
pub fn with_mclk(self, mclk: impl PeripheralOutput<'d>) -> Self {
let mclk = mclk.into();
mclk.set_to_push_pull_output();
self.i2s_tx.i2s.mclk_signal().connect_to(&mclk);
self
}
@ -729,35 +729,26 @@ mod private {
}
}
pub fn with_bclk<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
where
P: PeripheralOutput,
{
crate::into_mapped_ref!(pin);
pin.set_to_push_pull_output();
self.i2s.bclk_signal().connect_to(pin);
pub fn with_bclk(self, bclk: impl PeripheralOutput<'d>) -> Self {
let bclk = bclk.into();
bclk.set_to_push_pull_output();
self.i2s.bclk_signal().connect_to(&bclk);
self
}
pub fn with_ws<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
where
P: PeripheralOutput,
{
crate::into_mapped_ref!(pin);
pin.set_to_push_pull_output();
self.i2s.ws_signal().connect_to(pin);
pub fn with_ws(self, ws: impl PeripheralOutput<'d>) -> Self {
let ws = ws.into();
ws.set_to_push_pull_output();
self.i2s.ws_signal().connect_to(&ws);
self
}
pub fn with_dout<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
where
P: PeripheralOutput,
{
crate::into_mapped_ref!(pin);
pin.set_to_push_pull_output();
self.i2s.dout_signal().connect_to(pin);
pub fn with_dout(self, dout: impl PeripheralOutput<'d>) -> Self {
let dout = dout.into();
dout.set_to_push_pull_output();
self.i2s.dout_signal().connect_to(&dout);
self
}
@ -787,35 +778,26 @@ mod private {
}
}
pub fn with_bclk<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
where
P: PeripheralOutput,
{
crate::into_mapped_ref!(pin);
pin.set_to_push_pull_output();
self.i2s.bclk_rx_signal().connect_to(pin);
pub fn with_bclk(self, bclk: impl PeripheralOutput<'d>) -> Self {
let bclk = bclk.into();
bclk.set_to_push_pull_output();
self.i2s.bclk_rx_signal().connect_to(&bclk);
self
}
pub fn with_ws<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
where
P: PeripheralOutput,
{
crate::into_mapped_ref!(pin);
pin.set_to_push_pull_output();
self.i2s.ws_rx_signal().connect_to(pin);
pub fn with_ws(self, ws: impl PeripheralOutput<'d>) -> Self {
let ws = ws.into();
ws.set_to_push_pull_output();
self.i2s.ws_rx_signal().connect_to(&ws);
self
}
pub fn with_din<P>(self, pin: impl Peripheral<P = P> + 'd) -> Self
where
P: PeripheralInput,
{
crate::into_mapped_ref!(pin);
pin.init_input(crate::gpio::Pull::None);
self.i2s.din_signal().connect_to(pin);
pub fn with_din(self, din: impl PeripheralInput<'d>) -> Self {
let din = din.into();
din.init_input(crate::gpio::Pull::None);
self.i2s.din_signal().connect_to(&din);
self
}

View File

@ -138,39 +138,48 @@ pub trait TxPins<'d> {
/// Represents a group of 16 output pins configured for 16-bit parallel data
/// transmission.
pub struct TxSixteenBits<'d> {
pins: [PeripheralRef<'d, OutputConnection>; 16],
pins: [OutputConnection<'d>; 16],
}
impl<'d> TxSixteenBits<'d> {
#[allow(clippy::too_many_arguments)]
/// Creates a new `TxSixteenBits` instance with the provided output pins.
pub fn new(
pin_0: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_1: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_2: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_3: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_4: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_5: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_6: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_7: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_8: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_9: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_10: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_11: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_12: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_13: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_14: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_15: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_0: impl PeripheralOutput<'d>,
pin_1: impl PeripheralOutput<'d>,
pin_2: impl PeripheralOutput<'d>,
pin_3: impl PeripheralOutput<'d>,
pin_4: impl PeripheralOutput<'d>,
pin_5: impl PeripheralOutput<'d>,
pin_6: impl PeripheralOutput<'d>,
pin_7: impl PeripheralOutput<'d>,
pin_8: impl PeripheralOutput<'d>,
pin_9: impl PeripheralOutput<'d>,
pin_10: impl PeripheralOutput<'d>,
pin_11: impl PeripheralOutput<'d>,
pin_12: impl PeripheralOutput<'d>,
pin_13: impl PeripheralOutput<'d>,
pin_14: impl PeripheralOutput<'d>,
pin_15: impl PeripheralOutput<'d>,
) -> Self {
crate::into_mapped_ref!(
pin_0, pin_1, pin_2, pin_3, pin_4, pin_5, pin_6, pin_7, pin_8, pin_9, pin_10, pin_11,
pin_12, pin_13, pin_14, pin_15
);
Self {
pins: [
pin_0, pin_1, pin_2, pin_3, pin_4, pin_5, pin_6, pin_7, pin_8, pin_9, pin_10,
pin_11, pin_12, pin_13, pin_14, pin_15,
pin_0.into(),
pin_1.into(),
pin_2.into(),
pin_3.into(),
pin_4.into(),
pin_5.into(),
pin_6.into(),
pin_7.into(),
pin_8.into(),
pin_9.into(),
pin_10.into(),
pin_11.into(),
pin_12.into(),
pin_13.into(),
pin_14.into(),
pin_15.into(),
],
}
}
@ -194,26 +203,33 @@ impl<'d> TxPins<'d> for TxSixteenBits<'d> {
/// Represents a group of 8 output pins configured for 8-bit parallel data
/// transmission.
pub struct TxEightBits<'d> {
pins: [PeripheralRef<'d, OutputConnection>; 8],
pins: [OutputConnection<'d>; 8],
}
impl<'d> TxEightBits<'d> {
#[allow(clippy::too_many_arguments)]
/// Creates a new `TxSEightBits` instance with the provided output pins.
pub fn new(
pin_0: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_1: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_2: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_3: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_4: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_5: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_6: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_7: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_0: impl PeripheralOutput<'d>,
pin_1: impl PeripheralOutput<'d>,
pin_2: impl PeripheralOutput<'d>,
pin_3: impl PeripheralOutput<'d>,
pin_4: impl PeripheralOutput<'d>,
pin_5: impl PeripheralOutput<'d>,
pin_6: impl PeripheralOutput<'d>,
pin_7: impl PeripheralOutput<'d>,
) -> Self {
crate::into_mapped_ref!(pin_0, pin_1, pin_2, pin_3, pin_4, pin_5, pin_6, pin_7);
Self {
pins: [pin_0, pin_1, pin_2, pin_3, pin_4, pin_5, pin_6, pin_7],
pins: [
pin_0.into(),
pin_1.into(),
pin_2.into(),
pin_3.into(),
pin_4.into(),
pin_5.into(),
pin_6.into(),
pin_7.into(),
],
}
}
}
@ -250,13 +266,12 @@ impl<'d> I2sParallel<'d, Blocking> {
channel: impl Peripheral<P = CH> + 'd,
frequency: Rate,
mut pins: impl TxPins<'d>,
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
clock_pin: impl PeripheralOutput<'d>,
) -> Self
where
CH: DmaChannelFor<AnyI2s>,
{
crate::into_mapped_ref!(i2s);
crate::into_mapped_ref!(clock_pin);
let channel = Channel::new(channel.map(|ch| ch.degrade()));
channel.runtime_ensure_compatible(&i2s);
@ -266,8 +281,9 @@ impl<'d> I2sParallel<'d, Blocking> {
// configure the I2S peripheral for parallel mode
i2s.setup(frequency, pins.bus_width());
// setup the clock pin
let clock_pin = clock_pin.into();
clock_pin.set_to_push_pull_output();
i2s.ws_signal().connect_to(clock_pin);
i2s.ws_signal().connect_to(&clock_pin);
pins.configure(i2s.reborrow());
Self {

View File

@ -139,7 +139,7 @@ impl<const NUM: u8> SoftwareInterrupt<NUM> {
}
}
impl<const NUM: u8> crate::peripheral::Peripheral for SoftwareInterrupt<NUM> {
unsafe impl<const NUM: u8> crate::peripheral::Peripheral for SoftwareInterrupt<NUM> {
type P = SoftwareInterrupt<NUM>;
#[inline]

View File

@ -228,44 +228,38 @@ impl<'d> Camera<'d> {
impl<'d> Camera<'d> {
/// Configures the master clock (MCLK) pin for the camera interface.
pub fn with_master_clock<MCLK: PeripheralOutput>(
self,
mclk: impl Peripheral<P = MCLK> + 'd,
) -> Self {
crate::into_mapped_ref!(mclk);
pub fn with_master_clock(self, mclk: impl PeripheralOutput<'d>) -> Self {
let mclk = mclk.into();
mclk.set_to_push_pull_output();
OutputSignal::CAM_CLK.connect_to(mclk);
OutputSignal::CAM_CLK.connect_to(&mclk);
self
}
/// Configures the pixel clock (PCLK) pin for the camera interface.
pub fn with_pixel_clock<PCLK: PeripheralInput>(
self,
pclk: impl Peripheral<P = PCLK> + 'd,
) -> Self {
crate::into_mapped_ref!(pclk);
pub fn with_pixel_clock(self, pclk: impl PeripheralInput<'d>) -> Self {
let pclk = pclk.into();
pclk.init_input(Pull::None);
InputSignal::CAM_PCLK.connect_to(pclk);
InputSignal::CAM_PCLK.connect_to(&pclk);
self
}
/// Configures the control pins for the camera interface (VSYNC and
/// HENABLE).
pub fn with_ctrl_pins<VSYNC: PeripheralInput, HENABLE: PeripheralInput>(
pub fn with_ctrl_pins(
self,
vsync: impl Peripheral<P = VSYNC> + 'd,
h_enable: impl Peripheral<P = HENABLE> + 'd,
vsync: impl PeripheralInput<'d>,
h_enable: impl PeripheralInput<'d>,
) -> Self {
crate::into_mapped_ref!(vsync, h_enable);
let vsync = vsync.into();
let h_enable = h_enable.into();
vsync.init_input(Pull::None);
InputSignal::CAM_V_SYNC.connect_to(vsync);
InputSignal::CAM_V_SYNC.connect_to(&vsync);
h_enable.init_input(Pull::None);
InputSignal::CAM_H_ENABLE.connect_to(h_enable);
InputSignal::CAM_H_ENABLE.connect_to(&h_enable);
self.regs()
.cam_ctrl1()
@ -276,24 +270,22 @@ impl<'d> Camera<'d> {
/// Configures the control pins for the camera interface (VSYNC, HSYNC, and
/// HENABLE) with DE (data enable).
pub fn with_ctrl_pins_and_de<
VSYNC: PeripheralInput,
HSYNC: PeripheralInput,
HENABLE: PeripheralInput,
>(
pub fn with_ctrl_pins_and_de(
self,
vsync: impl Peripheral<P = VSYNC> + 'd,
hsync: impl Peripheral<P = HSYNC> + 'd,
h_enable: impl Peripheral<P = HENABLE> + 'd,
vsync: impl PeripheralInput<'d>,
hsync: impl PeripheralInput<'d>,
h_enable: impl PeripheralInput<'d>,
) -> Self {
crate::into_mapped_ref!(vsync, hsync, h_enable);
let vsync = vsync.into();
let hsync = hsync.into();
let h_enable = h_enable.into();
vsync.init_input(Pull::None);
InputSignal::CAM_V_SYNC.connect_to(vsync);
InputSignal::CAM_V_SYNC.connect_to(&vsync);
hsync.init_input(Pull::None);
InputSignal::CAM_H_SYNC.connect_to(hsync);
InputSignal::CAM_H_SYNC.connect_to(&hsync);
h_enable.init_input(Pull::None);
InputSignal::CAM_H_ENABLE.connect_to(h_enable);
InputSignal::CAM_H_ENABLE.connect_to(&h_enable);
self.regs()
.cam_ctrl1()
@ -477,38 +469,29 @@ impl RxEightBits {
/// Creates a new instance of `RxEightBits`, configuring the specified pins
/// as the 8-bit data bus.
pub fn new<'d>(
pin_0: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_1: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_2: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_3: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_4: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_5: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_6: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_7: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_0: impl PeripheralInput<'d>,
pin_1: impl PeripheralInput<'d>,
pin_2: impl PeripheralInput<'d>,
pin_3: impl PeripheralInput<'d>,
pin_4: impl PeripheralInput<'d>,
pin_5: impl PeripheralInput<'d>,
pin_6: impl PeripheralInput<'d>,
pin_7: impl PeripheralInput<'d>,
) -> Self {
crate::into_mapped_ref!(pin_0);
crate::into_mapped_ref!(pin_1);
crate::into_mapped_ref!(pin_2);
crate::into_mapped_ref!(pin_3);
crate::into_mapped_ref!(pin_4);
crate::into_mapped_ref!(pin_5);
crate::into_mapped_ref!(pin_6);
crate::into_mapped_ref!(pin_7);
let pairs = [
(pin_0, InputSignal::CAM_DATA_0),
(pin_1, InputSignal::CAM_DATA_1),
(pin_2, InputSignal::CAM_DATA_2),
(pin_3, InputSignal::CAM_DATA_3),
(pin_4, InputSignal::CAM_DATA_4),
(pin_5, InputSignal::CAM_DATA_5),
(pin_6, InputSignal::CAM_DATA_6),
(pin_7, InputSignal::CAM_DATA_7),
(pin_0.into(), InputSignal::CAM_DATA_0),
(pin_1.into(), InputSignal::CAM_DATA_1),
(pin_2.into(), InputSignal::CAM_DATA_2),
(pin_3.into(), InputSignal::CAM_DATA_3),
(pin_4.into(), InputSignal::CAM_DATA_4),
(pin_5.into(), InputSignal::CAM_DATA_5),
(pin_6.into(), InputSignal::CAM_DATA_6),
(pin_7.into(), InputSignal::CAM_DATA_7),
];
for (pin, signal) in pairs.into_iter() {
pin.init_input(Pull::None);
signal.connect_to(pin);
signal.connect_to(&pin);
}
Self { _pins: () }
@ -530,62 +513,45 @@ impl RxSixteenBits {
/// Creates a new instance of `RxSixteenBits`, configuring the specified
/// pins as the 16-bit data bus.
pub fn new<'d>(
pin_0: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_1: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_2: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_3: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_4: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_5: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_6: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_7: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_8: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_9: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_10: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_11: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_12: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_13: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_14: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_15: impl Peripheral<P = impl PeripheralInput> + 'd,
pin_0: impl PeripheralInput<'d>,
pin_1: impl PeripheralInput<'d>,
pin_2: impl PeripheralInput<'d>,
pin_3: impl PeripheralInput<'d>,
pin_4: impl PeripheralInput<'d>,
pin_5: impl PeripheralInput<'d>,
pin_6: impl PeripheralInput<'d>,
pin_7: impl PeripheralInput<'d>,
pin_8: impl PeripheralInput<'d>,
pin_9: impl PeripheralInput<'d>,
pin_10: impl PeripheralInput<'d>,
pin_11: impl PeripheralInput<'d>,
pin_12: impl PeripheralInput<'d>,
pin_13: impl PeripheralInput<'d>,
pin_14: impl PeripheralInput<'d>,
pin_15: impl PeripheralInput<'d>,
) -> Self {
crate::into_mapped_ref!(pin_0);
crate::into_mapped_ref!(pin_1);
crate::into_mapped_ref!(pin_2);
crate::into_mapped_ref!(pin_3);
crate::into_mapped_ref!(pin_4);
crate::into_mapped_ref!(pin_5);
crate::into_mapped_ref!(pin_6);
crate::into_mapped_ref!(pin_7);
crate::into_mapped_ref!(pin_8);
crate::into_mapped_ref!(pin_9);
crate::into_mapped_ref!(pin_10);
crate::into_mapped_ref!(pin_11);
crate::into_mapped_ref!(pin_12);
crate::into_mapped_ref!(pin_13);
crate::into_mapped_ref!(pin_14);
crate::into_mapped_ref!(pin_15);
let pairs = [
(pin_0, InputSignal::CAM_DATA_0),
(pin_1, InputSignal::CAM_DATA_1),
(pin_2, InputSignal::CAM_DATA_2),
(pin_3, InputSignal::CAM_DATA_3),
(pin_4, InputSignal::CAM_DATA_4),
(pin_5, InputSignal::CAM_DATA_5),
(pin_6, InputSignal::CAM_DATA_6),
(pin_7, InputSignal::CAM_DATA_7),
(pin_8, InputSignal::CAM_DATA_8),
(pin_9, InputSignal::CAM_DATA_9),
(pin_10, InputSignal::CAM_DATA_10),
(pin_11, InputSignal::CAM_DATA_11),
(pin_12, InputSignal::CAM_DATA_12),
(pin_13, InputSignal::CAM_DATA_13),
(pin_14, InputSignal::CAM_DATA_14),
(pin_15, InputSignal::CAM_DATA_15),
(pin_0.into(), InputSignal::CAM_DATA_0),
(pin_1.into(), InputSignal::CAM_DATA_1),
(pin_2.into(), InputSignal::CAM_DATA_2),
(pin_3.into(), InputSignal::CAM_DATA_3),
(pin_4.into(), InputSignal::CAM_DATA_4),
(pin_5.into(), InputSignal::CAM_DATA_5),
(pin_6.into(), InputSignal::CAM_DATA_6),
(pin_7.into(), InputSignal::CAM_DATA_7),
(pin_8.into(), InputSignal::CAM_DATA_8),
(pin_9.into(), InputSignal::CAM_DATA_9),
(pin_10.into(), InputSignal::CAM_DATA_10),
(pin_11.into(), InputSignal::CAM_DATA_11),
(pin_12.into(), InputSignal::CAM_DATA_12),
(pin_13.into(), InputSignal::CAM_DATA_13),
(pin_14.into(), InputSignal::CAM_DATA_14),
(pin_15.into(), InputSignal::CAM_DATA_15),
];
for (pin, signal) in pairs.into_iter() {
pin.init_input(Pull::None);
signal.connect_to(pin);
signal.connect_to(&pin);
}
Self { _pins: () }

View File

@ -317,10 +317,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the VSYNC
/// signal.
pub fn with_vsync<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_vsync(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_V_SYNC.connect_to(pin);
OutputSignal::LCD_V_SYNC.connect_to(&pin);
self
}
@ -329,10 +329,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the HSYNC
/// signal.
pub fn with_hsync<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_hsync(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_H_SYNC.connect_to(pin);
OutputSignal::LCD_H_SYNC.connect_to(&pin);
self
}
@ -341,10 +341,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DE
/// signal.
pub fn with_de<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_de(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_H_ENABLE.connect_to(pin);
OutputSignal::LCD_H_ENABLE.connect_to(&pin);
self
}
@ -353,10 +353,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the PCLK
/// signal.
pub fn with_pclk<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_pclk(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_PCLK.connect_to(pin);
OutputSignal::LCD_PCLK.connect_to(&pin);
self
}
@ -365,10 +365,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_0
/// signal.
pub fn with_data0<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data0(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_0.connect_to(pin);
OutputSignal::LCD_DATA_0.connect_to(&pin);
self
}
@ -377,10 +377,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_1
/// signal.
pub fn with_data1<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data1(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_1.connect_to(pin);
OutputSignal::LCD_DATA_1.connect_to(&pin);
self
}
@ -389,10 +389,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_2
/// signal.
pub fn with_data2<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data2(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_2.connect_to(pin);
OutputSignal::LCD_DATA_2.connect_to(&pin);
self
}
@ -401,10 +401,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_3
/// signal.
pub fn with_data3<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data3(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_3.connect_to(pin);
OutputSignal::LCD_DATA_3.connect_to(&pin);
self
}
@ -413,10 +413,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_4
/// signal.
pub fn with_data4<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data4(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_4.connect_to(pin);
OutputSignal::LCD_DATA_4.connect_to(&pin);
self
}
@ -425,10 +425,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_5
/// signal.
pub fn with_data5<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data5(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_5.connect_to(pin);
OutputSignal::LCD_DATA_5.connect_to(&pin);
self
}
@ -437,10 +437,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_6
/// signal.
pub fn with_data6<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data6(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_6.connect_to(pin);
OutputSignal::LCD_DATA_6.connect_to(&pin);
self
}
@ -449,10 +449,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_7
/// signal.
pub fn with_data7<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data7(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_7.connect_to(pin);
OutputSignal::LCD_DATA_7.connect_to(&pin);
self
}
@ -461,10 +461,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_8
/// signal.
pub fn with_data8<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data8(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_8.connect_to(pin);
OutputSignal::LCD_DATA_8.connect_to(&pin);
self
}
@ -473,10 +473,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the DATA_9
/// signal.
pub fn with_data9<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data9(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_9.connect_to(pin);
OutputSignal::LCD_DATA_9.connect_to(&pin);
self
}
@ -485,10 +485,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the
/// DATA_10 signal.
pub fn with_data10<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data10(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_10.connect_to(pin);
OutputSignal::LCD_DATA_10.connect_to(&pin);
self
}
@ -497,10 +497,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the
/// DATA_11 signal.
pub fn with_data11<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data11(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_11.connect_to(pin);
OutputSignal::LCD_DATA_11.connect_to(&pin);
self
}
@ -509,10 +509,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the
/// DATA_12 signal.
pub fn with_data12<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data12(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_12.connect_to(pin);
OutputSignal::LCD_DATA_12.connect_to(&pin);
self
}
@ -521,10 +521,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the
/// DATA_13 signal.
pub fn with_data13<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data13(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_13.connect_to(pin);
OutputSignal::LCD_DATA_13.connect_to(&pin);
self
}
@ -533,10 +533,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the
/// DATA_14 signal.
pub fn with_data14<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data14(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_14.connect_to(pin);
OutputSignal::LCD_DATA_14.connect_to(&pin);
self
}
@ -545,10 +545,10 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the
/// DATA_15 signal.
pub fn with_data15<S: PeripheralOutput>(self, pin: impl Peripheral<P = S> + 'd) -> Self {
crate::into_mapped_ref!(pin);
pub fn with_data15(self, pin: impl PeripheralOutput<'d>) -> Self {
let pin = pin.into();
pin.set_to_push_pull_output();
OutputSignal::LCD_DATA_15.connect_to(pin);
OutputSignal::LCD_DATA_15.connect_to(&pin);
self
}

View File

@ -273,27 +273,28 @@ where
}
/// Associates a CS pin with the I8080 interface.
pub fn with_cs<CS: PeripheralOutput>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
crate::into_mapped_ref!(cs);
pub fn with_cs(self, cs: impl PeripheralOutput<'d>) -> Self {
let cs = cs.into();
cs.set_to_push_pull_output();
OutputSignal::LCD_CS.connect_to(cs);
OutputSignal::LCD_CS.connect_to(&cs);
self
}
/// Configures the control pins for the I8080 interface.
pub fn with_ctrl_pins<DC: PeripheralOutput, WRX: PeripheralOutput>(
pub fn with_ctrl_pins(
self,
dc: impl Peripheral<P = DC> + 'd,
wrx: impl Peripheral<P = WRX> + 'd,
dc: impl PeripheralOutput<'d>,
wrx: impl PeripheralOutput<'d>,
) -> Self {
crate::into_mapped_ref!(dc, wrx);
let dc = dc.into();
let wrx = wrx.into();
dc.set_to_push_pull_output();
OutputSignal::LCD_DC.connect_to(dc);
OutputSignal::LCD_DC.connect_to(&dc);
wrx.set_to_push_pull_output();
OutputSignal::LCD_PCLK.connect_to(wrx);
OutputSignal::LCD_PCLK.connect_to(&wrx);
self
}
@ -620,33 +621,33 @@ impl From<u16> for Command<u16> {
/// Represents a group of 8 output pins configured for 8-bit parallel data
/// transmission.
pub struct TxEightBits<'d> {
pins: [PeripheralRef<'d, OutputConnection>; 8],
pins: [OutputConnection<'d>; 8],
}
impl<'d> TxEightBits<'d> {
#[allow(clippy::too_many_arguments)]
/// Creates a new `TxEightBits` instance with the provided output pins.
pub fn new(
pin_0: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_1: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_2: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_3: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_4: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_5: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_6: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_7: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_0: impl PeripheralOutput<'d>,
pin_1: impl PeripheralOutput<'d>,
pin_2: impl PeripheralOutput<'d>,
pin_3: impl PeripheralOutput<'d>,
pin_4: impl PeripheralOutput<'d>,
pin_5: impl PeripheralOutput<'d>,
pin_6: impl PeripheralOutput<'d>,
pin_7: impl PeripheralOutput<'d>,
) -> Self {
crate::into_mapped_ref!(pin_0);
crate::into_mapped_ref!(pin_1);
crate::into_mapped_ref!(pin_2);
crate::into_mapped_ref!(pin_3);
crate::into_mapped_ref!(pin_4);
crate::into_mapped_ref!(pin_5);
crate::into_mapped_ref!(pin_6);
crate::into_mapped_ref!(pin_7);
Self {
pins: [pin_0, pin_1, pin_2, pin_3, pin_4, pin_5, pin_6, pin_7],
pins: [
pin_0.into(),
pin_1.into(),
pin_2.into(),
pin_3.into(),
pin_4.into(),
pin_5.into(),
pin_6.into(),
pin_7.into(),
],
}
}
}
@ -664,7 +665,7 @@ impl TxPins for TxEightBits<'_> {
OutputSignal::LCD_DATA_7,
];
for (pin, signal) in self.pins.iter_mut().zip(SIGNALS.into_iter()) {
for (pin, signal) in self.pins.iter().zip(SIGNALS.into_iter()) {
pin.set_to_push_pull_output();
signal.connect_to(pin);
}
@ -674,39 +675,48 @@ impl TxPins for TxEightBits<'_> {
/// Represents a group of 16 output pins configured for 16-bit parallel data
/// transmission.
pub struct TxSixteenBits<'d> {
pins: [PeripheralRef<'d, OutputConnection>; 16],
pins: [OutputConnection<'d>; 16],
}
impl<'d> TxSixteenBits<'d> {
#[allow(clippy::too_many_arguments)]
/// Creates a new `TxSixteenBits` instance with the provided output pins.
pub fn new(
pin_0: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_1: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_2: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_3: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_4: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_5: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_6: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_7: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_8: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_9: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_10: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_11: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_12: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_13: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_14: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_15: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_0: impl PeripheralOutput<'d>,
pin_1: impl PeripheralOutput<'d>,
pin_2: impl PeripheralOutput<'d>,
pin_3: impl PeripheralOutput<'d>,
pin_4: impl PeripheralOutput<'d>,
pin_5: impl PeripheralOutput<'d>,
pin_6: impl PeripheralOutput<'d>,
pin_7: impl PeripheralOutput<'d>,
pin_8: impl PeripheralOutput<'d>,
pin_9: impl PeripheralOutput<'d>,
pin_10: impl PeripheralOutput<'d>,
pin_11: impl PeripheralOutput<'d>,
pin_12: impl PeripheralOutput<'d>,
pin_13: impl PeripheralOutput<'d>,
pin_14: impl PeripheralOutput<'d>,
pin_15: impl PeripheralOutput<'d>,
) -> Self {
crate::into_mapped_ref!(
pin_0, pin_1, pin_2, pin_3, pin_4, pin_5, pin_6, pin_7, pin_8, pin_9, pin_10, pin_11,
pin_12, pin_13, pin_14, pin_15
);
Self {
pins: [
pin_0, pin_1, pin_2, pin_3, pin_4, pin_5, pin_6, pin_7, pin_8, pin_9, pin_10,
pin_11, pin_12, pin_13, pin_14, pin_15,
pin_0.into(),
pin_1.into(),
pin_2.into(),
pin_3.into(),
pin_4.into(),
pin_5.into(),
pin_6.into(),
pin_7.into(),
pin_8.into(),
pin_9.into(),
pin_10.into(),
pin_11.into(),
pin_12.into(),
pin_13.into(),
pin_14.into(),
pin_15.into(),
],
}
}

View File

@ -16,7 +16,6 @@ use crate::{
OutputSignal,
},
pac::ledc::RegisterBlock,
peripheral::{Peripheral, PeripheralRef},
peripherals::LEDC,
};
@ -152,22 +151,18 @@ pub struct Channel<'a, S: TimerSpeed> {
ledc: &'a RegisterBlock,
timer: Option<&'a dyn TimerIFace<S>>,
number: Number,
output_pin: PeripheralRef<'a, OutputConnection>,
output_pin: OutputConnection<'a>,
}
impl<'a, S: TimerSpeed> Channel<'a, S> {
/// Return a new channel
pub fn new(
number: Number,
output_pin: impl Peripheral<P = impl PeripheralOutput> + 'a,
) -> Self {
crate::into_mapped_ref!(output_pin);
pub fn new(number: Number, output_pin: impl PeripheralOutput<'a>) -> Self {
let ledc = LEDC::regs();
Channel {
ledc,
timer: None,
number,
output_pin,
output_pin: output_pin.into(),
}
}
}
@ -614,7 +609,7 @@ where
Number::Channel7 => OutputSignal::LEDC_LS_SIG7,
};
signal.connect_to(&mut self.output_pin);
signal.connect_to(&self.output_pin);
} else {
return Err(Error::Timer);
}

View File

@ -180,7 +180,7 @@ impl<'d> Ledc<'d> {
pub fn channel<S: TimerSpeed>(
&self,
number: channel::Number,
output_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
output_pin: impl PeripheralOutput<'d>,
) -> Channel<'d, S> {
Channel::new(number, output_pin)
}

View File

@ -109,7 +109,7 @@ macro_rules! any_peripheral {
impl $crate::private::Sealed for $name {}
impl $crate::peripheral::Peripheral for $name {
unsafe impl $crate::peripheral::Peripheral for $name {
type P = $name;
unsafe fn clone_unchecked(&self) -> Self::P {

View File

@ -16,7 +16,6 @@ use crate::{
gpio::interconnect::{OutputConnection, PeripheralOutput},
mcpwm::{timer::Timer, PwmPeripheral},
pac,
peripheral::{Peripheral, PeripheralRef},
};
/// Input/Output Stream descriptor for each channel
@ -212,7 +211,7 @@ impl<'d, const OP: u8, PWM: PwmPeripheral> Operator<'d, OP, PWM> {
/// Use the A output with the given pin and configuration
pub fn with_pin_a(
self,
pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin: impl PeripheralOutput<'d>,
config: PwmPinConfig<true>,
) -> PwmPin<'d, PWM, OP, true> {
PwmPin::new(pin, config)
@ -221,7 +220,7 @@ impl<'d, const OP: u8, PWM: PwmPeripheral> Operator<'d, OP, PWM> {
/// Use the B output with the given pin and configuration
pub fn with_pin_b(
self,
pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin: impl PeripheralOutput<'d>,
config: PwmPinConfig<false>,
) -> PwmPin<'d, PWM, OP, false> {
PwmPin::new(pin, config)
@ -230,9 +229,9 @@ impl<'d, const OP: u8, PWM: PwmPeripheral> Operator<'d, OP, PWM> {
/// Use both the A and the B output with the given pins and configurations
pub fn with_pins(
self,
pin_a: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_a: impl PeripheralOutput<'d>,
config_a: PwmPinConfig<true>,
pin_b: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_b: impl PeripheralOutput<'d>,
config_b: PwmPinConfig<false>,
) -> (PwmPin<'d, PWM, OP, true>, PwmPin<'d, PWM, OP, false>) {
(PwmPin::new(pin_a, config_a), PwmPin::new(pin_b, config_b))
@ -244,9 +243,9 @@ impl<'d, const OP: u8, PWM: PwmPeripheral> Operator<'d, OP, PWM> {
/// configured deadtime
pub fn with_linked_pins(
self,
pin_a: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_a: impl PeripheralOutput<'d>,
config_a: PwmPinConfig<true>,
pin_b: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_b: impl PeripheralOutput<'d>,
config_b: PwmPinConfig<false>,
config_dt: DeadTimeCfg,
) -> LinkedPins<'d, PWM, OP> {
@ -287,17 +286,14 @@ impl<const IS_A: bool> PwmPinConfig<IS_A> {
/// A pin driven by an MCPWM operator
pub struct PwmPin<'d, PWM, const OP: u8, const IS_A: bool> {
pin: PeripheralRef<'d, OutputConnection>,
pin: OutputConnection<'d>,
phantom: PhantomData<PWM>,
_guard: PeripheralGuard,
}
impl<'d, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, PWM, OP, IS_A> {
fn new(
pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
config: PwmPinConfig<IS_A>,
) -> Self {
crate::into_mapped_ref!(pin);
fn new(pin: impl PeripheralOutput<'d>, config: PwmPinConfig<IS_A>) -> Self {
let pin = pin.into();
let guard = PeripheralGuard::new(PWM::peripheral());
@ -309,7 +305,7 @@ impl<'d, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, PWM, OP,
pin.set_actions(config.actions);
pin.set_update_method(config.update_method);
PWM::output_signal::<OP, IS_A>().connect_to(&mut pin.pin);
PWM::output_signal::<OP, IS_A>().connect_to(&pin.pin);
pin.pin.enable_output(true);
pin
@ -497,9 +493,9 @@ pub struct LinkedPins<'d, PWM, const OP: u8> {
impl<'d, PWM: PwmPeripheral, const OP: u8> LinkedPins<'d, PWM, OP> {
fn new(
pin_a: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_a: impl PeripheralOutput<'d>,
config_a: PwmPinConfig<true>,
pin_b: impl Peripheral<P = impl PeripheralOutput> + 'd,
pin_b: impl PeripheralOutput<'d>,
config_b: PwmPinConfig<false>,
config_dt: DeadTimeCfg,
) -> Self {

View File

@ -92,10 +92,10 @@ impl<'d> Usb<'d> {
use crate::gpio::Level;
InputSignal::USB_OTG_IDDIG.connect_to(Level::High); // connected connector is mini-B side
InputSignal::USB_SRP_BVALID.connect_to(Level::High); // HIGH to force USB device mode
InputSignal::USB_OTG_VBUSVALID.connect_to(Level::High); // receiving a valid Vbus from device
InputSignal::USB_OTG_AVALID.connect_to(Level::Low);
InputSignal::USB_OTG_IDDIG.connect_to(&Level::High); // connected connector is mini-B side
InputSignal::USB_SRP_BVALID.connect_to(&Level::High); // HIGH to force USB device mode
InputSignal::USB_OTG_VBUSVALID.connect_to(&Level::High); // receiving a valid Vbus from device
InputSignal::USB_OTG_AVALID.connect_to(&Level::Low);
}
fn _disable() {

View File

@ -125,7 +125,6 @@ use core::{
};
use enumset::{EnumSet, EnumSetType};
use peripheral::PeripheralRef;
use private::*;
use crate::{
@ -151,7 +150,7 @@ use crate::{
},
interrupt::InterruptHandler,
parl_io::asynch::interrupt_handler,
peripheral::{self, Peripheral},
peripheral::Peripheral,
peripherals::{Interrupt, PARL_IO, PCR},
system::{self, GenericPeripheralGuard},
time::Rate,
@ -364,31 +363,29 @@ impl RxClkPin for NoPin {
/// Wraps a GPIO pin which will be used as the clock output signal
pub struct ClkOutPin<'d> {
pin: PeripheralRef<'d, OutputConnection>,
pin: OutputConnection<'d>,
}
impl<'d> ClkOutPin<'d> {
/// Create a ClkOutPin
pub fn new(pin: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
crate::into_mapped_ref!(pin);
Self { pin }
pub fn new(pin: impl PeripheralOutput<'d>) -> Self {
Self { pin: pin.into() }
}
}
impl TxClkPin for ClkOutPin<'_> {
fn configure(&mut self) {
self.pin.set_to_push_pull_output();
crate::gpio::OutputSignal::PARL_TX_CLK.connect_to(&mut self.pin);
crate::gpio::OutputSignal::PARL_TX_CLK.connect_to(&self.pin);
}
}
/// Wraps a GPIO pin which will be used as the TX clock input signal
pub struct ClkInPin<'d> {
pin: PeripheralRef<'d, InputConnection>,
pin: InputConnection<'d>,
}
impl<'d> ClkInPin<'d> {
/// Create a new ClkInPin
pub fn new(pin: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
crate::into_mapped_ref!(pin);
Self { pin }
pub fn new(pin: impl PeripheralInput<'d>) -> Self {
Self { pin: pin.into() }
}
}
impl TxClkPin for ClkInPin<'_> {
@ -398,23 +395,22 @@ impl TxClkPin for ClkInPin<'_> {
.modify(|_, w| unsafe { w.parl_clk_tx_sel().bits(3).parl_clk_tx_div_num().bits(0) }); // PAD_CLK_TX, no divider
self.pin.init_input(crate::gpio::Pull::None);
crate::gpio::InputSignal::PARL_TX_CLK.connect_to(&mut self.pin);
crate::gpio::InputSignal::PARL_TX_CLK.connect_to(&self.pin);
}
}
/// Wraps a GPIO pin which will be used as the RX clock input signal
pub struct RxClkInPin<'d> {
pin: PeripheralRef<'d, InputConnection>,
pin: InputConnection<'d>,
sample_edge: SampleEdge,
}
impl<'d> RxClkInPin<'d> {
/// Create a new RxClkInPin
pub fn new(
pin: impl Peripheral<P = impl PeripheralInput> + 'd,
sample_edge: SampleEdge,
) -> Self {
crate::into_mapped_ref!(pin);
Self { pin, sample_edge }
pub fn new(pin: impl PeripheralInput<'d>, sample_edge: SampleEdge) -> Self {
Self {
pin: pin.into(),
sample_edge,
}
}
}
impl RxClkPin for RxClkInPin<'_> {
@ -424,7 +420,7 @@ impl RxClkPin for RxClkInPin<'_> {
.modify(|_, w| unsafe { w.parl_clk_rx_sel().bits(3).parl_clk_rx_div_num().bits(0) }); // PAD_CLK_TX, no divider
self.pin.init_input(crate::gpio::Pull::None);
crate::gpio::InputSignal::PARL_RX_CLK.connect_to(&mut self.pin);
crate::gpio::InputSignal::PARL_RX_CLK.connect_to(&self.pin);
Instance::set_rx_clk_edge_sel(self.sample_edge);
}
@ -436,7 +432,7 @@ where
P: NotContainsValidSignalPin + TxPins + ConfigurePins,
{
tx_pins: P,
valid_pin: PeripheralRef<'d, OutputConnection>,
valid_pin: OutputConnection<'d>,
}
impl<'d, P> TxPinConfigWithValidPin<'d, P>
@ -444,9 +440,11 @@ where
P: NotContainsValidSignalPin + TxPins + ConfigurePins,
{
/// Create a [TxPinConfigWithValidPin]
pub fn new(tx_pins: P, valid_pin: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
crate::into_mapped_ref!(valid_pin);
Self { tx_pins, valid_pin }
pub fn new(tx_pins: P, valid_pin: impl PeripheralOutput<'d>) -> Self {
Self {
tx_pins,
valid_pin: valid_pin.into(),
}
}
}
@ -462,7 +460,7 @@ where
fn configure(&mut self) -> Result<(), Error> {
self.tx_pins.configure()?;
self.valid_pin.set_to_push_pull_output();
Instance::tx_valid_pin_signal().connect_to(&mut self.valid_pin);
Instance::tx_valid_pin_signal().connect_to(&self.valid_pin);
Instance::set_tx_hw_valid_en(true);
Ok(())
}
@ -510,7 +508,7 @@ macro_rules! tx_pins {
#[doc = "bit output mode"]
pub struct $name<'d> {
$(
[< pin_ $pin:lower >] : PeripheralRef<'d, OutputConnection>,
[< pin_ $pin:lower >] : OutputConnection<'d >,
)+
}
@ -520,11 +518,10 @@ macro_rules! tx_pins {
#[allow(clippy::too_many_arguments)]
pub fn new(
$(
[< pin_ $pin:lower >] : impl Peripheral<P = impl PeripheralOutput > + 'd,
[< pin_ $pin:lower >] : impl PeripheralOutput<'d>,
)+
) -> Self {
crate::into_mapped_ref!($( [< pin_ $pin:lower >] ),+);
Self { $( [< pin_ $pin:lower >] ),+ }
Self { $( [< pin_ $pin:lower >]: [< pin_ $pin:lower >].into() ),+ }
}
}
@ -615,7 +612,7 @@ where
P: NotContainsValidSignalPin + RxPins + ConfigurePins,
{
rx_pins: P,
valid_pin: PeripheralRef<'d, InputConnection>,
valid_pin: InputConnection<'d>,
enable_mode: EnableMode,
}
@ -624,15 +621,10 @@ where
P: NotContainsValidSignalPin + RxPins + ConfigurePins,
{
/// Create a new [RxPinConfigWithValidPin]
pub fn new(
rx_pins: P,
valid_pin: impl Peripheral<P = impl PeripheralInput> + 'd,
enable_mode: EnableMode,
) -> Self {
crate::into_mapped_ref!(valid_pin);
pub fn new(rx_pins: P, valid_pin: impl PeripheralInput<'d>, enable_mode: EnableMode) -> Self {
Self {
rx_pins,
valid_pin,
valid_pin: valid_pin.into(),
enable_mode,
}
}
@ -650,7 +642,7 @@ where
fn configure(&mut self) -> Result<(), Error> {
self.rx_pins.configure()?;
self.valid_pin.init_input(crate::gpio::Pull::None);
Instance::rx_valid_pin_signal().connect_to(&mut self.valid_pin);
Instance::rx_valid_pin_signal().connect_to(&self.valid_pin);
Instance::set_rx_sw_en(false);
if let Some(sel) = self.enable_mode.pulse_submode_sel() {
Instance::set_rx_pulse_submode_sel(sel);
@ -722,7 +714,7 @@ macro_rules! rx_pins {
#[doc = "bit input mode"]
pub struct $name<'d> {
$(
[< pin_ $pin:lower >] : PeripheralRef<'d, InputConnection>,
[< pin_ $pin:lower >] : InputConnection<'d>,
)+
}
@ -732,11 +724,10 @@ macro_rules! rx_pins {
#[allow(clippy::too_many_arguments)]
pub fn new(
$(
[< pin_ $pin:lower >] : impl Peripheral<P = impl PeripheralInput > + 'd,
[< pin_ $pin:lower >] : impl PeripheralInput<'d>,
)+
) -> Self {
crate::into_mapped_ref!($( [< pin_ $pin:lower >] ),+);
Self { $( [< pin_ $pin:lower >] ),+ }
Self { $( [< pin_ $pin:lower >]: [< pin_ $pin:lower >].into() ),+ }
}
}
@ -745,7 +736,7 @@ macro_rules! rx_pins {
fn configure(&mut self) -> Result<(), Error> {
$(
self.[< pin_ $pin:lower >].init_input(crate::gpio::Pull::None);
crate::gpio::InputSignal::$signal.connect_to(&mut self.[< pin_ $pin:lower >]);
crate::gpio::InputSignal::$signal.connect_to(&self.[< pin_ $pin:lower >]);
)+
private::Instance::set_rx_bit_width( private::WidSel::[< Bits $width >]);

View File

@ -12,7 +12,6 @@ use core::marker::PhantomData;
pub use crate::pac::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE as EdgeMode};
use crate::{
gpio::{interconnect::PeripheralInput, InputSignal},
peripheral::Peripheral,
peripherals::PCNT,
system::GenericPeripheralGuard,
};
@ -72,7 +71,7 @@ impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
}
/// Set the control signal (pin/high/low) for this channel
pub fn set_ctrl_signal<P: PeripheralInput>(&self, source: impl Peripheral<P = P>) -> &Self {
pub fn set_ctrl_signal<'d>(&self, source: impl PeripheralInput<'d>) -> &Self {
let signal = match UNIT {
0 => match NUM {
0 => InputSignal::PCNT0_CTRL_CH0,
@ -122,15 +121,15 @@ impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
};
if (signal as usize) <= crate::gpio::INPUT_SIGNAL_MAX as usize {
crate::into_mapped_ref!(source);
let source = source.into();
source.enable_input(true);
signal.connect_to(source);
signal.connect_to(&source);
}
self
}
/// Set the edge signal (pin/high/low) for this channel
pub fn set_edge_signal<P: PeripheralInput>(&self, source: impl Peripheral<P = P>) -> &Self {
pub fn set_edge_signal<'d>(&self, source: impl PeripheralInput<'d>) -> &Self {
let signal = match UNIT {
0 => match NUM {
0 => InputSignal::PCNT0_SIG_CH0,
@ -180,9 +179,9 @@ impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
};
if (signal as usize) <= crate::gpio::INPUT_SIGNAL_MAX as usize {
crate::into_mapped_ref!(source);
let source = source.into();
source.enable_input(true);
signal.connect_to(source);
signal.connect_to(&source);
}
self
}

View File

@ -1,9 +1,6 @@
//! # Exclusive peripheral access
use core::{
marker::PhantomData,
ops::{Deref, DerefMut},
};
use core::{marker::PhantomData, ops::Deref};
/// An exclusive reference to a peripheral.
///
@ -27,6 +24,8 @@ pub struct PeripheralRef<'a, T> {
_lifetime: PhantomData<&'a mut T>,
}
impl<T> crate::private::Sealed for PeripheralRef<'_, T> {}
impl<'a, T> PeripheralRef<'a, T> {
/// Create a new exclusive reference to a peripheral
#[inline]
@ -146,7 +145,16 @@ impl<T> Deref for PeripheralRef<'_, T> {
///
/// `.into_ref()` on an owned `T` yields a `PeripheralRef<'static, T>`.
/// `.into_ref()` on an `&'a mut T` yields a `PeripheralRef<'a, T>`.
pub trait Peripheral: Sized {
///
/// # Safety
///
/// Implementing this trait is unsound on types that can be obtained again even
/// after calling `into_ref`. For example, implementing this trait for
/// `MutexGuard<P>` is unsound, as the guard is dropped to turn it into a
/// `PeripheralRef<'static, P>`, which allows the `Mutex` to be immediately
/// re-acquired, potentially resulting in multiple copies of
/// `PeripheralRef<'static, P>`.
pub unsafe trait Peripheral: Sized {
/// Peripheral singleton type
type P;
@ -201,19 +209,17 @@ pub trait Peripheral: Sized {
}
}
impl<T: DerefMut> Peripheral for T
where
T::Target: Peripheral,
{
type P = <T::Target as Peripheral>::P;
impl<T: Peripheral> crate::private::Sealed for &mut T {}
unsafe impl<T: Peripheral> Peripheral for &mut T {
type P = <T as Peripheral>::P;
#[inline]
unsafe fn clone_unchecked(&self) -> Self::P {
T::Target::clone_unchecked(self)
T::clone_unchecked(self)
}
}
impl<T: Peripheral> Peripheral for PeripheralRef<'_, T> {
unsafe impl<T: Peripheral> Peripheral for PeripheralRef<'_, T> {
type P = T::P;
#[inline]
@ -431,7 +437,7 @@ mod peripheral_macros {
}
}
impl $crate::peripheral::Peripheral for $name {
unsafe impl $crate::peripheral::Peripheral for $name {
type P = $name;
#[inline]

View File

@ -466,8 +466,8 @@ impl crate::interrupt::InterruptConfigurable for Rmt<'_, Blocking> {
}
}
fn configure_rx_channel<'d, P: PeripheralInput, T: RxChannelInternal>(
pin: impl Peripheral<P = P> + 'd,
fn configure_rx_channel<'d, T: RxChannelInternal>(
pin: impl PeripheralInput<'d>,
config: RxChannelConfig,
) -> Result<T, Error> {
cfg_if::cfg_if! {
@ -482,9 +482,9 @@ fn configure_rx_channel<'d, P: PeripheralInput, T: RxChannelInternal>(
return Err(Error::InvalidArgument);
}
crate::into_mapped_ref!(pin);
let pin = pin.into();
pin.init_input(crate::gpio::Pull::None);
T::input_signal().connect_to(pin);
T::input_signal().connect_to(&pin);
T::set_divider(config.clk_divider);
T::set_carrier(
@ -499,13 +499,13 @@ fn configure_rx_channel<'d, P: PeripheralInput, T: RxChannelInternal>(
Ok(T::new())
}
fn configure_tx_channel<'d, P: PeripheralOutput, T: TxChannelInternal>(
pin: impl Peripheral<P = P> + 'd,
fn configure_tx_channel<'d, T: TxChannelInternal>(
pin: impl PeripheralOutput<'d>,
config: TxChannelConfig,
) -> Result<T, Error> {
crate::into_mapped_ref!(pin);
let pin = pin.into();
pin.set_to_push_pull_output();
T::output_signal().connect_to(pin);
T::output_signal().connect_to(&pin);
T::set_divider(config.clk_divider);
T::set_carrier(
@ -520,17 +520,12 @@ fn configure_tx_channel<'d, P: PeripheralOutput, T: TxChannelInternal>(
}
/// Creates a TX channel
pub trait TxChannelCreator<'d, T, P>
pub trait TxChannelCreator<'d, T>
where
P: PeripheralOutput,
T: TxChannel,
{
/// Configure the TX channel
fn configure(
self,
pin: impl Peripheral<P = P> + 'd,
config: TxChannelConfig,
) -> Result<T, Error>
fn configure(self, pin: impl PeripheralOutput<'d>, config: TxChannelConfig) -> Result<T, Error>
where
Self: Sized,
{
@ -539,17 +534,12 @@ where
}
/// Creates a TX channel in async mode
pub trait TxChannelCreatorAsync<'d, T, P>
pub trait TxChannelCreatorAsync<'d, T>
where
P: PeripheralOutput,
T: TxChannelAsync,
{
/// Configure the TX channel
fn configure(
self,
pin: impl Peripheral<P = P> + 'd,
config: TxChannelConfig,
) -> Result<T, Error>
fn configure(self, pin: impl PeripheralOutput<'d>, config: TxChannelConfig) -> Result<T, Error>
where
Self: Sized,
{
@ -558,17 +548,12 @@ where
}
/// Creates a RX channel
pub trait RxChannelCreator<'d, T, P>
pub trait RxChannelCreator<'d, T>
where
P: PeripheralInput,
T: RxChannel,
{
/// Configure the RX channel
fn configure(
self,
pin: impl Peripheral<P = P> + 'd,
config: RxChannelConfig,
) -> Result<T, Error>
fn configure(self, pin: impl PeripheralInput<'d>, config: RxChannelConfig) -> Result<T, Error>
where
Self: Sized,
{
@ -577,17 +562,12 @@ where
}
/// Creates a RX channel in async mode
pub trait RxChannelCreatorAsync<'d, T, P>
pub trait RxChannelCreatorAsync<'d, T>
where
P: PeripheralInput,
T: RxChannelAsync,
{
/// Configure the RX channel
fn configure(
self,
pin: impl Peripheral<P = P> + 'd,
config: RxChannelConfig,
) -> Result<T, Error>
fn configure(self, pin: impl PeripheralInput<'d>, config: RxChannelConfig) -> Result<T, Error>
where
Self: Sized,
{
@ -725,21 +705,16 @@ where
macro_rules! impl_tx_channel_creator {
($channel:literal) => {
impl<'d, P>
$crate::rmt::TxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P>
impl<'d> $crate::rmt::TxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>>
for ChannelCreator<$crate::Blocking, $channel>
where
P: $crate::gpio::interconnect::PeripheralOutput,
{
}
impl $crate::rmt::TxChannel for $crate::rmt::Channel<$crate::Blocking, $channel> {}
impl<'d, P>
$crate::rmt::TxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P>
impl<'d>
$crate::rmt::TxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>>
for ChannelCreator<$crate::Async, $channel>
where
P: $crate::gpio::interconnect::PeripheralOutput,
{
}
@ -749,21 +724,16 @@ macro_rules! impl_tx_channel_creator {
macro_rules! impl_rx_channel_creator {
($channel:literal) => {
impl<'d, P>
$crate::rmt::RxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P>
impl<'d> $crate::rmt::RxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>>
for ChannelCreator<$crate::Blocking, $channel>
where
P: $crate::gpio::interconnect::PeripheralInput,
{
}
impl $crate::rmt::RxChannel for $crate::rmt::Channel<$crate::Blocking, $channel> {}
impl<'d, P>
$crate::rmt::RxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P>
impl<'d>
$crate::rmt::RxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>>
for ChannelCreator<$crate::Async, $channel>
where
P: $crate::gpio::interconnect::PeripheralInput,
{
}

View File

@ -138,7 +138,7 @@ impl Rng {
impl Sealed for Rng {}
impl Peripheral for Rng {
unsafe impl Peripheral for Rng {
type P = Self;
#[inline]
@ -287,7 +287,7 @@ impl rand_core09::CryptoRng for Trng<'_> {}
impl Sealed for Trng<'_> {}
impl Peripheral for Trng<'_> {
unsafe impl Peripheral for Trng<'_> {
type P = Self;
#[inline]

View File

@ -50,7 +50,7 @@ use crate::{
clock::Clocks,
dma::{DmaChannelFor, DmaEligible, DmaRxBuffer, DmaTxBuffer, Rx, Tx},
gpio::{
interconnect::{OutputConnection, PeripheralInput, PeripheralOutput},
interconnect::{PeripheralInput, PeripheralOutput},
InputSignal,
NoPin,
OutputSignal,
@ -711,10 +711,10 @@ impl<'d> Spi<'d, Blocking> {
let is_qspi = this.driver().info.sio2_input.is_some();
if is_qspi {
unwrap!(this.driver().info.sio2_input).connect_to(NoPin);
unwrap!(this.driver().info.sio2_output).connect_to(NoPin);
unwrap!(this.driver().info.sio3_input).connect_to(NoPin);
unwrap!(this.driver().info.sio3_output).connect_to(NoPin);
unwrap!(this.driver().info.sio2_input).connect_to(&NoPin);
unwrap!(this.driver().info.sio2_output).connect_to(&NoPin);
unwrap!(this.driver().info.sio3_input).connect_to(&NoPin);
unwrap!(this.driver().info.sio3_output).connect_to(&NoPin);
}
Ok(this)
@ -874,10 +874,10 @@ where
/// SPI clock signal.
///
/// Disconnects the previous pin that was assigned with `with_sck`.
pub fn with_sck<SCK: PeripheralOutput>(mut self, sclk: impl Peripheral<P = SCK> + 'd) -> Self {
crate::into_mapped_ref!(sclk);
pub fn with_sck(mut self, sclk: impl PeripheralOutput<'d>) -> Self {
let sclk = sclk.into();
sclk.set_to_push_pull_output();
self.pins.sclk_pin = OutputConnection::connect_with_guard(sclk, self.driver().info.sclk);
self.pins.sclk_pin = sclk.connect_with_guard(self.driver().info.sclk);
self
}
@ -890,14 +890,11 @@ where
///
/// Disconnects the previous pin that was assigned with `with_mosi` or
/// `with_sio0`.
pub fn with_mosi<MOSI: PeripheralOutput>(
mut self,
mosi: impl Peripheral<P = MOSI> + 'd,
) -> Self {
crate::into_mapped_ref!(mosi);
pub fn with_mosi(mut self, mosi: impl PeripheralOutput<'d>) -> Self {
let mosi = mosi.into();
mosi.enable_output(false);
self.pins.mosi_pin = OutputConnection::connect_with_guard(mosi, self.driver().info.mosi);
self.pins.mosi_pin = mosi.connect_with_guard(self.driver().info.mosi);
self
}
@ -909,11 +906,11 @@ where
///
/// You want to use this for full-duplex SPI or
/// [DataMode::SingleTwoDataLines]
pub fn with_miso<MISO: PeripheralInput>(self, miso: impl Peripheral<P = MISO> + 'd) -> Self {
crate::into_mapped_ref!(miso);
pub fn with_miso(self, miso: impl PeripheralInput<'d>) -> Self {
let miso = miso.into();
miso.enable_input(true);
self.driver().info.miso.connect_to(miso);
self.driver().info.miso.connect_to(&miso);
self
}
@ -932,16 +929,13 @@ where
///
/// Note: You do not need to call [Self::with_mosi] when this is used.
#[instability::unstable]
pub fn with_sio0<MOSI: PeripheralOutput>(
mut self,
mosi: impl Peripheral<P = MOSI> + 'd,
) -> Self {
crate::into_mapped_ref!(mosi);
pub fn with_sio0(mut self, mosi: impl PeripheralOutput<'d>) -> Self {
let mosi = mosi.into();
mosi.enable_output(true);
mosi.enable_input(true);
self.driver().info.sio0_input.connect_to(&mut mosi);
self.pins.mosi_pin = OutputConnection::connect_with_guard(mosi, self.driver().info.mosi);
self.driver().info.sio0_input.connect_to(&mosi);
self.pins.mosi_pin = mosi.connect_with_guard(self.driver().info.mosi);
self
}
@ -959,17 +953,13 @@ where
///
/// Note: You do not need to call [Self::with_miso] when this is used.
#[instability::unstable]
pub fn with_sio1<SIO1: PeripheralOutput>(
mut self,
miso: impl Peripheral<P = SIO1> + 'd,
) -> Self {
crate::into_mapped_ref!(miso);
miso.enable_input(true);
miso.enable_output(true);
pub fn with_sio1(mut self, sio1: impl PeripheralOutput<'d>) -> Self {
let sio1 = sio1.into();
sio1.enable_input(true);
sio1.enable_output(true);
self.driver().info.miso.connect_to(&mut miso);
self.pins.sio1_pin =
OutputConnection::connect_with_guard(miso, self.driver().info.sio1_output);
self.driver().info.miso.connect_to(&sio1);
self.pins.sio1_pin = sio1.connect_with_guard(self.driver().info.sio1_output);
self
}
@ -983,21 +973,18 @@ where
/// QSPI operations are unstable, associated pins configuration is
/// inefficient.
#[instability::unstable]
pub fn with_sio2<SIO2: PeripheralOutput>(
mut self,
sio2: impl Peripheral<P = SIO2> + 'd,
) -> Self {
pub fn with_sio2(mut self, sio2: impl PeripheralOutput<'d>) -> Self {
// TODO: panic if not QSPI?
crate::into_mapped_ref!(sio2);
let sio2 = sio2.into();
sio2.enable_input(true);
sio2.enable_output(true);
unwrap!(self.driver().info.sio2_input).connect_to(&mut sio2);
unwrap!(self.driver().info.sio2_input).connect_to(&sio2);
self.pins.sio2_pin = self
.driver()
.info
.sio2_output
.map(|signal| OutputConnection::connect_with_guard(sio2, signal));
.map(|signal| sio2.connect_with_guard(signal));
self
}
@ -1011,21 +998,18 @@ where
/// QSPI operations are unstable, associated pins configuration is
/// inefficient.
#[instability::unstable]
pub fn with_sio3<SIO3: PeripheralOutput>(
mut self,
sio3: impl Peripheral<P = SIO3> + 'd,
) -> Self {
pub fn with_sio3(mut self, sio3: impl PeripheralOutput<'d>) -> Self {
// TODO: panic if not QSPI?
crate::into_mapped_ref!(sio3);
let sio3 = sio3.into();
sio3.enable_input(true);
sio3.enable_output(true);
unwrap!(self.driver().info.sio3_input).connect_to(&mut sio3);
unwrap!(self.driver().info.sio3_input).connect_to(&sio3);
self.pins.sio3_pin = self
.driver()
.info
.sio3_output
.map(|signal| OutputConnection::connect_with_guard(sio3, signal));
.map(|signal| sio3.connect_with_guard(signal));
self
}
@ -1042,10 +1026,10 @@ where
/// be set, regardless of the total number available. There is no
/// mechanism to select which CS line to use.
#[instability::unstable]
pub fn with_cs<CS: PeripheralOutput>(mut self, cs: impl Peripheral<P = CS> + 'd) -> Self {
crate::into_mapped_ref!(cs);
pub fn with_cs(mut self, cs: impl PeripheralOutput<'d>) -> Self {
let cs = cs.into();
cs.set_to_push_pull_output();
self.pins.cs_pin = OutputConnection::connect_with_guard(cs, self.driver().info.cs);
self.pins.cs_pin = cs.connect_with_guard(self.driver().info.cs);
self
}

View File

@ -127,37 +127,37 @@ impl<'d> Spi<'d, Blocking> {
/// Assign the SCK (Serial Clock) pin for the SPI instance.
#[instability::unstable]
pub fn with_sck(self, sclk: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
crate::into_mapped_ref!(sclk);
pub fn with_sck(self, sclk: impl PeripheralInput<'d>) -> Self {
let sclk = sclk.into();
sclk.enable_input(true);
self.spi.info().sclk.connect_to(sclk);
self.spi.info().sclk.connect_to(&sclk);
self
}
/// Assign the MOSI (Master Out Slave In) pin for the SPI instance.
#[instability::unstable]
pub fn with_mosi(self, mosi: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
crate::into_mapped_ref!(mosi);
pub fn with_mosi(self, mosi: impl PeripheralInput<'d>) -> Self {
let mosi = mosi.into();
mosi.enable_input(true);
self.spi.info().mosi.connect_to(mosi);
self.spi.info().mosi.connect_to(&mosi);
self
}
/// Assign the MISO (Master In Slave Out) pin for the SPI instance.
#[instability::unstable]
pub fn with_miso(self, miso: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
crate::into_mapped_ref!(miso);
pub fn with_miso(self, miso: impl PeripheralOutput<'d>) -> Self {
let miso = miso.into();
miso.set_to_push_pull_output();
self.spi.info().miso.connect_to(miso);
self.spi.info().miso.connect_to(&miso);
self
}
/// Assign the CS (Chip Select) pin for the SPI instance.
#[instability::unstable]
pub fn with_cs(self, cs: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
crate::into_mapped_ref!(cs);
pub fn with_cs(self, cs: impl PeripheralInput<'d>) -> Self {
let cs = cs.into();
cs.enable_input(true);
self.spi.info().cs.connect_to(cs);
self.spi.info().cs.connect_to(&cs);
self
}
}

View File

@ -589,7 +589,7 @@ impl super::Timer for Alarm {
}
}
impl Peripheral for Alarm {
unsafe impl Peripheral for Alarm {
type P = Self;
#[inline]

View File

@ -356,7 +356,7 @@ impl super::Timer for Timer {
}
}
impl Peripheral for Timer {
unsafe impl Peripheral for Timer {
type P = Self;
#[inline]

View File

@ -667,15 +667,16 @@ impl<'d, Dm> TwaiConfiguration<'d, Dm>
where
Dm: DriverMode,
{
fn new_internal<TX: PeripheralOutput, RX: PeripheralInput>(
fn new_internal(
twai: PeripheralRef<'d, AnyTwai>,
rx_pin: impl Peripheral<P = RX> + 'd,
tx_pin: impl Peripheral<P = TX> + 'd,
rx_pin: impl PeripheralInput<'d>,
tx_pin: impl PeripheralOutput<'d>,
baud_rate: BaudRate,
no_transceiver: bool,
mode: TwaiMode,
) -> Self {
crate::into_mapped_ref!(tx_pin, rx_pin);
let rx_pin = rx_pin.into();
let tx_pin = tx_pin.into();
let guard = PeripheralGuard::new(twai.peripheral());
@ -710,13 +711,13 @@ where
tx_pin.set_to_push_pull_output();
Pull::None
};
this.twai.output_signal().connect_to(tx_pin);
this.twai.output_signal().connect_to(&tx_pin);
// Setting up RX pin later allows us to use a single pin in tests.
// `set_to_push_pull_output` disables input, here we re-enable it if rx_pin
// uses the same GPIO.
rx_pin.init_input(rx_pull);
this.twai.input_signal().connect_to(rx_pin);
this.twai.input_signal().connect_to(&rx_pin);
// Freeze REC by changing to LOM mode
this.set_mode(TwaiMode::ListenOnly);
@ -934,10 +935,10 @@ impl<'d> TwaiConfiguration<'d, Blocking> {
/// Create a new instance of [TwaiConfiguration]
///
/// You will need to use a transceiver to connect to the TWAI bus
pub fn new<RX: PeripheralInput, TX: PeripheralOutput>(
pub fn new(
peripheral: impl Peripheral<P = impl Instance> + 'd,
rx_pin: impl Peripheral<P = RX> + 'd,
tx_pin: impl Peripheral<P = TX> + 'd,
rx_pin: impl PeripheralInput<'d>,
tx_pin: impl PeripheralOutput<'d>,
baud_rate: BaudRate,
mode: TwaiMode,
) -> Self {
@ -950,10 +951,10 @@ impl<'d> TwaiConfiguration<'d, Blocking> {
///
/// You don't need a transceiver by following the description in the
/// `twai.rs` example
pub fn new_no_transceiver<RX: PeripheralInput, TX: PeripheralOutput>(
pub fn new_no_transceiver(
peripheral: impl Peripheral<P = impl Instance> + 'd,
rx_pin: impl Peripheral<P = RX> + 'd,
tx_pin: impl Peripheral<P = TX> + 'd,
rx_pin: impl PeripheralInput<'d>,
tx_pin: impl PeripheralOutput<'d>,
baud_rate: BaudRate,
mode: TwaiMode,
) -> Self {

View File

@ -52,7 +52,7 @@ use crate::{
asynch::AtomicWaker,
clock::Clocks,
gpio::{
interconnect::{OutputConnection, PeripheralInput, PeripheralOutput},
interconnect::{PeripheralInput, PeripheralOutput},
InputSignal,
OutputSignal,
PinGuard,
@ -675,10 +675,10 @@ where
{
/// Configure RTS pin
#[instability::unstable]
pub fn with_rts(mut self, rts: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
crate::into_mapped_ref!(rts);
pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
let rts = rts.into();
rts.set_to_push_pull_output();
self.rts_pin = OutputConnection::connect_with_guard(rts, self.uart.info().rts_signal);
self.rts_pin = rts.connect_with_guard(self.uart.info().rts_signal);
self
}
@ -690,12 +690,12 @@ where
///
/// Disconnects the previous pin that was assigned with `with_tx`.
#[instability::unstable]
pub fn with_tx(mut self, tx: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
crate::into_mapped_ref!(tx);
pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
let tx = tx.into();
// Make sure we don't cause an unexpected low pulse on the pin.
tx.set_output_high(true);
tx.set_to_push_pull_output();
self.tx_pin = OutputConnection::connect_with_guard(tx, self.uart.info().tx_signal);
self.tx_pin = tx.connect_with_guard(self.uart.info().tx_signal);
self
}
@ -1035,10 +1035,10 @@ where
///
/// Sets the specified pin to input and connects it to the UART CTS signal.
#[instability::unstable]
pub fn with_cts(self, cts: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
crate::into_mapped_ref!(cts);
pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
let cts = cts.into();
cts.init_input(Pull::None);
self.uart.info().cts_signal.connect_to(cts);
self.uart.info().cts_signal.connect_to(&cts);
self
}
@ -1052,10 +1052,10 @@ where
/// initially high, to avoid receiving a non-data byte caused by an
/// initial low signal level.
#[instability::unstable]
pub fn with_rx(self, rx: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
crate::into_mapped_ref!(rx);
pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
let rx = rx.into();
rx.init_input(Pull::Up);
self.uart.info().rx_signal.connect_to(rx);
self.uart.info().rx_signal.connect_to(&rx);
self
}
@ -1470,7 +1470,7 @@ where
/// configure the driver side (i.e. the TX pin), or ensure that the line is
/// initially high, to avoid receiving a non-data byte caused by an
/// initial low signal level.
pub fn with_rx(mut self, rx: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
self.rx = self.rx.with_rx(rx);
self
}
@ -1479,19 +1479,19 @@ where
///
/// Sets the specified pin to push-pull output and connects it to the UART
/// TX signal.
pub fn with_tx(mut self, tx: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
self.tx = self.tx.with_tx(tx);
self
}
/// Configure CTS pin
pub fn with_cts(mut self, cts: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
self.rx = self.rx.with_cts(cts);
self
}
/// Configure RTS pin
pub fn with_rts(mut self, rts: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
self.tx = self.tx.with_rts(rts);
self
}

View File

@ -51,6 +51,27 @@ pub fn interrupt_handler() {
});
}
// Compile-time test to check that GPIOs can be passed by reference.
fn _gpios_can_be_reused() {
let p = esp_hal::init(esp_hal::Config::default());
let mut gpio1 = p.GPIO1;
{
let _driver = Input::new(&mut gpio1, InputConfig::default().with_pull(Pull::Down));
}
{
let _driver = esp_hal::spi::master::Spi::new(p.SPI2, Default::default())
.unwrap()
.with_mosi(&mut gpio1);
}
{
let _driver = Input::new(&mut gpio1, InputConfig::default().with_pull(Pull::Down));
}
}
#[cfg(test)]
#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())]
mod tests {

View File

@ -36,10 +36,10 @@ use hil_test as _;
struct Context {
parl_io: PARL_IO,
dma_channel: DmaChannel0,
clock: OutputSignal,
valid: OutputSignal,
clock_loopback: InputSignal,
valid_loopback: InputSignal,
clock: OutputSignal<'static>,
valid: OutputSignal<'static>,
clock_loopback: InputSignal<'static>,
valid_loopback: InputSignal<'static>,
pcnt_unit: Unit<'static, 0>,
}

View File

@ -36,10 +36,10 @@ use hil_test as _;
struct Context {
parl_io: PARL_IO,
dma_channel: DmaChannel0,
clock: OutputSignal,
valid: OutputSignal,
clock_loopback: InputSignal,
valid_loopback: InputSignal,
clock: OutputSignal<'static>,
valid: OutputSignal<'static>,
clock_loopback: InputSignal<'static>,
valid_loopback: InputSignal<'static>,
pcnt_unit: Unit<'static, 0>,
}

View File

@ -24,7 +24,7 @@ use hil_test as _;
struct Context {
spi: SpiDma<'static, Blocking>,
pcnt_unit: Unit<'static, 0>,
pcnt_source: InputSignal,
pcnt_source: InputSignal<'static>,
}
fn perform_spi_writes_are_correctly_by_pcnt(ctx: Context, mode: DataMode) {

View File

@ -43,7 +43,7 @@ macro_rules! dma_alloc_buffer {
struct Context {
spi: SpiDma<'static, Blocking>,
pcnt_unit: Unit<'static, 0>,
pcnt_source: InputSignal,
pcnt_source: InputSignal<'static>,
}
#[cfg(test)]

View File

@ -115,6 +115,11 @@ mod tests {
}
}
// A bit of test-specific hackery, we need to be able to work with the Input
// driver directly while the SPI is driving the output signal part of
// the GPIO. This is currently not possible to describe in safe code.
let miso_pin_clone = unsafe { miso_pin.clone_unchecked() };
let mosi_gpio = Output::new(mosi_pin, Level::Low, OutputConfig::default());
let cs_gpio = Output::new(cs_pin, Level::High, OutputConfig::default());
let sclk_gpio = Output::new(sclk_pin, Level::Low, OutputConfig::default());
@ -123,7 +128,7 @@ mod tests {
let cs = cs_gpio.peripheral_input();
let sclk = sclk_gpio.peripheral_input();
let mosi = mosi_gpio.peripheral_input();
let miso = unsafe { miso_gpio.clone_unchecked() }.into_peripheral_output();
let miso = miso_pin_clone.split().1;
Context {
spi: Spi::new(peripherals.SPI2, Mode::_1)