mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 21:00:59 +00:00
GPIO interconnect (#2128)
* Allow accessing signal list via ErasedPin * Replace AnyPin with more flexible signal config * Update tests and examples * Fix enable_from_gpio value * Access signals from pin drivers * DummyPin is not a pin * Remove redundant public fns * Various fixes, rename ErasedPin * Changelog * rustfmt * Update i8080 * Typos and endless recursion * Drop Pin suffix from traits * Extract AF conversion * Touch up changelog * Clean up spi tests * Refactor pull resistor handling * Don't disable configured output functionality * Clean up TODO * Tweak docs * Clean up examples
This commit is contained in:
parent
f2e0211c1b
commit
7a733a75db
@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Previously unavailable memory is available via `.dram2_uninit` section (#2079)
|
||||
- You can now use `Input`, `Output`, `OutputOpenDrain` and `Flex` pins as EXTI and RTCIO wakeup sources (#2095)
|
||||
- Added `Rtc::set_current_time` to allow setting RTC time, and `Rtc::current_time` to getting RTC time while taking into account boot time (#1883)
|
||||
- Added APIs to allow connecting signals through the GPIO matrix. (#2128)
|
||||
|
||||
### Changed
|
||||
|
||||
@ -37,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- The (previously undocumented) `ErasedPin` enum has been replaced with the `ErasedPin` struct. (#2094)
|
||||
- Renamed and merged `Rtc::get_time_us` and `Rtc::get_time_ms` into `Rtc::time_since_boot` (#1883)
|
||||
- ESP32: Added support for touch sensing on GPIO32 and 33 (#2109)
|
||||
- Replaced `AnyPin` with `InputSignal` and `OutputSignal` and renamed `ErasedPin` to `AnyPin` (#2128)
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -48,7 +48,7 @@ You no longer have to spell out the GPIO pin type for `Input`, `Output`, `Output
|
||||
However, if you want to, you can keep using their typed form!
|
||||
|
||||
```rust
|
||||
let pin = Input::new(io.gpio0); // pin will have the type `Input<'some>` (or `Input<'some, ErasedPin>` if you want to be explicit about it)
|
||||
let pin = Input::new(io.gpio0); // pin will have the type `Input<'some>` (or `Input<'some, AnyPin>` if you want to be explicit about it)
|
||||
let pin = Input::new_typed(io.gpio0); // pin will have the type `Input<'some, GpioPin<0>>`
|
||||
```
|
||||
|
||||
|
@ -1,169 +0,0 @@
|
||||
use super::*;
|
||||
|
||||
/// A type-erased GPIO pin, with additional configuration options.
|
||||
///
|
||||
/// Note that accessing unsupported pin functions (e.g. trying to use an
|
||||
/// input-only pin as output) will panic.
|
||||
pub struct AnyPin<'d> {
|
||||
pin: ErasedPin,
|
||||
is_inverted: bool,
|
||||
_phantom: PhantomData<&'d ()>,
|
||||
}
|
||||
|
||||
impl<'d> AnyPin<'d> {
|
||||
/// Create wrapper for the given pin.
|
||||
#[inline]
|
||||
pub fn new<P>(pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: Pin,
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
let pin = pin.degrade_internal(private::Internal);
|
||||
|
||||
Self {
|
||||
pin,
|
||||
is_inverted: false,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create wrapper for the given pin. The peripheral signal will be
|
||||
/// inverted.
|
||||
#[inline]
|
||||
pub fn new_inverted<P>(pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: Pin,
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
let pin = pin.degrade_internal(private::Internal);
|
||||
|
||||
Self {
|
||||
pin,
|
||||
is_inverted: true,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> crate::peripheral::Peripheral for AnyPin<'d> {
|
||||
type P = Self;
|
||||
|
||||
unsafe fn clone_unchecked(&mut self) -> Self::P {
|
||||
Self {
|
||||
pin: unsafe { self.pin.clone_unchecked() },
|
||||
is_inverted: self.is_inverted,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> private::Sealed for AnyPin<'d> {}
|
||||
|
||||
impl<'d> Pin for AnyPin<'d> {
|
||||
delegate::delegate! {
|
||||
to self.pin {
|
||||
fn number(&self, _internal: private::Internal) -> u8;
|
||||
fn degrade_internal(&self, _internal: private::Internal) -> ErasedPin;
|
||||
fn sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn set_alternate_function(&mut self, alternate: AlternateFunction, _internal: private::Internal);
|
||||
fn is_listening(&self, _internal: private::Internal) -> bool;
|
||||
fn listen_with_options(
|
||||
&mut self,
|
||||
event: Event,
|
||||
int_enable: bool,
|
||||
nmi_enable: bool,
|
||||
wake_up_from_light_sleep: bool,
|
||||
_internal: private::Internal,
|
||||
);
|
||||
fn unlisten(&mut self, _internal: private::Internal);
|
||||
fn is_interrupt_set(&self, _internal: private::Internal) -> bool;
|
||||
fn clear_interrupt(&mut self, _internal: private::Internal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> OutputPin for AnyPin<'d> {
|
||||
delegate::delegate! {
|
||||
to self.pin {
|
||||
fn set_to_open_drain_output(&mut self, _internal: private::Internal);
|
||||
fn set_to_push_pull_output(&mut self, _internal: private::Internal);
|
||||
fn enable_output(&mut self, on: bool, _internal: private::Internal);
|
||||
fn set_output_high(&mut self, on: bool, _internal: private::Internal);
|
||||
fn set_drive_strength(&mut self, strength: DriveStrength, _internal: private::Internal);
|
||||
fn enable_open_drain(&mut self, on: bool, _internal: private::Internal);
|
||||
fn enable_output_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn internal_pull_up(&mut self, on: bool, _internal: private::Internal);
|
||||
fn internal_pull_down(&mut self, on: bool, _internal: private::Internal);
|
||||
fn disconnect_peripheral_from_output(&mut self, _internal: private::Internal);
|
||||
fn is_set_high(&self, _internal: private::Internal) -> bool;
|
||||
}
|
||||
}
|
||||
|
||||
fn connect_peripheral_to_output_with_options(
|
||||
&mut self,
|
||||
signal: OutputSignal,
|
||||
invert: bool,
|
||||
invert_enable: bool,
|
||||
enable_from_gpio: bool,
|
||||
force_via_gpio_mux: bool,
|
||||
_internal: private::Internal,
|
||||
) {
|
||||
if self.is_inverted {
|
||||
self.pin.connect_peripheral_to_output_with_options(
|
||||
signal,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
private::Internal,
|
||||
);
|
||||
} else {
|
||||
self.pin.connect_peripheral_to_output_with_options(
|
||||
signal,
|
||||
invert,
|
||||
invert_enable,
|
||||
enable_from_gpio,
|
||||
force_via_gpio_mux,
|
||||
private::Internal,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d> InputPin for AnyPin<'d> {
|
||||
delegate::delegate! {
|
||||
to self.pin {
|
||||
fn init_input(&self, pull_down: bool, pull_up: bool, _internal: private::Internal);
|
||||
fn enable_input(&mut self, on: bool, _internal: private::Internal);
|
||||
fn enable_input_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn is_input_high(&self, _internal: private::Internal) -> bool;
|
||||
fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _internal: private::Internal);
|
||||
}
|
||||
}
|
||||
|
||||
fn connect_input_to_peripheral_with_options(
|
||||
&mut self,
|
||||
signal: InputSignal,
|
||||
invert: bool,
|
||||
force_via_gpio_mux: bool,
|
||||
_internal: private::Internal,
|
||||
) {
|
||||
if self.is_inverted {
|
||||
self.pin.connect_input_to_peripheral_with_options(
|
||||
signal,
|
||||
true,
|
||||
true,
|
||||
private::Internal,
|
||||
);
|
||||
} else {
|
||||
self.pin.connect_input_to_peripheral_with_options(
|
||||
signal,
|
||||
invert,
|
||||
force_via_gpio_mux,
|
||||
private::Internal,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
//! "Dummy" pins".
|
||||
//! Placeholder pins.
|
||||
//!
|
||||
//! These are useful to pass them into peripheral drivers where you don't want
|
||||
//! an actual pin but one is required.
|
||||
|
||||
use super::*;
|
||||
|
||||
/// DummyPin, not useful everywhere as it panics if number() is called
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Clone)]
|
||||
pub struct DummyPin {
|
||||
value: bool,
|
||||
}
|
||||
@ -27,43 +28,72 @@ impl crate::peripheral::Peripheral for DummyPin {
|
||||
|
||||
impl private::Sealed for DummyPin {}
|
||||
|
||||
impl Pin for DummyPin {
|
||||
fn number(&self, _: private::Internal) -> u8 {
|
||||
panic!("DummyPin not supported here!");
|
||||
impl PeripheralInput for DummyPin {
|
||||
fn input_signals(&self, _: private::Internal) -> [Option<InputSignal>; 6] {
|
||||
[None; 6]
|
||||
}
|
||||
|
||||
fn degrade_internal(&self, _: private::Internal) -> ErasedPin {
|
||||
panic!("Can not type erase the DummyPin!");
|
||||
fn init_input(&self, _pull: Pull, _: private::Internal) {}
|
||||
|
||||
fn enable_input(&mut self, _on: bool, _: private::Internal) {}
|
||||
|
||||
fn enable_input_in_sleep_mode(&mut self, _on: bool, _: private::Internal) {}
|
||||
|
||||
fn is_input_high(&self, _: private::Internal) -> bool {
|
||||
self.value
|
||||
}
|
||||
|
||||
fn sleep_mode(&mut self, _on: bool, _: private::Internal) {}
|
||||
fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal) {
|
||||
let value = if self.value { ONE_INPUT } else { ZERO_INPUT };
|
||||
|
||||
fn set_alternate_function(&mut self, _alternate: AlternateFunction, _: private::Internal) {}
|
||||
|
||||
fn is_listening(&self, _: private::Internal) -> bool {
|
||||
false
|
||||
unsafe { &*GPIO::PTR }
|
||||
.func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET)
|
||||
.modify(|_, w| unsafe {
|
||||
w.sel()
|
||||
.set_bit()
|
||||
.in_inv_sel()
|
||||
.bit(false)
|
||||
.in_sel()
|
||||
.bits(value)
|
||||
});
|
||||
}
|
||||
|
||||
fn listen_with_options(
|
||||
&mut self,
|
||||
_event: Event,
|
||||
_int_enable: bool,
|
||||
_nmi_enable: bool,
|
||||
_wake_up_from_light_sleep: bool,
|
||||
_: private::Internal,
|
||||
) {
|
||||
}
|
||||
|
||||
fn unlisten(&mut self, _: private::Internal) {}
|
||||
|
||||
fn is_interrupt_set(&self, _: private::Internal) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn clear_interrupt(&mut self, _: private::Internal) {}
|
||||
fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _: private::Internal) {}
|
||||
}
|
||||
|
||||
impl OutputPin for DummyPin {
|
||||
impl PeripheralSignal for Level {
|
||||
delegate::delegate! {
|
||||
to match self {
|
||||
Level::High => DummyPin { value: true },
|
||||
Level::Low => DummyPin { value: false },
|
||||
} {
|
||||
fn pull_direction(&self, pull: Pull, _internal: private::Internal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PeripheralInput for Level {
|
||||
delegate::delegate! {
|
||||
to match self {
|
||||
Level::High => DummyPin { value: true },
|
||||
Level::Low => DummyPin { value: false },
|
||||
} {
|
||||
fn init_input(&self, _pull: Pull, _internal: private::Internal);
|
||||
fn enable_input(&mut self, _on: bool, _internal: private::Internal);
|
||||
fn enable_input_in_sleep_mode(&mut self, _on: bool, _internal: private::Internal);
|
||||
fn is_input_high(&self, _internal: private::Internal) -> bool;
|
||||
fn connect_input_to_peripheral(&mut self, _signal: InputSignal, _internal: private::Internal);
|
||||
fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _internal: private::Internal);
|
||||
fn input_signals(&self, _internal: private::Internal) -> [Option<InputSignal>; 6];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PeripheralSignal for DummyPin {
|
||||
fn pull_direction(&self, _pull: Pull, _internal: private::Internal) {}
|
||||
}
|
||||
|
||||
impl PeripheralOutput for DummyPin {
|
||||
fn set_to_open_drain_output(&mut self, _: private::Internal) {}
|
||||
|
||||
fn set_to_push_pull_output(&mut self, _: private::Internal) {}
|
||||
@ -84,53 +114,17 @@ impl OutputPin for DummyPin {
|
||||
|
||||
fn internal_pull_down_in_sleep_mode(&mut self, _on: bool, _: private::Internal) {}
|
||||
|
||||
fn internal_pull_up(&mut self, _on: bool, _: private::Internal) {}
|
||||
|
||||
fn internal_pull_down(&mut self, _on: bool, _: private::Internal) {}
|
||||
|
||||
fn connect_peripheral_to_output(&mut self, _signal: OutputSignal, _: private::Internal) {}
|
||||
|
||||
fn connect_peripheral_to_output_with_options(
|
||||
&mut self,
|
||||
_signal: OutputSignal,
|
||||
_invert: bool,
|
||||
_invert_enable: bool,
|
||||
_enable_from_gpio: bool,
|
||||
_force_via_gpio_mux: bool,
|
||||
_: private::Internal,
|
||||
) {
|
||||
}
|
||||
|
||||
fn disconnect_peripheral_from_output(&mut self, _: private::Internal) {}
|
||||
|
||||
fn is_set_high(&self, _: private::Internal) -> bool {
|
||||
self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl InputPin for DummyPin {
|
||||
fn init_input(&self, _pull_down: bool, _pull_up: bool, _: private::Internal) {}
|
||||
|
||||
fn enable_input(&mut self, _on: bool, _: private::Internal) {}
|
||||
|
||||
fn enable_input_in_sleep_mode(&mut self, _on: bool, _: private::Internal) {}
|
||||
|
||||
fn is_input_high(&self, _: private::Internal) -> bool {
|
||||
self.value
|
||||
fn output_signals(&self, _: private::Internal) -> [Option<OutputSignal>; 6] {
|
||||
[None; 6]
|
||||
}
|
||||
|
||||
fn connect_input_to_peripheral(&mut self, _signal: InputSignal, _: private::Internal) {}
|
||||
fn connect_peripheral_to_output(&mut self, _signal: OutputSignal, _: private::Internal) {}
|
||||
|
||||
fn connect_input_to_peripheral_with_options(
|
||||
&mut self,
|
||||
_signal: InputSignal,
|
||||
_invert: bool,
|
||||
_force_via_gpio_mux: bool,
|
||||
_: private::Internal,
|
||||
) {
|
||||
}
|
||||
|
||||
fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _: private::Internal) {}
|
||||
fn disconnect_from_peripheral_output(&mut self, _signal: OutputSignal, _: private::Internal) {}
|
||||
}
|
||||
|
||||
impl embedded_hal_02::digital::v2::OutputPin for DummyPin {
|
||||
@ -147,10 +141,10 @@ impl embedded_hal_02::digital::v2::OutputPin for DummyPin {
|
||||
}
|
||||
impl embedded_hal_02::digital::v2::StatefulOutputPin for DummyPin {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(OutputPin::is_set_high(self, private::Internal))
|
||||
Ok(PeripheralOutput::is_set_high(self, private::Internal))
|
||||
}
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(!OutputPin::is_set_high(self, private::Internal))
|
||||
Ok(!PeripheralOutput::is_set_high(self, private::Internal))
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,10 +166,10 @@ impl embedded_hal::digital::OutputPin for DummyPin {
|
||||
|
||||
impl embedded_hal::digital::StatefulOutputPin for DummyPin {
|
||||
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
|
||||
Ok(OutputPin::is_set_high(self, private::Internal))
|
||||
Ok(PeripheralOutput::is_set_high(self, private::Internal))
|
||||
}
|
||||
|
||||
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
|
||||
Ok(!OutputPin::is_set_high(self, private::Internal))
|
||||
Ok(!PeripheralOutput::is_set_high(self, private::Internal))
|
||||
}
|
||||
}
|
||||
|
@ -152,11 +152,7 @@ impl<const C: u8> GpioEtmEventChannel<C> {
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
|
||||
pin.init_input(
|
||||
pin_config.pull == Pull::Down,
|
||||
pin_config.pull == Pull::Up,
|
||||
private::Internal,
|
||||
);
|
||||
pin.init_input(pin_config.pull, private::Internal);
|
||||
|
||||
enable_event_channel(C, pin.number(private::Internal));
|
||||
GpioEtmEventChannelRising { _pin: pin }
|
||||
@ -173,11 +169,7 @@ impl<const C: u8> GpioEtmEventChannel<C> {
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
|
||||
pin.init_input(
|
||||
pin_config.pull == Pull::Down,
|
||||
pin_config.pull == Pull::Up,
|
||||
private::Internal,
|
||||
);
|
||||
pin.init_input(pin_config.pull, private::Internal);
|
||||
|
||||
enable_event_channel(C, pin.number(private::Internal));
|
||||
GpioEtmEventChannelFalling { _pin: pin }
|
||||
@ -194,11 +186,7 @@ impl<const C: u8> GpioEtmEventChannel<C> {
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
|
||||
pin.init_input(
|
||||
pin_config.pull == Pull::Down,
|
||||
pin_config.pull == Pull::Up,
|
||||
private::Internal,
|
||||
);
|
||||
pin.init_input(pin_config.pull, private::Internal);
|
||||
|
||||
enable_event_channel(C, pin.number(private::Internal));
|
||||
GpioEtmEventChannelAny { _pin: pin }
|
||||
@ -318,8 +306,7 @@ impl<const C: u8> GpioEtmTaskChannel<C> {
|
||||
|
||||
pin.set_output_high(pin_config.initial_state.into(), private::Internal);
|
||||
if pin_config.open_drain {
|
||||
pin.internal_pull_down(pin_config.pull == Pull::Down, private::Internal);
|
||||
pin.internal_pull_up(pin_config.pull == Pull::Up, private::Internal);
|
||||
pin.pull_direction(pin_config.pull, private::Internal);
|
||||
pin.set_to_open_drain_output(private::Internal);
|
||||
} else {
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
@ -342,8 +329,7 @@ impl<const C: u8> GpioEtmTaskChannel<C> {
|
||||
|
||||
pin.set_output_high(pin_config.initial_state.into(), private::Internal);
|
||||
if pin_config.open_drain {
|
||||
pin.internal_pull_down(pin_config.pull == Pull::Down, private::Internal);
|
||||
pin.internal_pull_up(pin_config.pull == Pull::Up, private::Internal);
|
||||
pin.pull_direction(pin_config.pull, private::Internal);
|
||||
pin.set_to_open_drain_output(private::Internal);
|
||||
} else {
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
@ -366,8 +352,7 @@ impl<const C: u8> GpioEtmTaskChannel<C> {
|
||||
|
||||
pin.set_output_high(pin_config.initial_state.into(), private::Internal);
|
||||
if pin_config.open_drain {
|
||||
pin.internal_pull_down(pin_config.pull == Pull::Down, private::Internal);
|
||||
pin.internal_pull_up(pin_config.pull == Pull::Up, private::Internal);
|
||||
pin.pull_direction(pin_config.pull, private::Internal);
|
||||
pin.set_to_open_drain_output(private::Internal);
|
||||
} else {
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
|
418
esp-hal/src/gpio/interconnect.rs
Normal file
418
esp-hal/src/gpio/interconnect.rs
Normal file
@ -0,0 +1,418 @@
|
||||
//! Peripheral signal interconnect using IOMUX or GPIOMUX.
|
||||
|
||||
use crate::{
|
||||
gpio::{
|
||||
self,
|
||||
AlternateFunction,
|
||||
AnyPin,
|
||||
DummyPin,
|
||||
GpioPin,
|
||||
GpioProperties,
|
||||
InputPin,
|
||||
Level,
|
||||
OutputSignalType,
|
||||
PeripheralInput,
|
||||
PeripheralOutput,
|
||||
PeripheralSignal,
|
||||
Pin,
|
||||
Pull,
|
||||
FUNC_IN_SEL_OFFSET,
|
||||
GPIO_FUNCTION,
|
||||
INPUT_SIGNAL_MAX,
|
||||
OUTPUT_SIGNAL_MAX,
|
||||
},
|
||||
peripheral::Peripheral,
|
||||
peripherals::GPIO,
|
||||
private::{self, Sealed},
|
||||
};
|
||||
|
||||
/// A configurable input signal between a peripheral and a GPIO pin.
|
||||
///
|
||||
/// Obtained by calling [`GpioPin::peripheral_input()`],
|
||||
/// [`super::Flex::peripheral_input()`] or [`super::Input::peripheral_input()`].
|
||||
///
|
||||
/// Multiple input signals can be connected to one pin.
|
||||
pub struct InputSignal {
|
||||
pin: AnyPin,
|
||||
is_inverted: bool,
|
||||
}
|
||||
|
||||
impl Clone for InputSignal {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
pin: unsafe { self.pin.clone_unchecked() },
|
||||
is_inverted: self.is_inverted,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Peripheral for InputSignal {
|
||||
type P = Self;
|
||||
|
||||
unsafe fn clone_unchecked(&mut self) -> Self::P {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Sealed for InputSignal {}
|
||||
|
||||
impl InputSignal {
|
||||
pub(crate) fn new(pin: AnyPin) -> Self {
|
||||
Self {
|
||||
pin,
|
||||
is_inverted: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Inverts the peripheral's input signal.
|
||||
///
|
||||
/// Calling this function multiple times toggles the setting.
|
||||
pub fn invert(&mut self) {
|
||||
self.is_inverted = !self.is_inverted;
|
||||
}
|
||||
|
||||
/// Consumed the signal and returns a new one that inverts the peripheral's
|
||||
/// input signal.
|
||||
///
|
||||
/// Calling this function multiple times toggles the setting.
|
||||
pub fn inverted(mut self) -> Self {
|
||||
self.invert();
|
||||
self
|
||||
}
|
||||
|
||||
/// - signal: The input signal to connect to the pin
|
||||
/// - invert: Configures whether or not to invert the input value
|
||||
/// - input: The GPIO number to connect to the input signal
|
||||
fn connect(&self, signal: usize, invert: bool, input: u8) {
|
||||
unsafe { &*GPIO::PTR }
|
||||
.func_in_sel_cfg(signal - FUNC_IN_SEL_OFFSET)
|
||||
.modify(|_, w| unsafe {
|
||||
w.sel()
|
||||
.set_bit()
|
||||
.in_inv_sel()
|
||||
.bit(invert)
|
||||
.in_sel()
|
||||
.bits(input)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl PeripheralSignal for InputSignal {
|
||||
delegate::delegate! {
|
||||
to self.pin {
|
||||
fn pull_direction(&self, pull: Pull, _internal: private::Internal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PeripheralInput for InputSignal {
|
||||
/// Connect the pin to a peripheral input signal.
|
||||
///
|
||||
/// Since there can only be one input signal connected to a peripheral at a
|
||||
/// time, this function will disconnect any previously connected input
|
||||
/// signals.
|
||||
fn connect_input_to_peripheral(&mut self, signal: gpio::InputSignal, _: private::Internal) {
|
||||
let signal_nr = signal as usize;
|
||||
|
||||
let af = if self.is_inverted {
|
||||
GPIO_FUNCTION
|
||||
} else {
|
||||
self.pin
|
||||
.input_signals(private::Internal)
|
||||
.into_iter()
|
||||
.position(|s| s == Some(signal))
|
||||
.ok_or(())
|
||||
.and_then(AlternateFunction::try_from)
|
||||
.unwrap_or(GPIO_FUNCTION)
|
||||
};
|
||||
|
||||
if af == GPIO_FUNCTION && signal_nr > INPUT_SIGNAL_MAX as usize {
|
||||
panic!("Cannot connect GPIO to this peripheral");
|
||||
}
|
||||
|
||||
self.pin.set_alternate_function(af, private::Internal);
|
||||
|
||||
if signal_nr <= INPUT_SIGNAL_MAX as usize {
|
||||
self.connect(
|
||||
signal_nr,
|
||||
self.is_inverted,
|
||||
self.pin.number(private::Internal),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove this pin from a connected peripheral input.
|
||||
///
|
||||
/// Clears the entry in the GPIO matrix / Io mux that associates this input
|
||||
/// pin with the given [input `signal`](`InputSignal`). Any other
|
||||
/// connected signals remain intact.
|
||||
fn disconnect_input_from_peripheral(
|
||||
&mut self,
|
||||
signal: gpio::InputSignal,
|
||||
_: private::Internal,
|
||||
) {
|
||||
self.pin
|
||||
.set_alternate_function(GPIO_FUNCTION, private::Internal);
|
||||
|
||||
unsafe { &*GPIO::PTR }
|
||||
.func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET)
|
||||
.modify(|_, w| w.sel().clear_bit());
|
||||
}
|
||||
|
||||
delegate::delegate! {
|
||||
to self.pin {
|
||||
fn init_input(&self, pull: Pull, _internal: private::Internal);
|
||||
fn is_input_high(&self, _internal: private::Internal) -> bool;
|
||||
fn input_signals(&self, _internal: private::Internal) -> [Option<gpio::InputSignal>; 6];
|
||||
fn enable_input(&mut self, on: bool, _internal: private::Internal);
|
||||
fn enable_input_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A configurable output signal between a peripheral and a GPIO pin.
|
||||
///
|
||||
/// Obtained by calling [`GpioPin::into_peripheral_output()`],
|
||||
/// [`super::Flex::into_peripheral_output()`] or
|
||||
/// [`super::Output::into_peripheral_output()`].
|
||||
///
|
||||
/// Multiple pins can be connected to one output signal.
|
||||
pub struct OutputSignal {
|
||||
pin: AnyPin,
|
||||
is_inverted: bool,
|
||||
}
|
||||
|
||||
impl Peripheral for OutputSignal {
|
||||
type P = Self;
|
||||
|
||||
unsafe fn clone_unchecked(&mut self) -> Self::P {
|
||||
Self {
|
||||
pin: self.pin.clone_unchecked(),
|
||||
is_inverted: self.is_inverted,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sealed for OutputSignal {}
|
||||
|
||||
impl OutputSignal {
|
||||
pub(crate) fn new(pin: AnyPin) -> Self {
|
||||
Self {
|
||||
pin,
|
||||
is_inverted: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Inverts the peripheral's output signal.
|
||||
///
|
||||
/// Calling this function multiple times toggles the setting.
|
||||
pub fn invert(&mut self) {
|
||||
self.is_inverted = !self.is_inverted;
|
||||
}
|
||||
|
||||
/// Consumed the signal and returns a new one that inverts the peripheral's
|
||||
/// output signal.
|
||||
///
|
||||
/// Calling this function multiple times toggles the setting.
|
||||
pub fn inverted(mut self) -> Self {
|
||||
self.invert();
|
||||
self
|
||||
}
|
||||
|
||||
/// - signal: The output signal to connect to the pin
|
||||
/// - invert: Configures whether or not to invert the output value
|
||||
/// - invert_enable: Configures whether or not to invert the output enable
|
||||
/// signal
|
||||
/// - enable_from_gpio: Configures to select the source of output enable
|
||||
/// signal.
|
||||
/// - false: Use output enable signal from peripheral
|
||||
/// - true: Force the output enable signal to be sourced from bit n of
|
||||
/// GPIO_ENABLE_REG
|
||||
/// - output: The GPIO number to connect to the output signal
|
||||
fn connect(
|
||||
&self,
|
||||
signal: OutputSignalType,
|
||||
invert: bool,
|
||||
invert_enable: bool,
|
||||
enable_from_gpio: bool,
|
||||
output: u8,
|
||||
) {
|
||||
unsafe { &*GPIO::PTR }
|
||||
.func_out_sel_cfg(output as usize)
|
||||
.modify(|_, w| unsafe {
|
||||
w.out_sel()
|
||||
.bits(signal)
|
||||
.inv_sel()
|
||||
.bit(invert)
|
||||
.oen_sel()
|
||||
.bit(enable_from_gpio)
|
||||
.oen_inv_sel()
|
||||
.bit(invert_enable)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl PeripheralSignal for OutputSignal {
|
||||
delegate::delegate! {
|
||||
to self.pin {
|
||||
fn pull_direction(&self, pull: Pull, _internal: private::Internal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PeripheralOutput for OutputSignal {
|
||||
/// Connect the pin to a peripheral output signal.
|
||||
fn connect_peripheral_to_output(&mut self, signal: gpio::OutputSignal, _: private::Internal) {
|
||||
let af = if self.is_inverted {
|
||||
GPIO_FUNCTION
|
||||
} else {
|
||||
self.pin
|
||||
.output_signals(private::Internal)
|
||||
.into_iter()
|
||||
.position(|s| s == Some(signal))
|
||||
.ok_or(())
|
||||
.and_then(AlternateFunction::try_from)
|
||||
.unwrap_or(GPIO_FUNCTION)
|
||||
};
|
||||
|
||||
self.pin.set_alternate_function(af, private::Internal);
|
||||
|
||||
let clipped_signal = if signal as usize <= OUTPUT_SIGNAL_MAX as usize {
|
||||
signal as OutputSignalType
|
||||
} else {
|
||||
OUTPUT_SIGNAL_MAX
|
||||
};
|
||||
|
||||
self.connect(
|
||||
clipped_signal,
|
||||
self.is_inverted,
|
||||
false,
|
||||
false,
|
||||
self.pin.number(private::Internal),
|
||||
);
|
||||
}
|
||||
|
||||
/// Remove this output pin from a connected [signal](`OutputSignal`).
|
||||
///
|
||||
/// Clears the entry in the GPIO matrix / Io mux that associates this output
|
||||
/// pin with a previously connected [signal](`OutputSignal`). Any other
|
||||
/// outputs connected to the peripheral remain intact.
|
||||
fn disconnect_from_peripheral_output(
|
||||
&mut self,
|
||||
signal: gpio::OutputSignal,
|
||||
_: private::Internal,
|
||||
) {
|
||||
self.pin
|
||||
.set_alternate_function(GPIO_FUNCTION, private::Internal);
|
||||
|
||||
unsafe { &*GPIO::PTR }
|
||||
.func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET)
|
||||
.modify(|_, w| w.sel().clear_bit());
|
||||
}
|
||||
|
||||
delegate::delegate! {
|
||||
to self.pin {
|
||||
fn set_to_open_drain_output(&mut self, _internal: private::Internal);
|
||||
fn set_to_push_pull_output(&mut self, _internal: private::Internal);
|
||||
fn enable_output(&mut self, on: bool, _internal: private::Internal);
|
||||
fn set_output_high(&mut self, on: bool, _internal: private::Internal);
|
||||
fn set_drive_strength(&mut self, strength: gpio::DriveStrength, _internal: private::Internal);
|
||||
fn enable_open_drain(&mut self, on: bool, _internal: private::Internal);
|
||||
fn enable_output_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn is_set_high(&self, _internal: private::Internal) -> bool;
|
||||
fn output_signals(&self, _internal: private::Internal) -> [Option<gpio::OutputSignal>; 6];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum AnyInputSignalInner {
|
||||
Input(InputSignal),
|
||||
Constant(Level),
|
||||
Dummy(DummyPin),
|
||||
}
|
||||
|
||||
/// A type-erased input signal.
|
||||
#[derive(Clone)]
|
||||
pub struct AnyInputSignal(AnyInputSignalInner);
|
||||
|
||||
impl Peripheral for AnyInputSignal {
|
||||
type P = Self;
|
||||
|
||||
unsafe fn clone_unchecked(&mut self) -> Self::P {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InputSignal> for AnyInputSignal {
|
||||
fn from(input: InputSignal) -> Self {
|
||||
Self(AnyInputSignalInner::Input(input))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Level> for AnyInputSignal {
|
||||
fn from(level: Level) -> Self {
|
||||
Self(AnyInputSignalInner::Constant(level))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DummyPin> for AnyInputSignal {
|
||||
fn from(pin: DummyPin) -> Self {
|
||||
Self(AnyInputSignalInner::Dummy(pin))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AnyPin> for AnyInputSignal {
|
||||
fn from(input: AnyPin) -> Self {
|
||||
Self(AnyInputSignalInner::Input(input.peripheral_input()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<const GPIONUM: u8> From<GpioPin<GPIONUM>> for AnyInputSignal
|
||||
where
|
||||
GpioPin<GPIONUM>: InputPin + GpioProperties,
|
||||
{
|
||||
fn from(pin: GpioPin<GPIONUM>) -> Self {
|
||||
Self(AnyInputSignalInner::Input(pin.peripheral_input()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Sealed for AnyInputSignal {}
|
||||
impl PeripheralSignal for AnyInputSignal {
|
||||
delegate::delegate! {
|
||||
to match &self.0 {
|
||||
AnyInputSignalInner::Input(pin) => pin,
|
||||
AnyInputSignalInner::Constant(level) => level,
|
||||
AnyInputSignalInner::Dummy(pin) => pin,
|
||||
} {
|
||||
fn pull_direction(&self, pull: Pull, _internal: private::Internal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PeripheralInput for AnyInputSignal {
|
||||
delegate::delegate! {
|
||||
to match &self.0 {
|
||||
AnyInputSignalInner::Input(pin) => pin,
|
||||
AnyInputSignalInner::Constant(level) => level,
|
||||
AnyInputSignalInner::Dummy(pin) => pin,
|
||||
} {
|
||||
fn init_input(&self, pull: Pull, _internal: private::Internal);
|
||||
fn is_input_high(&self, _internal: private::Internal) -> bool;
|
||||
fn input_signals(&self, _internal: private::Internal) -> [Option<gpio::InputSignal>; 6];
|
||||
}
|
||||
|
||||
to match &mut self.0 {
|
||||
AnyInputSignalInner::Input(pin) => pin,
|
||||
AnyInputSignalInner::Constant(level) => level,
|
||||
AnyInputSignalInner::Dummy(pin) => pin,
|
||||
} {
|
||||
fn enable_input(&mut self, on: bool, _internal: private::Internal);
|
||||
fn enable_input_in_sleep_mode(&mut self, on: bool, _internal: private::Internal);
|
||||
fn connect_input_to_peripheral(&mut self, signal: crate::gpio::InputSignal, _internal: private::Internal);
|
||||
fn disconnect_input_from_peripheral(&mut self, signal: crate::gpio::InputSignal, _internal: private::Internal);
|
||||
}
|
||||
}
|
||||
}
|
@ -264,7 +264,7 @@ macro_rules! lp_gpio {
|
||||
($this:expr, $inner:ident, $code:tt) => {
|
||||
match $this {
|
||||
$(
|
||||
ErasedPinInner::[<Gpio $gpionum >]($inner) => {
|
||||
AnyPinInner::[<Gpio $gpionum >]($inner) => {
|
||||
$code
|
||||
},
|
||||
)+
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -57,7 +57,7 @@ use fugit::HertzU32;
|
||||
|
||||
use crate::{
|
||||
clock::Clocks,
|
||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
||||
gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput, Pull},
|
||||
interrupt::InterruptHandler,
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::i2c0::{RegisterBlock, COMD},
|
||||
@ -321,7 +321,10 @@ impl<'d, T, DM: crate::Mode> I2C<'d, T, DM>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
fn new_internal<SDA: OutputPin + InputPin, SCL: OutputPin + InputPin>(
|
||||
fn new_internal<
|
||||
SDA: PeripheralOutput + PeripheralInput,
|
||||
SCL: PeripheralOutput + PeripheralInput,
|
||||
>(
|
||||
i2c: impl Peripheral<P = T> + 'd,
|
||||
sda: impl Peripheral<P = SDA> + 'd,
|
||||
scl: impl Peripheral<P = SCL> + 'd,
|
||||
@ -355,27 +358,29 @@ where
|
||||
|
||||
scl.set_to_open_drain_output(crate::private::Internal);
|
||||
scl.enable_input(true, crate::private::Internal);
|
||||
scl.internal_pull_up(true, crate::private::Internal);
|
||||
scl.connect_peripheral_to_output(
|
||||
i2c.peripheral.scl_output_signal(),
|
||||
crate::private::Internal,
|
||||
);
|
||||
scl.pull_direction(Pull::Up, crate::private::Internal);
|
||||
|
||||
scl.connect_input_to_peripheral(
|
||||
i2c.peripheral.scl_input_signal(),
|
||||
crate::private::Internal,
|
||||
);
|
||||
scl.connect_peripheral_to_output(
|
||||
i2c.peripheral.scl_output_signal(),
|
||||
crate::private::Internal,
|
||||
);
|
||||
|
||||
sda.set_to_open_drain_output(crate::private::Internal);
|
||||
sda.enable_input(true, crate::private::Internal);
|
||||
sda.internal_pull_up(true, crate::private::Internal);
|
||||
sda.connect_peripheral_to_output(
|
||||
i2c.peripheral.sda_output_signal(),
|
||||
crate::private::Internal,
|
||||
);
|
||||
sda.pull_direction(Pull::Up, crate::private::Internal);
|
||||
|
||||
sda.connect_input_to_peripheral(
|
||||
i2c.peripheral.sda_input_signal(),
|
||||
crate::private::Internal,
|
||||
);
|
||||
sda.connect_peripheral_to_output(
|
||||
i2c.peripheral.sda_output_signal(),
|
||||
crate::private::Internal,
|
||||
);
|
||||
|
||||
i2c.peripheral.setup(frequency, timeout);
|
||||
i2c
|
||||
@ -396,7 +401,7 @@ where
|
||||
/// 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<SDA: OutputPin + InputPin, SCL: OutputPin + InputPin>(
|
||||
pub fn new<SDA: PeripheralOutput + PeripheralInput, SCL: PeripheralOutput + PeripheralInput>(
|
||||
i2c: impl Peripheral<P = T> + 'd,
|
||||
sda: impl Peripheral<P = SDA> + 'd,
|
||||
scl: impl Peripheral<P = SCL> + 'd,
|
||||
@ -408,7 +413,10 @@ where
|
||||
/// Create a new I2C instance with a custom timeout value.
|
||||
/// This will enable the peripheral but the peripheral won't get
|
||||
/// automatically disabled when this gets dropped.
|
||||
pub fn new_with_timeout<SDA: OutputPin + InputPin, SCL: OutputPin + InputPin>(
|
||||
pub fn new_with_timeout<
|
||||
SDA: PeripheralOutput + PeripheralInput,
|
||||
SCL: PeripheralOutput + PeripheralInput,
|
||||
>(
|
||||
i2c: impl Peripheral<P = T> + 'd,
|
||||
sda: impl Peripheral<P = SDA> + 'd,
|
||||
scl: impl Peripheral<P = SCL> + 'd,
|
||||
@ -437,7 +445,10 @@ where
|
||||
/// 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_async<SDA: OutputPin + InputPin, SCL: OutputPin + InputPin>(
|
||||
pub fn new_async<
|
||||
SDA: PeripheralOutput + PeripheralInput,
|
||||
SCL: PeripheralOutput + PeripheralInput,
|
||||
>(
|
||||
i2c: impl Peripheral<P = T> + 'd,
|
||||
sda: impl Peripheral<P = SDA> + 'd,
|
||||
scl: impl Peripheral<P = SCL> + 'd,
|
||||
@ -449,7 +460,10 @@ where
|
||||
/// Create a new I2C instance with a custom timeout value.
|
||||
/// This will enable the peripheral but the peripheral won't get
|
||||
/// automatically disabled when this gets dropped.
|
||||
pub fn new_with_timeout_async<SDA: OutputPin + InputPin, SCL: OutputPin + InputPin>(
|
||||
pub fn new_with_timeout_async<
|
||||
SDA: PeripheralOutput + PeripheralInput,
|
||||
SCL: PeripheralOutput + PeripheralInput,
|
||||
>(
|
||||
i2c: impl Peripheral<P = T> + 'd,
|
||||
sda: impl Peripheral<P = SDA> + 'd,
|
||||
scl: impl Peripheral<P = SCL> + 'd,
|
||||
|
@ -107,7 +107,7 @@ use crate::{
|
||||
TxPrivate,
|
||||
WriteBuffer,
|
||||
},
|
||||
gpio::OutputPin,
|
||||
gpio::PeripheralOutput,
|
||||
interrupt::InterruptHandler,
|
||||
into_ref,
|
||||
peripheral::Peripheral,
|
||||
@ -495,10 +495,11 @@ where
|
||||
}
|
||||
|
||||
/// Configures the I2S peripheral to use a master clock (MCLK) output pin.
|
||||
pub fn with_mclk<P: OutputPin>(self, pin: impl Peripheral<P = P> + 'd) -> Self {
|
||||
pub fn with_mclk<P: PeripheralOutput>(self, pin: impl Peripheral<P = P> + 'd) -> Self {
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(I::mclk_signal(), crate::private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -890,7 +891,7 @@ mod private {
|
||||
use crate::peripherals::{i2s1::RegisterBlock, I2S1};
|
||||
use crate::{
|
||||
dma::{ChannelRx, ChannelTx, DmaChannel, DmaDescriptor, DmaPeripheral},
|
||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
||||
gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput},
|
||||
interrupt::InterruptHandler,
|
||||
into_ref,
|
||||
peripherals::I2S0,
|
||||
@ -923,31 +924,34 @@ mod private {
|
||||
|
||||
pub fn with_bclk<P>(self, pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
pin.connect_peripheral_to_output(T::bclk_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_ws<P>(self, pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
pin.connect_peripheral_to_output(T::ws_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_dout<P>(self, pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
pin.connect_peripheral_to_output(T::dout_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -976,31 +980,34 @@ mod private {
|
||||
|
||||
pub fn with_bclk<P>(self, pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(T::bclk_rx_signal(), crate::private::Internal);
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
pin.connect_peripheral_to_output(T::bclk_rx_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_ws<P>(self, pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(T::ws_rx_signal(), crate::private::Internal);
|
||||
pin.set_to_push_pull_output(private::Internal);
|
||||
pin.connect_peripheral_to_output(T::ws_rx_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_din<P>(self, pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
|
||||
where
|
||||
P: InputPin,
|
||||
P: PeripheralInput,
|
||||
{
|
||||
into_ref!(pin);
|
||||
pin.init_input(false, false, crate::private::Internal);
|
||||
pin.connect_input_to_peripheral(T::din_signal(), crate::private::Internal);
|
||||
pin.init_input(crate::gpio::Pull::None, private::Internal);
|
||||
pin.connect_input_to_peripheral(T::din_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ use crate::{
|
||||
RxPrivate,
|
||||
WriteBuffer,
|
||||
},
|
||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal, Pull},
|
||||
lcd_cam::{cam::private::RxPins, private::calculate_clkm, BitOrder, ByteOrder},
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::LCD_CAM,
|
||||
@ -311,7 +311,7 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> {
|
||||
pub fn with_pixel_clock<PCLK: InputPin>(self, pclk: impl Peripheral<P = PCLK> + 'd) -> Self {
|
||||
crate::into_ref!(pclk);
|
||||
|
||||
pclk.init_input(false, false, crate::private::Internal);
|
||||
pclk.init_input(Pull::None, crate::private::Internal);
|
||||
pclk.connect_input_to_peripheral(InputSignal::CAM_PCLK, crate::private::Internal);
|
||||
|
||||
self
|
||||
@ -327,9 +327,9 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> {
|
||||
crate::into_ref!(vsync);
|
||||
crate::into_ref!(h_enable);
|
||||
|
||||
vsync.init_input(false, false, crate::private::Internal);
|
||||
vsync.init_input(Pull::None, crate::private::Internal);
|
||||
vsync.connect_input_to_peripheral(InputSignal::CAM_V_SYNC, crate::private::Internal);
|
||||
h_enable.init_input(false, false, crate::private::Internal);
|
||||
h_enable.init_input(Pull::None, crate::private::Internal);
|
||||
h_enable.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE, crate::private::Internal);
|
||||
|
||||
self.lcd_cam
|
||||
@ -351,11 +351,11 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> {
|
||||
crate::into_ref!(hsync);
|
||||
crate::into_ref!(h_enable);
|
||||
|
||||
vsync.init_input(false, false, crate::private::Internal);
|
||||
vsync.init_input(Pull::None, crate::private::Internal);
|
||||
vsync.connect_input_to_peripheral(InputSignal::CAM_V_SYNC, crate::private::Internal);
|
||||
hsync.init_input(false, false, crate::private::Internal);
|
||||
hsync.init_input(Pull::None, crate::private::Internal);
|
||||
hsync.connect_input_to_peripheral(InputSignal::CAM_H_SYNC, crate::private::Internal);
|
||||
h_enable.init_input(false, false, crate::private::Internal);
|
||||
h_enable.init_input(Pull::None, crate::private::Internal);
|
||||
h_enable.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE, crate::private::Internal);
|
||||
|
||||
self.lcd_cam
|
||||
@ -475,21 +475,21 @@ impl RxEightBits {
|
||||
crate::into_ref!(pin_6);
|
||||
crate::into_ref!(pin_7);
|
||||
|
||||
pin_0.init_input(false, false, crate::private::Internal);
|
||||
pin_0.init_input(Pull::None, crate::private::Internal);
|
||||
pin_0.connect_input_to_peripheral(InputSignal::CAM_DATA_0, crate::private::Internal);
|
||||
pin_1.init_input(false, false, crate::private::Internal);
|
||||
pin_1.init_input(Pull::None, crate::private::Internal);
|
||||
pin_1.connect_input_to_peripheral(InputSignal::CAM_DATA_1, crate::private::Internal);
|
||||
pin_2.init_input(false, false, crate::private::Internal);
|
||||
pin_2.init_input(Pull::None, crate::private::Internal);
|
||||
pin_2.connect_input_to_peripheral(InputSignal::CAM_DATA_2, crate::private::Internal);
|
||||
pin_3.init_input(false, false, crate::private::Internal);
|
||||
pin_3.init_input(Pull::None, crate::private::Internal);
|
||||
pin_3.connect_input_to_peripheral(InputSignal::CAM_DATA_3, crate::private::Internal);
|
||||
pin_4.init_input(false, false, crate::private::Internal);
|
||||
pin_4.init_input(Pull::None, crate::private::Internal);
|
||||
pin_4.connect_input_to_peripheral(InputSignal::CAM_DATA_4, crate::private::Internal);
|
||||
pin_5.init_input(false, false, crate::private::Internal);
|
||||
pin_5.init_input(Pull::None, crate::private::Internal);
|
||||
pin_5.connect_input_to_peripheral(InputSignal::CAM_DATA_5, crate::private::Internal);
|
||||
pin_6.init_input(false, false, crate::private::Internal);
|
||||
pin_6.init_input(Pull::None, crate::private::Internal);
|
||||
pin_6.connect_input_to_peripheral(InputSignal::CAM_DATA_6, crate::private::Internal);
|
||||
pin_7.init_input(false, false, crate::private::Internal);
|
||||
pin_7.init_input(Pull::None, crate::private::Internal);
|
||||
pin_7.connect_input_to_peripheral(InputSignal::CAM_DATA_7, crate::private::Internal);
|
||||
|
||||
Self { _pins: () }
|
||||
@ -563,37 +563,37 @@ impl RxSixteenBits {
|
||||
crate::into_ref!(pin_14);
|
||||
crate::into_ref!(pin_15);
|
||||
|
||||
pin_0.init_input(false, false, crate::private::Internal);
|
||||
pin_0.init_input(Pull::None, crate::private::Internal);
|
||||
pin_0.connect_input_to_peripheral(InputSignal::CAM_DATA_0, crate::private::Internal);
|
||||
pin_1.init_input(false, false, crate::private::Internal);
|
||||
pin_1.init_input(Pull::None, crate::private::Internal);
|
||||
pin_1.connect_input_to_peripheral(InputSignal::CAM_DATA_1, crate::private::Internal);
|
||||
pin_2.init_input(false, false, crate::private::Internal);
|
||||
pin_2.init_input(Pull::None, crate::private::Internal);
|
||||
pin_2.connect_input_to_peripheral(InputSignal::CAM_DATA_2, crate::private::Internal);
|
||||
pin_3.init_input(false, false, crate::private::Internal);
|
||||
pin_3.init_input(Pull::None, crate::private::Internal);
|
||||
pin_3.connect_input_to_peripheral(InputSignal::CAM_DATA_3, crate::private::Internal);
|
||||
pin_4.init_input(false, false, crate::private::Internal);
|
||||
pin_4.init_input(Pull::None, crate::private::Internal);
|
||||
pin_4.connect_input_to_peripheral(InputSignal::CAM_DATA_4, crate::private::Internal);
|
||||
pin_5.init_input(false, false, crate::private::Internal);
|
||||
pin_5.init_input(Pull::None, crate::private::Internal);
|
||||
pin_5.connect_input_to_peripheral(InputSignal::CAM_DATA_5, crate::private::Internal);
|
||||
pin_6.init_input(false, false, crate::private::Internal);
|
||||
pin_6.init_input(Pull::None, crate::private::Internal);
|
||||
pin_6.connect_input_to_peripheral(InputSignal::CAM_DATA_6, crate::private::Internal);
|
||||
pin_7.init_input(false, false, crate::private::Internal);
|
||||
pin_7.init_input(Pull::None, crate::private::Internal);
|
||||
pin_7.connect_input_to_peripheral(InputSignal::CAM_DATA_7, crate::private::Internal);
|
||||
pin_8.init_input(false, false, crate::private::Internal);
|
||||
pin_8.init_input(Pull::None, crate::private::Internal);
|
||||
pin_8.connect_input_to_peripheral(InputSignal::CAM_DATA_8, crate::private::Internal);
|
||||
pin_9.init_input(false, false, crate::private::Internal);
|
||||
pin_9.init_input(Pull::None, crate::private::Internal);
|
||||
pin_9.connect_input_to_peripheral(InputSignal::CAM_DATA_9, crate::private::Internal);
|
||||
pin_10.init_input(false, false, crate::private::Internal);
|
||||
pin_10.init_input(Pull::None, crate::private::Internal);
|
||||
pin_10.connect_input_to_peripheral(InputSignal::CAM_DATA_10, crate::private::Internal);
|
||||
pin_11.init_input(false, false, crate::private::Internal);
|
||||
pin_11.init_input(Pull::None, crate::private::Internal);
|
||||
pin_11.connect_input_to_peripheral(InputSignal::CAM_DATA_11, crate::private::Internal);
|
||||
pin_12.init_input(false, false, crate::private::Internal);
|
||||
pin_12.init_input(Pull::None, crate::private::Internal);
|
||||
pin_12.connect_input_to_peripheral(InputSignal::CAM_DATA_12, crate::private::Internal);
|
||||
pin_13.init_input(false, false, crate::private::Internal);
|
||||
pin_13.init_input(Pull::None, crate::private::Internal);
|
||||
pin_13.connect_input_to_peripheral(InputSignal::CAM_DATA_13, crate::private::Internal);
|
||||
pin_14.init_input(false, false, crate::private::Internal);
|
||||
pin_14.init_input(Pull::None, crate::private::Internal);
|
||||
pin_14.connect_input_to_peripheral(InputSignal::CAM_DATA_14, crate::private::Internal);
|
||||
pin_15.init_input(false, false, crate::private::Internal);
|
||||
pin_15.init_input(Pull::None, crate::private::Internal);
|
||||
pin_15.connect_input_to_peripheral(InputSignal::CAM_DATA_15, crate::private::Internal);
|
||||
|
||||
Self { _pins: () }
|
||||
|
@ -76,7 +76,7 @@ use crate::{
|
||||
ReadBuffer,
|
||||
TxPrivate,
|
||||
},
|
||||
gpio::{OutputPin, OutputSignal},
|
||||
gpio::{OutputSignal, PeripheralOutput},
|
||||
lcd_cam::{
|
||||
asynch::LcdDoneFuture,
|
||||
lcd::{i8080::private::TxPins, ClockMode, DelayMode, Phase, Polarity},
|
||||
@ -309,7 +309,7 @@ where
|
||||
}
|
||||
|
||||
/// Associates a CS pin with the I8080 interface.
|
||||
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||
pub fn with_cs<CS: PeripheralOutput>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output(crate::private::Internal);
|
||||
cs.connect_peripheral_to_output(OutputSignal::LCD_CS, crate::private::Internal);
|
||||
@ -318,7 +318,7 @@ where
|
||||
}
|
||||
|
||||
/// Configures the control pins for the I8080 interface.
|
||||
pub fn with_ctrl_pins<DC: OutputPin, WRX: OutputPin>(
|
||||
pub fn with_ctrl_pins<DC: PeripheralOutput, WRX: PeripheralOutput>(
|
||||
self,
|
||||
dc: impl Peripheral<P = DC> + 'd,
|
||||
wrx: impl Peripheral<P = WRX> + 'd,
|
||||
@ -593,14 +593,14 @@ pub struct TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7> {
|
||||
|
||||
impl<'d, P0, P1, P2, P3, P4, P5, P6, P7> TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7>
|
||||
where
|
||||
P0: OutputPin,
|
||||
P1: OutputPin,
|
||||
P2: OutputPin,
|
||||
P3: OutputPin,
|
||||
P4: OutputPin,
|
||||
P5: OutputPin,
|
||||
P6: OutputPin,
|
||||
P7: OutputPin,
|
||||
P0: PeripheralOutput,
|
||||
P1: PeripheralOutput,
|
||||
P2: PeripheralOutput,
|
||||
P3: PeripheralOutput,
|
||||
P4: PeripheralOutput,
|
||||
P5: PeripheralOutput,
|
||||
P6: PeripheralOutput,
|
||||
P7: PeripheralOutput,
|
||||
{
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
/// Creates a new `TxEightBits` instance with the provided output pins.
|
||||
@ -638,14 +638,14 @@ where
|
||||
|
||||
impl<'d, P0, P1, P2, P3, P4, P5, P6, P7> TxPins for TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7>
|
||||
where
|
||||
P0: OutputPin,
|
||||
P1: OutputPin,
|
||||
P2: OutputPin,
|
||||
P3: OutputPin,
|
||||
P4: OutputPin,
|
||||
P5: OutputPin,
|
||||
P6: OutputPin,
|
||||
P7: OutputPin,
|
||||
P0: PeripheralOutput,
|
||||
P1: PeripheralOutput,
|
||||
P2: PeripheralOutput,
|
||||
P3: PeripheralOutput,
|
||||
P4: PeripheralOutput,
|
||||
P5: PeripheralOutput,
|
||||
P6: PeripheralOutput,
|
||||
P7: PeripheralOutput,
|
||||
{
|
||||
type Word = u8;
|
||||
|
||||
@ -701,22 +701,22 @@ pub struct TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P
|
||||
impl<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15>
|
||||
TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15>
|
||||
where
|
||||
P0: OutputPin,
|
||||
P1: OutputPin,
|
||||
P2: OutputPin,
|
||||
P3: OutputPin,
|
||||
P4: OutputPin,
|
||||
P5: OutputPin,
|
||||
P6: OutputPin,
|
||||
P7: OutputPin,
|
||||
P8: OutputPin,
|
||||
P9: OutputPin,
|
||||
P10: OutputPin,
|
||||
P11: OutputPin,
|
||||
P12: OutputPin,
|
||||
P13: OutputPin,
|
||||
P14: OutputPin,
|
||||
P15: OutputPin,
|
||||
P0: PeripheralOutput,
|
||||
P1: PeripheralOutput,
|
||||
P2: PeripheralOutput,
|
||||
P3: PeripheralOutput,
|
||||
P4: PeripheralOutput,
|
||||
P5: PeripheralOutput,
|
||||
P6: PeripheralOutput,
|
||||
P7: PeripheralOutput,
|
||||
P8: PeripheralOutput,
|
||||
P9: PeripheralOutput,
|
||||
P10: PeripheralOutput,
|
||||
P11: PeripheralOutput,
|
||||
P12: PeripheralOutput,
|
||||
P13: PeripheralOutput,
|
||||
P14: PeripheralOutput,
|
||||
P15: PeripheralOutput,
|
||||
{
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
/// Creates a new `TxSixteenBits` instance with the provided output pins.
|
||||
@ -779,22 +779,22 @@ where
|
||||
impl<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> TxPins
|
||||
for TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15>
|
||||
where
|
||||
P0: OutputPin,
|
||||
P1: OutputPin,
|
||||
P2: OutputPin,
|
||||
P3: OutputPin,
|
||||
P4: OutputPin,
|
||||
P5: OutputPin,
|
||||
P6: OutputPin,
|
||||
P7: OutputPin,
|
||||
P8: OutputPin,
|
||||
P9: OutputPin,
|
||||
P10: OutputPin,
|
||||
P11: OutputPin,
|
||||
P12: OutputPin,
|
||||
P13: OutputPin,
|
||||
P14: OutputPin,
|
||||
P15: OutputPin,
|
||||
P0: PeripheralOutput,
|
||||
P1: PeripheralOutput,
|
||||
P2: PeripheralOutput,
|
||||
P3: PeripheralOutput,
|
||||
P4: PeripheralOutput,
|
||||
P5: PeripheralOutput,
|
||||
P6: PeripheralOutput,
|
||||
P7: PeripheralOutput,
|
||||
P8: PeripheralOutput,
|
||||
P9: PeripheralOutput,
|
||||
P10: PeripheralOutput,
|
||||
P11: PeripheralOutput,
|
||||
P12: PeripheralOutput,
|
||||
P13: PeripheralOutput,
|
||||
P14: PeripheralOutput,
|
||||
P15: PeripheralOutput,
|
||||
{
|
||||
type Word = u16;
|
||||
fn configure(&mut self) {
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
use super::timer::{TimerIFace, TimerSpeed};
|
||||
use crate::{
|
||||
gpio::{OutputPin, OutputSignal},
|
||||
gpio::{OutputSignal, PeripheralOutput},
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::ledc::RegisterBlock,
|
||||
};
|
||||
@ -95,7 +95,7 @@ pub mod config {
|
||||
}
|
||||
|
||||
/// Channel interface
|
||||
pub trait ChannelIFace<'a, S: TimerSpeed + 'a, O: OutputPin + 'a>
|
||||
pub trait ChannelIFace<'a, S: TimerSpeed + 'a, O: PeripheralOutput + 'a>
|
||||
where
|
||||
Channel<'a, S, O>: ChannelHW<O>,
|
||||
{
|
||||
@ -118,7 +118,7 @@ where
|
||||
}
|
||||
|
||||
/// Channel HW interface
|
||||
pub trait ChannelHW<O: OutputPin> {
|
||||
pub trait ChannelHW<O: PeripheralOutput> {
|
||||
/// Configure Channel HW except for the duty which is set via
|
||||
/// [`Self::set_duty_hw`].
|
||||
fn configure_hw(&mut self) -> Result<(), Error>;
|
||||
@ -144,14 +144,14 @@ pub trait ChannelHW<O: OutputPin> {
|
||||
}
|
||||
|
||||
/// Channel struct
|
||||
pub struct Channel<'a, S: TimerSpeed, O: OutputPin> {
|
||||
pub struct Channel<'a, S: TimerSpeed, O: PeripheralOutput> {
|
||||
ledc: &'a RegisterBlock,
|
||||
timer: Option<&'a dyn TimerIFace<S>>,
|
||||
number: Number,
|
||||
output_pin: PeripheralRef<'a, O>,
|
||||
}
|
||||
|
||||
impl<'a, S: TimerSpeed, O: OutputPin> Channel<'a, S, O> {
|
||||
impl<'a, S: TimerSpeed, O: PeripheralOutput> Channel<'a, S, O> {
|
||||
/// Return a new channel
|
||||
pub fn new(number: Number, output_pin: impl Peripheral<P = O> + 'a) -> Self {
|
||||
crate::into_ref!(output_pin);
|
||||
@ -165,7 +165,7 @@ impl<'a, S: TimerSpeed, O: OutputPin> Channel<'a, S, O> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: TimerSpeed, O: OutputPin> ChannelIFace<'a, S, O> for Channel<'a, S, O>
|
||||
impl<'a, S: TimerSpeed, O: PeripheralOutput> ChannelIFace<'a, S, O> for Channel<'a, S, O>
|
||||
where
|
||||
Channel<'a, S, O>: ChannelHW<O>,
|
||||
{
|
||||
@ -337,7 +337,7 @@ mod ehal1 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, O: OutputPin, S: crate::ledc::timer::TimerSpeed> Channel<'a, S, O> {
|
||||
impl<'a, O: PeripheralOutput, S: crate::ledc::timer::TimerSpeed> Channel<'a, S, O> {
|
||||
#[cfg(esp32)]
|
||||
fn set_channel(&mut self, timer_number: u8) {
|
||||
if S::IS_HS {
|
||||
@ -537,7 +537,7 @@ impl<'a, O: OutputPin, S: crate::ledc::timer::TimerSpeed> Channel<'a, S, O> {
|
||||
|
||||
impl<'a, O, S> ChannelHW<O> for Channel<'a, S, O>
|
||||
where
|
||||
O: OutputPin,
|
||||
O: PeripheralOutput,
|
||||
S: crate::ledc::timer::TimerSpeed,
|
||||
{
|
||||
/// Configure Channel HW
|
||||
@ -604,6 +604,7 @@ where
|
||||
#[cfg(not(any(esp32c2, esp32c3, esp32c6, esp32h2)))]
|
||||
Number::Channel7 => OutputSignal::LEDC_LS_SIG7,
|
||||
};
|
||||
|
||||
self.output_pin
|
||||
.connect_peripheral_to_output(signal, crate::private::Internal);
|
||||
} else {
|
||||
|
@ -12,7 +12,7 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
gpio::OutputPin,
|
||||
gpio::PeripheralOutput,
|
||||
mcpwm::{timer::Timer, PwmPeripheral},
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
private,
|
||||
@ -204,7 +204,7 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
||||
}
|
||||
|
||||
/// Use the A output with the given pin and configuration
|
||||
pub fn with_pin_a<'d, Pin: OutputPin>(
|
||||
pub fn with_pin_a<'d, Pin: PeripheralOutput>(
|
||||
self,
|
||||
pin: impl Peripheral<P = Pin> + 'd,
|
||||
config: PwmPinConfig<true>,
|
||||
@ -213,7 +213,7 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
||||
}
|
||||
|
||||
/// Use the B output with the given pin and configuration
|
||||
pub fn with_pin_b<'d, Pin: OutputPin>(
|
||||
pub fn with_pin_b<'d, Pin: PeripheralOutput>(
|
||||
self,
|
||||
pin: impl Peripheral<P = Pin> + 'd,
|
||||
config: PwmPinConfig<false>,
|
||||
@ -222,7 +222,7 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
||||
}
|
||||
|
||||
/// Use both the A and the B output with the given pins and configurations
|
||||
pub fn with_pins<'d, PinA: OutputPin, PinB: OutputPin>(
|
||||
pub fn with_pins<'d, PinA: PeripheralOutput, PinB: PeripheralOutput>(
|
||||
self,
|
||||
pin_a: impl Peripheral<P = PinA> + 'd,
|
||||
config_a: PwmPinConfig<true>,
|
||||
@ -239,7 +239,7 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
||||
///
|
||||
/// This is useful for complementary or mirrored signals with or without
|
||||
/// configured deadtime
|
||||
pub fn with_linked_pins<'d, PinA: OutputPin, PinB: OutputPin>(
|
||||
pub fn with_linked_pins<'d, PinA: PeripheralOutput, PinB: PeripheralOutput>(
|
||||
self,
|
||||
pin_a: impl Peripheral<P = PinA> + 'd,
|
||||
config_a: PwmPinConfig<true>,
|
||||
@ -288,7 +288,7 @@ pub struct PwmPin<'d, Pin, PWM, const OP: u8, const IS_A: bool> {
|
||||
phantom: PhantomData<PWM>,
|
||||
}
|
||||
|
||||
impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
impl<'d, Pin: PeripheralOutput, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
PwmPin<'d, Pin, PWM, OP, IS_A>
|
||||
{
|
||||
fn new(pin: impl Peripheral<P = Pin> + 'd, config: PwmPinConfig<IS_A>) -> Self {
|
||||
@ -304,6 +304,7 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
pin.pin
|
||||
.connect_peripheral_to_output(output_signal, private::Internal);
|
||||
pin.pin.enable_output(true, private::Internal);
|
||||
|
||||
pin
|
||||
}
|
||||
|
||||
@ -414,8 +415,8 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> embedded_hal_02::PwmPin
|
||||
for PwmPin<'d, Pin, PWM, OP, IS_A>
|
||||
impl<'d, Pin: PeripheralOutput, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
embedded_hal_02::PwmPin for PwmPin<'d, Pin, PWM, OP, IS_A>
|
||||
{
|
||||
type Duty = u16;
|
||||
|
||||
@ -448,14 +449,14 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> emb
|
||||
}
|
||||
|
||||
/// Implement no error type for the PwmPin because the method are infallible
|
||||
impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
impl<'d, Pin: PeripheralOutput, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
embedded_hal::pwm::ErrorType for PwmPin<'d, Pin, PWM, OP, IS_A>
|
||||
{
|
||||
type Error = core::convert::Infallible;
|
||||
}
|
||||
|
||||
/// Implement the trait SetDutyCycle for PwmPin
|
||||
impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
impl<'d, Pin: PeripheralOutput, PWM: PwmPeripheral, const OP: u8, const IS_A: bool>
|
||||
embedded_hal::pwm::SetDutyCycle for PwmPin<'d, Pin, PWM, OP, IS_A>
|
||||
{
|
||||
/// Get the max duty of the PwmPin
|
||||
@ -522,7 +523,7 @@ pub struct LinkedPins<'d, PinA, PinB, PWM, const OP: u8> {
|
||||
pin_b: PwmPin<'d, PinB, PWM, OP, false>,
|
||||
}
|
||||
|
||||
impl<'d, PinA: OutputPin, PinB: OutputPin, PWM: PwmPeripheral, const OP: u8>
|
||||
impl<'d, PinA: PeripheralOutput, PinB: PeripheralOutput, PWM: PwmPeripheral, const OP: u8>
|
||||
LinkedPins<'d, PinA, PinB, PWM, OP>
|
||||
{
|
||||
fn new(
|
||||
|
@ -43,6 +43,7 @@ use crate::{
|
||||
gpio::InputSignal,
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals,
|
||||
private::Internal,
|
||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
||||
};
|
||||
|
||||
@ -101,10 +102,12 @@ impl<'d> Usb<'d> {
|
||||
.modify(|_, w| w.sw_hw_usb_phy_sel().set_bit().sw_usb_phy_sel().set_bit());
|
||||
}
|
||||
|
||||
crate::gpio::connect_high_to_peripheral(InputSignal::USB_OTG_IDDIG); // connected connector is mini-B side
|
||||
crate::gpio::connect_high_to_peripheral(InputSignal::USB_SRP_BVALID); // HIGH to force USB device mode
|
||||
crate::gpio::connect_high_to_peripheral(InputSignal::USB_OTG_VBUSVALID); // receiving a valid Vbus from device
|
||||
crate::gpio::connect_low_to_peripheral(InputSignal::USB_OTG_AVALID);
|
||||
use crate::gpio::{Level, PeripheralInput};
|
||||
|
||||
Level::High.connect_input_to_peripheral(InputSignal::USB_OTG_IDDIG, Internal); // connected connector is mini-B side
|
||||
Level::High.connect_input_to_peripheral(InputSignal::USB_SRP_BVALID, Internal); // HIGH to force USB device mode
|
||||
Level::High.connect_input_to_peripheral(InputSignal::USB_OTG_VBUSVALID, Internal); // receiving a valid Vbus from device
|
||||
Level::Low.connect_input_to_peripheral(InputSignal::USB_OTG_AVALID, Internal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ use crate::{
|
||||
TxPrivate,
|
||||
WriteBuffer,
|
||||
},
|
||||
gpio::{InputPin, OutputPin},
|
||||
gpio::{PeripheralInput, PeripheralOutput},
|
||||
interrupt::InterruptHandler,
|
||||
peripheral::{self, Peripheral},
|
||||
peripherals,
|
||||
@ -279,13 +279,13 @@ pub fn no_clk_pin() -> &'static mut NoClkPin {
|
||||
/// Wraps a GPIO pin which will be used as the clock output signal
|
||||
pub struct ClkOutPin<'d, P>
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
{
|
||||
pin: PeripheralRef<'d, P>,
|
||||
}
|
||||
impl<'d, P> ClkOutPin<'d, P>
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
{
|
||||
/// Create a ClkOutPin
|
||||
pub fn new(pin: impl Peripheral<P = P> + 'd) -> Self {
|
||||
@ -295,7 +295,7 @@ where
|
||||
}
|
||||
impl<'d, P> TxClkPin for ClkOutPin<'d, P>
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
{
|
||||
fn configure(&mut self) {
|
||||
self.pin.set_to_push_pull_output(crate::private::Internal);
|
||||
@ -309,13 +309,13 @@ where
|
||||
/// Wraps a GPIO pin which will be used as the TX clock input signal
|
||||
pub struct ClkInPin<'d, P>
|
||||
where
|
||||
P: InputPin,
|
||||
P: PeripheralInput,
|
||||
{
|
||||
pin: PeripheralRef<'d, P>,
|
||||
}
|
||||
impl<'d, P> ClkInPin<'d, P>
|
||||
where
|
||||
P: InputPin,
|
||||
P: PeripheralInput,
|
||||
{
|
||||
/// Create a new ClkInPin
|
||||
pub fn new(pin: impl Peripheral<P = P> + 'd) -> Self {
|
||||
@ -325,14 +325,15 @@ where
|
||||
}
|
||||
impl<'d, P> TxClkPin for ClkInPin<'d, P>
|
||||
where
|
||||
P: InputPin,
|
||||
P: PeripheralInput,
|
||||
{
|
||||
fn configure(&mut self) {
|
||||
let pcr = unsafe { &*crate::peripherals::PCR::PTR };
|
||||
pcr.parl_clk_tx_conf()
|
||||
.modify(|_, w| unsafe { w.parl_clk_tx_sel().bits(3).parl_clk_tx_div_num().bits(0) }); // PAD_CLK_TX, no divider
|
||||
|
||||
self.pin.init_input(false, false, crate::private::Internal);
|
||||
self.pin
|
||||
.init_input(crate::gpio::Pull::None, crate::private::Internal);
|
||||
self.pin.connect_input_to_peripheral(
|
||||
crate::gpio::InputSignal::PARL_TX_CLK,
|
||||
crate::private::Internal,
|
||||
@ -343,14 +344,14 @@ where
|
||||
/// Wraps a GPIO pin which will be used as the RX clock input signal
|
||||
pub struct RxClkInPin<'d, P>
|
||||
where
|
||||
P: InputPin,
|
||||
P: PeripheralInput,
|
||||
{
|
||||
pin: PeripheralRef<'d, P>,
|
||||
sample_edge: SampleEdge,
|
||||
}
|
||||
impl<'d, P> RxClkInPin<'d, P>
|
||||
where
|
||||
P: InputPin,
|
||||
P: PeripheralInput,
|
||||
{
|
||||
/// Create a new RxClkInPin
|
||||
pub fn new(pin: impl Peripheral<P = P> + 'd, sample_edge: SampleEdge) -> Self {
|
||||
@ -360,14 +361,15 @@ where
|
||||
}
|
||||
impl<'d, P> RxClkPin for RxClkInPin<'d, P>
|
||||
where
|
||||
P: InputPin,
|
||||
P: PeripheralInput,
|
||||
{
|
||||
fn configure(&mut self) {
|
||||
let pcr = unsafe { &*crate::peripherals::PCR::PTR };
|
||||
pcr.parl_clk_rx_conf()
|
||||
.modify(|_, w| unsafe { w.parl_clk_rx_sel().bits(3).parl_clk_rx_div_num().bits(0) }); // PAD_CLK_TX, no divider
|
||||
|
||||
self.pin.init_input(false, false, crate::private::Internal);
|
||||
self.pin
|
||||
.init_input(crate::gpio::Pull::None, crate::private::Internal);
|
||||
self.pin.connect_input_to_peripheral(
|
||||
crate::gpio::InputSignal::PARL_RX_CLK,
|
||||
crate::private::Internal,
|
||||
@ -381,7 +383,7 @@ where
|
||||
pub struct TxPinConfigWithValidPin<'d, P, VP>
|
||||
where
|
||||
P: NotContainsValidSignalPin + TxPins + ConfigurePins,
|
||||
VP: OutputPin,
|
||||
VP: PeripheralOutput,
|
||||
{
|
||||
tx_pins: P,
|
||||
valid_pin: PeripheralRef<'d, VP>,
|
||||
@ -390,7 +392,7 @@ where
|
||||
impl<'d, P, VP> TxPinConfigWithValidPin<'d, P, VP>
|
||||
where
|
||||
P: NotContainsValidSignalPin + TxPins + ConfigurePins,
|
||||
VP: OutputPin,
|
||||
VP: PeripheralOutput,
|
||||
{
|
||||
/// Create a [TxPinConfigWithValidPin]
|
||||
pub fn new(tx_pins: P, valid_pin: impl Peripheral<P = VP> + 'd) -> Self {
|
||||
@ -402,14 +404,14 @@ where
|
||||
impl<'d, P, VP> TxPins for TxPinConfigWithValidPin<'d, P, VP>
|
||||
where
|
||||
P: NotContainsValidSignalPin + TxPins + ConfigurePins,
|
||||
VP: OutputPin,
|
||||
VP: PeripheralOutput,
|
||||
{
|
||||
}
|
||||
|
||||
impl<'d, P, VP> ConfigurePins for TxPinConfigWithValidPin<'d, P, VP>
|
||||
where
|
||||
P: NotContainsValidSignalPin + TxPins + ConfigurePins,
|
||||
VP: OutputPin,
|
||||
VP: PeripheralOutput,
|
||||
{
|
||||
fn configure(&mut self) -> Result<(), Error> {
|
||||
self.tx_pins.configure()?;
|
||||
@ -472,7 +474,7 @@ macro_rules! tx_pins {
|
||||
|
||||
impl<'d, $($pin),+> $name<'d, $($pin),+>
|
||||
where
|
||||
$($pin: OutputPin),+
|
||||
$($pin: PeripheralOutput),+
|
||||
{
|
||||
/// Create a new TX pin
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@ -488,7 +490,7 @@ macro_rules! tx_pins {
|
||||
|
||||
impl<'d, $($pin),+> ConfigurePins for $name<'d, $($pin),+>
|
||||
where
|
||||
$($pin: OutputPin),+
|
||||
$($pin: PeripheralOutput),+
|
||||
{
|
||||
fn configure(&mut self) -> Result<(), Error>{
|
||||
$(
|
||||
@ -590,7 +592,7 @@ impl<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15>
|
||||
pub struct RxPinConfigWithValidPin<'d, P, VP>
|
||||
where
|
||||
P: NotContainsValidSignalPin + RxPins + ConfigurePins,
|
||||
VP: InputPin,
|
||||
VP: PeripheralInput,
|
||||
{
|
||||
rx_pins: P,
|
||||
valid_pin: PeripheralRef<'d, VP>,
|
||||
@ -601,7 +603,7 @@ where
|
||||
impl<'d, P, VP> RxPinConfigWithValidPin<'d, P, VP>
|
||||
where
|
||||
P: NotContainsValidSignalPin + RxPins + ConfigurePins,
|
||||
VP: InputPin,
|
||||
VP: PeripheralInput,
|
||||
{
|
||||
/// Create a new [RxPinConfigWithValidPin]
|
||||
pub fn new(
|
||||
@ -623,19 +625,19 @@ where
|
||||
impl<'d, P, VP> RxPins for RxPinConfigWithValidPin<'d, P, VP>
|
||||
where
|
||||
P: NotContainsValidSignalPin + RxPins + ConfigurePins,
|
||||
VP: InputPin,
|
||||
VP: PeripheralInput,
|
||||
{
|
||||
}
|
||||
|
||||
impl<'d, P, VP> ConfigurePins for RxPinConfigWithValidPin<'d, P, VP>
|
||||
where
|
||||
P: NotContainsValidSignalPin + RxPins + ConfigurePins,
|
||||
VP: InputPin,
|
||||
VP: PeripheralInput,
|
||||
{
|
||||
fn configure(&mut self) -> Result<(), Error> {
|
||||
self.rx_pins.configure()?;
|
||||
self.valid_pin
|
||||
.init_input(false, false, crate::private::Internal);
|
||||
.init_input(crate::gpio::Pull::None, crate::private::Internal);
|
||||
self.valid_pin
|
||||
.connect_input_to_peripheral(Instance::rx_valid_pin_signal(), crate::private::Internal);
|
||||
Instance::set_rx_sw_en(false);
|
||||
@ -719,7 +721,7 @@ macro_rules! rx_pins {
|
||||
|
||||
impl<'d, $($pin),+> $name<'d, $($pin),+>
|
||||
where
|
||||
$($pin: InputPin),+
|
||||
$($pin: PeripheralInput),+
|
||||
{
|
||||
/// Create a new RX pin
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
@ -735,12 +737,12 @@ macro_rules! rx_pins {
|
||||
|
||||
impl<'d, $($pin),+> ConfigurePins for $name<'d, $($pin),+>
|
||||
where
|
||||
$($pin: InputPin),+
|
||||
$($pin: PeripheralInput),+
|
||||
{
|
||||
fn configure(&mut self) -> Result<(), Error> {
|
||||
$(
|
||||
self.[< pin_ $pin:lower >].init_input(false, false, $crate::private::Internal);
|
||||
self.[< pin_ $pin:lower >].connect_input_to_peripheral(crate::gpio::InputSignal::$signal, $crate::private::Internal);
|
||||
self.[< pin_ $pin:lower >].init_input(crate::gpio::Pull::None, crate::private::Internal);
|
||||
self.[< pin_ $pin:lower >].connect_input_to_peripheral(crate::gpio::InputSignal::$signal, crate::private::Internal);
|
||||
)+
|
||||
|
||||
private::Instance::set_rx_bit_width( private::WidSel::[< Bits $width >]);
|
||||
|
@ -9,11 +9,7 @@
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::{
|
||||
gpio::{InputPin, InputSignal, Pull, ONE_INPUT, ZERO_INPUT},
|
||||
peripheral::Peripheral,
|
||||
peripherals::GPIO,
|
||||
};
|
||||
use crate::gpio::{interconnect::AnyInputSignal, InputSignal, PeripheralInput, Pull};
|
||||
|
||||
/// Configuration for an PCNT input pin
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@ -32,55 +28,19 @@ impl Default for PcntInputConfig {
|
||||
pub use crate::peripherals::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE as EdgeMode};
|
||||
|
||||
/// PcntPin can be always high, always low, or an actual pin
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone)]
|
||||
pub struct PcntSource {
|
||||
source: u8,
|
||||
inverted: bool,
|
||||
source: AnyInputSignal,
|
||||
}
|
||||
|
||||
impl PcntSource {
|
||||
/// Creates a `PcntSource` from an input pin with the specified
|
||||
/// configuration.
|
||||
pub fn from_pin<'a, P: InputPin>(
|
||||
pin: impl Peripheral<P = P> + 'a,
|
||||
pin_config: PcntInputConfig,
|
||||
) -> Self {
|
||||
crate::into_ref!(pin);
|
||||
pub fn from(source: impl Into<AnyInputSignal>, pin_config: PcntInputConfig) -> Self {
|
||||
let source = source.into();
|
||||
source.init_input(pin_config.pull, crate::private::Internal);
|
||||
|
||||
pin.init_input(
|
||||
pin_config.pull == Pull::Down,
|
||||
pin_config.pull == Pull::Up,
|
||||
crate::private::Internal,
|
||||
);
|
||||
|
||||
Self {
|
||||
source: pin.number(crate::private::Internal),
|
||||
inverted: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a `PcntSource` that is always high.
|
||||
pub fn always_high() -> Self {
|
||||
Self {
|
||||
source: ONE_INPUT,
|
||||
inverted: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a `PcntSource` that is always low.
|
||||
pub fn always_low() -> Self {
|
||||
Self {
|
||||
source: ZERO_INPUT,
|
||||
inverted: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Inverts the `PcntSource` signal.
|
||||
pub fn invert(self) -> Self {
|
||||
Self {
|
||||
source: self.source,
|
||||
inverted: !self.inverted,
|
||||
}
|
||||
Self { source }
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,7 +95,7 @@ impl<'d, const UNIT: usize, const NUM: usize> Channel<'d, UNIT, NUM> {
|
||||
}
|
||||
|
||||
/// Set the control signal (pin/high/low) for this channel
|
||||
pub fn set_ctrl_signal(&self, source: PcntSource) -> &Self {
|
||||
pub fn set_ctrl_signal(&self, mut source: PcntSource) -> &Self {
|
||||
let signal = match UNIT {
|
||||
0 => match NUM {
|
||||
0 => InputSignal::PCNT0_CTRL_CH0,
|
||||
@ -185,19 +145,15 @@ impl<'d, const UNIT: usize, const NUM: usize> Channel<'d, UNIT, NUM> {
|
||||
};
|
||||
|
||||
if (signal as usize) <= crate::gpio::INPUT_SIGNAL_MAX as usize {
|
||||
unsafe { &*GPIO::PTR }
|
||||
.func_in_sel_cfg(signal as usize)
|
||||
.modify(|_, w| unsafe {
|
||||
w.sel().set_bit();
|
||||
w.in_inv_sel().bit(source.inverted);
|
||||
w.in_sel().bits(source.source)
|
||||
});
|
||||
source
|
||||
.source
|
||||
.connect_input_to_peripheral(signal, crate::private::Internal);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the edge signal (pin/high/low) for this channel
|
||||
pub fn set_edge_signal(&self, source: PcntSource) -> &Self {
|
||||
pub fn set_edge_signal(&self, mut source: PcntSource) -> &Self {
|
||||
let signal = match UNIT {
|
||||
0 => match NUM {
|
||||
0 => InputSignal::PCNT0_SIG_CH0,
|
||||
@ -247,13 +203,9 @@ impl<'d, const UNIT: usize, const NUM: usize> Channel<'d, UNIT, NUM> {
|
||||
};
|
||||
|
||||
if (signal as usize) <= crate::gpio::INPUT_SIGNAL_MAX as usize {
|
||||
unsafe { &*GPIO::PTR }
|
||||
.func_in_sel_cfg(signal as usize)
|
||||
.modify(|_, w| unsafe {
|
||||
w.sel().set_bit();
|
||||
w.in_inv_sel().bit(source.inverted);
|
||||
w.in_sel().bits(source.source)
|
||||
});
|
||||
source
|
||||
.source
|
||||
.connect_input_to_peripheral(signal, crate::private::Internal);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ use core::{
|
||||
/// dedicated struct is memory efficiency:
|
||||
///
|
||||
/// Peripheral singletons are typically either zero-sized (for concrete
|
||||
/// peripherals like `PA9` or `Spi4`) or very small (for example `AnyPin` which
|
||||
/// is 1 byte). However `&mut T` is always 4 bytes for 32-bit targets, even if T
|
||||
/// is zero-sized. PeripheralRef stores a copy of `T` instead, so it's the same
|
||||
/// size.
|
||||
/// peripherals like `PA9` or `Spi4`) or very small (for example `AnyPin`
|
||||
/// which is 1 byte). However `&mut T` is always 4 bytes for 32-bit targets,
|
||||
/// even if T is zero-sized. PeripheralRef stores a copy of `T` instead, so it's
|
||||
/// the same size.
|
||||
///
|
||||
/// but it is the size of `T` not the size
|
||||
/// of a pointer. This is useful if T is a zero sized type.
|
||||
|
@ -85,7 +85,7 @@ use core::marker::PhantomData;
|
||||
use fugit::HertzU32;
|
||||
|
||||
use crate::{
|
||||
gpio::{InputPin, OutputPin},
|
||||
gpio::{PeripheralInput, PeripheralOutput},
|
||||
interrupt::InterruptHandler,
|
||||
peripheral::Peripheral,
|
||||
rmt::private::CreateInstance,
|
||||
@ -295,10 +295,77 @@ impl<'d> Rmt<'d, crate::Async> {
|
||||
}
|
||||
}
|
||||
|
||||
fn configure_rx_channel<
|
||||
'd,
|
||||
P: PeripheralInput,
|
||||
T: private::RxChannelInternal<M>,
|
||||
M: crate::Mode,
|
||||
>(
|
||||
pin: impl Peripheral<P = P> + 'd,
|
||||
config: RxChannelConfig,
|
||||
) -> Result<T, Error> {
|
||||
if config.filter_threshold > 0b111_1111 {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(esp32, esp32s2))] {
|
||||
let threshold = 0b111_1111_1111_1111;
|
||||
} else {
|
||||
let threshold = 0b11_1111_1111_1111;
|
||||
}
|
||||
}
|
||||
|
||||
if config.idle_threshold > threshold {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
|
||||
crate::into_ref!(pin);
|
||||
pin.init_input(crate::gpio::Pull::None, crate::private::Internal);
|
||||
pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal);
|
||||
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
config.carrier_high,
|
||||
config.carrier_low,
|
||||
config.carrier_level,
|
||||
);
|
||||
T::set_filter_threshold(config.filter_threshold);
|
||||
T::set_idle_threshold(config.idle_threshold);
|
||||
|
||||
Ok(T::new())
|
||||
}
|
||||
|
||||
fn configure_tx_channel<
|
||||
'd,
|
||||
P: PeripheralOutput,
|
||||
T: private::TxChannelInternal<M>,
|
||||
M: crate::Mode,
|
||||
>(
|
||||
pin: impl Peripheral<P = P> + 'd,
|
||||
config: TxChannelConfig,
|
||||
) -> Result<T, Error> {
|
||||
crate::into_ref!(pin);
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal);
|
||||
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
config.carrier_high,
|
||||
config.carrier_low,
|
||||
config.carrier_level,
|
||||
);
|
||||
T::set_idle_output(config.idle_output, config.idle_output_level);
|
||||
|
||||
Ok(T::new())
|
||||
}
|
||||
|
||||
/// Creates a TX channel
|
||||
pub trait TxChannelCreator<'d, T, P>
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
T: TxChannel,
|
||||
{
|
||||
/// Configure the TX channel
|
||||
@ -310,26 +377,14 @@ where
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal);
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
config.carrier_high,
|
||||
config.carrier_low,
|
||||
config.carrier_level,
|
||||
);
|
||||
T::set_idle_output(config.idle_output, config.idle_output_level);
|
||||
|
||||
Ok(T::new())
|
||||
configure_tx_channel(pin, config)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a TX channel in async mode
|
||||
pub trait TxChannelCreatorAsync<'d, T, P>
|
||||
where
|
||||
P: OutputPin,
|
||||
P: PeripheralOutput,
|
||||
T: TxChannelAsync,
|
||||
{
|
||||
/// Configure the TX channel
|
||||
@ -341,26 +396,14 @@ where
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
crate::into_ref!(pin);
|
||||
pin.set_to_push_pull_output(crate::private::Internal);
|
||||
pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal);
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
config.carrier_high,
|
||||
config.carrier_low,
|
||||
config.carrier_level,
|
||||
);
|
||||
T::set_idle_output(config.idle_output, config.idle_output_level);
|
||||
|
||||
Ok(T::new())
|
||||
configure_tx_channel(pin, config)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a RX channel
|
||||
pub trait RxChannelCreator<'d, T, P>
|
||||
where
|
||||
P: InputPin,
|
||||
P: PeripheralInput,
|
||||
T: RxChannel,
|
||||
{
|
||||
/// Configure the RX channel
|
||||
@ -372,41 +415,14 @@ where
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
if config.filter_threshold > 0b111_1111 {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
|
||||
#[cfg(any(esp32, esp32s2))]
|
||||
if config.idle_threshold > 0b111_1111_1111_1111 {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
|
||||
#[cfg(not(any(esp32, esp32s2)))]
|
||||
if config.idle_threshold > 0b11_1111_1111_1111 {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
|
||||
crate::into_ref!(pin);
|
||||
pin.init_input(false, false, crate::private::Internal);
|
||||
pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal);
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
config.carrier_high,
|
||||
config.carrier_low,
|
||||
config.carrier_level,
|
||||
);
|
||||
T::set_filter_threshold(config.filter_threshold);
|
||||
T::set_idle_threshold(config.idle_threshold);
|
||||
|
||||
Ok(T::new())
|
||||
configure_rx_channel(pin, config)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a RX channel in async mode
|
||||
pub trait RxChannelCreatorAsync<'d, T, P>
|
||||
where
|
||||
P: InputPin,
|
||||
P: PeripheralInput,
|
||||
T: RxChannelAsync,
|
||||
{
|
||||
/// Configure the RX channel
|
||||
@ -418,34 +434,7 @@ where
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
if config.filter_threshold > 0b111_1111 {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
|
||||
#[cfg(any(esp32, esp32s2))]
|
||||
if config.idle_threshold > 0b111_1111_1111_1111 {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
|
||||
#[cfg(not(any(esp32, esp32s2)))]
|
||||
if config.idle_threshold > 0b11_1111_1111_1111 {
|
||||
return Err(Error::InvalidArgument);
|
||||
}
|
||||
|
||||
crate::into_ref!(pin);
|
||||
pin.init_input(false, false, crate::private::Internal);
|
||||
pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal);
|
||||
T::set_divider(config.clk_divider);
|
||||
T::set_carrier(
|
||||
config.carrier_modulation,
|
||||
config.carrier_high,
|
||||
config.carrier_low,
|
||||
config.carrier_level,
|
||||
);
|
||||
T::set_filter_threshold(config.filter_threshold);
|
||||
T::set_idle_threshold(config.idle_threshold);
|
||||
|
||||
Ok(T::new())
|
||||
configure_rx_channel(pin, config)
|
||||
}
|
||||
}
|
||||
|
||||
@ -586,7 +575,7 @@ macro_rules! impl_tx_channel_creator {
|
||||
impl<'d, P> $crate::rmt::TxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P>
|
||||
for ChannelCreator<$crate::Blocking, $channel>
|
||||
where
|
||||
P: $crate::gpio::OutputPin,
|
||||
P: $crate::gpio::PeripheralOutput,
|
||||
{
|
||||
}
|
||||
|
||||
@ -595,7 +584,7 @@ macro_rules! impl_tx_channel_creator {
|
||||
impl<'d, P> $crate::rmt::TxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P>
|
||||
for ChannelCreator<$crate::Async, $channel>
|
||||
where
|
||||
P: $crate::gpio::OutputPin,
|
||||
P: $crate::gpio::PeripheralOutput,
|
||||
{
|
||||
}
|
||||
|
||||
@ -608,7 +597,7 @@ macro_rules! impl_rx_channel_creator {
|
||||
impl<'d, P> $crate::rmt::RxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P>
|
||||
for ChannelCreator<$crate::Blocking, $channel>
|
||||
where
|
||||
P: $crate::gpio::InputPin,
|
||||
P: $crate::gpio::PeripheralInput,
|
||||
{
|
||||
}
|
||||
|
||||
@ -617,7 +606,7 @@ macro_rules! impl_rx_channel_creator {
|
||||
impl<'d, P> $crate::rmt::RxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P>
|
||||
for ChannelCreator<$crate::Async, $channel>
|
||||
where
|
||||
P: $crate::gpio::InputPin,
|
||||
P: $crate::gpio::PeripheralInput,
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ use super::{
|
||||
use crate::{
|
||||
clock::Clocks,
|
||||
dma::{DmaPeripheral, DmaRxBuffer, DmaTxBuffer, Rx, Tx},
|
||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
||||
gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput},
|
||||
interrupt::InterruptHandler,
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::spi2::RegisterBlock,
|
||||
@ -457,6 +457,35 @@ pub struct Spi<'d, T, M> {
|
||||
_mode: PhantomData<M>,
|
||||
}
|
||||
|
||||
impl<'d, T, M> Spi<'d, T, M>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
/// Assign the SCK (Serial Clock) pin for the SPI instance.
|
||||
///
|
||||
/// Sets the specified pin to push-pull output and connects it to the SPI
|
||||
/// clock signal.
|
||||
pub fn with_sck<SCK: PeripheralOutput>(self, sclk: impl Peripheral<P = SCK> + 'd) -> Self {
|
||||
crate::into_ref!(sclk);
|
||||
sclk.set_to_push_pull_output(private::Internal);
|
||||
sclk.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Assign the CS (Chip Select) pin for the SPI instance.
|
||||
///
|
||||
/// Sets the specified pin to push-pull output and connects it to the SPI CS
|
||||
/// signal.
|
||||
pub fn with_cs<CS: PeripheralOutput>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output(private::Internal);
|
||||
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T> Spi<'d, T, FullDuplexMode>
|
||||
where
|
||||
T: Instance,
|
||||
@ -513,23 +542,11 @@ where
|
||||
Self::new_internal(spi, frequency, mode)
|
||||
}
|
||||
|
||||
/// Assign the SCK (Serial Clock) pin for the SPI instance.
|
||||
///
|
||||
/// Sets the specified pin to push-pull output and connects it to the SPI
|
||||
/// clock signal.
|
||||
pub fn with_sck<SCK: OutputPin>(self, sck: impl Peripheral<P = SCK> + 'd) -> Self {
|
||||
crate::into_ref!(sck);
|
||||
sck.set_to_push_pull_output(private::Internal);
|
||||
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Assign the MOSI (Master Out Slave In) pin for the SPI instance.
|
||||
///
|
||||
/// Sets the specified pin to push-pull output and connects it to the SPI
|
||||
/// MOSI signal.
|
||||
pub fn with_mosi<MOSI: OutputPin>(self, mosi: impl Peripheral<P = MOSI> + 'd) -> Self {
|
||||
pub fn with_mosi<MOSI: PeripheralOutput>(self, mosi: impl Peripheral<P = MOSI> + 'd) -> Self {
|
||||
crate::into_ref!(mosi);
|
||||
mosi.set_to_push_pull_output(private::Internal);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||
@ -540,26 +557,14 @@ where
|
||||
/// Assign the MISO (Master In Slave Out) pin for the SPI instance.
|
||||
///
|
||||
/// Sets the specified pin to input and connects it to the SPI MISO signal.
|
||||
pub fn with_miso<MISO: InputPin>(self, miso: impl Peripheral<P = MISO> + 'd) -> Self {
|
||||
pub fn with_miso<MISO: PeripheralInput>(self, miso: impl Peripheral<P = MISO> + 'd) -> Self {
|
||||
crate::into_ref!(miso);
|
||||
miso.init_input(false, false, private::Internal);
|
||||
miso.init_input(crate::gpio::Pull::None, private::Internal);
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Assign the CS (Chip Select) pin for the SPI instance.
|
||||
///
|
||||
/// Sets the specified pin to push-pull output and connects it to the SPI CS
|
||||
/// signal.
|
||||
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output(private::Internal);
|
||||
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the bit order for the SPI instance.
|
||||
///
|
||||
/// The default is MSB first for both read and write.
|
||||
@ -572,38 +577,43 @@ where
|
||||
///
|
||||
/// All pins are optional. Pass [crate::gpio::NO_PIN] if you don't need the
|
||||
/// given pin.
|
||||
pub fn with_pins<SCK: OutputPin, MOSI: OutputPin, MISO: InputPin, CS: OutputPin>(
|
||||
pub fn with_pins<
|
||||
SCK: PeripheralOutput,
|
||||
MOSI: PeripheralOutput,
|
||||
MISO: PeripheralInput,
|
||||
CS: PeripheralOutput,
|
||||
>(
|
||||
self,
|
||||
sck: Option<impl Peripheral<P = SCK> + 'd>,
|
||||
mosi: Option<impl Peripheral<P = MOSI> + 'd>,
|
||||
miso: Option<impl Peripheral<P = MISO> + 'd>,
|
||||
cs: Option<impl Peripheral<P = CS> + 'd>,
|
||||
) -> Self {
|
||||
if let Some(sck) = sck {
|
||||
crate::into_ref!(sck);
|
||||
sck.set_to_push_pull_output(private::Internal);
|
||||
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(sck) = sck {
|
||||
self.with_sck(sck)
|
||||
} else {
|
||||
self
|
||||
};
|
||||
|
||||
if let Some(mosi) = mosi {
|
||||
crate::into_ref!(mosi);
|
||||
mosi.set_to_push_pull_output(private::Internal);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(mosi) = mosi {
|
||||
this.with_mosi(mosi)
|
||||
} else {
|
||||
this
|
||||
};
|
||||
|
||||
if let Some(miso) = miso {
|
||||
crate::into_ref!(miso);
|
||||
miso.init_input(false, false, private::Internal);
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(miso) = miso {
|
||||
this.with_miso(miso)
|
||||
} else {
|
||||
this
|
||||
};
|
||||
|
||||
if let Some(cs) = cs {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output(private::Internal);
|
||||
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(cs) = cs {
|
||||
this.with_cs(cs)
|
||||
} else {
|
||||
this
|
||||
};
|
||||
|
||||
self
|
||||
this
|
||||
}
|
||||
|
||||
pub(crate) fn new_internal(
|
||||
@ -651,32 +661,21 @@ where
|
||||
Self::new_internal(spi, frequency, mode)
|
||||
}
|
||||
|
||||
/// Assign the SCK (Serial Clock) pin for the SPI instance.
|
||||
///
|
||||
/// Sets the specified pin to push-pull output and connects it to the SPI
|
||||
/// clock signal.
|
||||
pub fn with_sck<SCK: OutputPin>(self, sck: impl Peripheral<P = SCK> + 'd) -> Self {
|
||||
crate::into_ref!(sck);
|
||||
sck.set_to_push_pull_output(private::Internal);
|
||||
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Assign the MOSI (Master Out Slave In) pin for the SPI instance in
|
||||
/// half-duplex mode.
|
||||
///
|
||||
/// Enables both input and output functionality for the pin, and connects it
|
||||
/// to the MOSI signal and SIO0 input signal.
|
||||
pub fn with_mosi<MOSI: OutputPin + InputPin>(
|
||||
pub fn with_mosi<MOSI: PeripheralOutput + PeripheralInput>(
|
||||
self,
|
||||
mosi: impl Peripheral<P = MOSI> + 'd,
|
||||
) -> Self {
|
||||
crate::into_ref!(mosi);
|
||||
mosi.enable_output(true, private::Internal);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||
mosi.enable_input(true, private::Internal);
|
||||
mosi.enable_output(true, private::Internal);
|
||||
|
||||
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal(), private::Internal);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -686,15 +685,16 @@ where
|
||||
///
|
||||
/// Enables both input and output functionality for the pin, and connects it
|
||||
/// to the MISO signal and SIO1 input signal.
|
||||
pub fn with_miso<MISO: OutputPin + InputPin>(
|
||||
pub fn with_miso<MISO: PeripheralOutput + PeripheralInput>(
|
||||
self,
|
||||
miso: impl Peripheral<P = MISO> + 'd,
|
||||
) -> Self {
|
||||
crate::into_ref!(miso);
|
||||
miso.enable_output(true, private::Internal);
|
||||
miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal);
|
||||
miso.enable_input(true, private::Internal);
|
||||
miso.enable_output(true, private::Internal);
|
||||
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||
miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -703,15 +703,16 @@ where
|
||||
///
|
||||
/// Enables both input and output functionality for the pin, and connects it
|
||||
/// to the SIO2 output and input signals.
|
||||
pub fn with_sio2<SIO2: OutputPin + InputPin>(
|
||||
pub fn with_sio2<SIO2: PeripheralOutput + PeripheralInput>(
|
||||
self,
|
||||
sio2: impl Peripheral<P = SIO2> + 'd,
|
||||
) -> Self {
|
||||
crate::into_ref!(sio2);
|
||||
sio2.enable_output(true, private::Internal);
|
||||
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal);
|
||||
sio2.enable_input(true, private::Internal);
|
||||
sio2.enable_output(true, private::Internal);
|
||||
|
||||
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal(), private::Internal);
|
||||
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -720,27 +721,16 @@ where
|
||||
///
|
||||
/// Enables both input and output functionality for the pin, and connects it
|
||||
/// to the SIO3 output and input signals.
|
||||
pub fn with_sio3<SIO3: OutputPin + InputPin>(
|
||||
pub fn with_sio3<SIO3: PeripheralOutput + PeripheralInput>(
|
||||
self,
|
||||
sio3: impl Peripheral<P = SIO3> + 'd,
|
||||
) -> Self {
|
||||
crate::into_ref!(sio3);
|
||||
sio3.enable_output(true, private::Internal);
|
||||
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal);
|
||||
sio3.enable_input(true, private::Internal);
|
||||
sio3.enable_output(true, private::Internal);
|
||||
|
||||
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Assign the CS (Chip Select) pin for the SPI instance.
|
||||
///
|
||||
/// Sets the specified pin to push-pull output and connects it to the SPI CS
|
||||
/// signal.
|
||||
pub fn with_cs<CS: OutputPin>(self, cs: impl Peripheral<P = CS> + 'd) -> Self {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output(private::Internal);
|
||||
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal);
|
||||
|
||||
self
|
||||
}
|
||||
@ -750,12 +740,12 @@ where
|
||||
/// All pins are optional. Pass [crate::gpio::NO_PIN] if you don't need the
|
||||
/// given pin.
|
||||
pub fn with_pins<
|
||||
SCK: OutputPin,
|
||||
MOSI: OutputPin + InputPin,
|
||||
MISO: OutputPin + InputPin,
|
||||
SIO2: OutputPin + InputPin,
|
||||
SIO3: OutputPin + InputPin,
|
||||
CS: OutputPin,
|
||||
SCK: PeripheralOutput,
|
||||
MOSI: PeripheralOutput + PeripheralInput,
|
||||
MISO: PeripheralOutput + PeripheralInput,
|
||||
SIO2: PeripheralOutput + PeripheralInput,
|
||||
SIO3: PeripheralOutput + PeripheralInput,
|
||||
CS: PeripheralOutput,
|
||||
>(
|
||||
self,
|
||||
sck: Option<impl Peripheral<P = SCK> + 'd>,
|
||||
@ -765,51 +755,43 @@ where
|
||||
sio3: Option<impl Peripheral<P = SIO3> + 'd>,
|
||||
cs: Option<impl Peripheral<P = CS> + 'd>,
|
||||
) -> Self {
|
||||
if let Some(sck) = sck {
|
||||
crate::into_ref!(sck);
|
||||
sck.set_to_push_pull_output(private::Internal);
|
||||
sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(sck) = sck {
|
||||
self.with_sck(sck)
|
||||
} else {
|
||||
self
|
||||
};
|
||||
|
||||
if let Some(mosi) = mosi {
|
||||
crate::into_ref!(mosi);
|
||||
mosi.enable_output(true, private::Internal);
|
||||
mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal);
|
||||
mosi.enable_input(true, private::Internal);
|
||||
mosi.connect_input_to_peripheral(self.spi.sio0_input_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(mosi) = mosi {
|
||||
this.with_mosi(mosi)
|
||||
} else {
|
||||
this
|
||||
};
|
||||
|
||||
if let Some(miso) = miso {
|
||||
crate::into_ref!(miso);
|
||||
miso.enable_output(true, private::Internal);
|
||||
miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal);
|
||||
miso.enable_input(true, private::Internal);
|
||||
miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(miso) = miso {
|
||||
this.with_miso(miso)
|
||||
} else {
|
||||
this
|
||||
};
|
||||
|
||||
if let Some(sio2) = sio2 {
|
||||
crate::into_ref!(sio2);
|
||||
sio2.enable_output(true, private::Internal);
|
||||
sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal);
|
||||
sio2.enable_input(true, private::Internal);
|
||||
sio2.connect_input_to_peripheral(self.spi.sio2_input_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(sio2) = sio2 {
|
||||
this.with_sio2(sio2)
|
||||
} else {
|
||||
this
|
||||
};
|
||||
|
||||
if let Some(sio3) = sio3 {
|
||||
crate::into_ref!(sio3);
|
||||
sio3.enable_output(true, private::Internal);
|
||||
sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal);
|
||||
sio3.enable_input(true, private::Internal);
|
||||
sio3.connect_input_to_peripheral(self.spi.sio3_input_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(sio3) = sio3 {
|
||||
this.with_sio3(sio3)
|
||||
} else {
|
||||
this
|
||||
};
|
||||
|
||||
if let Some(cs) = cs {
|
||||
crate::into_ref!(cs);
|
||||
cs.set_to_push_pull_output(private::Internal);
|
||||
cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal);
|
||||
}
|
||||
let this = if let Some(cs) = cs {
|
||||
this.with_cs(cs)
|
||||
} else {
|
||||
this
|
||||
};
|
||||
|
||||
self
|
||||
this
|
||||
}
|
||||
|
||||
pub(crate) fn new_internal(
|
||||
|
@ -73,7 +73,7 @@ use core::marker::PhantomData;
|
||||
use super::{Error, FullDuplexMode, SpiMode};
|
||||
use crate::{
|
||||
dma::{DescriptorChain, DmaPeripheral, Rx, Tx},
|
||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
||||
gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput, Pull},
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::spi2::RegisterBlock,
|
||||
private,
|
||||
@ -106,25 +106,31 @@ where
|
||||
T: Instance,
|
||||
{
|
||||
/// Constructs an SPI instance in 8bit dataframe mode.
|
||||
pub fn new<SCK: InputPin, MOSI: InputPin, MISO: OutputPin, CS: InputPin>(
|
||||
pub fn new<
|
||||
SCK: PeripheralInput,
|
||||
MOSI: PeripheralInput,
|
||||
MISO: PeripheralOutput,
|
||||
CS: PeripheralInput,
|
||||
>(
|
||||
spi: impl Peripheral<P = T> + 'd,
|
||||
sck: impl Peripheral<P = SCK> + 'd,
|
||||
sclk: impl Peripheral<P = SCK> + 'd,
|
||||
mosi: impl Peripheral<P = MOSI> + 'd,
|
||||
miso: impl Peripheral<P = MISO> + 'd,
|
||||
cs: impl Peripheral<P = CS> + 'd,
|
||||
mode: SpiMode,
|
||||
) -> Spi<'d, T, FullDuplexMode> {
|
||||
crate::into_ref!(spi, sck, mosi, miso, cs);
|
||||
sck.init_input(false, false, private::Internal);
|
||||
sck.connect_input_to_peripheral(spi.sclk_signal(), private::Internal);
|
||||
crate::into_ref!(spi, sclk, mosi, miso, cs);
|
||||
|
||||
mosi.init_input(false, false, private::Internal);
|
||||
sclk.init_input(Pull::None, private::Internal);
|
||||
sclk.connect_input_to_peripheral(spi.sclk_signal(), private::Internal);
|
||||
|
||||
mosi.init_input(Pull::None, private::Internal);
|
||||
mosi.connect_input_to_peripheral(spi.mosi_signal(), private::Internal);
|
||||
|
||||
miso.set_to_push_pull_output(private::Internal);
|
||||
miso.connect_peripheral_to_output(spi.miso_signal(), private::Internal);
|
||||
|
||||
cs.init_input(false, false, private::Internal);
|
||||
cs.init_input(Pull::None, private::Internal);
|
||||
cs.connect_input_to_peripheral(spi.cs_signal(), private::Internal);
|
||||
|
||||
Self::new_internal(spi, mode)
|
||||
@ -148,7 +154,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// DMA (Direct Memory Access) funtionality (Slave).
|
||||
/// DMA (Direct Memory Access) functionality (Slave).
|
||||
pub mod dma {
|
||||
use super::*;
|
||||
#[cfg(spi3)]
|
||||
|
@ -133,7 +133,7 @@ use core::marker::PhantomData;
|
||||
|
||||
use self::filter::{Filter, FilterType};
|
||||
use crate::{
|
||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
||||
gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput, Pull},
|
||||
interrupt::InterruptHandler,
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::twai0::RegisterBlock,
|
||||
@ -716,7 +716,7 @@ where
|
||||
T: Instance,
|
||||
DM: crate::Mode,
|
||||
{
|
||||
fn new_internal<TX: OutputPin, RX: InputPin>(
|
||||
fn new_internal<TX: PeripheralOutput, RX: PeripheralInput>(
|
||||
_peripheral: impl Peripheral<P = T> + 'd,
|
||||
rx_pin: impl Peripheral<P = RX> + 'd,
|
||||
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||
@ -736,13 +736,15 @@ where
|
||||
.mode()
|
||||
.write(|w| w.reset_mode().set_bit());
|
||||
|
||||
rx_pin.init_input(Pull::None, crate::private::Internal);
|
||||
rx_pin.connect_input_to_peripheral(T::INPUT_SIGNAL, crate::private::Internal);
|
||||
|
||||
if no_transceiver {
|
||||
tx_pin.set_to_open_drain_output(crate::private::Internal);
|
||||
} else {
|
||||
tx_pin.set_to_push_pull_output(crate::private::Internal);
|
||||
}
|
||||
tx_pin.set_to_push_pull_output(crate::private::Internal);
|
||||
tx_pin.connect_peripheral_to_output(T::OUTPUT_SIGNAL, crate::private::Internal);
|
||||
rx_pin.init_input(false, false, crate::private::Internal);
|
||||
rx_pin.connect_input_to_peripheral(T::INPUT_SIGNAL, crate::private::Internal);
|
||||
|
||||
// Set the operating mode based on provided option
|
||||
match mode {
|
||||
@ -903,7 +905,7 @@ where
|
||||
/// Create a new instance of [TwaiConfiguration]
|
||||
///
|
||||
/// You will need to use a transceiver to connect to the TWAI bus
|
||||
pub fn new<RX: InputPin, TX: OutputPin>(
|
||||
pub fn new<RX: PeripheralInput, TX: PeripheralOutput>(
|
||||
peripheral: impl Peripheral<P = T> + 'd,
|
||||
rx_pin: impl Peripheral<P = RX> + 'd,
|
||||
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||
@ -918,7 +920,7 @@ where
|
||||
///
|
||||
/// You don't need a transceiver by following the description in the
|
||||
/// `twai.rs` example
|
||||
pub fn new_no_transceiver<RX: InputPin, TX: OutputPin>(
|
||||
pub fn new_no_transceiver<RX: PeripheralInput, TX: PeripheralOutput>(
|
||||
peripheral: impl Peripheral<P = T> + 'd,
|
||||
rx_pin: impl Peripheral<P = RX> + 'd,
|
||||
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||
@ -947,7 +949,7 @@ where
|
||||
/// Create a new instance of [TwaiConfiguration] in async mode
|
||||
///
|
||||
/// You will need to use a transceiver to connect to the TWAI bus
|
||||
pub fn new_async<RX: InputPin, TX: OutputPin>(
|
||||
pub fn new_async<RX: PeripheralInput, TX: PeripheralOutput>(
|
||||
peripheral: impl Peripheral<P = T> + 'd,
|
||||
rx_pin: impl Peripheral<P = RX> + 'd,
|
||||
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||
@ -964,7 +966,7 @@ where
|
||||
///
|
||||
/// You don't need a transceiver by following the description in the
|
||||
/// `twai.rs` example
|
||||
pub fn new_async_no_transceiver<RX: InputPin, TX: OutputPin>(
|
||||
pub fn new_async_no_transceiver<RX: PeripheralInput, TX: PeripheralOutput>(
|
||||
peripheral: impl Peripheral<P = T> + 'd,
|
||||
rx_pin: impl Peripheral<P = RX> + 'd,
|
||||
tx_pin: impl Peripheral<P = TX> + 'd,
|
||||
|
@ -94,12 +94,12 @@
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::uart::Uart;
|
||||
//! use esp_hal::gpio::{AnyPin, Io};
|
||||
//! use esp_hal::gpio::Io;
|
||||
//!
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//!
|
||||
//! let rx = AnyPin::new_inverted(io.pins.gpio2);
|
||||
//! let tx = AnyPin::new_inverted(io.pins.gpio1);
|
||||
//! let rx = io.pins.gpio2.peripheral_input().inverted();
|
||||
//! let tx = io.pins.gpio1.into_peripheral_output().inverted();
|
||||
//! let mut uart1 = Uart::new(
|
||||
//! peripherals.UART1,
|
||||
//! rx,
|
||||
@ -112,7 +112,7 @@
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! # use esp_hal::uart::{UartTx, UartRx};
|
||||
//! use esp_hal::gpio::{AnyPin, Io};
|
||||
//! use esp_hal::gpio::Io;
|
||||
//!
|
||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
//!
|
||||
@ -131,7 +131,7 @@ use core::marker::PhantomData;
|
||||
use self::config::Config;
|
||||
use crate::{
|
||||
clock::Clocks,
|
||||
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
|
||||
gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput, Pull},
|
||||
interrupt::InterruptHandler,
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
peripherals::{uart0::RegisterBlock, Interrupt},
|
||||
@ -451,15 +451,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn with_rx<RX: InputPin>(self, rx: impl Peripheral<P = RX> + 'd) -> Self {
|
||||
fn with_rx<RX: PeripheralInput>(self, rx: impl Peripheral<P = RX> + 'd) -> Self {
|
||||
crate::into_ref!(rx);
|
||||
rx.init_input(false, false, Internal);
|
||||
rx.init_input(Pull::Up, Internal);
|
||||
rx.connect_input_to_peripheral(T::rx_signal(), Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn with_tx<TX: OutputPin>(self, tx: impl Peripheral<P = TX> + 'd) -> Self {
|
||||
fn with_tx<TX: PeripheralOutput>(self, tx: impl Peripheral<P = TX> + 'd) -> Self {
|
||||
crate::into_ref!(tx);
|
||||
tx.set_to_push_pull_output(Internal);
|
||||
tx.connect_peripheral_to_output(T::tx_signal(), Internal);
|
||||
@ -536,7 +536,7 @@ where
|
||||
}
|
||||
|
||||
/// Configure RTS pin
|
||||
pub fn with_rts<RTS: OutputPin>(self, rts: impl Peripheral<P = RTS> + 'd) -> Self {
|
||||
pub fn with_rts<RTS: PeripheralOutput>(self, rts: impl Peripheral<P = RTS> + 'd) -> Self {
|
||||
crate::into_ref!(rts);
|
||||
rts.set_to_push_pull_output(Internal);
|
||||
rts.connect_peripheral_to_output(T::rts_signal(), Internal);
|
||||
@ -581,7 +581,7 @@ where
|
||||
T: Instance + 'd,
|
||||
{
|
||||
/// Create a new UART TX instance in [`Blocking`] mode.
|
||||
pub fn new<TX: OutputPin>(
|
||||
pub fn new<TX: PeripheralOutput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
tx: impl Peripheral<P = TX> + 'd,
|
||||
) -> Result<Self, Error> {
|
||||
@ -590,7 +590,7 @@ where
|
||||
|
||||
/// Create a new UART TX instance with configuration options in
|
||||
/// [`Blocking`] mode.
|
||||
pub fn new_with_config<TX: OutputPin>(
|
||||
pub fn new_with_config<TX: PeripheralOutput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
config: Config,
|
||||
tx: impl Peripheral<P = TX> + 'd,
|
||||
@ -620,9 +620,9 @@ where
|
||||
}
|
||||
|
||||
/// Configure CTS pin
|
||||
pub fn with_cts<CTS: InputPin>(self, cts: impl Peripheral<P = CTS> + 'd) -> Self {
|
||||
pub fn with_cts<CTS: PeripheralInput>(self, cts: impl Peripheral<P = CTS> + 'd) -> Self {
|
||||
crate::into_ref!(cts);
|
||||
cts.init_input(false, false, Internal);
|
||||
cts.init_input(Pull::None, Internal);
|
||||
cts.connect_input_to_peripheral(T::cts_signal(), Internal);
|
||||
|
||||
self
|
||||
@ -794,7 +794,7 @@ where
|
||||
T: Instance + 'd,
|
||||
{
|
||||
/// Create a new UART RX instance in [`Blocking`] mode.
|
||||
pub fn new<RX: InputPin>(
|
||||
pub fn new<RX: PeripheralInput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
rx: impl Peripheral<P = RX> + 'd,
|
||||
) -> Result<Self, Error> {
|
||||
@ -803,7 +803,7 @@ where
|
||||
|
||||
/// Create a new UART RX instance with configuration options in
|
||||
/// [`Blocking`] mode.
|
||||
pub fn new_with_config<RX: InputPin>(
|
||||
pub fn new_with_config<RX: PeripheralInput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
config: Config,
|
||||
rx: impl Peripheral<P = RX> + 'd,
|
||||
@ -820,7 +820,7 @@ where
|
||||
{
|
||||
/// Create a new UART instance with configuration options in [`Blocking`]
|
||||
/// mode.
|
||||
pub fn new_with_config<TX: OutputPin, RX: InputPin>(
|
||||
pub fn new_with_config<TX: PeripheralOutput, RX: PeripheralInput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
config: Config,
|
||||
rx: impl Peripheral<P = RX> + 'd,
|
||||
@ -835,7 +835,7 @@ where
|
||||
}
|
||||
|
||||
/// Create a new UART instance with defaults in [`Blocking`] mode.
|
||||
pub fn new<TX: OutputPin, RX: InputPin>(
|
||||
pub fn new<TX: PeripheralOutput, RX: PeripheralInput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
rx: impl Peripheral<P = RX> + 'd,
|
||||
tx: impl Peripheral<P = TX> + 'd,
|
||||
@ -857,16 +857,16 @@ where
|
||||
}
|
||||
|
||||
/// Configure CTS pin
|
||||
pub fn with_cts<CTS: InputPin>(self, cts: impl Peripheral<P = CTS> + 'd) -> Self {
|
||||
pub fn with_cts<CTS: PeripheralInput>(self, cts: impl Peripheral<P = CTS> + 'd) -> Self {
|
||||
crate::into_ref!(cts);
|
||||
cts.init_input(false, false, Internal);
|
||||
cts.init_input(Pull::None, Internal);
|
||||
cts.connect_input_to_peripheral(T::cts_signal(), Internal);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure RTS pin
|
||||
pub fn with_rts<RTS: OutputPin>(self, rts: impl Peripheral<P = RTS> + 'd) -> Self {
|
||||
pub fn with_rts<RTS: PeripheralOutput>(self, rts: impl Peripheral<P = RTS> + 'd) -> Self {
|
||||
crate::into_ref!(rts);
|
||||
rts.set_to_push_pull_output(Internal);
|
||||
rts.connect_peripheral_to_output(T::rts_signal(), Internal);
|
||||
@ -2058,7 +2058,7 @@ mod asynch {
|
||||
{
|
||||
/// Create a new UART instance with configuration options in [`Async`]
|
||||
/// mode.
|
||||
pub fn new_async_with_config<RX: InputPin, TX: OutputPin>(
|
||||
pub fn new_async_with_config<RX: PeripheralInput, TX: PeripheralOutput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
config: Config,
|
||||
rx: impl Peripheral<P = RX> + 'd,
|
||||
@ -2086,7 +2086,7 @@ mod asynch {
|
||||
}
|
||||
|
||||
/// Create a new UART instance with defaults in [`Async`] mode.
|
||||
pub fn new_async<RX: InputPin, TX: OutputPin>(
|
||||
pub fn new_async<RX: PeripheralInput, TX: PeripheralOutput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
rx: impl Peripheral<P = RX> + 'd,
|
||||
tx: impl Peripheral<P = TX> + 'd,
|
||||
@ -2121,7 +2121,7 @@ mod asynch {
|
||||
T: Instance + 'd,
|
||||
{
|
||||
/// Create a new UART TX instance in [`Async`] mode.
|
||||
pub fn new_async<TX: OutputPin>(
|
||||
pub fn new_async<TX: PeripheralOutput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
tx: impl Peripheral<P = TX> + 'd,
|
||||
) -> Result<Self, Error> {
|
||||
@ -2130,7 +2130,7 @@ mod asynch {
|
||||
|
||||
/// Create a new UART TX instance with configuration options in
|
||||
/// [`Async`] mode.
|
||||
pub fn new_async_with_config<TX: OutputPin>(
|
||||
pub fn new_async_with_config<TX: PeripheralOutput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
config: Config,
|
||||
tx: impl Peripheral<P = TX> + 'd,
|
||||
@ -2202,7 +2202,7 @@ mod asynch {
|
||||
T: Instance + 'd,
|
||||
{
|
||||
/// Create a new UART RX instance in [`Async`] mode.
|
||||
pub fn new_async<RX: InputPin>(
|
||||
pub fn new_async<RX: PeripheralInput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
rx: impl Peripheral<P = RX> + 'd,
|
||||
) -> Result<Self, Error> {
|
||||
@ -2211,7 +2211,7 @@ mod asynch {
|
||||
|
||||
/// Create a new UART RX instance with configuration options in
|
||||
/// [`Async`] mode.
|
||||
pub fn new_async_with_config<RX: InputPin>(
|
||||
pub fn new_async_with_config<RX: PeripheralInput>(
|
||||
uart: impl Peripheral<P = T> + 'd,
|
||||
config: Config,
|
||||
rx: impl Peripheral<P = RX> + 'd,
|
||||
|
@ -12,13 +12,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Added `have-strchr` feature to disable including `strchr` (#2096)
|
||||
|
||||
### Changed
|
||||
|
||||
- esp-wifi now allocates memory from the global allocator provided by `esp-alloc` (#2099)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Feature `wifi-logs` doesn't break the build anymore (#2117)
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed the `clocks` parameter from `esp_wifi::initialize` (#1999)
|
||||
|
||||
## 0.9.1 - 2024-09-03
|
||||
|
||||
### Added
|
||||
@ -43,8 +47,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed the `clocks` parameter from `esp_wifi::initialize` (#1999)
|
||||
|
||||
## 0.8.0 - 2024-08-29
|
||||
|
||||
### Added
|
||||
|
@ -14,7 +14,7 @@
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{ErasedPin, Input, Io, Level, Output, Pin, Pull},
|
||||
gpio::{Input, Io, Level, Output, Pin, Pull},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
@ -47,7 +47,7 @@ fn main() -> ! {
|
||||
}
|
||||
}
|
||||
|
||||
fn toggle_pins(leds: &mut [Output<ErasedPin>], button: &Input<ErasedPin>) {
|
||||
fn toggle_pins(leds: &mut [Output], button: &Input) {
|
||||
for pin in leds.iter_mut() {
|
||||
pin.toggle();
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
//! This is an example of running the embassy executor with IC2. It uses an
|
||||
//! LIS3DH to get accelerometer data.
|
||||
//!
|
||||
//! Folowing pins are used:
|
||||
//! Following pins are used:
|
||||
//! - SDA => GPIO4
|
||||
//! - SCL => GPIO5
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
//! This example dumps the calibration data from a BMP180 sensor by reading by reading
|
||||
//! with the direct I2C API and the embedded-hal-async I2C API.
|
||||
//!
|
||||
//! Folowing pins are used:
|
||||
//! Following pins are used:
|
||||
//! - SDA => GPIO4
|
||||
//! - SCL => GPIO5
|
||||
//!
|
||||
|
@ -21,7 +21,7 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
cpu_control::{CpuControl, Stack},
|
||||
get_core,
|
||||
gpio::{ErasedPin, Io, Level, Output, Pin},
|
||||
gpio::{Io, Level, Output, Pin},
|
||||
timer::{timg::TimerGroup, ErasedTimer},
|
||||
};
|
||||
use esp_hal_embassy::Executor;
|
||||
@ -34,7 +34,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new();
|
||||
/// duration of time.
|
||||
#[embassy_executor::task]
|
||||
async fn control_led(
|
||||
mut led: Output<'static, ErasedPin>,
|
||||
mut led: Output<'static>,
|
||||
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
||||
) {
|
||||
println!("Starting control_led() on core {}", get_core() as usize);
|
||||
|
@ -20,7 +20,7 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
cpu_control::{CpuControl, Stack},
|
||||
get_core,
|
||||
gpio::{ErasedPin, Io, Level, Output, Pin},
|
||||
gpio::{Io, Level, Output, Pin},
|
||||
interrupt::{software::SoftwareInterruptControl, Priority},
|
||||
prelude::*,
|
||||
timer::{timg::TimerGroup, ErasedTimer},
|
||||
@ -35,7 +35,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new();
|
||||
/// duration of time.
|
||||
#[embassy_executor::task]
|
||||
async fn control_led(
|
||||
mut led: Output<'static, ErasedPin>,
|
||||
mut led: Output<'static>,
|
||||
control: &'static Signal<CriticalSectionRawMutex, bool>,
|
||||
) {
|
||||
println!("Starting control_led() on core {}", get_core() as usize);
|
||||
|
@ -53,15 +53,15 @@ fn main() -> ! {
|
||||
|
||||
println!("setup channel 0");
|
||||
let ch0 = &u0.channel0;
|
||||
let mut pin_a = io.pins.gpio4;
|
||||
let mut pin_b = io.pins.gpio5;
|
||||
let pin_a = io.pins.gpio4;
|
||||
let pin_b = io.pins.gpio5;
|
||||
|
||||
ch0.set_ctrl_signal(PcntSource::from_pin(
|
||||
&mut pin_a,
|
||||
ch0.set_ctrl_signal(PcntSource::from(
|
||||
pin_a.peripheral_input(),
|
||||
PcntInputConfig { pull: Pull::Up },
|
||||
));
|
||||
ch0.set_edge_signal(PcntSource::from_pin(
|
||||
&mut pin_b,
|
||||
ch0.set_edge_signal(PcntSource::from(
|
||||
pin_b.peripheral_input(),
|
||||
PcntInputConfig { pull: Pull::Up },
|
||||
));
|
||||
ch0.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep);
|
||||
@ -69,12 +69,12 @@ fn main() -> ! {
|
||||
|
||||
println!("setup channel 1");
|
||||
let ch1 = &u0.channel1;
|
||||
ch1.set_ctrl_signal(PcntSource::from_pin(
|
||||
&mut pin_b,
|
||||
ch1.set_ctrl_signal(PcntSource::from(
|
||||
pin_b.peripheral_input(),
|
||||
PcntInputConfig { pull: Pull::Up },
|
||||
));
|
||||
ch1.set_edge_signal(PcntSource::from_pin(
|
||||
&mut pin_a,
|
||||
ch1.set_edge_signal(PcntSource::from(
|
||||
pin_a.peripheral_input(),
|
||||
PcntInputConfig { pull: Pull::Up },
|
||||
));
|
||||
ch1.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep);
|
||||
|
@ -2,16 +2,13 @@
|
||||
//!
|
||||
//! The following wiring is assumed:
|
||||
//! - SCLK => GPIO0
|
||||
//! - MISO => GPIO2
|
||||
//! - MOSI => GPIO4
|
||||
//! - MISO/MOSI => GPIO2
|
||||
//! - CS => GPIO5
|
||||
//!
|
||||
//! Depending on your target and the board you are using you have to change the
|
||||
//! pins.
|
||||
//!
|
||||
//! This example transfers data via SPI.
|
||||
//! Connect MISO and MOSI pins to see the outgoing data is read as incoming
|
||||
//! data.
|
||||
|
||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||
|
||||
@ -21,7 +18,7 @@
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{AnyPin, Io},
|
||||
gpio::Io,
|
||||
prelude::*,
|
||||
spi::{master::Spi, SpiMode},
|
||||
};
|
||||
@ -33,12 +30,11 @@ fn main() -> ! {
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let sclk = io.pins.gpio0;
|
||||
let miso = io.pins.gpio2;
|
||||
let mosi = io.pins.gpio4;
|
||||
let miso_mosi = io.pins.gpio2;
|
||||
let cs = io.pins.gpio5;
|
||||
|
||||
let miso = AnyPin::new(miso);
|
||||
let mosi = AnyPin::new(mosi);
|
||||
let miso = miso_mosi.peripheral_input();
|
||||
let mosi = miso_mosi.into_peripheral_output();
|
||||
|
||||
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0).with_pins(
|
||||
Some(sclk),
|
||||
|
@ -11,7 +11,7 @@ use core::cell::RefCell;
|
||||
use critical_section::Mutex;
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{AnyPin, ErasedPin, Input, Io, Level, Output, Pin, Pull},
|
||||
gpio::{AnyPin, Input, Io, Level, Output, Pin, Pull},
|
||||
macros::handler,
|
||||
timer::timg::TimerGroup,
|
||||
InterruptConfigurable,
|
||||
@ -22,8 +22,8 @@ static COUNTER: Mutex<RefCell<u32>> = Mutex::new(RefCell::new(0));
|
||||
static INPUT_PIN: Mutex<RefCell<Option<Input>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
struct Context {
|
||||
test_gpio1: ErasedPin,
|
||||
test_gpio2: ErasedPin,
|
||||
test_gpio1: AnyPin,
|
||||
test_gpio2: AnyPin,
|
||||
delay: Delay,
|
||||
}
|
||||
|
||||
@ -267,8 +267,8 @@ mod tests {
|
||||
// https://github.com/esp-rs/esp-hal/issues/1943
|
||||
#[test]
|
||||
fn test_gpio_touch_anypin_output(ctx: Context) {
|
||||
let any_pin2 = AnyPin::new(ctx.test_gpio1);
|
||||
let any_pin3 = AnyPin::new(ctx.test_gpio2);
|
||||
let any_pin2 = ctx.test_gpio1;
|
||||
let any_pin3 = ctx.test_gpio2;
|
||||
|
||||
let out_pin = Output::new(any_pin2, Level::High);
|
||||
let in_pin = Input::new(any_pin3, Pull::Down);
|
||||
@ -281,8 +281,8 @@ mod tests {
|
||||
// https://github.com/esp-rs/esp-hal/issues/1943
|
||||
#[test]
|
||||
fn test_gpio_touch_anypin_input(ctx: Context) {
|
||||
let any_pin2 = AnyPin::new(ctx.test_gpio1);
|
||||
let any_pin3 = AnyPin::new(ctx.test_gpio2);
|
||||
let any_pin2 = ctx.test_gpio1;
|
||||
let any_pin3 = ctx.test_gpio2;
|
||||
|
||||
let out_pin = Output::new(any_pin3, Level::Low);
|
||||
let in_pin = Input::new(any_pin2, Pull::Down);
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
use esp_hal::{
|
||||
delay::Delay,
|
||||
gpio::{AnyPin, Io, Level, Output, Pull},
|
||||
gpio::{AnyPin, Io, Level, Output, Pin, Pull},
|
||||
pcnt::{
|
||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
||||
Pcnt,
|
||||
@ -17,8 +17,8 @@ use hil_test as _;
|
||||
|
||||
struct Context<'d> {
|
||||
pcnt: Pcnt<'d>,
|
||||
input: AnyPin<'d>,
|
||||
output: AnyPin<'d>,
|
||||
input: AnyPin,
|
||||
output: AnyPin,
|
||||
delay: Delay,
|
||||
}
|
||||
|
||||
@ -35,8 +35,8 @@ mod tests {
|
||||
|
||||
let (din, dout) = hil_test::common_test_pins!(io);
|
||||
|
||||
let din = AnyPin::new(din);
|
||||
let dout = AnyPin::new(dout);
|
||||
let din = din.degrade();
|
||||
let dout = dout.degrade();
|
||||
|
||||
Context {
|
||||
pcnt: Pcnt::new(peripherals.PCNT),
|
||||
@ -51,7 +51,7 @@ mod tests {
|
||||
let unit = ctx.pcnt.unit0;
|
||||
|
||||
// Setup channel 0 to increment the count when gpio2 does LOW -> HIGH
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
unit.channel0.set_edge_signal(PcntSource::from(
|
||||
ctx.input,
|
||||
PcntInputConfig { pull: Pull::Down },
|
||||
));
|
||||
@ -90,7 +90,7 @@ mod tests {
|
||||
let unit = ctx.pcnt.unit1;
|
||||
|
||||
// Setup channel 0 to increment the count when gpio2 does LOW -> HIGH
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
unit.channel0.set_edge_signal(PcntSource::from(
|
||||
ctx.input,
|
||||
PcntInputConfig { pull: Pull::Up },
|
||||
));
|
||||
@ -131,7 +131,7 @@ mod tests {
|
||||
unit.set_high_limit(Some(3)).unwrap();
|
||||
|
||||
// Setup channel 0 to increment the count when gpio2 does LOW -> HIGH
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
unit.channel0.set_edge_signal(PcntSource::from(
|
||||
ctx.input,
|
||||
PcntInputConfig { pull: Pull::Up },
|
||||
));
|
||||
@ -194,7 +194,7 @@ mod tests {
|
||||
unit.clear();
|
||||
|
||||
// Setup channel 0 to increment the count when gpio2 does LOW -> HIGH
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
unit.channel0.set_edge_signal(PcntSource::from(
|
||||
ctx.input,
|
||||
PcntInputConfig { pull: Pull::Up },
|
||||
));
|
||||
@ -261,7 +261,7 @@ mod tests {
|
||||
unit.clear();
|
||||
|
||||
// Setup channel 0 to decrement the count when gpio2 does LOW -> HIGH
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
unit.channel0.set_edge_signal(PcntSource::from(
|
||||
ctx.input,
|
||||
PcntInputConfig { pull: Pull::Up },
|
||||
));
|
||||
@ -319,7 +319,7 @@ mod tests {
|
||||
let unit = ctx.pcnt.unit2;
|
||||
|
||||
// Setup channel 1 to increment the count when gpio2 does LOW -> HIGH
|
||||
unit.channel1.set_edge_signal(PcntSource::from_pin(
|
||||
unit.channel1.set_edge_signal(PcntSource::from(
|
||||
ctx.input,
|
||||
PcntInputConfig { pull: Pull::Up },
|
||||
));
|
||||
|
@ -8,7 +8,7 @@
|
||||
use esp_hal::{
|
||||
dma::{Channel, Dma, DmaPriority, DmaRxBuf},
|
||||
dma_buffers,
|
||||
gpio::{ErasedPin, Io, Level, Output},
|
||||
gpio::{AnyPin, Io, Level, Output},
|
||||
prelude::*,
|
||||
spi::{
|
||||
master::{Address, Command, Spi, SpiDma},
|
||||
@ -34,7 +34,7 @@ cfg_if::cfg_if! {
|
||||
struct Context {
|
||||
spi: esp_hal::peripherals::SPI2,
|
||||
dma_channel: Channel<'static, DmaChannel0, Blocking>,
|
||||
miso: ErasedPin,
|
||||
miso: AnyPin,
|
||||
miso_mirror: Output<'static>,
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,10 @@ cfg_if::cfg_if! {
|
||||
|
||||
struct Context {
|
||||
spi: esp_hal::peripherals::SPI2,
|
||||
pcnt_source: PcntSource,
|
||||
pcnt: esp_hal::peripherals::PCNT,
|
||||
dma_channel: Channel<'static, DmaChannel0, Blocking>,
|
||||
mosi: AnyPin<'static>,
|
||||
mosi_mirror: AnyPin<'static>,
|
||||
mosi: AnyPin,
|
||||
}
|
||||
|
||||
fn execute(
|
||||
@ -103,10 +103,9 @@ mod tests {
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
let (mosi, mosi_mirror) = hil_test::common_test_pins!(io);
|
||||
let (mosi, _) = hil_test::common_test_pins!(io);
|
||||
|
||||
let mosi = AnyPin::new(mosi);
|
||||
let mosi_mirror = AnyPin::new(mosi_mirror);
|
||||
let mosi = mosi.degrade();
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
|
||||
@ -122,10 +121,13 @@ mod tests {
|
||||
|
||||
Context {
|
||||
spi: peripherals.SPI2,
|
||||
pcnt_source: PcntSource::from(
|
||||
mosi.peripheral_input(),
|
||||
PcntInputConfig { pull: Pull::None },
|
||||
),
|
||||
pcnt: peripherals.PCNT,
|
||||
dma_channel,
|
||||
mosi,
|
||||
mosi_mirror,
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,10 +148,7 @@ mod tests {
|
||||
let pcnt = Pcnt::new(ctx.pcnt);
|
||||
let unit = pcnt.unit0;
|
||||
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::None },
|
||||
));
|
||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
unit.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
|
||||
@ -173,10 +172,7 @@ mod tests {
|
||||
let pcnt = Pcnt::new(ctx.pcnt);
|
||||
let unit = pcnt.unit0;
|
||||
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::None },
|
||||
));
|
||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
unit.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
|
||||
@ -200,10 +196,7 @@ mod tests {
|
||||
let pcnt = Pcnt::new(ctx.pcnt);
|
||||
let unit = pcnt.unit0;
|
||||
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::None },
|
||||
));
|
||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
unit.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
|
||||
@ -227,10 +220,7 @@ mod tests {
|
||||
let pcnt = Pcnt::new(ctx.pcnt);
|
||||
let unit = pcnt.unit0;
|
||||
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::None },
|
||||
));
|
||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
unit.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
use esp_hal::{
|
||||
dma::{Channel, Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{ErasedPin, Io, Level, Output},
|
||||
gpio::{AnyPin, Io, Level, Output},
|
||||
prelude::*,
|
||||
spi::{
|
||||
master::{Address, Command, Spi, SpiDma},
|
||||
@ -36,7 +36,7 @@ cfg_if::cfg_if! {
|
||||
struct Context {
|
||||
spi: esp_hal::peripherals::SPI2,
|
||||
dma_channel: Channel<'static, DmaChannel0, Blocking>,
|
||||
mosi: ErasedPin,
|
||||
mosi: AnyPin,
|
||||
mosi_mirror: Output<'static>,
|
||||
}
|
||||
|
||||
|
@ -31,12 +31,13 @@ mod tests {
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
let sclk = io.pins.gpio0;
|
||||
let (miso, mosi) = hil_test::common_test_pins!(io);
|
||||
let (_, mosi) = hil_test::common_test_pins!(io);
|
||||
|
||||
let spi = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0)
|
||||
let mosi_loopback = mosi.peripheral_input();
|
||||
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
||||
.with_sck(sclk)
|
||||
.with_mosi(mosi)
|
||||
.with_miso(miso);
|
||||
.with_miso(mosi_loopback);
|
||||
|
||||
Context { spi }
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ mod tests {
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let sclk = io.pins.gpio0;
|
||||
let (miso, mosi) = hil_test::common_test_pins!(io);
|
||||
let (_, mosi) = hil_test::common_test_pins!(io);
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
|
||||
@ -60,10 +60,11 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
let mosi_loopback = mosi.peripheral_input();
|
||||
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
||||
.with_sck(sclk)
|
||||
.with_mosi(mosi)
|
||||
.with_miso(miso)
|
||||
.with_miso(mosi_loopback)
|
||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
||||
|
||||
Context { spi }
|
||||
|
@ -10,7 +10,7 @@ use embedded_hal_async::spi::SpiBus;
|
||||
use esp_hal::{
|
||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{ErasedPin, Io, Level, Output, Pull},
|
||||
gpio::{Io, Pull},
|
||||
pcnt::{
|
||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
||||
unit::Unit,
|
||||
@ -42,9 +42,8 @@ const DMA_BUFFER_SIZE: usize = 5;
|
||||
|
||||
struct Context {
|
||||
spi: SpiDmaBus<'static, SPI2, DmaChannel0, FullDuplexMode, Async>,
|
||||
pcnt_source: PcntSource,
|
||||
pcnt_unit: Unit<'static, 0>,
|
||||
out_pin: Output<'static>,
|
||||
mosi_mirror: ErasedPin,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -62,13 +61,7 @@ mod tests {
|
||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
||||
let sclk = io.pins.gpio0;
|
||||
|
||||
let (mosi_mirror, mosi) = hil_test::common_test_pins!(io);
|
||||
let miso = io.pins.gpio4;
|
||||
let mosi_mirror = mosi_mirror.degrade();
|
||||
|
||||
let mut out_pin = Output::new(io.pins.gpio5, Level::Low);
|
||||
out_pin.set_low();
|
||||
assert_eq!(out_pin.is_set_low(), true);
|
||||
let (_, mosi) = hil_test::common_test_pins!(io);
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
|
||||
@ -84,28 +77,26 @@ mod tests {
|
||||
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||
|
||||
let mosi_loopback = mosi.peripheral_input();
|
||||
let mosi_loopback_pcnt = mosi.peripheral_input();
|
||||
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
||||
.with_sck(sclk)
|
||||
.with_mosi(mosi)
|
||||
.with_miso(miso)
|
||||
.with_miso(mosi_loopback)
|
||||
.with_dma(dma_channel.configure_for_async(false, DmaPriority::Priority0))
|
||||
.with_buffers(dma_rx_buf, dma_tx_buf);
|
||||
|
||||
Context {
|
||||
spi,
|
||||
pcnt_source: PcntSource::from(mosi_loopback_pcnt, PcntInputConfig { pull: Pull::Down }),
|
||||
pcnt_unit: pcnt.unit0,
|
||||
out_pin,
|
||||
mosi_mirror,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
async fn test_async_dma_read_dma_write_pcnt(mut ctx: Context) {
|
||||
ctx.pcnt_unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::Down },
|
||||
));
|
||||
ctx.pcnt_unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
ctx.pcnt_unit
|
||||
.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
@ -115,8 +106,6 @@ mod tests {
|
||||
// Fill the buffer where each byte has 3 pos edges.
|
||||
let transmit = [0b0110_1010; DMA_BUFFER_SIZE];
|
||||
|
||||
assert_eq!(ctx.out_pin.is_set_low(), true);
|
||||
|
||||
for i in 1..4 {
|
||||
receive.copy_from_slice(&[5, 5, 5, 5, 5]);
|
||||
SpiBus::read(&mut ctx.spi, &mut receive).await.unwrap();
|
||||
@ -130,10 +119,7 @@ mod tests {
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
async fn test_async_dma_read_dma_transfer_pcnt(mut ctx: Context) {
|
||||
ctx.pcnt_unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::Down },
|
||||
));
|
||||
ctx.pcnt_unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
ctx.pcnt_unit
|
||||
.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
@ -143,8 +129,6 @@ mod tests {
|
||||
// Fill the buffer where each byte has 3 pos edges.
|
||||
let transmit = [0b0110_1010; DMA_BUFFER_SIZE];
|
||||
|
||||
assert_eq!(ctx.out_pin.is_set_low(), true);
|
||||
|
||||
for i in 1..4 {
|
||||
receive.copy_from_slice(&[5, 5, 5, 5, 5]);
|
||||
SpiBus::read(&mut ctx.spi, &mut receive).await.unwrap();
|
||||
|
@ -8,7 +8,7 @@
|
||||
use esp_hal::{
|
||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{ErasedPin, Io, Level, Output, Pull},
|
||||
gpio::{Io, Pull},
|
||||
pcnt::{
|
||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
||||
unit::Unit,
|
||||
@ -38,9 +38,8 @@ cfg_if::cfg_if! {
|
||||
|
||||
struct Context {
|
||||
spi: SpiDma<'static, SPI2, DmaChannel0, FullDuplexMode, Blocking>,
|
||||
pcnt_source: PcntSource,
|
||||
pcnt_unit: Unit<'static, 0>,
|
||||
out_pin: Output<'static>,
|
||||
mosi_mirror: ErasedPin,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -56,8 +55,7 @@ mod tests {
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let sclk = io.pins.gpio0;
|
||||
let (mosi_mirror, mosi) = hil_test::common_test_pins!(io);
|
||||
let miso = io.pins.gpio4;
|
||||
let (_, mosi) = hil_test::common_test_pins!(io);
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
|
||||
@ -69,24 +67,20 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
let mosi_loopback = mosi.peripheral_input();
|
||||
let mosi_loopback_pcnt = mosi.peripheral_input();
|
||||
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
||||
.with_sck(sclk)
|
||||
.with_mosi(mosi)
|
||||
.with_miso(miso)
|
||||
.with_miso(mosi_loopback)
|
||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
||||
|
||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
||||
|
||||
let mut out_pin = Output::new(io.pins.gpio5, Level::Low);
|
||||
out_pin.set_low();
|
||||
assert_eq!(out_pin.is_set_low(), true);
|
||||
let mosi_mirror = mosi_mirror.degrade();
|
||||
|
||||
Context {
|
||||
spi,
|
||||
pcnt_source: PcntSource::from(mosi_loopback_pcnt, PcntInputConfig { pull: Pull::Down }),
|
||||
pcnt_unit: pcnt.unit0,
|
||||
out_pin,
|
||||
mosi_mirror,
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,18 +95,13 @@ mod tests {
|
||||
let unit = ctx.pcnt_unit;
|
||||
let mut spi = ctx.spi;
|
||||
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::Down },
|
||||
));
|
||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
unit.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
|
||||
// Fill the buffer where each byte has 3 pos edges.
|
||||
dma_tx_buf.as_mut_slice().fill(0b0110_1010);
|
||||
|
||||
assert_eq!(ctx.out_pin.is_set_low(), true);
|
||||
|
||||
for i in 1..4 {
|
||||
dma_rx_buf.as_mut_slice().copy_from_slice(&[5, 5, 5, 5, 5]);
|
||||
let transfer = spi.dma_read(dma_rx_buf).map_err(|e| e.0).unwrap();
|
||||
@ -136,18 +125,13 @@ mod tests {
|
||||
let unit = ctx.pcnt_unit;
|
||||
let mut spi = ctx.spi;
|
||||
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::Down },
|
||||
));
|
||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
unit.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
|
||||
// Fill the buffer where each byte has 3 pos edges.
|
||||
dma_tx_buf.as_mut_slice().fill(0b0110_1010);
|
||||
|
||||
assert_eq!(ctx.out_pin.is_set_low(), true);
|
||||
|
||||
for i in 1..4 {
|
||||
dma_rx_buf.as_mut_slice().copy_from_slice(&[5, 5, 5, 5, 5]);
|
||||
let transfer = spi.dma_read(dma_rx_buf).map_err(|e| e.0).unwrap();
|
||||
|
@ -8,7 +8,7 @@
|
||||
use esp_hal::{
|
||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
||||
dma_buffers,
|
||||
gpio::{AnyPin, Io, Pull},
|
||||
gpio::{Io, Pull},
|
||||
pcnt::{
|
||||
channel::{EdgeMode, PcntInputConfig, PcntSource},
|
||||
unit::Unit,
|
||||
@ -40,7 +40,7 @@ cfg_if::cfg_if! {
|
||||
struct Context {
|
||||
spi: SpiDma<'static, SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
|
||||
pcnt_unit: Unit<'static, 0>,
|
||||
mosi_mirror: AnyPin<'static>,
|
||||
pcnt_source: PcntSource,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -59,9 +59,7 @@ mod tests {
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let sclk = io.pins.gpio0;
|
||||
let (mosi, mosi_mirror) = hil_test::common_test_pins!(io);
|
||||
|
||||
let mosi_mirror = AnyPin::new(mosi_mirror);
|
||||
let (mosi, _) = hil_test::common_test_pins!(io);
|
||||
|
||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
@ -74,6 +72,8 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
let mosi_loopback = mosi.peripheral_input();
|
||||
|
||||
let spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
||||
.with_sck(sclk)
|
||||
.with_mosi(mosi)
|
||||
@ -81,7 +81,7 @@ mod tests {
|
||||
|
||||
Context {
|
||||
spi,
|
||||
mosi_mirror,
|
||||
pcnt_source: PcntSource::from(mosi_loopback, PcntInputConfig { pull: Pull::Down }),
|
||||
pcnt_unit: pcnt.unit0,
|
||||
}
|
||||
}
|
||||
@ -97,10 +97,7 @@ mod tests {
|
||||
let unit = ctx.pcnt_unit;
|
||||
let mut spi = ctx.spi;
|
||||
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::Down },
|
||||
));
|
||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
unit.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
|
||||
@ -148,10 +145,7 @@ mod tests {
|
||||
let unit = ctx.pcnt_unit;
|
||||
let mut spi = ctx.spi.with_buffers(dma_rx_buf, dma_tx_buf);
|
||||
|
||||
unit.channel0.set_edge_signal(PcntSource::from_pin(
|
||||
ctx.mosi_mirror,
|
||||
PcntInputConfig { pull: Pull::Down },
|
||||
));
|
||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||
unit.channel0
|
||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user