Remove all instance type params (#2907)
This commit is contained in:
parent
409641dd7e
commit
0ef00206d5
@ -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.
|
||||
|
||||
@ -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()),
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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)
|
||||
/// }
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(())
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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> {
|
||||
|
||||
@ -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,
|
||||
{
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 }
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user