Remove all instance type params (#2907)

This commit is contained in:
Dániel Buga 2025-01-09 12:27:48 +01:00 committed by GitHub
parent 409641dd7e
commit 0ef00206d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 449 additions and 1124 deletions

View File

@ -26,17 +26,15 @@ In general, the [Rust API Guidelines](https://rust-lang.github.io/api-guidelines
- Drivers must take peripherals via the `PeripheralRef` pattern - they don't consume peripherals directly.
- If a driver requires pins, those pins should be configured using `fn with_signal_name(self, pin: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self` or `fn with_signal_name(self, pin: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self`
- If a driver supports multiple peripheral instances (for example, I2C0 is one such instance):
- The peripheral instance type must be positioned as the last type parameter of the driver type.
- The peripheral instance type must default to a type that supports any of the peripheral instances.
- The driver should not be generic over the peripheral instance.
- The author must to use `crate::any_peripheral` to define the "any" peripheral instance type.
- The driver must implement a `new` constructor that automatically converts the peripheral instance into the any type, and a `new_typed` that preserves the peripheral type.
- The driver must implement a `new` constructor that automatically converts the peripheral instance into the any type.
- If a driver is configurable, configuration options should be implemented as a `Config` struct in the same module where the driver is located.
- The driver's constructor should take the config struct by value, and it should return `Result<Self, ConfigError>`.
- The `ConfigError` enum should be separate from other `Error` enums used by the driver.
- The driver should implement `fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError>`.
- In case the driver's configuration is infallible (all possible combinations of options are supported by the hardware), the `ConfigError` should be implemented as an empty `enum`.
- Configuration structs should derive `procmacros::BuilderLite` in order to automatically implement the Builder Lite pattern for them.
- If a driver only supports a single peripheral instance, no instance type parameter is necessary.
- If a driver implements both blocking and async operations, or only implements blocking operations, but may support asynchronous ones in the future, the driver's type signature must include a `crate::Mode` type parameter.
- By default, constructors must configure the driver for blocking mode. The driver must implement `into_async` (and a matching `into_blocking`) function that reconfigures the driver.
- `into_async` must configure the driver and/or the associated DMA channels. This most often means enabling an interrupt handler.

View File

@ -5,11 +5,11 @@ use esp_hal::{
interrupt::{InterruptHandler, Priority},
sync::Locked,
time::{now, ExtU64},
timer::{AnyTimer, OneShotTimer},
timer::OneShotTimer,
Blocking,
};
pub type Timer = OneShotTimer<'static, Blocking, AnyTimer>;
pub type Timer = OneShotTimer<'static, Blocking>;
enum AlarmState {
Created(extern "C" fn()),

View File

@ -127,6 +127,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The `prelude` module has been removed (#2845)
- Removed all peripheral instance type parameters and `new_typed` constructors (#2907)
## [0.22.0] - 2024-11-20
### Added

View File

@ -262,6 +262,15 @@ is not compatible with the hardware.
+.unwrap();
```
## Peripheral instance type parameters and `new_typed` constructors have been removed
Call `new` instead and remove the type parameters if you've used them.
```diff
-let mut spi: Spi<'lt, SPI2> = Spi::new_typed(..).unwrap();
+let mut spi: Spi<'lt> = Spi::new(..).unwrap();
```
## LCD_CAM configuration changes
- `cam` now has a `Config` strurct that contains frequency, bit/byte order, VSync filter options.

View File

@ -1668,18 +1668,18 @@ impl<DEG: DmaChannel> DmaChannelConvert<DEG> for DEG {
///
/// ```rust,no_run
#[doc = crate::before_snippet!()]
/// use esp_hal::spi::AnySpi;
/// use esp_hal::spi::master::{Spi, SpiDma, Config, Instance as SpiInstance};
/// use esp_hal::dma::DmaChannelFor;
/// use esp_hal::peripheral::Peripheral;
/// use esp_hal::Blocking;
///
/// fn configures_spi_dma<'d, S, CH>(
/// spi: Spi<'d, Blocking, S>,
/// fn configures_spi_dma<'d, CH>(
/// spi: Spi<'d, Blocking>,
/// channel: impl Peripheral<P = CH> + 'd,
/// ) -> SpiDma<'d, Blocking, S>
/// ) -> SpiDma<'d, Blocking>
/// where
/// S: SpiInstance,
/// CH: DmaChannelFor<S> + 'd,
/// CH: DmaChannelFor<AnySpi> + 'd,
/// {
/// spi.with_dma(channel)
/// }

View File

@ -41,8 +41,8 @@ impl<P: InputPin> PeripheralInput for P {}
impl<P: OutputPin> PeripheralOutput for P {}
// Pin drivers
impl<P: InputPin> PeripheralInput for Flex<'static, P> {}
impl<P: OutputPin> PeripheralOutput for Flex<'static, P> {}
impl PeripheralInput for Flex<'static> {}
impl PeripheralOutput for Flex<'static> {}
// Placeholders
impl PeripheralInput for NoPin {}
@ -226,11 +226,8 @@ where
}
}
impl<P> From<Flex<'static, P>> for InputSignal
where
P: InputPin,
{
fn from(input: Flex<'static, P>) -> Self {
impl From<Flex<'static>> for InputSignal {
fn from(input: Flex<'static>) -> Self {
Self::new(input.degrade())
}
}
@ -364,11 +361,8 @@ where
}
}
impl<P> From<Flex<'static, P>> for OutputSignal
where
P: OutputPin,
{
fn from(input: Flex<'static, P>) -> Self {
impl From<Flex<'static>> for OutputSignal {
fn from(input: Flex<'static>) -> Self {
Self::new(input.degrade())
}
}
@ -576,11 +570,8 @@ impl From<OutputConnection> for InputConnection {
}
}
impl<P> From<Flex<'static, P>> for InputConnection
where
P: InputPin,
{
fn from(pin: Flex<'static, P>) -> Self {
impl From<Flex<'static>> for InputConnection {
fn from(pin: Flex<'static>) -> Self {
pin.peripheral_input().into()
}
}
@ -668,11 +659,8 @@ impl From<OutputSignal> for OutputConnection {
}
}
impl<P> From<Flex<'static, P>> for OutputConnection
where
P: OutputPin,
{
fn from(pin: Flex<'static, P>) -> Self {
impl From<Flex<'static>> for OutputConnection {
fn from(pin: Flex<'static>) -> Self {
pin.into_peripheral_output().into()
}
}

View File

@ -18,10 +18,7 @@
//! into peripheral signals for advanced use.
//!
//! Pin drivers can be created using [`Flex::new`], [`Input::new`],
//! [`Output::new`] and [`OutputOpenDrain::new`]. If you need the pin drivers to
//! carry the type of the pin, you can use the [`Flex::new_typed`],
//! [`Input::new_typed`], [`Output::new_typed`], and
//! [`OutputOpenDrain::new_typed`] functions.
//! [`Output::new`] and [`OutputOpenDrain::new`].
//!
//! Each pin is a different type initially. Internally, `esp-hal` will often
//! erase their types automatically, but they can also be converted into
@ -313,6 +310,7 @@ pub trait RtcPin: Pin {
/// Trait implemented by RTC pins which supporting internal pull-up / pull-down
/// resistors.
#[instability::unstable]
#[cfg(any(lp_io, rtc_cntl))]
pub trait RtcPinWithResistors: RtcPin {
/// Enable/disable the internal pull-up resistor
fn rtcio_pullup(&mut self, enable: bool);
@ -1096,7 +1094,7 @@ macro_rules! gpio {
}
impl $crate::gpio::AnyPin {
/// Conjure a new, type-erased GPIO pin out of thin air.
/// Conjure a new GPIO pin out of thin air.
///
/// # Safety
///
@ -1110,6 +1108,15 @@ macro_rules! gpio {
assert!(PINS.contains(&pin), "Pin {} does not exist", pin);
Self(pin)
}
pub(crate) fn is_output(&self) -> bool {
match self.0 {
$(
$gpionum => $crate::if_output_pin!($($type),* { true } else { false }),
)+
_ => false,
}
}
}
// These macros call the code block on the actually contained GPIO pin.
@ -1208,21 +1215,21 @@ macro_rules! gpio {
/// for both high and low logical [`Level`]s.
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Output<'d, P = AnyPin> {
pin: Flex<'d, P>,
pub struct Output<'d> {
pin: Flex<'d>,
}
impl<P> private::Sealed for Output<'_, P> {}
impl private::Sealed for Output<'_> {}
impl<'d, P> Peripheral for Output<'d, P> {
type P = Flex<'d, P>;
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, type-erased GPIO output driver.
/// Creates a new GPIO output driver.
///
/// The `initial_output` parameter sets the initial output level of the pin.
///
@ -1251,47 +1258,7 @@ impl<'d> Output<'d> {
/// ```
#[inline]
pub fn new(pin: impl Peripheral<P = impl OutputPin> + 'd, initial_output: Level) -> Self {
Self::new_typed(pin.map_into(), initial_output)
}
}
impl<'d, P> Output<'d, P>
where
P: OutputPin,
{
/// Creates a new, typed GPIO output driver.
///
/// The `initial_output` parameter sets the initial output level of the pin.
///
/// This constructor is useful when you want to limit which GPIO pin can be
/// used for a particular function.
///
/// ## Example
///
/// The following example configures `GPIO5` to pulse a LED once. The
/// example assumes that the LED is connected such that it is on when
/// the pin is low.
///
/// ```rust, no_run
#[doc = crate::before_snippet!()]
/// use esp_hal::gpio::{GpioPin, Level, Output};
/// use esp_hal::delay::Delay;
///
/// fn blink_once(led: &mut Output<'_, GpioPin<5>>, delay: &mut Delay) {
/// led.set_low();
/// delay.delay_millis(500);
/// led.set_high();
/// }
///
/// let mut led = Output::new_typed(peripherals.GPIO5, Level::High);
/// let mut delay = Delay::new();
///
/// blink_once(&mut led, &mut delay);
/// # }
/// ```
#[inline]
pub fn new_typed(pin: impl Peripheral<P = P> + 'd, initial_output: Level) -> Self {
let mut pin = Flex::new_typed(pin);
let mut pin = Flex::new(pin);
pin.set_level(initial_output);
pin.set_as_output();
@ -1381,21 +1348,21 @@ where
/// voltage of their pins and convert it to a logical [`Level`].
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Input<'d, P = AnyPin> {
pin: Flex<'d, P>,
pub struct Input<'d> {
pin: Flex<'d>,
}
impl<P> private::Sealed for Input<'_, P> {}
impl private::Sealed for Input<'_> {}
impl<'d, P> Peripheral for Input<'d, P> {
type P = Flex<'d, P>;
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, type-erased GPIO input.
/// Creates a new GPIO input.
///
/// The `pull` parameter configures internal pull-up or pull-down
/// resistors.
@ -1434,60 +1401,7 @@ impl<'d> Input<'d> {
/// ```
#[inline]
pub fn new(pin: impl Peripheral<P = impl InputPin> + 'd, pull: Pull) -> Self {
Self::new_typed(pin.map_into(), pull)
}
}
impl<'d, P> Input<'d, P>
where
P: InputPin,
{
/// Creates a new, typed GPIO input.
///
/// The `pull` parameter configures internal pull-up or pull-down
/// resistors.
///
/// This constructor is useful when you want to limit which GPIO pin can be
/// used for a particular function.
///
/// ## Example
///
/// The following example configures `GPIO5` to read a button press. The
/// example assumes that the button is connected such that the pin is low
/// when the button is pressed.
///
/// ```rust, no_run
#[doc = crate::before_snippet!()]
/// use esp_hal::gpio::{GpioPin, Level, Input, Pull};
/// use esp_hal::delay::Delay;
///
/// fn print_when_pressed(
/// button: &mut Input<'_, GpioPin<5>>,
/// delay: &mut Delay,
/// ) {
/// let mut was_pressed = false;
/// loop {
/// let is_pressed = button.is_low();
/// if is_pressed && !was_pressed {
/// println!("Button pressed!");
/// }
/// was_pressed = is_pressed;
/// delay.delay_millis(100);
/// }
/// }
///
/// let mut button = Input::new_typed(
/// peripherals.GPIO5,
/// Pull::Up,
/// );
/// let mut delay = Delay::new();
///
/// print_when_pressed(&mut button, &mut delay);
/// # }
/// ```
#[inline]
pub fn new_typed(pin: impl Peripheral<P = P> + 'd, pull: Pull) -> Self {
let mut pin = Flex::new_typed(pin);
let mut pin = Flex::new(pin);
pin.set_as_input(pull);
@ -1620,12 +1534,7 @@ where
pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) {
self.pin.wakeup_enable(enable, event);
}
}
impl<P> Input<'_, P>
where
P: InputPin + OutputPin,
{
/// Split the pin into an input and output signal.
///
/// Peripheral signals allow connecting peripherals together without using
@ -1654,21 +1563,21 @@ where
/// resistors.
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct OutputOpenDrain<'d, P = AnyPin> {
pin: Flex<'d, P>,
pub struct OutputOpenDrain<'d> {
pin: Flex<'d>,
}
impl<P> private::Sealed for OutputOpenDrain<'_, P> {}
impl private::Sealed for OutputOpenDrain<'_> {}
impl<'d, P> Peripheral for OutputOpenDrain<'d, P> {
type P = Flex<'d, P>;
impl<'d> Peripheral for OutputOpenDrain<'d> {
type P = Flex<'d>;
unsafe fn clone_unchecked(&self) -> Self::P {
self.pin.clone_unchecked()
}
}
impl<'d> OutputOpenDrain<'d> {
/// Creates a new, type-erased GPIO output driver.
/// Creates a new GPIO output driver.
///
/// The `initial_output` parameter sets the initial output level of the pin.
/// The `pull` parameter configures internal pull-up or pull-down
@ -1707,53 +1616,7 @@ impl<'d> OutputOpenDrain<'d> {
initial_output: Level,
pull: Pull,
) -> Self {
Self::new_typed(pin.map_into(), initial_output, pull)
}
}
impl<'d, P> OutputOpenDrain<'d, P>
where
P: InputPin + OutputPin,
{
/// Creates a new, typed GPIO output driver.
///
/// The `initial_output` parameter sets the initial output level of the pin.
/// The `pull` parameter configures internal pull-up or pull-down
/// resistors.
///
/// ## Example
///
/// The following example configures `GPIO5` to pulse a LED once. The
/// example assumes that the LED is connected such that it is on when
/// the pin is low.
///
/// ```rust, no_run
#[doc = crate::before_snippet!()]
/// use esp_hal::gpio::{GpioPin, Level, OutputOpenDrain, Pull};
/// use esp_hal::delay::Delay;
///
/// fn blink_once(
/// led: &mut OutputOpenDrain<'_, GpioPin<5>>,
/// delay: &mut Delay,
/// ) {
/// led.set_low();
/// delay.delay_millis(500);
/// led.set_high();
/// }
///
/// let mut led = OutputOpenDrain::new_typed(
/// peripherals.GPIO5,
/// Level::High,
/// Pull::Up,
/// );
/// let mut delay = Delay::new();
///
/// blink_once(&mut led, &mut delay);
/// # }
/// ```
#[inline]
pub fn new_typed(pin: impl Peripheral<P = P> + 'd, initial_output: Level, pull: Pull) -> Self {
let mut pin = Flex::new_typed(pin);
let mut pin = Flex::new(pin);
pin.set_level(initial_output);
pin.set_as_open_drain(pull);
@ -1879,17 +1742,17 @@ where
/// This driver allows changing the pin mode between input and output.
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Flex<'d, P = AnyPin> {
pin: PeripheralRef<'d, P>,
pub struct Flex<'d> {
pin: PeripheralRef<'d, AnyPin>,
}
impl<P> private::Sealed for Flex<'_, P> {}
impl private::Sealed for Flex<'_> {}
impl<P> Peripheral for Flex<'_, P> {
impl Peripheral for Flex<'_> {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
Self {
pin: PeripheralRef::new(core::ptr::read(&*self.pin as *const P)),
pin: PeripheralRef::new(core::ptr::read(&*self.pin as *const AnyPin)),
}
}
}
@ -1899,19 +1762,7 @@ impl<'d> Flex<'d> {
/// No mode change happens.
#[inline]
pub fn new(pin: impl Peripheral<P = impl Into<AnyPin>> + 'd) -> Self {
Self::new_typed(pin.map_into())
}
}
impl<'d, P> Flex<'d, P>
where
P: Pin,
{
/// Create flexible pin driver for a [Pin].
/// No mode change happens.
#[inline]
pub fn new_typed(pin: impl Peripheral<P = P> + 'd) -> Self {
crate::into_ref!(pin);
crate::into_mapped_ref!(pin);
Self { pin }
}
@ -1923,12 +1774,7 @@ where
pub fn peripheral_input(&self) -> interconnect::InputSignal {
self.pin.degrade_pin(private::Internal).split().0
}
}
impl<P> Flex<'_, P>
where
P: InputPin,
{
/// Set the GPIO to input mode.
pub fn set_as_input(&mut self, pull: Pull) {
self.pin.init_input(pull, private::Internal);
@ -2020,12 +1866,7 @@ where
pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) {
self.listen_with_options(event.into(), false, false, enable);
}
}
impl<P> Flex<'_, P>
where
P: OutputPin,
{
/// Set the GPIO to output mode.
#[instability::unstable]
#[inline]
@ -2093,6 +1934,7 @@ where
/// Peripheral signals allow connecting peripherals together without using
/// external hardware.
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
assert!(self.pin.is_output());
self.pin.degrade_pin(private::Internal).split()
}
@ -2110,7 +1952,7 @@ where
// Unfortunate implementation details responsible for:
// - making pin drivers work with the peripheral signal system
// - making the pin drivers work with the sleep API
impl<P: Pin> Pin for Flex<'_, P> {
impl Pin for Flex<'_> {
delegate::delegate! {
to self.pin {
fn number(&self) -> u8;
@ -2120,7 +1962,8 @@ impl<P: Pin> Pin for Flex<'_, P> {
}
}
}
impl<P: RtcPin> RtcPin for Flex<'_, P> {
#[cfg(any(lp_io, rtc_cntl))]
impl RtcPin for Flex<'_> {
delegate::delegate! {
to self.pin {
#[cfg(xtensa)]
@ -2133,7 +1976,8 @@ impl<P: RtcPin> RtcPin for Flex<'_, P> {
}
}
}
impl<P: RtcPinWithResistors> RtcPinWithResistors for Flex<'_, P> {
#[cfg(any(lp_io, rtc_cntl))]
impl RtcPinWithResistors for Flex<'_> {
delegate::delegate! {
to self.pin {
fn rtcio_pullup(&mut self, enable: bool);
@ -2262,7 +2106,7 @@ pub(crate) mod internal {
}
}
#[cfg(any(xtensa, esp32c2, esp32c3, esp32c6))]
#[cfg(any(lp_io, rtc_cntl))]
impl RtcPin for AnyPin {
#[cfg(xtensa)]
#[allow(unused_braces)] // False positive :/
@ -2291,7 +2135,7 @@ pub(crate) mod internal {
}
}
#[cfg(any(esp32c2, esp32c3, esp32c6, xtensa))]
#[cfg(any(lp_io, rtc_cntl))]
impl RtcPinWithResistors for AnyPin {
fn rtcio_pullup(&mut self, enable: bool) {
handle_rtcio_with_resistors!(self, target, {
@ -2348,10 +2192,7 @@ mod asynch {
pub(super) static PIN_WAKERS: [AtomicWaker; NUM_PINS] =
[const { AtomicWaker::new() }; NUM_PINS];
impl<P> Flex<'_, P>
where
P: InputPin,
{
impl Flex<'_> {
/// Wait until the pin experiences a particular [`Event`].
///
/// The GPIO driver will disable listening for the event once it occurs,
@ -2434,10 +2275,7 @@ mod asynch {
}
}
impl<P> Input<'_, P>
where
P: InputPin,
{
impl Input<'_> {
/// Wait until the pin experiences a particular [`Event`].
///
/// The GPIO driver will disable listening for the event once it occurs,
@ -2488,11 +2326,11 @@ mod asynch {
}
#[must_use = "futures do nothing unless you `.await` or poll them"]
struct PinFuture<'d, P: InputPin> {
pin: Flex<'d, P>,
struct PinFuture<'d> {
pin: Flex<'d>,
}
impl<P: InputPin> PinFuture<'_, P> {
impl PinFuture<'_> {
fn pin_mask(&self) -> u32 {
let bank = GpioRegisterAccess::from(self.pin.number() as usize);
1 << (self.pin.number() - bank.offset())
@ -2509,7 +2347,7 @@ mod asynch {
}
}
impl<P: InputPin> core::future::Future for PinFuture<'_, P> {
impl core::future::Future for PinFuture<'_> {
type Output = ();
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
@ -2523,7 +2361,7 @@ mod asynch {
}
}
impl<P: InputPin> Drop for PinFuture<'_, P> {
impl Drop for PinFuture<'_> {
fn drop(&mut self) {
// If the pin isn't listening, the future has either been dropped before setup,
// or the interrupt has already been handled.
@ -2554,17 +2392,11 @@ mod embedded_hal_impls {
use super::*;
impl<P> digital::ErrorType for Input<'_, P>
where
P: InputPin,
{
impl digital::ErrorType for Input<'_> {
type Error = core::convert::Infallible;
}
impl<P> digital::InputPin for Input<'_, P>
where
P: InputPin,
{
impl digital::InputPin for Input<'_> {
fn is_high(&mut self) -> Result<bool, Self::Error> {
Ok(Self::is_high(self))
}
@ -2574,17 +2406,11 @@ mod embedded_hal_impls {
}
}
impl<P> digital::ErrorType for Output<'_, P>
where
P: OutputPin,
{
impl digital::ErrorType for Output<'_> {
type Error = core::convert::Infallible;
}
impl<P> digital::OutputPin for Output<'_, P>
where
P: OutputPin,
{
impl digital::OutputPin for Output<'_> {
fn set_low(&mut self) -> Result<(), Self::Error> {
Self::set_low(self);
Ok(())
@ -2596,10 +2422,7 @@ mod embedded_hal_impls {
}
}
impl<P> digital::StatefulOutputPin for Output<'_, P>
where
P: OutputPin,
{
impl digital::StatefulOutputPin for Output<'_> {
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
Ok(Self::is_set_high(self))
}
@ -2609,10 +2432,7 @@ mod embedded_hal_impls {
}
}
impl<P> digital::InputPin for OutputOpenDrain<'_, P>
where
P: InputPin + OutputPin,
{
impl digital::InputPin for OutputOpenDrain<'_> {
fn is_high(&mut self) -> Result<bool, Self::Error> {
Ok(Self::is_high(self))
}
@ -2622,17 +2442,11 @@ mod embedded_hal_impls {
}
}
impl<P> digital::ErrorType for OutputOpenDrain<'_, P>
where
P: InputPin + OutputPin,
{
impl digital::ErrorType for OutputOpenDrain<'_> {
type Error = core::convert::Infallible;
}
impl<P> digital::OutputPin for OutputOpenDrain<'_, P>
where
P: InputPin + OutputPin,
{
impl digital::OutputPin for OutputOpenDrain<'_> {
fn set_low(&mut self) -> Result<(), Self::Error> {
Self::set_low(self);
Ok(())
@ -2644,10 +2458,7 @@ mod embedded_hal_impls {
}
}
impl<P> digital::StatefulOutputPin for OutputOpenDrain<'_, P>
where
P: InputPin + OutputPin,
{
impl digital::StatefulOutputPin for OutputOpenDrain<'_> {
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
Ok(Self::is_set_high(self))
}
@ -2657,10 +2468,7 @@ mod embedded_hal_impls {
}
}
impl<P> digital::InputPin for Flex<'_, P>
where
P: InputPin,
{
impl digital::InputPin for Flex<'_> {
fn is_high(&mut self) -> Result<bool, Self::Error> {
Ok(Self::is_high(self))
}
@ -2670,14 +2478,11 @@ mod embedded_hal_impls {
}
}
impl<P> digital::ErrorType for Flex<'_, P> {
impl digital::ErrorType for Flex<'_> {
type Error = core::convert::Infallible;
}
impl<P> digital::OutputPin for Flex<'_, P>
where
P: OutputPin,
{
impl digital::OutputPin for Flex<'_> {
fn set_low(&mut self) -> Result<(), Self::Error> {
Self::set_low(self);
Ok(())
@ -2689,10 +2494,7 @@ mod embedded_hal_impls {
}
}
impl<P> digital::StatefulOutputPin for Flex<'_, P>
where
P: OutputPin,
{
impl digital::StatefulOutputPin for Flex<'_> {
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
Ok(Self::is_set_high(self))
}
@ -2708,10 +2510,7 @@ mod embedded_hal_async_impls {
use super::*;
impl<P> Wait for Flex<'_, P>
where
P: InputPin,
{
impl Wait for Flex<'_> {
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
Self::wait_for_high(self).await;
Ok(())
@ -2738,10 +2537,7 @@ mod embedded_hal_async_impls {
}
}
impl<P> Wait for Input<'_, P>
where
P: InputPin,
{
impl Wait for Input<'_> {
async fn wait_for_high(&mut self) -> Result<(), Self::Error> {
Self::wait_for_high(self).await;
Ok(())

View File

@ -320,8 +320,8 @@ impl Default for Config {
/// I2C driver
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct I2c<'d, Dm: DriverMode, T = AnyI2c> {
i2c: PeripheralRef<'d, T>,
pub struct I2c<'d, Dm: DriverMode> {
i2c: PeripheralRef<'d, AnyI2c>,
phantom: PhantomData<Dm>,
config: Config,
guard: PeripheralGuard,
@ -329,7 +329,7 @@ pub struct I2c<'d, Dm: DriverMode, T = AnyI2c> {
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T: Instance, Dm: DriverMode> SetConfig for I2c<'_, Dm, T> {
impl<Dm: DriverMode> SetConfig for I2c<'_, Dm> {
type Config = Config;
type ConfigError = ConfigError;
@ -338,14 +338,11 @@ impl<T: Instance, Dm: DriverMode> SetConfig for I2c<'_, Dm, T> {
}
}
impl<T, Dm: DriverMode> embedded_hal::i2c::ErrorType for I2c<'_, Dm, T> {
impl<Dm: DriverMode> embedded_hal::i2c::ErrorType for I2c<'_, Dm> {
type Error = Error;
}
impl<T, Dm: DriverMode> embedded_hal::i2c::I2c for I2c<'_, Dm, T>
where
T: Instance,
{
impl<Dm: DriverMode> embedded_hal::i2c::I2c for I2c<'_, Dm> {
fn transaction(
&mut self,
address: u8,
@ -356,10 +353,7 @@ where
}
}
impl<'d, T, Dm: DriverMode> I2c<'d, Dm, T>
where
T: Instance,
{
impl<'d, Dm: DriverMode> I2c<'d, Dm> {
fn driver(&self) -> Driver<'_> {
Driver {
info: self.i2c.info(),
@ -475,22 +469,7 @@ impl<'d> I2c<'d, Blocking> {
i2c: impl Peripheral<P = impl Instance> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_typed(i2c.map_into(), config)
}
}
impl<'d, T> I2c<'d, Blocking, T>
where
T: Instance,
{
/// Create a new I2C instance
/// This will enable the peripheral but the peripheral won't get
/// automatically disabled when this gets dropped.
pub fn new_typed(
i2c: impl Peripheral<P = T> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
crate::into_ref!(i2c);
crate::into_mapped_ref!(i2c);
let guard = PeripheralGuard::new(i2c.info().peripheral);
@ -509,7 +488,7 @@ where
// TODO: missing interrupt APIs
/// Configures the I2C peripheral to operate in asynchronous mode.
pub fn into_async(mut self) -> I2c<'d, Async, T> {
pub fn into_async(mut self) -> I2c<'d, Async> {
self.set_interrupt_handler(self.driver().info.async_handler);
I2c {
@ -581,12 +560,9 @@ where
}
}
impl<T> private::Sealed for I2c<'_, Blocking, T> where T: Instance {}
impl private::Sealed for I2c<'_, Blocking> {}
impl<T> InterruptConfigurable for I2c<'_, Blocking, T>
where
T: Instance,
{
impl InterruptConfigurable for I2c<'_, Blocking> {
fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
let interrupt = self.driver().info.interrupt;
for core in Cpu::other() {
@ -698,12 +674,9 @@ impl core::future::Future for I2cFuture<'_> {
}
}
impl<'d, T> I2c<'d, Async, T>
where
T: Instance,
{
impl<'d> I2c<'d, Async> {
/// Configure the I2C peripheral to operate in blocking mode.
pub fn into_blocking(self) -> I2c<'d, Blocking, T> {
pub fn into_blocking(self) -> I2c<'d, Blocking> {
crate::interrupt::disable(Cpu::current(), self.driver().info.interrupt);
I2c {
@ -832,10 +805,7 @@ where
}
}
impl<T> embedded_hal_async::i2c::I2c for I2c<'_, Async, T>
where
T: Instance,
{
impl embedded_hal_async::i2c::I2c for I2c<'_, Async> {
async fn transaction(
&mut self,
address: u8,

View File

@ -90,7 +90,6 @@ use crate::{
DmaTransferRxCircular,
DmaTransferTx,
DmaTransferTxCircular,
PeripheralDmaChannel,
PeripheralRxChannel,
PeripheralTxChannel,
ReadBuffer,
@ -251,67 +250,18 @@ impl DataFormat {
/// Instance of the I2S peripheral driver
#[non_exhaustive]
pub struct I2s<'d, Dm, T = AnyI2s>
pub struct I2s<'d, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
/// Handles the reception (RX) side of the I2S peripheral.
pub i2s_rx: RxCreator<'d, Dm, T>,
pub i2s_rx: RxCreator<'d, Dm>,
/// Handles the transmission (TX) side of the I2S peripheral.
pub i2s_tx: TxCreator<'d, Dm, T>,
pub i2s_tx: TxCreator<'d, Dm>,
}
impl<'d, T> I2s<'d, Blocking, T>
impl<Dm> I2s<'_, Dm>
where
T: RegisterAccess,
{
#[allow(clippy::too_many_arguments)]
fn new_internal(
i2s: PeripheralRef<'d, T>,
standard: Standard,
data_format: DataFormat,
sample_rate: impl Into<fugit::HertzU32>,
channel: PeripheralRef<'d, PeripheralDmaChannel<T>>,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> Self {
let channel = Channel::new(channel);
channel.runtime_ensure_compatible(&i2s);
// on ESP32-C3 / ESP32-S3 and later RX and TX are independent and
// could be configured totally independently but for now handle all
// the targets the same and force same configuration for both, TX and RX
// make sure the peripheral is enabled before configuring it
let peripheral = i2s.peripheral();
let rx_guard = PeripheralGuard::new(peripheral);
let tx_guard = PeripheralGuard::new(peripheral);
i2s.set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits()));
i2s.configure(&standard, &data_format);
i2s.set_master();
i2s.update();
Self {
i2s_rx: RxCreator {
i2s: unsafe { i2s.clone_unchecked() },
rx_channel: channel.rx,
descriptors: rx_descriptors,
guard: rx_guard,
},
i2s_tx: TxCreator {
i2s,
tx_channel: channel.tx,
descriptors: tx_descriptors,
guard: tx_guard,
},
}
}
}
impl<Dm, T> I2s<'_, Dm, T>
where
T: RegisterAccess,
Dm: DriverMode,
{
/// Sets the interrupt handler
@ -347,16 +297,10 @@ where
}
}
impl<Dm, I> crate::private::Sealed for I2s<'_, Dm, I>
where
I: RegisterAccess,
Dm: DriverMode,
{
}
impl<Dm> crate::private::Sealed for I2s<'_, Dm> where Dm: DriverMode {}
impl<Dm, I> InterruptConfigurable for I2s<'_, Dm, I>
impl<Dm> InterruptConfigurable for I2s<'_, Dm>
where
I: RegisterAccess,
Dm: DriverMode,
{
fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
@ -379,52 +323,46 @@ impl<'d> I2s<'d, Blocking> {
) -> Self
where
CH: DmaChannelFor<AnyI2s>,
{
Self::new_typed(
i2s.map_into(),
standard,
data_format,
sample_rate,
channel,
rx_descriptors,
tx_descriptors,
)
}
}
impl<'d, T> I2s<'d, Blocking, T>
where
T: RegisterAccess,
{
/// Construct a new I2S peripheral driver instance for the first I2S
/// peripheral
#[allow(clippy::too_many_arguments)]
pub fn new_typed<CH>(
i2s: impl Peripheral<P = T> + 'd,
standard: Standard,
data_format: DataFormat,
sample_rate: impl Into<fugit::HertzU32>,
channel: impl Peripheral<P = CH> + 'd,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> Self
where
CH: DmaChannelFor<T>,
{
crate::into_ref!(i2s);
Self::new_internal(
i2s,
standard,
data_format,
sample_rate,
channel.map(|ch| ch.degrade()).into_ref(),
rx_descriptors,
tx_descriptors,
)
let channel = Channel::new(channel.map(|ch| ch.degrade()));
channel.runtime_ensure_compatible(&i2s);
// on ESP32-C3 / ESP32-S3 and later RX and TX are independent and
// could be configured totally independently but for now handle all
// the targets the same and force same configuration for both, TX and RX
// make sure the peripheral is enabled before configuring it
let peripheral = i2s.peripheral();
let rx_guard = PeripheralGuard::new(peripheral);
let tx_guard = PeripheralGuard::new(peripheral);
i2s.set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits()));
i2s.configure(&standard, &data_format);
i2s.set_master();
i2s.update();
let i2s = i2s.map_into();
Self {
i2s_rx: RxCreator {
i2s: unsafe { i2s.clone_unchecked() },
rx_channel: channel.rx,
descriptors: rx_descriptors,
guard: rx_guard,
},
i2s_tx: TxCreator {
i2s,
tx_channel: channel.tx,
descriptors: tx_descriptors,
guard: tx_guard,
},
}
}
/// Converts the I2S instance into async mode.
pub fn into_async(self) -> I2s<'d, Async, T> {
pub fn into_async(self) -> I2s<'d, Async> {
I2s {
i2s_rx: RxCreator {
i2s: self.i2s_rx.i2s,
@ -442,9 +380,8 @@ where
}
}
impl<'d, Dm, T> I2s<'d, Dm, T>
impl<'d, Dm> I2s<'d, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
/// Configures the I2S peripheral to use a master clock (MCLK) output pin.
@ -458,20 +395,18 @@ where
}
/// I2S TX channel
pub struct I2sTx<'d, Dm, T = AnyI2s>
pub struct I2sTx<'d, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
i2s: PeripheralRef<'d, T>,
tx_channel: ChannelTx<'d, Dm, PeripheralTxChannel<T>>,
i2s: PeripheralRef<'d, AnyI2s>,
tx_channel: ChannelTx<'d, Dm, PeripheralTxChannel<AnyI2s>>,
tx_chain: DescriptorChain,
_guard: PeripheralGuard,
}
impl<Dm, T> core::fmt::Debug for I2sTx<'_, Dm, T>
impl<Dm> core::fmt::Debug for I2sTx<'_, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
@ -479,9 +414,8 @@ where
}
}
impl<Dm, T> DmaSupport for I2sTx<'_, Dm, T>
impl<Dm> DmaSupport for I2sTx<'_, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
fn peripheral_wait_dma(&mut self, _is_rx: bool, _is_tx: bool) {
@ -493,12 +427,11 @@ where
}
}
impl<'d, Dm, T> DmaSupportTx for I2sTx<'d, Dm, T>
impl<'d, Dm> DmaSupportTx for I2sTx<'d, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
type TX = ChannelTx<'d, Dm, PeripheralTxChannel<T>>;
type TX = ChannelTx<'d, Dm, PeripheralTxChannel<AnyI2s>>;
fn tx(&mut self) -> &mut Self::TX {
&mut self.tx_channel
@ -509,9 +442,8 @@ where
}
}
impl<Dm, T> I2sTx<'_, Dm, T>
impl<Dm> I2sTx<'_, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
fn write_bytes(&mut self, data: &[u8]) -> Result<(), Error> {
@ -591,20 +523,18 @@ where
}
/// I2S RX channel
pub struct I2sRx<'d, Dm, T = AnyI2s>
pub struct I2sRx<'d, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
i2s: PeripheralRef<'d, T>,
rx_channel: ChannelRx<'d, Dm, PeripheralRxChannel<T>>,
i2s: PeripheralRef<'d, AnyI2s>,
rx_channel: ChannelRx<'d, Dm, PeripheralRxChannel<AnyI2s>>,
rx_chain: DescriptorChain,
_guard: PeripheralGuard,
}
impl<Dm, T> core::fmt::Debug for I2sRx<'_, Dm, T>
impl<Dm> core::fmt::Debug for I2sRx<'_, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
@ -612,9 +542,8 @@ where
}
}
impl<Dm, T> DmaSupport for I2sRx<'_, Dm, T>
impl<Dm> DmaSupport for I2sRx<'_, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
fn peripheral_wait_dma(&mut self, _is_rx: bool, _is_tx: bool) {
@ -626,12 +555,11 @@ where
}
}
impl<'d, Dm, T> DmaSupportRx for I2sRx<'d, Dm, T>
impl<'d, Dm> DmaSupportRx for I2sRx<'d, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
type RX = ChannelRx<'d, Dm, PeripheralRxChannel<T>>;
type RX = ChannelRx<'d, Dm, PeripheralRxChannel<AnyI2s>>;
fn rx(&mut self) -> &mut Self::RX {
&mut self.rx_channel
@ -642,9 +570,8 @@ where
}
}
impl<Dm, T> I2sRx<'_, Dm, T>
impl<Dm> I2sRx<'_, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
fn read_bytes(&mut self, mut data: &mut [u8]) -> Result<(), Error> {
@ -761,23 +688,21 @@ mod private {
DriverMode,
};
pub struct TxCreator<'d, Dm, T>
pub struct TxCreator<'d, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
pub i2s: PeripheralRef<'d, T>,
pub tx_channel: ChannelTx<'d, Dm, PeripheralTxChannel<T>>,
pub i2s: PeripheralRef<'d, AnyI2s>,
pub tx_channel: ChannelTx<'d, Dm, PeripheralTxChannel<AnyI2s>>,
pub descriptors: &'static mut [DmaDescriptor],
pub(crate) guard: PeripheralGuard,
}
impl<'d, Dm, T> TxCreator<'d, Dm, T>
impl<'d, Dm> TxCreator<'d, Dm>
where
Dm: DriverMode,
T: RegisterAccess,
{
pub fn build(self) -> I2sTx<'d, Dm, T> {
pub fn build(self) -> I2sTx<'d, Dm> {
let peripheral = self.i2s.peripheral();
I2sTx {
i2s: self.i2s,
@ -821,23 +746,21 @@ mod private {
}
}
pub struct RxCreator<'d, Dm, T>
pub struct RxCreator<'d, Dm>
where
T: RegisterAccess,
Dm: DriverMode,
{
pub i2s: PeripheralRef<'d, T>,
pub rx_channel: ChannelRx<'d, Dm, PeripheralRxChannel<T>>,
pub i2s: PeripheralRef<'d, AnyI2s>,
pub rx_channel: ChannelRx<'d, Dm, PeripheralRxChannel<AnyI2s>>,
pub descriptors: &'static mut [DmaDescriptor],
pub(crate) guard: PeripheralGuard,
}
impl<'d, Dm, T> RxCreator<'d, Dm, T>
impl<'d, Dm> RxCreator<'d, Dm>
where
Dm: DriverMode,
T: RegisterAccess,
{
pub fn build(self) -> I2sRx<'d, Dm, T> {
pub fn build(self) -> I2sRx<'d, Dm> {
let peripheral = self.i2s.peripheral();
I2sRx {
i2s: self.i2s,
@ -1876,10 +1799,11 @@ mod private {
/// Async functionality
pub mod asynch {
use super::{Error, I2sRx, I2sTx, RegisterAccess};
use super::{Error, I2sRx, I2sTx, RegisterAccessPrivate};
use crate::{
dma::{
asynch::{DmaRxDoneChFuture, DmaRxFuture, DmaTxDoneChFuture, DmaTxFuture},
DmaEligible,
ReadBuffer,
Rx,
RxCircularState,
@ -1890,10 +1814,7 @@ pub mod asynch {
Async,
};
impl<'d, T> I2sTx<'d, Async, T>
where
T: RegisterAccess,
{
impl<'d> I2sTx<'d, Async> {
/// One-shot write I2S.
pub async fn write_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error> {
let (ptr, len) = (words.as_ptr(), words.len());
@ -1920,7 +1841,7 @@ pub mod asynch {
pub fn write_dma_circular_async<TXBUF: ReadBuffer>(
mut self,
words: TXBUF,
) -> Result<I2sWriteDmaTransferAsync<'d, TXBUF, T>, Error> {
) -> Result<I2sWriteDmaTransferAsync<'d, TXBUF>, Error> {
let (ptr, len) = unsafe { words.read_buffer() };
// Reset TX unit and TX FIFO
@ -1951,19 +1872,13 @@ pub mod asynch {
}
/// An in-progress async circular DMA write transfer.
pub struct I2sWriteDmaTransferAsync<'d, BUFFER, T = super::AnyI2s>
where
T: RegisterAccess,
{
i2s_tx: I2sTx<'d, Async, T>,
pub struct I2sWriteDmaTransferAsync<'d, BUFFER> {
i2s_tx: I2sTx<'d, Async>,
state: TxCircularState,
_buffer: BUFFER,
}
impl<T, BUFFER> I2sWriteDmaTransferAsync<'_, BUFFER, T>
where
T: RegisterAccess,
{
impl<BUFFER> I2sWriteDmaTransferAsync<'_, BUFFER> {
/// How many bytes can be pushed into the DMA transaction.
/// Will wait for more than 0 bytes available.
pub async fn available(&mut self) -> Result<usize, Error> {
@ -2000,10 +1915,7 @@ pub mod asynch {
}
}
impl<'d, T> I2sRx<'d, Async, T>
where
T: RegisterAccess,
{
impl<'d> I2sRx<'d, Async> {
/// One-shot read I2S.
pub async fn read_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error> {
let (ptr, len) = (words.as_mut_ptr(), words.len());
@ -2038,7 +1950,7 @@ pub mod asynch {
pub fn read_dma_circular_async<RXBUF>(
mut self,
mut words: RXBUF,
) -> Result<I2sReadDmaTransferAsync<'d, RXBUF, T>, Error>
) -> Result<I2sReadDmaTransferAsync<'d, RXBUF>, Error>
where
RXBUF: WriteBuffer,
{
@ -2074,19 +1986,13 @@ pub mod asynch {
}
/// An in-progress async circular DMA read transfer.
pub struct I2sReadDmaTransferAsync<'d, BUFFER, T = super::AnyI2s>
where
T: RegisterAccess,
{
i2s_rx: I2sRx<'d, Async, T>,
pub struct I2sReadDmaTransferAsync<'d, BUFFER> {
i2s_rx: I2sRx<'d, Async>,
state: RxCircularState,
_buffer: BUFFER,
}
impl<T, BUFFER> I2sReadDmaTransferAsync<'_, BUFFER, T>
where
T: RegisterAccess,
{
impl<BUFFER> I2sReadDmaTransferAsync<'_, BUFFER> {
/// How many bytes can be popped from the DMA transaction.
/// Will wait for more than 0 bytes available.
pub async fn available(&mut self) -> Result<usize, Error> {

View File

@ -235,13 +235,12 @@ impl<'d> TxPins<'d> for TxEightBits<'d> {
}
/// I2S Parallel Interface
pub struct I2sParallel<'d, Dm, I = AnyI2s>
pub struct I2sParallel<'d, Dm>
where
Dm: DriverMode,
I: Instance,
{
instance: PeripheralRef<'d, I>,
tx_channel: ChannelTx<'d, Dm, PeripheralTxChannel<I>>,
instance: PeripheralRef<'d, AnyI2s>,
tx_channel: ChannelTx<'d, Dm, PeripheralTxChannel<AnyI2s>>,
_guard: PeripheralGuard,
}
@ -251,32 +250,13 @@ impl<'d> I2sParallel<'d, Blocking> {
i2s: impl Peripheral<P = impl Instance> + 'd,
channel: impl Peripheral<P = CH> + 'd,
frequency: impl Into<fugit::HertzU32>,
pins: impl TxPins<'d>,
mut pins: impl TxPins<'d>,
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
) -> Self
where
CH: DmaChannelFor<AnyI2s>,
{
Self::new_typed(i2s.map_into(), channel, frequency, pins, clock_pin)
}
}
impl<'d, I> I2sParallel<'d, Blocking, I>
where
I: Instance,
{
/// Create a new I2S Parallel Interface
pub fn new_typed<CH>(
i2s: impl Peripheral<P = I> + 'd,
channel: impl Peripheral<P = CH> + 'd,
frequency: impl Into<fugit::HertzU32>,
mut pins: impl TxPins<'d>,
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
) -> Self
where
CH: DmaChannelFor<I>,
{
crate::into_ref!(i2s);
crate::into_mapped_ref!(i2s);
crate::into_mapped_ref!(clock_pin);
let channel = Channel::new(channel.map(|ch| ch.degrade()));
@ -299,7 +279,7 @@ where
}
/// Converts the I2S instance into async mode.
pub fn into_async(self) -> I2sParallel<'d, Async, I> {
pub fn into_async(self) -> I2sParallel<'d, Async> {
I2sParallel {
instance: self.instance,
tx_channel: self.tx_channel.into_async(),
@ -308,12 +288,9 @@ where
}
}
impl<'d, I> I2sParallel<'d, Async, I>
where
I: Instance,
{
impl<'d> I2sParallel<'d, Async> {
/// Converts the I2S instance into async mode.
pub fn into_blocking(self) -> I2sParallel<'d, Blocking, I> {
pub fn into_blocking(self) -> I2sParallel<'d, Blocking> {
I2sParallel {
instance: self.instance,
tx_channel: self.tx_channel.into_blocking(),
@ -322,16 +299,15 @@ where
}
}
impl<'d, I, Dm> I2sParallel<'d, Dm, I>
impl<'d, Dm> I2sParallel<'d, Dm>
where
I: Instance,
Dm: DriverMode,
{
/// Write data to the I2S peripheral
pub fn send<BUF: DmaTxBuffer>(
mut self,
mut data: BUF,
) -> Result<I2sParallelTransfer<'d, BUF, Dm, I>, (DmaError, Self, BUF)> {
) -> Result<I2sParallelTransfer<'d, BUF, Dm>, (DmaError, Self, BUF)> {
self.instance.tx_reset();
self.instance.tx_fifo_reset();
let result = unsafe {
@ -353,19 +329,17 @@ where
/// Represents an ongoing (or potentially finished) transfer using the i2s
/// parallel interface
pub struct I2sParallelTransfer<'d, BUF, Dm, I = AnyI2s>
pub struct I2sParallelTransfer<'d, BUF, Dm>
where
I: Instance,
BUF: DmaTxBuffer,
Dm: DriverMode,
{
i2s: ManuallyDrop<I2sParallel<'d, Dm, I>>,
i2s: ManuallyDrop<I2sParallel<'d, Dm>>,
buf_view: ManuallyDrop<BUF::View>,
}
impl<'d, I, BUF, Dm> I2sParallelTransfer<'d, BUF, Dm, I>
impl<'d, BUF, Dm> I2sParallelTransfer<'d, BUF, Dm>
where
I: Instance,
BUF: DmaTxBuffer,
Dm: DriverMode,
{
@ -375,7 +349,7 @@ where
}
/// Wait for the transfer to finish
pub fn wait(mut self) -> (I2sParallel<'d, Dm, I>, BUF) {
pub fn wait(mut self) -> (I2sParallel<'d, Dm>, BUF) {
self.i2s.instance.tx_wait_done();
let i2s = unsafe { ManuallyDrop::take(&mut self.i2s) };
let view = unsafe { ManuallyDrop::take(&mut self.buf_view) };
@ -389,9 +363,8 @@ where
}
}
impl<'d, I, BUF> I2sParallelTransfer<'d, BUF, Async, I>
impl<'d, BUF> I2sParallelTransfer<'d, BUF, Async>
where
I: Instance,
BUF: DmaTxBuffer,
{
/// Wait for the transfer to finish
@ -400,9 +373,8 @@ where
}
}
impl<I, BUF, Dm> Deref for I2sParallelTransfer<'_, BUF, Dm, I>
impl<BUF, Dm> Deref for I2sParallelTransfer<'_, BUF, Dm>
where
I: Instance,
BUF: DmaTxBuffer,
Dm: DriverMode,
{
@ -413,9 +385,8 @@ where
}
}
impl<I, BUF, Dm> DerefMut for I2sParallelTransfer<'_, BUF, Dm, I>
impl<BUF, Dm> DerefMut for I2sParallelTransfer<'_, BUF, Dm>
where
I: Instance,
BUF: DmaTxBuffer,
Dm: DriverMode,
{
@ -424,9 +395,8 @@ where
}
}
impl<I, BUF, Dm> Drop for I2sParallelTransfer<'_, BUF, Dm, I>
impl<BUF, Dm> Drop for I2sParallelTransfer<'_, BUF, Dm>
where
I: Instance,
BUF: DmaTxBuffer,
Dm: DriverMode,
{

View File

@ -485,17 +485,16 @@ pub enum ConfigError {}
/// SPI peripheral driver
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Spi<'d, Dm, T = AnySpi> {
spi: PeripheralRef<'d, T>,
pub struct Spi<'d, Dm> {
spi: PeripheralRef<'d, AnySpi>,
_mode: PhantomData<Dm>,
guard: PeripheralGuard,
}
impl<Dm: DriverMode, T: Instance> Sealed for Spi<'_, Dm, T> {}
impl<Dm: DriverMode> Sealed for Spi<'_, Dm> {}
impl<Dm, T> Spi<'_, Dm, T>
impl<Dm> Spi<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn driver(&self) -> Driver {
@ -539,16 +538,38 @@ impl<'d> Spi<'d, Blocking> {
spi: impl Peripheral<P = impl PeripheralInstance> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_typed(spi.map_into(), config)
}
}
crate::into_mapped_ref!(spi);
let guard = PeripheralGuard::new(spi.info().peripheral);
let mut this = Spi {
spi,
_mode: PhantomData,
guard,
};
this.driver().init();
this.apply_config(&config)?;
let this = this
.with_mosi(NoPin)
.with_miso(NoPin)
.with_sck(NoPin)
.with_cs(NoPin);
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);
}
Ok(this)
}
impl<'d, T> Spi<'d, Blocking, T>
where
T: Instance,
{
/// Converts the SPI instance into async mode.
pub fn into_async(mut self) -> Spi<'d, Async, T> {
pub fn into_async(mut self) -> Spi<'d, Async> {
self.set_interrupt_handler(self.spi.handler());
Spi {
spi: self.spi,
@ -563,18 +584,15 @@ where
/// and returns an instance of `SpiDma` that supports DMA
/// operations.
#[instability::unstable]
pub fn with_dma<CH>(self, channel: impl Peripheral<P = CH> + 'd) -> SpiDma<'d, Blocking, T>
pub fn with_dma<CH>(self, channel: impl Peripheral<P = CH> + 'd) -> SpiDma<'d, Blocking>
where
CH: DmaChannelFor<T>,
CH: DmaChannelFor<AnySpi>,
{
SpiDma::new(self.spi, channel.map(|ch| ch.degrade()).into_ref())
}
}
impl<T> InterruptConfigurable for Spi<'_, Blocking, T>
where
T: Instance,
{
impl InterruptConfigurable for Spi<'_, Blocking> {
/// Sets the interrupt handler
///
/// Interrupts are not enabled at the peripheral level here.
@ -588,12 +606,9 @@ where
}
}
impl<'d, T> Spi<'d, Async, T>
where
T: Instance,
{
impl<'d> Spi<'d, Async> {
/// Converts the SPI instance into blocking mode.
pub fn into_blocking(self) -> Spi<'d, Blocking, T> {
pub fn into_blocking(self) -> Spi<'d, Blocking> {
crate::interrupt::disable(Cpu::current(), self.driver().info.interrupt);
Spi {
spi: self.spi,
@ -624,46 +639,10 @@ where
}
}
impl<'d, Dm, T> Spi<'d, Dm, T>
impl<'d, Dm> Spi<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
/// Constructs an SPI instance in 8bit dataframe mode.
pub fn new_typed(
spi: impl Peripheral<P = T> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
crate::into_ref!(spi);
let guard = PeripheralGuard::new(spi.info().peripheral);
let mut this = Spi {
spi,
_mode: PhantomData,
guard,
};
this.driver().init();
this.apply_config(&config)?;
let this = this
.with_mosi(NoPin)
.with_miso(NoPin)
.with_sck(NoPin)
.with_cs(NoPin);
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);
}
Ok(this)
}
/// Assign the MOSI (Master Out Slave In) pin for the SPI instance.
///
/// Enables both input and output functionality for the pin, and connects it
@ -742,9 +721,8 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<Dm, T> SetConfig for Spi<'_, Dm, T>
impl<Dm> SetConfig for Spi<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
type Config = Config;
@ -755,9 +733,8 @@ where
}
}
impl<'d, Dm, T> Spi<'d, Dm, T>
impl<'d, Dm> Spi<'d, Dm>
where
T: Instance + QspiInstance,
Dm: DriverMode,
{
/// Assign the SIO2 pin for the SPI instance.
@ -765,10 +742,8 @@ where
/// Enables both input and output functionality for the pin, and connects it
/// to the SIO2 output and input signals.
#[instability::unstable]
pub fn with_sio2<SIO2: PeripheralOutput>(self, sio2: impl Peripheral<P = SIO2> + 'd) -> Self
where
T: QspiInstance,
{
pub fn with_sio2<SIO2: PeripheralOutput>(self, sio2: impl Peripheral<P = SIO2> + 'd) -> Self {
// TODO: panic if not QSPI?
crate::into_mapped_ref!(sio2);
sio2.enable_input(true, private::Internal);
sio2.enable_output(true, private::Internal);
@ -784,10 +759,8 @@ where
/// Enables both input and output functionality for the pin, and connects it
/// to the SIO3 output and input signals.
#[instability::unstable]
pub fn with_sio3<SIO3: PeripheralOutput>(self, sio3: impl Peripheral<P = SIO3> + 'd) -> Self
where
T: QspiInstance,
{
pub fn with_sio3<SIO3: PeripheralOutput>(self, sio3: impl Peripheral<P = SIO3> + 'd) -> Self {
// TODO: panic if not QSPI?
crate::into_mapped_ref!(sio3);
sio3.enable_input(true, private::Internal);
sio3.enable_output(true, private::Internal);
@ -799,9 +772,8 @@ where
}
}
impl<Dm, T> Spi<'_, Dm, T>
impl<Dm> Spi<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
/// Half-duplex read.
@ -927,13 +899,12 @@ mod dma {
/// embedded-hal traits.
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[instability::unstable]
pub struct SpiDma<'d, Dm, T = AnySpi>
pub struct SpiDma<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
pub(crate) spi: PeripheralRef<'d, T>,
pub(crate) channel: Channel<'d, Dm, PeripheralDmaChannel<T>>,
pub(crate) spi: PeripheralRef<'d, AnySpi>,
pub(crate) channel: Channel<'d, Dm, PeripheralDmaChannel<AnySpi>>,
tx_transfer_in_progress: bool,
rx_transfer_in_progress: bool,
#[cfg(all(esp32, spi_address_workaround))]
@ -941,20 +912,12 @@ mod dma {
guard: PeripheralGuard,
}
impl<Dm, T> crate::private::Sealed for SpiDma<'_, Dm, T>
where
T: Instance,
Dm: DriverMode,
{
}
impl<Dm> crate::private::Sealed for SpiDma<'_, Dm> where Dm: DriverMode {}
impl<'d, T> SpiDma<'d, Blocking, T>
where
T: Instance,
{
impl<'d> SpiDma<'d, Blocking> {
/// Converts the SPI instance into async mode.
#[instability::unstable]
pub fn into_async(self) -> SpiDma<'d, Async, T> {
pub fn into_async(self) -> SpiDma<'d, Async> {
SpiDma {
spi: self.spi,
channel: self.channel.into_async(),
@ -967,13 +930,10 @@ mod dma {
}
}
impl<'d, T> SpiDma<'d, Async, T>
where
T: Instance,
{
impl<'d> SpiDma<'d, Async> {
/// Converts the SPI instance into async mode.
#[instability::unstable]
pub fn into_blocking(self) -> SpiDma<'d, Blocking, T> {
pub fn into_blocking(self) -> SpiDma<'d, Blocking> {
SpiDma {
spi: self.spi,
channel: self.channel.into_blocking(),
@ -986,9 +946,8 @@ mod dma {
}
}
impl<Dm, T> core::fmt::Debug for SpiDma<'_, Dm, T>
impl<Dm> core::fmt::Debug for SpiDma<'_, Dm>
where
T: Instance + core::fmt::Debug,
Dm: DriverMode,
{
/// Formats the `SpiDma` instance for debugging purposes.
@ -1000,10 +959,7 @@ mod dma {
}
}
impl<T> InterruptConfigurable for SpiDma<'_, Blocking, T>
where
T: Instance,
{
impl InterruptConfigurable for SpiDma<'_, Blocking> {
/// Sets the interrupt handler
///
/// Interrupts are not enabled at the peripheral level here.
@ -1019,10 +975,7 @@ mod dma {
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T> SpiDma<'_, Blocking, T>
where
T: Instance,
{
impl SpiDma<'_, Blocking> {
/// Listen for the given interrupts
pub fn listen(&mut self, interrupts: impl Into<EnumSet<SpiInterrupt>>) {
self.driver().enable_listen(interrupts.into(), true);
@ -1044,13 +997,10 @@ mod dma {
}
}
impl<'d, T> SpiDma<'d, Blocking, T>
where
T: Instance,
{
impl<'d> SpiDma<'d, Blocking> {
pub(super) fn new(
spi: PeripheralRef<'d, T>,
channel: PeripheralRef<'d, PeripheralDmaChannel<T>>,
spi: PeripheralRef<'d, AnySpi>,
channel: PeripheralRef<'d, PeripheralDmaChannel<AnySpi>>,
) -> Self {
let channel = Channel::new(channel);
channel.runtime_ensure_compatible(&spi);
@ -1088,9 +1038,8 @@ mod dma {
}
}
impl<'d, Dm, T> SpiDma<'d, Dm, T>
impl<'d, Dm> SpiDma<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn driver(&self) -> Driver {
@ -1273,20 +1222,15 @@ mod dma {
/// It returns an instance of `SpiDmaBus` that can be used for SPI
/// communication.
#[instability::unstable]
pub fn with_buffers(
self,
dma_rx_buf: DmaRxBuf,
dma_tx_buf: DmaTxBuf,
) -> SpiDmaBus<'d, Dm, T> {
pub fn with_buffers(self, dma_rx_buf: DmaRxBuf, dma_tx_buf: DmaTxBuf) -> SpiDmaBus<'d, Dm> {
SpiDmaBus::new(self, dma_rx_buf, dma_tx_buf)
}
}
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<Dm, T> SetConfig for SpiDma<'_, Dm, T>
impl<Dm> SetConfig for SpiDma<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
type Config = Config;
@ -1302,21 +1246,19 @@ mod dma {
/// This structure holds references to the SPI instance, DMA buffers, and
/// transfer status.
#[instability::unstable]
pub struct SpiDmaTransfer<'d, Dm, Buf, T = AnySpi>
pub struct SpiDmaTransfer<'d, Dm, Buf>
where
T: Instance,
Dm: DriverMode,
{
spi_dma: ManuallyDrop<SpiDma<'d, Dm, T>>,
spi_dma: ManuallyDrop<SpiDma<'d, Dm>>,
dma_buf: ManuallyDrop<Buf>,
}
impl<'d, Dm, T, Buf> SpiDmaTransfer<'d, Dm, Buf, T>
impl<'d, Dm, Buf> SpiDmaTransfer<'d, Dm, Buf>
where
T: Instance,
Dm: DriverMode,
{
fn new(spi_dma: SpiDma<'d, Dm, T>, dma_buf: Buf) -> Self {
fn new(spi_dma: SpiDma<'d, Dm>, dma_buf: Buf) -> Self {
Self {
spi_dma: ManuallyDrop::new(spi_dma),
dma_buf: ManuallyDrop::new(dma_buf),
@ -1336,7 +1278,7 @@ mod dma {
/// This method blocks until the transfer is finished and returns the
/// `SpiDma` instance and the associated buffer.
#[instability::unstable]
pub fn wait(mut self) -> (SpiDma<'d, Dm, T>, Buf) {
pub fn wait(mut self) -> (SpiDma<'d, Dm>, Buf) {
self.spi_dma.wait_for_idle();
let retval = unsafe {
(
@ -1357,9 +1299,8 @@ mod dma {
}
}
impl<Dm, T, Buf> Drop for SpiDmaTransfer<'_, Dm, Buf, T>
impl<Dm, Buf> Drop for SpiDmaTransfer<'_, Dm, Buf>
where
T: Instance,
Dm: DriverMode,
{
fn drop(&mut self) {
@ -1375,10 +1316,7 @@ mod dma {
}
}
impl<T, Buf> SpiDmaTransfer<'_, Async, Buf, T>
where
T: Instance,
{
impl<Buf> SpiDmaTransfer<'_, Async, Buf> {
/// Waits for the DMA transfer to complete asynchronously.
///
/// This method awaits the completion of both RX and TX operations.
@ -1388,9 +1326,8 @@ mod dma {
}
}
impl<'d, Dm, T> SpiDma<'d, Dm, T>
impl<'d, Dm> SpiDma<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
/// # Safety:
@ -1418,7 +1355,7 @@ mod dma {
mut self,
bytes_to_write: usize,
mut buffer: TX,
) -> Result<SpiDmaTransfer<'d, Dm, TX, T>, (Error, Self, TX)> {
) -> Result<SpiDmaTransfer<'d, Dm, TX>, (Error, Self, TX)> {
self.wait_for_idle();
match unsafe { self.start_dma_write(bytes_to_write, &mut buffer) } {
@ -1452,7 +1389,7 @@ mod dma {
mut self,
bytes_to_read: usize,
mut buffer: RX,
) -> Result<SpiDmaTransfer<'d, Dm, RX, T>, (Error, Self, RX)> {
) -> Result<SpiDmaTransfer<'d, Dm, RX>, (Error, Self, RX)> {
self.wait_for_idle();
match unsafe { self.start_dma_read(bytes_to_read, &mut buffer) } {
Ok(_) => Ok(SpiDmaTransfer::new(self, buffer)),
@ -1489,7 +1426,7 @@ mod dma {
mut rx_buffer: RX,
bytes_to_write: usize,
mut tx_buffer: TX,
) -> Result<SpiDmaTransfer<'d, Dm, (RX, TX), T>, (Error, Self, RX, TX)> {
) -> Result<SpiDmaTransfer<'d, Dm, (RX, TX)>, (Error, Self, RX, TX)> {
self.wait_for_idle();
match unsafe {
self.start_dma_transfer(
@ -1543,7 +1480,7 @@ mod dma {
dummy: u8,
bytes_to_read: usize,
mut buffer: RX,
) -> Result<SpiDmaTransfer<'d, Dm, RX, T>, (Error, Self, RX)> {
) -> Result<SpiDmaTransfer<'d, Dm, RX>, (Error, Self, RX)> {
self.wait_for_idle();
match unsafe {
@ -1609,7 +1546,7 @@ mod dma {
dummy: u8,
bytes_to_write: usize,
mut buffer: TX,
) -> Result<SpiDmaTransfer<'d, Dm, TX, T>, (Error, Self, TX)> {
) -> Result<SpiDmaTransfer<'d, Dm, TX>, (Error, Self, TX)> {
self.wait_for_idle();
match unsafe {
@ -1635,30 +1572,21 @@ mod dma {
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[instability::unstable]
pub struct SpiDmaBus<'d, Dm, T = AnySpi>
pub struct SpiDmaBus<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
spi_dma: SpiDma<'d, Dm, T>,
spi_dma: SpiDma<'d, Dm>,
rx_buf: DmaRxBuf,
tx_buf: DmaTxBuf,
}
impl<Dm, T> crate::private::Sealed for SpiDmaBus<'_, Dm, T>
where
T: Instance,
Dm: DriverMode,
{
}
impl<Dm> crate::private::Sealed for SpiDmaBus<'_, Dm> where Dm: DriverMode {}
impl<'d, T> SpiDmaBus<'d, Blocking, T>
where
T: Instance,
{
impl<'d> SpiDmaBus<'d, Blocking> {
/// Converts the SPI instance into async mode.
#[instability::unstable]
pub fn into_async(self) -> SpiDmaBus<'d, Async, T> {
pub fn into_async(self) -> SpiDmaBus<'d, Async> {
SpiDmaBus {
spi_dma: self.spi_dma.into_async(),
rx_buf: self.rx_buf,
@ -1667,13 +1595,10 @@ mod dma {
}
}
impl<'d, T> SpiDmaBus<'d, Async, T>
where
T: Instance,
{
impl<'d> SpiDmaBus<'d, Async> {
/// Converts the SPI instance into async mode.
#[instability::unstable]
pub fn into_blocking(self) -> SpiDmaBus<'d, Blocking, T> {
pub fn into_blocking(self) -> SpiDmaBus<'d, Blocking> {
SpiDmaBus {
spi_dma: self.spi_dma.into_blocking(),
rx_buf: self.rx_buf,
@ -1682,14 +1607,13 @@ mod dma {
}
}
impl<'d, Dm, T> SpiDmaBus<'d, Dm, T>
impl<'d, Dm> SpiDmaBus<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
/// Creates a new `SpiDmaBus` with the specified SPI instance and DMA
/// buffers.
pub fn new(spi_dma: SpiDma<'d, Dm, T>, rx_buf: DmaRxBuf, tx_buf: DmaTxBuf) -> Self {
pub fn new(spi_dma: SpiDma<'d, Dm>, rx_buf: DmaRxBuf, tx_buf: DmaTxBuf) -> Self {
Self {
spi_dma,
rx_buf,
@ -1699,16 +1623,13 @@ mod dma {
/// Splits [SpiDmaBus] back into [SpiDma], [DmaRxBuf] and [DmaTxBuf].
#[instability::unstable]
pub fn split(mut self) -> (SpiDma<'d, Dm, T>, DmaRxBuf, DmaTxBuf) {
pub fn split(mut self) -> (SpiDma<'d, Dm>, DmaRxBuf, DmaTxBuf) {
self.wait_for_idle();
(self.spi_dma, self.rx_buf, self.tx_buf)
}
}
impl<T> InterruptConfigurable for SpiDmaBus<'_, Blocking, T>
where
T: Instance,
{
impl InterruptConfigurable for SpiDmaBus<'_, Blocking> {
/// Sets the interrupt handler
///
/// Interrupts are not enabled at the peripheral level here.
@ -1719,10 +1640,7 @@ mod dma {
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T> SpiDmaBus<'_, Blocking, T>
where
T: Instance,
{
impl SpiDmaBus<'_, Blocking> {
/// Listen for the given interrupts
pub fn listen(&mut self, interrupts: impl Into<EnumSet<SpiInterrupt>>) {
self.spi_dma.listen(interrupts.into());
@ -1744,9 +1662,8 @@ mod dma {
}
}
impl<Dm, T> SpiDmaBus<'_, Dm, T>
impl<Dm> SpiDmaBus<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn wait_for_idle(&mut self) {
@ -1943,9 +1860,8 @@ mod dma {
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<Dm, T> SetConfig for SpiDmaBus<'_, Dm, T>
impl<Dm> SetConfig for SpiDmaBus<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
type Config = Config;
@ -2006,10 +1922,7 @@ mod dma {
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T> SpiDmaBus<'_, Async, T>
where
T: Instance,
{
impl SpiDmaBus<'_, Async> {
/// Fill the given buffer with data from the bus.
#[instability::unstable]
pub async fn read_async(&mut self, words: &mut [u8]) -> Result<(), Error> {
@ -2140,10 +2053,7 @@ mod dma {
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T> embedded_hal_async::spi::SpiBus for SpiDmaBus<'_, Async, T>
where
T: Instance,
{
impl embedded_hal_async::spi::SpiBus for SpiDmaBus<'_, Async> {
async fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.read_async(words).await
}
@ -2176,9 +2086,8 @@ mod dma {
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<Dm, T> ErrorType for SpiDmaBus<'_, Dm, T>
impl<Dm> ErrorType for SpiDmaBus<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
type Error = Error;
@ -2186,9 +2095,8 @@ mod dma {
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<Dm, T> SpiBus for SpiDmaBus<'_, Dm, T>
impl<Dm> SpiBus for SpiDmaBus<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
@ -2222,13 +2130,12 @@ mod ehal1 {
use super::*;
impl<Dm, T> embedded_hal::spi::ErrorType for Spi<'_, Dm, T> {
impl<Dm> embedded_hal::spi::ErrorType for Spi<'_, Dm> {
type Error = Error;
}
impl<Dm, T> FullDuplex for Spi<'_, Dm, T>
impl<Dm> FullDuplex for Spi<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn read(&mut self) -> nb::Result<u8, Self::Error> {
@ -2240,9 +2147,8 @@ mod ehal1 {
}
}
impl<Dm, T> SpiBus for Spi<'_, Dm, T>
impl<Dm> SpiBus for Spi<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
@ -2308,10 +2214,7 @@ mod ehal1 {
}
}
impl<T> SpiBusAsync for Spi<'_, Async, T>
where
T: Instance,
{
impl SpiBusAsync for Spi<'_, Async> {
async fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
// We need to flush because the blocking transfer functions may return while a
// transfer is still in progress.

View File

@ -94,8 +94,8 @@ const MAX_DMA_SIZE: usize = 32768 - 32;
///
/// See the [module-level documentation][self] for more details.
#[instability::unstable]
pub struct Spi<'d, Dm, T = AnySpi> {
spi: PeripheralRef<'d, T>,
pub struct Spi<'d, Dm> {
spi: PeripheralRef<'d, AnySpi>,
#[allow(dead_code)]
data_mode: Mode,
_mode: PhantomData<Dm>,
@ -105,18 +105,7 @@ impl<'d> Spi<'d, Blocking> {
/// Constructs an SPI instance in 8bit dataframe mode.
#[instability::unstable]
pub fn new(spi: impl Peripheral<P = impl Instance> + 'd, mode: Mode) -> Spi<'d, Blocking> {
Self::new_typed(spi.map_into(), mode)
}
}
impl<'d, Dm, T> Spi<'d, Dm, T>
where
T: Instance,
{
/// Constructs an SPI instance in 8bit dataframe mode.
#[instability::unstable]
pub fn new_typed(spi: impl Peripheral<P = T> + 'd, mode: Mode) -> Spi<'d, Dm, T> {
crate::into_ref!(spi);
crate::into_mapped_ref!(spi);
let guard = PeripheralGuard::new(spi.info().peripheral);
@ -200,10 +189,7 @@ pub mod dma {
DriverMode,
};
impl<'d, T> Spi<'d, Blocking, T>
where
T: InstanceDma,
{
impl<'d> Spi<'d, Blocking> {
/// Configures the SPI peripheral with the provided DMA channel and
/// descriptors.
#[cfg_attr(esp32, doc = "\n\n**Note**: ESP32 only supports Mode 1 and 3.")]
@ -213,9 +199,9 @@ pub mod dma {
channel: impl Peripheral<P = CH> + 'd,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, Blocking, T>
) -> SpiDma<'d, Blocking>
where
CH: DmaChannelFor<T>,
CH: DmaChannelFor<AnySpi>,
{
self.spi.info().set_data_mode(self.data_mode, true);
SpiDma::new(
@ -229,21 +215,19 @@ pub mod dma {
/// A DMA capable SPI instance.
#[instability::unstable]
pub struct SpiDma<'d, Dm, T = AnySpi>
pub struct SpiDma<'d, Dm>
where
T: InstanceDma,
Dm: DriverMode,
{
pub(crate) spi: PeripheralRef<'d, T>,
pub(crate) channel: Channel<'d, Dm, PeripheralDmaChannel<T>>,
pub(crate) spi: PeripheralRef<'d, AnySpi>,
pub(crate) channel: Channel<'d, Dm, PeripheralDmaChannel<AnySpi>>,
rx_chain: DescriptorChain,
tx_chain: DescriptorChain,
_guard: PeripheralGuard,
}
impl<Dm, T> core::fmt::Debug for SpiDma<'_, Dm, T>
impl<Dm> core::fmt::Debug for SpiDma<'_, Dm>
where
T: InstanceDma,
Dm: DriverMode,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
@ -251,9 +235,8 @@ pub mod dma {
}
}
impl<Dm, T> DmaSupport for SpiDma<'_, Dm, T>
impl<Dm> DmaSupport for SpiDma<'_, Dm>
where
T: InstanceDma,
Dm: DriverMode,
{
fn peripheral_wait_dma(&mut self, is_rx: bool, is_tx: bool) {
@ -270,12 +253,11 @@ pub mod dma {
}
}
impl<'d, Dm, T> DmaSupportTx for SpiDma<'d, Dm, T>
impl<'d, Dm> DmaSupportTx for SpiDma<'d, Dm>
where
T: InstanceDma,
Dm: DriverMode,
{
type TX = ChannelTx<'d, Dm, PeripheralTxChannel<T>>;
type TX = ChannelTx<'d, Dm, PeripheralTxChannel<AnySpi>>;
fn tx(&mut self) -> &mut Self::TX {
&mut self.channel.tx
@ -286,12 +268,11 @@ pub mod dma {
}
}
impl<'d, Dm, T> DmaSupportRx for SpiDma<'d, Dm, T>
impl<'d, Dm> DmaSupportRx for SpiDma<'d, Dm>
where
T: InstanceDma,
Dm: DriverMode,
{
type RX = ChannelRx<'d, Dm, PeripheralRxChannel<T>>;
type RX = ChannelRx<'d, Dm, PeripheralRxChannel<AnySpi>>;
fn rx(&mut self) -> &mut Self::RX {
&mut self.channel.rx
@ -302,13 +283,10 @@ pub mod dma {
}
}
impl<'d, T> SpiDma<'d, Blocking, T>
where
T: InstanceDma,
{
impl<'d> SpiDma<'d, Blocking> {
fn new(
spi: PeripheralRef<'d, T>,
channel: PeripheralRef<'d, PeripheralDmaChannel<T>>,
spi: PeripheralRef<'d, AnySpi>,
channel: PeripheralRef<'d, PeripheralDmaChannel<AnySpi>>,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> Self {
@ -326,10 +304,9 @@ pub mod dma {
}
}
impl<Dm, T> SpiDma<'_, Dm, T>
impl<Dm> SpiDma<'_, Dm>
where
Dm: DriverMode,
T: InstanceDma,
{
fn driver(&self) -> DmaDriver {
DmaDriver {

View File

@ -119,33 +119,25 @@ pub trait Timer: Into<AnyTimer> + InterruptConfigurable + 'static + crate::priva
}
/// A one-shot timer.
pub struct OneShotTimer<'d, Dm, T = AnyTimer> {
inner: PeripheralRef<'d, T>,
pub struct OneShotTimer<'d, Dm> {
inner: PeripheralRef<'d, AnyTimer>,
_ph: PhantomData<Dm>,
}
impl<'d> OneShotTimer<'d, Blocking> {
/// Construct a new instance of [`OneShotTimer`].
pub fn new(inner: impl Peripheral<P = impl Timer> + 'd) -> OneShotTimer<'d, Blocking> {
Self::new_typed(inner.map_into())
}
}
impl<'d, T> OneShotTimer<'d, Blocking, T>
where
T: Timer,
{
/// Construct a typed instance of [`OneShotTimer`].
pub fn new_typed(inner: impl Peripheral<P = T> + 'd) -> Self {
crate::into_ref!(inner);
crate::into_mapped_ref!(inner);
Self {
inner,
_ph: PhantomData,
}
}
}
impl<'d> OneShotTimer<'d, Blocking> {
/// Converts the driver to [`Async`] mode.
pub fn into_async(mut self) -> OneShotTimer<'d, Async, T> {
pub fn into_async(mut self) -> OneShotTimer<'d, Async> {
let handler = self.inner.async_interrupt_handler();
self.inner.set_interrupt_handler(handler);
OneShotTimer {
@ -155,10 +147,7 @@ where
}
}
impl<T> OneShotTimer<'_, Async, T>
where
T: Timer,
{
impl OneShotTimer<'_, Async> {
/// Converts the driver to [`Blocking`] mode.
pub fn into_blocking(self) -> Self {
crate::interrupt::disable(Cpu::current(), self.inner.peripheral_interrupt());
@ -167,12 +156,7 @@ where
_ph: PhantomData,
}
}
}
impl<T> OneShotTimer<'_, Async, T>
where
T: Timer,
{
/// Delay for *at least* `ns` nanoseconds.
pub async fn delay_nanos_async(&mut self, ns: u32) {
self.delay_async(MicrosDurationU64::from_ticks(ns.div_ceil(1000) as u64))
@ -197,10 +181,9 @@ where
}
}
impl<Dm, T> OneShotTimer<'_, Dm, T>
impl<Dm> OneShotTimer<'_, Dm>
where
Dm: DriverMode,
T: Timer,
{
/// Delay for *at least* `ms` milliseconds.
pub fn delay_millis(&mut self, ms: u32) {
@ -267,61 +250,39 @@ where
}
}
impl<Dm, T> crate::private::Sealed for OneShotTimer<'_, Dm, T>
where
T: Timer,
Dm: DriverMode,
{
}
impl<Dm> crate::private::Sealed for OneShotTimer<'_, Dm> where Dm: DriverMode {}
impl<Dm, T> InterruptConfigurable for OneShotTimer<'_, Dm, T>
impl<Dm> InterruptConfigurable for OneShotTimer<'_, Dm>
where
Dm: DriverMode,
T: Timer,
{
fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
OneShotTimer::set_interrupt_handler(self, handler);
}
}
impl<T> embedded_hal::delay::DelayNs for OneShotTimer<'_, Blocking, T>
where
T: Timer,
{
impl embedded_hal::delay::DelayNs for OneShotTimer<'_, Blocking> {
fn delay_ns(&mut self, ns: u32) {
self.delay_nanos(ns);
}
}
impl<T> embedded_hal_async::delay::DelayNs for OneShotTimer<'_, Async, T>
where
T: Timer,
{
impl embedded_hal_async::delay::DelayNs for OneShotTimer<'_, Async> {
async fn delay_ns(&mut self, ns: u32) {
self.delay_nanos_async(ns).await
}
}
/// A periodic timer.
pub struct PeriodicTimer<'d, Dm, T = AnyTimer> {
inner: PeripheralRef<'d, T>,
pub struct PeriodicTimer<'d, Dm> {
inner: PeripheralRef<'d, AnyTimer>,
_ph: PhantomData<Dm>,
}
impl<'d> PeriodicTimer<'d, Blocking> {
/// Construct a new instance of [`PeriodicTimer`].
pub fn new(inner: impl Peripheral<P = impl Timer> + 'd) -> PeriodicTimer<'d, Blocking> {
Self::new_typed(inner.map_into())
}
}
impl<'d, T> PeriodicTimer<'d, Blocking, T>
where
T: Timer,
{
/// Construct a typed instance of [`PeriodicTimer`].
pub fn new_typed(inner: impl Peripheral<P = T> + 'd) -> Self {
crate::into_ref!(inner);
crate::into_mapped_ref!(inner);
Self {
inner,
_ph: PhantomData,
@ -329,10 +290,9 @@ where
}
}
impl<Dm, T> PeriodicTimer<'_, Dm, T>
impl<Dm> PeriodicTimer<'_, Dm>
where
Dm: DriverMode,
T: Timer,
{
/// Start a new count down.
pub fn start(&mut self, timeout: MicrosDurationU64) -> Result<(), Error> {
@ -390,12 +350,11 @@ where
}
}
impl<Dm, T> crate::private::Sealed for PeriodicTimer<'_, Dm, T> where T: Timer {}
impl<Dm> crate::private::Sealed for PeriodicTimer<'_, Dm> {}
impl<Dm, T> InterruptConfigurable for PeriodicTimer<'_, Dm, T>
impl<Dm> InterruptConfigurable for PeriodicTimer<'_, Dm>
where
Dm: DriverMode,
T: Timer,
{
fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
PeriodicTimer::set_interrupt_handler(self, handler);

View File

@ -134,6 +134,7 @@ use crate::{
twai::filter::SingleStandardFilter,
Async,
Blocking,
DriverMode,
};
pub mod filter;
@ -662,28 +663,26 @@ impl BaudRate {
}
/// An inactive TWAI peripheral in the "Reset"/configuration state.
pub struct TwaiConfiguration<'d, Dm: crate::DriverMode, T = AnyTwai> {
twai: PeripheralRef<'d, T>,
pub struct TwaiConfiguration<'d, Dm: DriverMode> {
twai: PeripheralRef<'d, AnyTwai>,
filter: Option<(FilterType, [u8; 8])>,
phantom: PhantomData<Dm>,
mode: TwaiMode,
_guard: PeripheralGuard,
}
impl<'d, Dm, T> TwaiConfiguration<'d, Dm, T>
impl<'d, Dm> TwaiConfiguration<'d, Dm>
where
T: Instance,
Dm: crate::DriverMode,
Dm: DriverMode,
{
fn new_internal<TX: PeripheralOutput, RX: PeripheralInput>(
twai: impl Peripheral<P = T> + 'd,
twai: PeripheralRef<'d, AnyTwai>,
rx_pin: impl Peripheral<P = RX> + 'd,
tx_pin: impl Peripheral<P = TX> + 'd,
baud_rate: BaudRate,
no_transceiver: bool,
mode: TwaiMode,
) -> Self {
crate::into_ref!(twai);
crate::into_mapped_ref!(tx_pin, rx_pin);
let guard = PeripheralGuard::new(twai.peripheral());
@ -906,7 +905,7 @@ where
/// Put the peripheral into Operation Mode, allowing the transmission and
/// reception of packets using the new object.
pub fn start(self) -> Twai<'d, Dm, T> {
pub fn start(self) -> Twai<'d, Dm> {
self.apply_filter();
self.set_mode(self.mode);
@ -975,7 +974,8 @@ impl<'d> TwaiConfiguration<'d, Blocking> {
baud_rate: BaudRate,
mode: TwaiMode,
) -> Self {
Self::new_typed(peripheral.map_into(), rx_pin, tx_pin, baud_rate, mode)
crate::into_mapped_ref!(peripheral);
Self::new_internal(peripheral, rx_pin, tx_pin, baud_rate, false, mode)
}
/// Create a new instance of [TwaiConfiguration] meant to connect two ESP32s
@ -990,44 +990,12 @@ impl<'d> TwaiConfiguration<'d, Blocking> {
baud_rate: BaudRate,
mode: TwaiMode,
) -> Self {
Self::new_no_transceiver_typed(peripheral.map_into(), rx_pin, tx_pin, baud_rate, mode)
}
}
impl<'d, T> TwaiConfiguration<'d, Blocking, T>
where
T: Instance,
{
/// Create a new instance of [TwaiConfiguration]
///
/// You will need to use a transceiver to connect to the TWAI bus
pub fn new_typed<RX: PeripheralInput, TX: PeripheralOutput>(
peripheral: impl Peripheral<P = T> + 'd,
rx_pin: impl Peripheral<P = RX> + 'd,
tx_pin: impl Peripheral<P = TX> + 'd,
baud_rate: BaudRate,
mode: TwaiMode,
) -> Self {
Self::new_internal(peripheral, rx_pin, tx_pin, baud_rate, false, mode)
}
/// Create a new instance of [TwaiConfiguration] meant to connect two ESP32s
/// directly
///
/// You don't need a transceiver by following the description in the
/// `twai.rs` example
pub fn new_no_transceiver_typed<RX: PeripheralInput, TX: PeripheralOutput>(
peripheral: impl Peripheral<P = T> + 'd,
rx_pin: impl Peripheral<P = RX> + 'd,
tx_pin: impl Peripheral<P = TX> + 'd,
baud_rate: BaudRate,
mode: TwaiMode,
) -> Self {
crate::into_mapped_ref!(peripheral);
Self::new_internal(peripheral, rx_pin, tx_pin, baud_rate, true, mode)
}
/// Convert the configuration into an async configuration.
pub fn into_async(mut self) -> TwaiConfiguration<'d, Async, T> {
pub fn into_async(mut self) -> TwaiConfiguration<'d, Async> {
self.set_interrupt_handler(self.twai.async_handler());
TwaiConfiguration {
twai: self.twai,
@ -1039,12 +1007,9 @@ where
}
}
impl<'d, T> TwaiConfiguration<'d, Async, T>
where
T: Instance,
{
impl<'d> TwaiConfiguration<'d, Async> {
/// Convert the configuration into a blocking configuration.
pub fn into_blocking(self) -> TwaiConfiguration<'d, Blocking, T> {
pub fn into_blocking(self) -> TwaiConfiguration<'d, Blocking> {
use crate::{interrupt, Cpu};
interrupt::disable(Cpu::current(), self.twai.interrupt());
@ -1060,12 +1025,9 @@ where
}
}
impl<T> crate::private::Sealed for TwaiConfiguration<'_, Blocking, T> where T: Instance {}
impl crate::private::Sealed for TwaiConfiguration<'_, Blocking> {}
impl<T> InterruptConfigurable for TwaiConfiguration<'_, Blocking, T>
where
T: Instance,
{
impl InterruptConfigurable for TwaiConfiguration<'_, Blocking> {
fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
self.internal_set_interrupt_handler(handler);
}
@ -1075,17 +1037,16 @@ where
///
/// In this mode, the TWAI controller can transmit and receive messages
/// including error signals (such as error and overload frames).
pub struct Twai<'d, Dm: crate::DriverMode, T = AnyTwai> {
twai: PeripheralRef<'d, T>,
tx: TwaiTx<'d, Dm, T>,
rx: TwaiRx<'d, Dm, T>,
pub struct Twai<'d, Dm: DriverMode> {
twai: PeripheralRef<'d, AnyTwai>,
tx: TwaiTx<'d, Dm>,
rx: TwaiRx<'d, Dm>,
phantom: PhantomData<Dm>,
}
impl<'d, T, Dm> Twai<'d, Dm, T>
impl<'d, Dm> Twai<'d, Dm>
where
T: Instance,
Dm: crate::DriverMode,
Dm: DriverMode,
{
fn mode(&self) -> TwaiMode {
let mode = self.twai.register_block().mode().read();
@ -1101,7 +1062,7 @@ where
/// Stop the peripheral, putting it into reset mode and enabling
/// reconfiguration.
pub fn stop(self) -> TwaiConfiguration<'d, Dm, T> {
pub fn stop(self) -> TwaiConfiguration<'d, Dm> {
// Put the peripheral into reset/configuration mode by setting the reset mode
// bit.
self.twai
@ -1190,22 +1151,21 @@ where
/// Consumes this `Twai` instance and splits it into transmitting and
/// receiving halves.
pub fn split(self) -> (TwaiRx<'d, Dm, T>, TwaiTx<'d, Dm, T>) {
pub fn split(self) -> (TwaiRx<'d, Dm>, TwaiTx<'d, Dm>) {
(self.rx, self.tx)
}
}
/// Interface to the TWAI transmitter part.
pub struct TwaiTx<'d, Dm: crate::DriverMode, T = AnyTwai> {
twai: PeripheralRef<'d, T>,
pub struct TwaiTx<'d, Dm: DriverMode> {
twai: PeripheralRef<'d, AnyTwai>,
phantom: PhantomData<Dm>,
_guard: PeripheralGuard,
}
impl<Dm, T> TwaiTx<'_, Dm, T>
impl<Dm> TwaiTx<'_, Dm>
where
T: Instance,
Dm: crate::DriverMode,
Dm: DriverMode,
{
/// Transmit a frame.
///
@ -1239,16 +1199,15 @@ where
}
/// Interface to the TWAI receiver part.
pub struct TwaiRx<'d, Dm: crate::DriverMode, T = AnyTwai> {
twai: PeripheralRef<'d, T>,
pub struct TwaiRx<'d, Dm: DriverMode> {
twai: PeripheralRef<'d, AnyTwai>,
phantom: PhantomData<Dm>,
_guard: PeripheralGuard,
}
impl<Dm, T> TwaiRx<'_, Dm, T>
impl<Dm> TwaiRx<'_, Dm>
where
T: Instance,
Dm: crate::DriverMode,
Dm: DriverMode,
{
/// Receive a frame
pub fn receive(&mut self) -> nb::Result<EspTwaiFrame, EspTwaiError> {
@ -1335,10 +1294,9 @@ unsafe fn copy_to_data_register(dest: *mut u32, src: &[u8]) {
}
#[cfg(any(doc, feature = "unstable"))]
impl<Dm, T> embedded_can::nb::Can for Twai<'_, Dm, T>
impl<Dm> embedded_can::nb::Can for Twai<'_, Dm>
where
T: Instance,
Dm: crate::DriverMode,
Dm: DriverMode,
{
type Frame = EspTwaiFrame;
type Error = EspTwaiError;
@ -1699,10 +1657,7 @@ mod asynch {
}
}
impl<T> Twai<'_, crate::Async, T>
where
T: Instance,
{
impl Twai<'_, Async> {
/// Transmits an `EspTwaiFrame` asynchronously over the TWAI bus.
pub async fn transmit_async(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> {
self.tx.transmit_async(frame).await
@ -1713,10 +1668,7 @@ mod asynch {
}
}
impl<T> TwaiTx<'_, crate::Async, T>
where
T: Instance,
{
impl TwaiTx<'_, Async> {
/// Transmits an `EspTwaiFrame` asynchronously over the TWAI bus.
pub async fn transmit_async(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> {
self.twai.enable_interrupts();
@ -1743,10 +1695,7 @@ mod asynch {
}
}
impl<T> TwaiRx<'_, crate::Async, T>
where
T: Instance,
{
impl TwaiRx<'_, Async> {
/// Receives an `EspTwaiFrame` asynchronously over the TWAI bus.
pub async fn receive_async(&mut self) -> Result<EspTwaiFrame, EspTwaiError> {
self.twai.enable_interrupts();

View File

@ -482,25 +482,24 @@ impl Default for AtCmdConfig {
}
}
struct UartBuilder<'d, Dm, T = AnyUart> {
uart: PeripheralRef<'d, T>,
struct UartBuilder<'d, Dm> {
uart: PeripheralRef<'d, AnyUart>,
phantom: PhantomData<Dm>,
}
impl<'d, Dm, T> UartBuilder<'d, Dm, T>
impl<'d, Dm> UartBuilder<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn new(uart: impl Peripheral<P = T> + 'd) -> Self {
crate::into_ref!(uart);
fn new(uart: impl Peripheral<P = impl Instance> + 'd) -> Self {
crate::into_mapped_ref!(uart);
Self {
uart,
phantom: PhantomData,
}
}
fn init(self, config: Config) -> Result<Uart<'d, Dm, T>, ConfigError> {
fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
let rx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
let tx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
@ -523,21 +522,21 @@ where
}
/// UART (Full-duplex)
pub struct Uart<'d, Dm, T = AnyUart> {
rx: UartRx<'d, Dm, T>,
tx: UartTx<'d, Dm, T>,
pub struct Uart<'d, Dm> {
rx: UartRx<'d, Dm>,
tx: UartTx<'d, Dm>,
}
/// UART (Transmit)
pub struct UartTx<'d, Dm, T = AnyUart> {
uart: PeripheralRef<'d, T>,
pub struct UartTx<'d, Dm> {
uart: PeripheralRef<'d, AnyUart>,
phantom: PhantomData<Dm>,
guard: PeripheralGuard,
}
/// UART (Receive)
pub struct UartRx<'d, Dm, T = AnyUart> {
uart: PeripheralRef<'d, T>,
pub struct UartRx<'d, Dm> {
uart: PeripheralRef<'d, AnyUart>,
phantom: PhantomData<Dm>,
guard: PeripheralGuard,
}
@ -568,9 +567,8 @@ impl core::fmt::Display for ConfigError {
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<Dm, T> SetConfig for Uart<'_, Dm, T>
impl<Dm> SetConfig for Uart<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
type Config = Config;
@ -583,9 +581,8 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<Dm, T> SetConfig for UartRx<'_, Dm, T>
impl<Dm> SetConfig for UartRx<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
type Config = Config;
@ -598,9 +595,8 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<Dm, T> SetConfig for UartTx<'_, Dm, T>
impl<Dm> SetConfig for UartTx<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
type Config = Config;
@ -611,9 +607,8 @@ where
}
}
impl<'d, Dm, T> UartTx<'d, Dm, T>
impl<'d, Dm> UartTx<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
/// Configure RTS pin
@ -734,28 +729,13 @@ impl<'d> UartTx<'d, Blocking> {
uart: impl Peripheral<P = impl Instance> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_typed(uart.map_into(), config)
}
}
impl<'d, T> UartTx<'d, Blocking, T>
where
T: Instance,
{
/// Create a new UART TX instance in [`Blocking`] mode.
pub fn new_typed(
uart: impl Peripheral<P = T> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
let (_, uart_tx) = UartBuilder::<'d, Blocking, T>::new(uart)
.init(config)?
.split();
let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
Ok(uart_tx)
}
/// Reconfigures the driver to operate in [`Async`] mode.
pub fn into_async(self) -> UartTx<'d, Async, T> {
pub fn into_async(self) -> UartTx<'d, Async> {
if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
self.uart
.info()
@ -771,12 +751,9 @@ where
}
}
impl<'d, T> UartTx<'d, Async, T>
where
T: Instance,
{
impl<'d> UartTx<'d, Async> {
/// Reconfigures the driver to operate in [`Blocking`] mode.
pub fn into_blocking(self) -> UartTx<'d, Blocking, T> {
pub fn into_blocking(self) -> UartTx<'d, Blocking> {
self.uart
.state()
.is_tx_async
@ -813,9 +790,8 @@ fn sync_regs(_register_block: &RegisterBlock) {
}
}
impl<'d, Dm, T> UartRx<'d, Dm, T>
impl<'d, Dm> UartRx<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
/// Configure CTS pin
@ -960,19 +936,6 @@ impl<'d> UartRx<'d, Blocking> {
pub fn new(
uart: impl Peripheral<P = impl Instance> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
UartRx::new_typed(uart.map_into(), config)
}
}
impl<'d, T> UartRx<'d, Blocking, T>
where
T: Instance,
{
/// Create a new UART RX instance in [`Blocking`] mode.
pub fn new_typed(
uart: impl Peripheral<P = T> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
@ -980,7 +943,7 @@ where
}
/// Reconfigures the driver to operate in [`Async`] mode.
pub fn into_async(self) -> UartRx<'d, Async, T> {
pub fn into_async(self) -> UartRx<'d, Async> {
if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
self.uart
.info()
@ -996,12 +959,9 @@ where
}
}
impl<'d, T> UartRx<'d, Async, T>
where
T: Instance,
{
impl<'d> UartRx<'d, Async> {
/// Reconfigures the driver to operate in [`Blocking`] mode.
pub fn into_blocking(self) -> UartRx<'d, Blocking, T> {
pub fn into_blocking(self) -> UartRx<'d, Blocking> {
self.uart
.state()
.is_rx_async
@ -1023,25 +983,12 @@ impl<'d> Uart<'d, Blocking> {
pub fn new(
uart: impl Peripheral<P = impl Instance> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
Self::new_typed(uart.map_into(), config)
}
}
impl<'d, T> Uart<'d, Blocking, T>
where
T: Instance,
{
/// Create a new UART instance in [`Blocking`] mode.
pub fn new_typed(
uart: impl Peripheral<P = T> + 'd,
config: Config,
) -> Result<Self, ConfigError> {
UartBuilder::new(uart).init(config)
}
/// Reconfigures the driver to operate in [`Async`] mode.
pub fn into_async(self) -> Uart<'d, Async, T> {
pub fn into_async(self) -> Uart<'d, Async> {
Uart {
rx: self.rx.into_async(),
tx: self.tx.into_async(),
@ -1079,12 +1026,9 @@ where
}
}
impl<'d, T> Uart<'d, Async, T>
where
T: Instance,
{
impl<'d> Uart<'d, Async> {
/// Reconfigures the driver to operate in [`Blocking`] mode.
pub fn into_blocking(self) -> Uart<'d, Blocking, T> {
pub fn into_blocking(self) -> Uart<'d, Blocking> {
Uart {
rx: self.rx.into_blocking(),
tx: self.tx.into_blocking(),
@ -1109,9 +1053,8 @@ pub enum UartInterrupt {
RxFifoFull,
}
impl<'d, Dm, T> Uart<'d, Dm, T>
impl<'d, Dm> Uart<'d, Dm>
where
T: Instance,
Dm: DriverMode,
{
/// Configure CTS pin
@ -1135,7 +1078,7 @@ where
///
/// This is particularly useful when having two tasks correlating to
/// transmitting and receiving.
pub fn split(self) -> (UartRx<'d, Dm, T>, UartTx<'d, Dm, T>) {
pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
(self.rx, self.tx)
}
@ -1284,22 +1227,16 @@ where
}
}
impl<T> crate::private::Sealed for Uart<'_, Blocking, T> where T: Instance {}
impl crate::private::Sealed for Uart<'_, Blocking> {}
impl<T> InterruptConfigurable for Uart<'_, Blocking, T>
where
T: Instance,
{
impl InterruptConfigurable for Uart<'_, Blocking> {
fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) {
// `self.tx.uart` and `self.rx.uart` are the same
self.tx.uart.info().set_interrupt_handler(handler);
}
}
impl<T> Uart<'_, Blocking, T>
where
T: Instance,
{
impl Uart<'_, Blocking> {
/// Listen for the given interrupts
pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
self.tx.uart.info().enable_listen(interrupts.into(), true)
@ -1321,9 +1258,8 @@ where
}
}
impl<T, Dm> ufmt_write::uWrite for Uart<'_, Dm, T>
impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
type Error = Error;
@ -1339,9 +1275,8 @@ where
}
}
impl<T, Dm> ufmt_write::uWrite for UartTx<'_, Dm, T>
impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
type Error = Error;
@ -1353,9 +1288,8 @@ where
}
}
impl<T, Dm> core::fmt::Write for Uart<'_, Dm, T>
impl<Dm> core::fmt::Write for Uart<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
#[inline]
@ -1364,9 +1298,8 @@ where
}
}
impl<T, Dm> core::fmt::Write for UartTx<'_, Dm, T>
impl<Dm> core::fmt::Write for UartTx<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
#[inline]
@ -1377,21 +1310,20 @@ where
}
}
impl<T, Dm> embedded_hal_nb::serial::ErrorType for Uart<'_, Dm, T> {
impl<Dm> embedded_hal_nb::serial::ErrorType for Uart<'_, Dm> {
type Error = Error;
}
impl<T, Dm> embedded_hal_nb::serial::ErrorType for UartTx<'_, Dm, T> {
impl<Dm> embedded_hal_nb::serial::ErrorType for UartTx<'_, Dm> {
type Error = Error;
}
impl<T, Dm> embedded_hal_nb::serial::ErrorType for UartRx<'_, Dm, T> {
impl<Dm> embedded_hal_nb::serial::ErrorType for UartRx<'_, Dm> {
type Error = Error;
}
impl<T, Dm> embedded_hal_nb::serial::Read for Uart<'_, Dm, T>
impl<Dm> embedded_hal_nb::serial::Read for Uart<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn read(&mut self) -> nb::Result<u8, Self::Error> {
@ -1399,9 +1331,8 @@ where
}
}
impl<T, Dm> embedded_hal_nb::serial::Read for UartRx<'_, Dm, T>
impl<Dm> embedded_hal_nb::serial::Read for UartRx<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn read(&mut self) -> nb::Result<u8, Self::Error> {
@ -1409,9 +1340,8 @@ where
}
}
impl<T, Dm> embedded_hal_nb::serial::Write for Uart<'_, Dm, T>
impl<Dm> embedded_hal_nb::serial::Write for Uart<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
@ -1423,9 +1353,8 @@ where
}
}
impl<T, Dm> embedded_hal_nb::serial::Write for UartTx<'_, Dm, T>
impl<Dm> embedded_hal_nb::serial::Write for UartTx<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
@ -1439,27 +1368,26 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T, Dm> embedded_io::ErrorType for Uart<'_, Dm, T> {
impl<Dm> embedded_io::ErrorType for Uart<'_, Dm> {
type Error = Error;
}
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T, Dm> embedded_io::ErrorType for UartTx<'_, Dm, T> {
impl<Dm> embedded_io::ErrorType for UartTx<'_, Dm> {
type Error = Error;
}
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T, Dm> embedded_io::ErrorType for UartRx<'_, Dm, T> {
impl<Dm> embedded_io::ErrorType for UartRx<'_, Dm> {
type Error = Error;
}
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T, Dm> embedded_io::Read for Uart<'_, Dm, T>
impl<Dm> embedded_io::Read for Uart<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
@ -1469,9 +1397,8 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T, Dm> embedded_io::Read for UartRx<'_, Dm, T>
impl<Dm> embedded_io::Read for UartRx<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
@ -1489,9 +1416,8 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T, Dm> embedded_io::ReadReady for Uart<'_, Dm, T>
impl<Dm> embedded_io::ReadReady for Uart<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn read_ready(&mut self) -> Result<bool, Self::Error> {
@ -1501,9 +1427,8 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T, Dm> embedded_io::ReadReady for UartRx<'_, Dm, T>
impl<Dm> embedded_io::ReadReady for UartRx<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn read_ready(&mut self) -> Result<bool, Self::Error> {
@ -1513,9 +1438,8 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T, Dm> embedded_io::Write for Uart<'_, Dm, T>
impl<Dm> embedded_io::Write for Uart<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
@ -1529,9 +1453,8 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T, Dm> embedded_io::Write for UartTx<'_, Dm, T>
impl<Dm> embedded_io::Write for UartTx<'_, Dm>
where
T: Instance,
Dm: DriverMode,
{
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
@ -1735,10 +1658,7 @@ impl Drop for UartTxFuture {
}
}
impl<T> Uart<'_, Async, T>
where
T: Instance,
{
impl Uart<'_, Async> {
/// Asynchronously reads data from the UART receive buffer into the
/// provided buffer.
pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
@ -1756,10 +1676,7 @@ where
}
}
impl<T> UartTx<'_, Async, T>
where
T: Instance,
{
impl UartTx<'_, Async> {
/// Asynchronously writes data to the UART transmit buffer in chunks.
///
/// This function sends the contents of the provided buffer `words` over
@ -1806,10 +1723,7 @@ where
}
}
impl<T> UartRx<'_, Async, T>
where
T: Instance,
{
impl UartRx<'_, Async> {
/// Read async to buffer slice `buf`.
/// Waits until at least one byte is in the Rx FiFo
/// and one of the following interrupts occurs:
@ -1888,10 +1802,7 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T> embedded_io_async::Read for Uart<'_, Async, T>
where
T: Instance,
{
impl embedded_io_async::Read for Uart<'_, Async> {
/// In contrast to the documentation of embedded_io_async::Read, this
/// method blocks until an uart interrupt occurs.
/// See UartRx::read_async for more details.
@ -1902,10 +1813,7 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T> embedded_io_async::Read for UartRx<'_, Async, T>
where
T: Instance,
{
impl embedded_io_async::Read for UartRx<'_, Async> {
/// In contrast to the documentation of embedded_io_async::Read, this
/// method blocks until an uart interrupt occurs.
/// See UartRx::read_async for more details.
@ -1916,10 +1824,7 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T> embedded_io_async::Write for Uart<'_, Async, T>
where
T: Instance,
{
impl embedded_io_async::Write for Uart<'_, Async> {
async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
self.write_async(buf).await
}
@ -1931,10 +1836,7 @@ where
#[cfg(any(doc, feature = "unstable"))]
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
impl<T> embedded_io_async::Write for UartTx<'_, Async, T>
where
T: Instance,
{
impl embedded_io_async::Write for UartTx<'_, Async> {
async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
self.write_async(buf).await
}

View File

@ -234,7 +234,7 @@ const _: () = {
core::assert!(CONFIG.rx_ba_win < (CONFIG.static_rx_buf_num * 2), "WiFi configuration check: rx_ba_win should not be larger than double of the static_rx_buf_num!");
};
type TimeBase = PeriodicTimer<'static, Blocking, AnyTimer>;
type TimeBase = PeriodicTimer<'static, Blocking>;
pub(crate) mod flags {
use portable_atomic::{AtomicBool, AtomicUsize};

View File

@ -64,7 +64,7 @@ mod test_cases {
}
pub fn run_test_periodic_timer<T: esp_hal::timer::Timer>(timer: impl Peripheral<P = T>) {
let mut periodic = PeriodicTimer::new_typed(timer);
let mut periodic = PeriodicTimer::new(timer);
let t1 = esp_hal::time::now();
periodic.start(100.millis()).unwrap();
@ -81,7 +81,7 @@ mod test_cases {
}
pub fn run_test_oneshot_timer<T: esp_hal::timer::Timer>(timer: impl Peripheral<P = T>) {
let mut timer = OneShotTimer::new_typed(timer);
let mut timer = OneShotTimer::new(timer);
let t1 = esp_hal::time::now();
timer.delay_millis(50);

View File

@ -14,7 +14,6 @@ use esp_hal::{
dma::{DmaDescriptor, DmaRxBuf, DmaTxBuf},
dma_buffers,
gpio::{Level, NoPin},
peripheral::Peripheral,
spi::master::{Config, Spi},
time::RateExtU32,
Blocking,

View File

@ -167,15 +167,12 @@ fn main() -> ! {
pub const OV2640_ADDRESS: u8 = 0x30;
pub struct Sccb<'d, T> {
i2c: I2c<'d, Blocking, T>,
pub struct Sccb<'d> {
i2c: I2c<'d, Blocking>,
}
impl<'d, T> Sccb<'d, T>
where
T: i2c::master::Instance,
{
pub fn new(i2c: I2c<'d, Blocking, T>) -> Self {
impl<'d> Sccb<'d> {
pub fn new(i2c: I2c<'d, Blocking>) -> Self {
Self { i2c }
}