mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00
Peripheral interconnect redo, vol 2 (split()
) (#2418)
* Replace peripheral connection conversions with split * Constrain Flex conversions
This commit is contained in:
parent
177db100fb
commit
0c86740418
@ -26,6 +26,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- `DmaDescriptor` is now `Send` (#2456)
|
- `DmaDescriptor` is now `Send` (#2456)
|
||||||
- `into_async` and `into_blocking` functions for most peripherals (#2430)
|
- `into_async` and `into_blocking` functions for most peripherals (#2430)
|
||||||
- API mode type parameter (currently always `Blocking`) to `master::Spi` and `slave::Spi` (#2430)
|
- API mode type parameter (currently always `Blocking`) to `master::Spi` and `slave::Spi` (#2430)
|
||||||
|
- `gpio::{GpioPin, AnyPin, Flex, Output, OutputOpenDrain}::split()` to obtain peripheral interconnect signals. (#2418)
|
||||||
|
- `gpio::Input::{split(), into_peripheral_output()}` when used with output pins. (#2418)
|
||||||
|
- `gpio::Output::peripheral_input()` (#2418)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@ -42,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- SPI interrupt listening is now only available in Blocking mode. The `set_interrupt_handler` is available via `InterruptConfigurable` (#2442)
|
- SPI interrupt listening is now only available in Blocking mode. The `set_interrupt_handler` is available via `InterruptConfigurable` (#2442)
|
||||||
- Allow users to create DMA `Preparation`s (#2455)
|
- Allow users to create DMA `Preparation`s (#2455)
|
||||||
- The `rmt::asynch::RxChannelAsync` and `rmt::asynch::TxChannelAsync` traits have been moved to `rmt` (#2430)
|
- The `rmt::asynch::RxChannelAsync` and `rmt::asynch::TxChannelAsync` traits have been moved to `rmt` (#2430)
|
||||||
|
- Calling `AnyPin::output_signals` on an input-only pin (ESP32 GPIO 34-39) will now result in a panic. (#2418)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -194,7 +194,8 @@ You can now listen/unlisten multiple interrupt bits at once:
|
|||||||
-uart0.listen_at_cmd();
|
-uart0.listen_at_cmd();
|
||||||
-uart0.listen_rx_fifo_full();
|
-uart0.listen_rx_fifo_full();
|
||||||
+uart0.listen(UartInterrupt::AtCmd | UartConterrupt::RxFifoFull);
|
+uart0.listen(UartInterrupt::AtCmd | UartConterrupt::RxFifoFull);
|
||||||
```˛
|
```
|
||||||
|
|
||||||
## Circular DMA transfer's `available` returns `Result<usize, DmaError>` now
|
## Circular DMA transfer's `available` returns `Result<usize, DmaError>` now
|
||||||
|
|
||||||
In case of any error you should drop the transfer and restart it.
|
In case of any error you should drop the transfer and restart it.
|
||||||
@ -211,3 +212,21 @@ In case of any error you should drop the transfer and restart it.
|
|||||||
+ },
|
+ },
|
||||||
+ };
|
+ };
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Removed `peripheral_input` and `into_peripheral_output` from GPIO pin types
|
||||||
|
|
||||||
|
Creating peripheral interconnect signals now consume the GPIO pin used for the connection.
|
||||||
|
|
||||||
|
The previous signal function have been replaced by `split`. This change affects the following APIs:
|
||||||
|
|
||||||
|
- `GpioPin`
|
||||||
|
- `AnyPin`
|
||||||
|
|
||||||
|
```diff
|
||||||
|
-let input_signal = gpioN.peripheral_input();
|
||||||
|
-let output_signal = gpioN.into_peripheral_output();
|
||||||
|
+let (input_signal, output_signal) = gpioN.split();
|
||||||
|
```
|
||||||
|
|
||||||
|
`into_peripheral_output`, `split` (for output pins only) and `peripheral_input` have been added to
|
||||||
|
the GPIO drivers (`Input`, `Output`, `OutputOpenDrain` and `Flex`) instead.
|
||||||
|
@ -54,9 +54,6 @@ impl PeripheralOutput for OutputConnection {}
|
|||||||
|
|
||||||
/// A configurable input signal between a peripheral and a GPIO pin.
|
/// A configurable input signal between a peripheral and a GPIO pin.
|
||||||
///
|
///
|
||||||
/// Obtained by calling [`super::GpioPin::peripheral_input()`],
|
|
||||||
/// [`super::Flex::peripheral_input()`] or [`super::Input::peripheral_input()`].
|
|
||||||
///
|
|
||||||
/// Multiple input signals can be connected to one pin.
|
/// Multiple input signals can be connected to one pin.
|
||||||
pub struct InputSignal {
|
pub struct InputSignal {
|
||||||
pin: AnyPin,
|
pin: AnyPin,
|
||||||
@ -188,10 +185,6 @@ impl InputSignal {
|
|||||||
|
|
||||||
/// A configurable output signal between a peripheral and a GPIO pin.
|
/// A configurable output signal between a peripheral and a GPIO pin.
|
||||||
///
|
///
|
||||||
/// Obtained by calling [`super::GpioPin::into_peripheral_output()`],
|
|
||||||
/// [`super::Flex::into_peripheral_output()`] or
|
|
||||||
/// [`super::Output::into_peripheral_output()`].
|
|
||||||
///
|
|
||||||
/// Multiple pins can be connected to one output signal.
|
/// Multiple pins can be connected to one output signal.
|
||||||
pub struct OutputSignal {
|
pub struct OutputSignal {
|
||||||
pin: AnyPin,
|
pin: AnyPin,
|
||||||
@ -441,9 +434,9 @@ where
|
|||||||
P: InputPin,
|
P: InputPin,
|
||||||
{
|
{
|
||||||
fn from(input: P) -> Self {
|
fn from(input: P) -> Self {
|
||||||
Self(InputConnectionInner::Input(
|
Self(InputConnectionInner::Input(InputSignal::new(
|
||||||
input.degrade().peripheral_input(),
|
input.degrade(),
|
||||||
))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,9 +527,9 @@ where
|
|||||||
P: OutputPin,
|
P: OutputPin,
|
||||||
{
|
{
|
||||||
fn from(input: P) -> Self {
|
fn from(input: P) -> Self {
|
||||||
Self(OutputConnectionInner::Output(
|
Self(OutputConnectionInner::Output(OutputSignal::new(
|
||||||
input.degrade().into_peripheral_output(),
|
input.degrade(),
|
||||||
))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,13 +723,15 @@ where
|
|||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a peripheral [input][interconnect::InputSignal] connected to
|
/// Split the pin into an input and output signal.
|
||||||
/// this pin.
|
|
||||||
///
|
///
|
||||||
/// The input signal can be passed to peripherals in place of an input pin.
|
/// Peripheral signals allow connecting peripherals together without using
|
||||||
#[inline]
|
/// external hardware.
|
||||||
pub fn peripheral_input(&self) -> interconnect::InputSignal {
|
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
|
||||||
interconnect::InputSignal::new(self.degrade_pin(private::Internal))
|
(
|
||||||
|
interconnect::InputSignal::new(self.degrade_pin(private::Internal)),
|
||||||
|
interconnect::OutputSignal::new(self.degrade_pin(private::Internal)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,21 +779,6 @@ where
|
|||||||
|
|
||||||
impl<const GPIONUM: u8> private::Sealed for GpioPin<GPIONUM> {}
|
impl<const GPIONUM: u8> private::Sealed for GpioPin<GPIONUM> {}
|
||||||
|
|
||||||
impl<const GPIONUM: u8> GpioPin<GPIONUM>
|
|
||||||
where
|
|
||||||
Self: OutputPin,
|
|
||||||
{
|
|
||||||
/// Turns the pin object into a peripheral
|
|
||||||
/// [output][interconnect::OutputSignal].
|
|
||||||
///
|
|
||||||
/// The output signal can be passed to peripherals in place of an output
|
|
||||||
/// pin.
|
|
||||||
#[inline]
|
|
||||||
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
|
|
||||||
interconnect::OutputSignal::new(self.degrade_pin(private::Internal))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// General Purpose Input/Output driver
|
/// General Purpose Input/Output driver
|
||||||
pub struct Io {
|
pub struct Io {
|
||||||
_io_mux: IO_MUX,
|
_io_mux: IO_MUX,
|
||||||
@ -1151,20 +1138,41 @@ where
|
|||||||
/// Create GPIO output driver for a [GpioPin] with the provided level
|
/// Create GPIO output driver for a [GpioPin] with the provided level
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_typed(pin: impl Peripheral<P = P> + 'd, initial_output: Level) -> Self {
|
pub fn new_typed(pin: impl Peripheral<P = P> + 'd, initial_output: Level) -> Self {
|
||||||
let pin = Flex::new_typed(pin);
|
let mut pin = Flex::new_typed(pin);
|
||||||
|
|
||||||
Self::new_inner(pin, initial_output)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_inner(mut pin: Flex<'d, P>, initial_output: Level) -> Self {
|
|
||||||
pin.pin
|
|
||||||
.set_output_high(initial_output.into(), private::Internal);
|
|
||||||
|
|
||||||
|
pin.set_level(initial_output);
|
||||||
pin.set_as_output();
|
pin.set_as_output();
|
||||||
|
|
||||||
Self { pin }
|
Self { pin }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Split the pin into an input and output signal.
|
||||||
|
///
|
||||||
|
/// Peripheral signals allow connecting peripherals together without using
|
||||||
|
/// external hardware.
|
||||||
|
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
|
||||||
|
self.pin.split()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a peripheral [input][interconnect::InputSignal] connected to
|
||||||
|
/// this pin.
|
||||||
|
///
|
||||||
|
/// The input signal can be passed to peripherals in place of an input pin.
|
||||||
|
#[inline]
|
||||||
|
pub fn peripheral_input(&self) -> interconnect::InputSignal {
|
||||||
|
self.pin.peripheral_input()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns the pin object into a peripheral
|
||||||
|
/// [output][interconnect::OutputSignal].
|
||||||
|
///
|
||||||
|
/// The output signal can be passed to peripherals in place of an output
|
||||||
|
/// pin.
|
||||||
|
#[inline]
|
||||||
|
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
|
||||||
|
self.pin.into_peripheral_output()
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the output as high.
|
/// Set the output as high.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_high(&mut self) {
|
pub fn set_high(&mut self) {
|
||||||
@ -1212,16 +1220,6 @@ where
|
|||||||
pub fn set_drive_strength(&mut self, strength: DriveStrength) {
|
pub fn set_drive_strength(&mut self, strength: DriveStrength) {
|
||||||
self.pin.set_drive_strength(strength);
|
self.pin.set_drive_strength(strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turns the pin object into a peripheral
|
|
||||||
/// [output][interconnect::OutputSignal].
|
|
||||||
///
|
|
||||||
/// The output signal can be passed to peripherals in place of an output
|
|
||||||
/// pin.
|
|
||||||
#[inline]
|
|
||||||
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
|
|
||||||
self.pin.into_peripheral_output()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GPIO input driver.
|
/// GPIO input driver.
|
||||||
@ -1262,6 +1260,15 @@ where
|
|||||||
Self { pin }
|
Self { pin }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a peripheral [input][interconnect::InputSignal] connected to
|
||||||
|
/// this pin.
|
||||||
|
///
|
||||||
|
/// The input signal can be passed to peripherals in place of an input pin.
|
||||||
|
#[inline]
|
||||||
|
pub fn peripheral_input(&self) -> interconnect::InputSignal {
|
||||||
|
self.pin.peripheral_input()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get whether the pin input level is high.
|
/// Get whether the pin input level is high.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_high(&self) -> bool {
|
pub fn is_high(&self) -> bool {
|
||||||
@ -1311,14 +1318,28 @@ where
|
|||||||
pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) {
|
pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) {
|
||||||
self.pin.wakeup_enable(enable, event);
|
self.pin.wakeup_enable(enable, event);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a peripheral [input][interconnect::InputSignal] connected to
|
impl<P> Input<'_, P>
|
||||||
/// this pin.
|
where
|
||||||
|
P: InputPin + OutputPin,
|
||||||
|
{
|
||||||
|
/// Split the pin into an input and output signal.
|
||||||
///
|
///
|
||||||
/// The input signal can be passed to peripherals in place of an input pin.
|
/// Peripheral signals allow connecting peripherals together without using
|
||||||
|
/// external hardware.
|
||||||
|
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
|
||||||
|
self.pin.split()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns the pin object into a peripheral
|
||||||
|
/// [output][interconnect::OutputSignal].
|
||||||
|
///
|
||||||
|
/// The output signal can be passed to peripherals in place of an output
|
||||||
|
/// pin.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn peripheral_input(&self) -> interconnect::InputSignal {
|
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
|
||||||
self.pin.peripheral_input()
|
self.pin.into_peripheral_output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1365,6 +1386,33 @@ where
|
|||||||
Self { pin }
|
Self { pin }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Split the pin into an input and output signal.
|
||||||
|
///
|
||||||
|
/// Peripheral signals allow connecting peripherals together without using
|
||||||
|
/// external hardware.
|
||||||
|
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
|
||||||
|
self.pin.split()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a peripheral [input][interconnect::InputSignal] connected to
|
||||||
|
/// this pin.
|
||||||
|
///
|
||||||
|
/// The input signal can be passed to peripherals in place of an input pin.
|
||||||
|
#[inline]
|
||||||
|
pub fn peripheral_input(&self) -> interconnect::InputSignal {
|
||||||
|
self.pin.peripheral_input()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns the pin object into a peripheral
|
||||||
|
/// [output][interconnect::OutputSignal].
|
||||||
|
///
|
||||||
|
/// The output signal can be passed to peripherals in place of an output
|
||||||
|
/// pin.
|
||||||
|
#[inline]
|
||||||
|
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
|
||||||
|
self.pin.into_peripheral_output()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get whether the pin input level is high.
|
/// Get whether the pin input level is high.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_high(&self) -> bool {
|
pub fn is_high(&self) -> bool {
|
||||||
@ -1441,16 +1489,6 @@ where
|
|||||||
pub fn set_drive_strength(&mut self, strength: DriveStrength) {
|
pub fn set_drive_strength(&mut self, strength: DriveStrength) {
|
||||||
self.pin.set_drive_strength(strength);
|
self.pin.set_drive_strength(strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turns the pin object into a peripheral
|
|
||||||
/// [output][interconnect::OutputSignal].
|
|
||||||
///
|
|
||||||
/// The output signal can be passed to peripherals in place of an output
|
|
||||||
/// pin.
|
|
||||||
#[inline]
|
|
||||||
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
|
|
||||||
self.pin.into_peripheral_output()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flexible pin driver.
|
/// Flexible pin driver.
|
||||||
@ -1487,6 +1525,15 @@ where
|
|||||||
crate::into_ref!(pin);
|
crate::into_ref!(pin);
|
||||||
Self { pin }
|
Self { pin }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a peripheral [input][interconnect::InputSignal] connected to
|
||||||
|
/// this pin.
|
||||||
|
///
|
||||||
|
/// The input signal can be passed to peripherals in place of an input pin.
|
||||||
|
#[inline]
|
||||||
|
pub fn peripheral_input(&self) -> interconnect::InputSignal {
|
||||||
|
self.pin.degrade_pin(private::Internal).split().0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> Flex<'_, P>
|
impl<P> Flex<'_, P>
|
||||||
@ -1577,15 +1624,6 @@ where
|
|||||||
pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) {
|
pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) {
|
||||||
self.listen_with_options(event.into(), false, false, enable);
|
self.listen_with_options(event.into(), false, false, enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a peripheral [input][interconnect::InputSignal] connected to
|
|
||||||
/// this pin.
|
|
||||||
///
|
|
||||||
/// The input signal can be passed to peripherals in place of an input pin.
|
|
||||||
#[inline]
|
|
||||||
pub fn peripheral_input(&self) -> interconnect::InputSignal {
|
|
||||||
interconnect::InputSignal::new(self.pin.degrade_pin(private::Internal))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> Flex<'_, P>
|
impl<P> Flex<'_, P>
|
||||||
@ -1646,6 +1684,20 @@ where
|
|||||||
self.pin.set_drive_strength(strength, private::Internal);
|
self.pin.set_drive_strength(strength, private::Internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the GPIO to open-drain mode.
|
||||||
|
pub fn set_as_open_drain(&mut self, pull: Pull) {
|
||||||
|
self.pin.set_to_open_drain_output(private::Internal);
|
||||||
|
self.pin.pull_direction(pull, private::Internal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Split the pin into an input and output signal.
|
||||||
|
///
|
||||||
|
/// Peripheral signals allow connecting peripherals together without using
|
||||||
|
/// external hardware.
|
||||||
|
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
|
||||||
|
self.pin.degrade_pin(private::Internal).split()
|
||||||
|
}
|
||||||
|
|
||||||
/// Turns the pin object into a peripheral
|
/// Turns the pin object into a peripheral
|
||||||
/// [output][interconnect::OutputSignal].
|
/// [output][interconnect::OutputSignal].
|
||||||
///
|
///
|
||||||
@ -1653,18 +1705,7 @@ where
|
|||||||
/// pin.
|
/// pin.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
|
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
|
||||||
interconnect::OutputSignal::new(self.pin.degrade_pin(private::Internal))
|
self.split().1
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Flex<'_, P>
|
|
||||||
where
|
|
||||||
P: InputPin + OutputPin,
|
|
||||||
{
|
|
||||||
/// Set the GPIO to open-drain mode.
|
|
||||||
pub fn set_as_open_drain(&mut self, pull: Pull) {
|
|
||||||
self.pin.set_to_open_drain_output(private::Internal);
|
|
||||||
self.pin.pull_direction(pull, private::Internal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1674,24 +1715,13 @@ pub(crate) mod internal {
|
|||||||
impl private::Sealed for AnyPin {}
|
impl private::Sealed for AnyPin {}
|
||||||
|
|
||||||
impl AnyPin {
|
impl AnyPin {
|
||||||
/// Returns a peripheral [input][interconnect::InputSignal] connected to
|
/// Split the pin into an input and output signal.
|
||||||
/// this pin.
|
|
||||||
///
|
///
|
||||||
/// The input signal can be passed to peripherals in place of an input
|
/// Peripheral signals allow connecting peripherals together without
|
||||||
/// pin.
|
/// using external hardware.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn peripheral_input(&self) -> interconnect::InputSignal {
|
pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) {
|
||||||
handle_gpio_input!(&self.0, target, { target.peripheral_input() })
|
handle_gpio_input!(self.0, target, { target.split() })
|
||||||
}
|
|
||||||
|
|
||||||
/// Turns the pin object into a peripheral
|
|
||||||
/// [output][interconnect::OutputSignal].
|
|
||||||
///
|
|
||||||
/// The output signal can be passed to peripherals in place of an output
|
|
||||||
/// pin.
|
|
||||||
#[inline]
|
|
||||||
pub fn into_peripheral_output(self) -> interconnect::OutputSignal {
|
|
||||||
handle_gpio_output!(self.0, target, { target.into_peripheral_output() })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1717,7 +1747,7 @@ pub(crate) mod internal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn output_signals(&self, _: private::Internal) -> &[(AlternateFunction, OutputSignal)] {
|
fn output_signals(&self, _: private::Internal) -> &[(AlternateFunction, OutputSignal)] {
|
||||||
handle_gpio_input!(&self.0, target, {
|
handle_gpio_output!(&self.0, target, {
|
||||||
Pin::output_signals(target, private::Internal)
|
Pin::output_signals(target, private::Internal)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1736,7 +1766,74 @@ pub(crate) mod internal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InputPin for AnyPin {}
|
impl InputPin for AnyPin {}
|
||||||
impl OutputPin for AnyPin {}
|
|
||||||
|
// Need to forward these one by one because not all pins support all functions.
|
||||||
|
impl OutputPin for AnyPin {
|
||||||
|
fn init_output(
|
||||||
|
&mut self,
|
||||||
|
alternate: AlternateFunction,
|
||||||
|
open_drain: bool,
|
||||||
|
_: private::Internal,
|
||||||
|
) {
|
||||||
|
handle_gpio_output!(&mut self.0, target, {
|
||||||
|
OutputPin::init_output(target, alternate, open_drain, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_to_open_drain_output(&mut self, _: private::Internal) {
|
||||||
|
handle_gpio_output!(&mut self.0, target, {
|
||||||
|
OutputPin::set_to_open_drain_output(target, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_to_push_pull_output(&mut self, _: private::Internal) {
|
||||||
|
handle_gpio_output!(&mut self.0, target, {
|
||||||
|
OutputPin::set_to_push_pull_output(target, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_output_high(&mut self, high: bool, _: private::Internal) {
|
||||||
|
handle_gpio_output!(&mut self.0, target, {
|
||||||
|
OutputPin::set_output_high(target, high, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_drive_strength(&mut self, strength: DriveStrength, _: private::Internal) {
|
||||||
|
handle_gpio_output!(&mut self.0, target, {
|
||||||
|
OutputPin::set_drive_strength(target, strength, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enable_open_drain(&mut self, on: bool, _: private::Internal) {
|
||||||
|
handle_gpio_output!(&mut self.0, target, {
|
||||||
|
OutputPin::enable_open_drain(target, on, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enable_output_in_sleep_mode(&mut self, on: bool, _: private::Internal) {
|
||||||
|
handle_gpio_output!(&mut self.0, target, {
|
||||||
|
OutputPin::enable_output_in_sleep_mode(target, on, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _: private::Internal) {
|
||||||
|
handle_gpio_output!(&mut self.0, target, {
|
||||||
|
OutputPin::internal_pull_up_in_sleep_mode(target, on, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _: private::Internal) {
|
||||||
|
handle_gpio_output!(&mut self.0, target, {
|
||||||
|
OutputPin::internal_pull_down_in_sleep_mode(target, on, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_set_high(&self, _: private::Internal) -> bool {
|
||||||
|
handle_gpio_output!(&self.0, target, {
|
||||||
|
OutputPin::is_set_high(target, private::Internal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(xtensa, esp32c2, esp32c3, esp32c6))]
|
#[cfg(any(xtensa, esp32c2, esp32c3, esp32c6))]
|
||||||
impl RtcPin for AnyPin {
|
impl RtcPin for AnyPin {
|
||||||
|
@ -98,12 +98,12 @@
|
|||||||
//!
|
//!
|
||||||
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
//! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
//!
|
//!
|
||||||
//! let rx = io.pins.gpio2.peripheral_input().inverted();
|
//! let (rx, _) = io.pins.gpio2.split();
|
||||||
//! let tx = io.pins.gpio1.into_peripheral_output().inverted();
|
//! let (_, tx) = io.pins.gpio1.split();
|
||||||
//! let mut uart1 = Uart::new(
|
//! let mut uart1 = Uart::new(
|
||||||
//! peripherals.UART1,
|
//! peripherals.UART1,
|
||||||
//! rx,
|
//! rx.inverted(),
|
||||||
//! tx,
|
//! tx.inverted(),
|
||||||
//! ).unwrap();
|
//! ).unwrap();
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
@ -94,11 +94,11 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
|
|
||||||
let tx_pin = io.pins.gpio2;
|
|
||||||
// let rx_pin = io.pins.gpio0; // Uncomment if you want to use an external transceiver.
|
|
||||||
|
|
||||||
// Without an external transceiver, we only need a single line between the two MCUs.
|
// Without an external transceiver, we only need a single line between the two MCUs.
|
||||||
let rx_pin = tx_pin.peripheral_input(); // Comment this line if you want to use an external transceiver.
|
let (rx_pin, tx_pin) = io.pins.gpio2.split();
|
||||||
|
// Use these if you want to use an external transceiver:
|
||||||
|
// let tx_pin = io.pins.gpio2;
|
||||||
|
// let rx_pin = io.pins.gpio0;
|
||||||
|
|
||||||
// The speed of the bus.
|
// The speed of the bus.
|
||||||
const TWAI_BAUDRATE: twai::BaudRate = twai::BaudRate::B125K;
|
const TWAI_BAUDRATE: twai::BaudRate = twai::BaudRate::B125K;
|
||||||
|
@ -49,18 +49,22 @@ fn main() -> ! {
|
|||||||
|
|
||||||
println!("setup channel 0");
|
println!("setup channel 0");
|
||||||
let ch0 = &u0.channel0;
|
let ch0 = &u0.channel0;
|
||||||
|
|
||||||
let pin_a = Input::new(io.pins.gpio4, Pull::Up);
|
let pin_a = Input::new(io.pins.gpio4, Pull::Up);
|
||||||
let pin_b = Input::new(io.pins.gpio5, Pull::Up);
|
let pin_b = Input::new(io.pins.gpio5, Pull::Up);
|
||||||
|
|
||||||
ch0.set_ctrl_signal(pin_a.peripheral_input());
|
let (input_a, _) = pin_a.split();
|
||||||
ch0.set_edge_signal(pin_b.peripheral_input());
|
let (input_b, _) = pin_b.split();
|
||||||
|
|
||||||
|
ch0.set_ctrl_signal(input_a.clone());
|
||||||
|
ch0.set_edge_signal(input_b.clone());
|
||||||
ch0.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep);
|
ch0.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep);
|
||||||
ch0.set_input_mode(channel::EdgeMode::Increment, channel::EdgeMode::Decrement);
|
ch0.set_input_mode(channel::EdgeMode::Increment, channel::EdgeMode::Decrement);
|
||||||
|
|
||||||
println!("setup channel 1");
|
println!("setup channel 1");
|
||||||
let ch1 = &u0.channel1;
|
let ch1 = &u0.channel1;
|
||||||
ch1.set_ctrl_signal(pin_b.peripheral_input());
|
ch1.set_ctrl_signal(input_b);
|
||||||
ch1.set_edge_signal(pin_a.peripheral_input());
|
ch1.set_edge_signal(input_a);
|
||||||
ch1.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep);
|
ch1.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep);
|
||||||
ch1.set_input_mode(channel::EdgeMode::Decrement, channel::EdgeMode::Increment);
|
ch1.set_input_mode(channel::EdgeMode::Decrement, channel::EdgeMode::Increment);
|
||||||
|
|
||||||
|
@ -42,11 +42,11 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
|
|
||||||
let tx_pin = io.pins.gpio2;
|
|
||||||
// let rx_pin = io.pins.gpio0; // Uncomment if you want to use an external transceiver.
|
|
||||||
|
|
||||||
// Without an external transceiver, we only need a single line between the two MCUs.
|
// Without an external transceiver, we only need a single line between the two MCUs.
|
||||||
let rx_pin = tx_pin.peripheral_input(); // Comment this line if you want to use an external transceiver.
|
let (rx_pin, tx_pin) = io.pins.gpio2.split();
|
||||||
|
// Use these if you want to use an external transceiver:
|
||||||
|
// let tx_pin = io.pins.gpio2;
|
||||||
|
// let rx_pin = io.pins.gpio0;
|
||||||
|
|
||||||
// The speed of the bus.
|
// The speed of the bus.
|
||||||
const TWAI_BAUDRATE: twai::BaudRate = twai::BaudRate::B125K;
|
const TWAI_BAUDRATE: twai::BaudRate = twai::BaudRate::B125K;
|
||||||
|
@ -151,7 +151,7 @@ mod tests {
|
|||||||
|
|
||||||
let (_, dout) = hil_test::common_test_pins!(ctx.io);
|
let (_, dout) = hil_test::common_test_pins!(ctx.io);
|
||||||
|
|
||||||
let din = dout.peripheral_input();
|
let (din, dout) = dout.split();
|
||||||
|
|
||||||
let i2s_tx = i2s
|
let i2s_tx = i2s
|
||||||
.i2s_tx
|
.i2s_tx
|
||||||
@ -205,7 +205,7 @@ mod tests {
|
|||||||
|
|
||||||
let (_, dout) = hil_test::common_test_pins!(ctx.io);
|
let (_, dout) = hil_test::common_test_pins!(ctx.io);
|
||||||
|
|
||||||
let din = dout.peripheral_input();
|
let (din, dout) = dout.split();
|
||||||
|
|
||||||
let mut i2s_tx = i2s
|
let mut i2s_tx = i2s
|
||||||
.i2s_tx
|
.i2s_tx
|
||||||
@ -347,7 +347,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let (_, dout) = hil_test::common_test_pins!(ctx.io);
|
let (_, dout) = hil_test::common_test_pins!(ctx.io);
|
||||||
let din = dout.peripheral_input();
|
|
||||||
|
let (din, dout) = dout.split();
|
||||||
|
|
||||||
let mut i2s_rx = i2s
|
let mut i2s_rx = i2s
|
||||||
.i2s_rx
|
.i2s_rx
|
||||||
|
@ -102,20 +102,14 @@ mod tests {
|
|||||||
// issue with configuring pins as outputs after inputs have been sorted
|
// issue with configuring pins as outputs after inputs have been sorted
|
||||||
// out. See https://github.com/esp-rs/esp-hal/pull/2173#issue-2529323702
|
// out. See https://github.com/esp-rs/esp-hal/pull/2173#issue-2529323702
|
||||||
|
|
||||||
let cs_signal = ctx.io.pins.gpio8;
|
let (unit_ctrl, cs_signal) = ctx.io.pins.gpio8.split();
|
||||||
let unit0_signal = ctx.io.pins.gpio11;
|
let (unit0_input, unit0_signal) = ctx.io.pins.gpio11.split();
|
||||||
let unit1_signal = ctx.io.pins.gpio12;
|
let (unit1_input, unit1_signal) = ctx.io.pins.gpio12.split();
|
||||||
let unit2_signal = ctx.io.pins.gpio16;
|
let (unit2_input, unit2_signal) = ctx.io.pins.gpio16.split();
|
||||||
let unit3_signal = ctx.io.pins.gpio17;
|
let (unit3_input, unit3_signal) = ctx.io.pins.gpio17.split();
|
||||||
|
|
||||||
let pcnt = ctx.pcnt;
|
let pcnt = ctx.pcnt;
|
||||||
|
|
||||||
let unit_ctrl = cs_signal.peripheral_input();
|
|
||||||
let unit0_input = unit0_signal.peripheral_input();
|
|
||||||
let unit1_input = unit1_signal.peripheral_input();
|
|
||||||
let unit2_input = unit2_signal.peripheral_input();
|
|
||||||
let unit3_input = unit3_signal.peripheral_input();
|
|
||||||
|
|
||||||
pcnt.unit0
|
pcnt.unit0
|
||||||
.channel0
|
.channel0
|
||||||
.set_ctrl_mode(CtrlMode::Keep, CtrlMode::Disable);
|
.set_ctrl_mode(CtrlMode::Keep, CtrlMode::Disable);
|
||||||
@ -219,20 +213,14 @@ mod tests {
|
|||||||
// issue with configuring pins as outputs after inputs have been sorted
|
// issue with configuring pins as outputs after inputs have been sorted
|
||||||
// out. See https://github.com/esp-rs/esp-hal/pull/2173#issue-2529323702
|
// out. See https://github.com/esp-rs/esp-hal/pull/2173#issue-2529323702
|
||||||
|
|
||||||
let cs_signal = ctx.io.pins.gpio8;
|
let (unit_ctrl, cs_signal) = ctx.io.pins.gpio8.split();
|
||||||
let unit0_signal = ctx.io.pins.gpio11;
|
let (unit0_input, unit0_signal) = ctx.io.pins.gpio11.split();
|
||||||
let unit1_signal = ctx.io.pins.gpio12;
|
let (unit1_input, unit1_signal) = ctx.io.pins.gpio12.split();
|
||||||
let unit2_signal = ctx.io.pins.gpio16;
|
let (unit2_input, unit2_signal) = ctx.io.pins.gpio16.split();
|
||||||
let unit3_signal = ctx.io.pins.gpio17;
|
let (unit3_input, unit3_signal) = ctx.io.pins.gpio17.split();
|
||||||
|
|
||||||
let pcnt = ctx.pcnt;
|
let pcnt = ctx.pcnt;
|
||||||
|
|
||||||
let unit_ctrl = cs_signal.peripheral_input();
|
|
||||||
let unit0_input = unit0_signal.peripheral_input();
|
|
||||||
let unit1_input = unit1_signal.peripheral_input();
|
|
||||||
let unit2_input = unit2_signal.peripheral_input();
|
|
||||||
let unit3_input = unit3_signal.peripheral_input();
|
|
||||||
|
|
||||||
pcnt.unit0
|
pcnt.unit0
|
||||||
.channel0
|
.channel0
|
||||||
.set_ctrl_mode(CtrlMode::Keep, CtrlMode::Disable);
|
.set_ctrl_mode(CtrlMode::Keep, CtrlMode::Disable);
|
||||||
|
@ -8,7 +8,11 @@
|
|||||||
use esp_hal::parl_io::{TxPinConfigWithValidPin, TxSixteenBits};
|
use esp_hal::parl_io::{TxPinConfigWithValidPin, TxSixteenBits};
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{ChannelCreator, Dma, DmaPriority},
|
dma::{ChannelCreator, Dma, DmaPriority},
|
||||||
gpio::{interconnect::InputSignal, AnyPin, Io, NoPin},
|
gpio::{
|
||||||
|
interconnect::{InputSignal, OutputSignal},
|
||||||
|
Io,
|
||||||
|
NoPin,
|
||||||
|
},
|
||||||
parl_io::{
|
parl_io::{
|
||||||
BitPackOrder,
|
BitPackOrder,
|
||||||
ClkOutPin,
|
ClkOutPin,
|
||||||
@ -30,8 +34,8 @@ use hil_test as _;
|
|||||||
struct Context {
|
struct Context {
|
||||||
parl_io: PARL_IO,
|
parl_io: PARL_IO,
|
||||||
dma_channel: ChannelCreator<0>,
|
dma_channel: ChannelCreator<0>,
|
||||||
clock: AnyPin,
|
clock: OutputSignal,
|
||||||
valid: AnyPin,
|
valid: OutputSignal,
|
||||||
clock_loopback: InputSignal,
|
clock_loopback: InputSignal,
|
||||||
valid_loopback: InputSignal,
|
valid_loopback: InputSignal,
|
||||||
pcnt_unit: Unit<'static, 0>,
|
pcnt_unit: Unit<'static, 0>,
|
||||||
@ -50,10 +54,9 @@ mod tests {
|
|||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let (clock, _) = hil_test::common_test_pins!(io);
|
let (clock, _) = hil_test::common_test_pins!(io);
|
||||||
let valid = io.pins.gpio0.degrade();
|
let valid = hil_test::unconnected_pin!(io);
|
||||||
let clock_loopback = clock.peripheral_input();
|
let (clock_loopback, clock) = clock.split();
|
||||||
let valid_loopback = valid.peripheral_input();
|
let (valid_loopback, valid) = valid.split();
|
||||||
let clock = clock.degrade();
|
|
||||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
let pcnt = Pcnt::new(peripherals.PCNT);
|
||||||
let pcnt_unit = pcnt.unit0;
|
let pcnt_unit = pcnt.unit0;
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
|
@ -10,7 +10,11 @@
|
|||||||
use esp_hal::parl_io::{TxPinConfigWithValidPin, TxSixteenBits};
|
use esp_hal::parl_io::{TxPinConfigWithValidPin, TxSixteenBits};
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{ChannelCreator, Dma, DmaPriority},
|
dma::{ChannelCreator, Dma, DmaPriority},
|
||||||
gpio::{interconnect::InputSignal, AnyPin, Io, NoPin},
|
gpio::{
|
||||||
|
interconnect::{InputSignal, OutputSignal},
|
||||||
|
Io,
|
||||||
|
NoPin,
|
||||||
|
},
|
||||||
parl_io::{
|
parl_io::{
|
||||||
BitPackOrder,
|
BitPackOrder,
|
||||||
ClkOutPin,
|
ClkOutPin,
|
||||||
@ -32,8 +36,8 @@ use hil_test as _;
|
|||||||
struct Context {
|
struct Context {
|
||||||
parl_io: PARL_IO,
|
parl_io: PARL_IO,
|
||||||
dma_channel: ChannelCreator<0>,
|
dma_channel: ChannelCreator<0>,
|
||||||
clock: AnyPin,
|
clock: OutputSignal,
|
||||||
valid: AnyPin,
|
valid: OutputSignal,
|
||||||
clock_loopback: InputSignal,
|
clock_loopback: InputSignal,
|
||||||
valid_loopback: InputSignal,
|
valid_loopback: InputSignal,
|
||||||
pcnt_unit: Unit<'static, 0>,
|
pcnt_unit: Unit<'static, 0>,
|
||||||
@ -52,10 +56,9 @@ mod tests {
|
|||||||
|
|
||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let (clock, _) = hil_test::common_test_pins!(io);
|
let (clock, _) = hil_test::common_test_pins!(io);
|
||||||
let valid = io.pins.gpio0.degrade();
|
let valid = hil_test::unconnected_pin!(io);
|
||||||
let clock_loopback = clock.peripheral_input();
|
let (clock_loopback, clock) = clock.split();
|
||||||
let valid_loopback = valid.peripheral_input();
|
let (valid_loopback, valid) = valid.split();
|
||||||
let clock = clock.degrade();
|
|
||||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
let pcnt = Pcnt::new(peripherals.PCNT);
|
||||||
let pcnt_unit = pcnt.unit0;
|
let pcnt_unit = pcnt.unit0;
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
|
@ -335,7 +335,9 @@ mod tests {
|
|||||||
let unit0 = pcnt.unit0;
|
let unit0 = pcnt.unit0;
|
||||||
let unit1 = pcnt.unit1;
|
let unit1 = pcnt.unit1;
|
||||||
|
|
||||||
unit0.channel0.set_edge_signal(mosi.peripheral_input());
|
let (mosi_loopback, mosi) = mosi.split();
|
||||||
|
|
||||||
|
unit0.channel0.set_edge_signal(mosi_loopback);
|
||||||
unit0
|
unit0
|
||||||
.channel0
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
@ -359,12 +361,15 @@ mod tests {
|
|||||||
let unit0 = pcnt.unit0;
|
let unit0 = pcnt.unit0;
|
||||||
let unit1 = pcnt.unit1;
|
let unit1 = pcnt.unit1;
|
||||||
|
|
||||||
unit0.channel0.set_edge_signal(mosi.peripheral_input());
|
let (mosi_loopback, mosi) = mosi.split();
|
||||||
|
let (gpio_loopback, gpio) = gpio.split();
|
||||||
|
|
||||||
|
unit0.channel0.set_edge_signal(mosi_loopback);
|
||||||
unit0
|
unit0
|
||||||
.channel0
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
|
||||||
unit1.channel0.set_edge_signal(gpio.peripheral_input());
|
unit1.channel0.set_edge_signal(gpio_loopback);
|
||||||
unit1
|
unit1
|
||||||
.channel0
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
@ -389,12 +394,15 @@ mod tests {
|
|||||||
let unit0 = pcnt.unit0;
|
let unit0 = pcnt.unit0;
|
||||||
let unit1 = pcnt.unit1;
|
let unit1 = pcnt.unit1;
|
||||||
|
|
||||||
unit0.channel0.set_edge_signal(mosi.peripheral_input());
|
let (mosi_loopback, mosi) = mosi.split();
|
||||||
|
let (gpio_loopback, gpio) = gpio.split();
|
||||||
|
|
||||||
|
unit0.channel0.set_edge_signal(mosi_loopback);
|
||||||
unit0
|
unit0
|
||||||
.channel0
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
|
||||||
unit1.channel0.set_edge_signal(gpio.peripheral_input());
|
unit1.channel0.set_edge_signal(gpio_loopback);
|
||||||
unit1
|
unit1
|
||||||
.channel0
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
@ -419,12 +427,15 @@ mod tests {
|
|||||||
let unit0 = pcnt.unit0;
|
let unit0 = pcnt.unit0;
|
||||||
let unit1 = pcnt.unit1;
|
let unit1 = pcnt.unit1;
|
||||||
|
|
||||||
unit0.channel0.set_edge_signal(mosi.peripheral_input());
|
let (mosi_loopback, mosi) = mosi.split();
|
||||||
|
let (gpio_loopback, gpio) = gpio.split();
|
||||||
|
|
||||||
|
unit0.channel0.set_edge_signal(mosi_loopback);
|
||||||
unit0
|
unit0
|
||||||
.channel0
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
|
||||||
unit1.channel0.set_edge_signal(gpio.peripheral_input());
|
unit1.channel0.set_edge_signal(gpio_loopback);
|
||||||
unit1
|
unit1
|
||||||
.channel0
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
@ -73,7 +73,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(pcnt)]
|
#[cfg(pcnt)]
|
||||||
let mosi_loopback_pcnt = mosi.peripheral_input();
|
let (mosi_loopback_pcnt, mosi) = mosi.split();
|
||||||
// Need to set miso first so that mosi can overwrite the
|
// Need to set miso first so that mosi can overwrite the
|
||||||
// output connection (because we are using the same pin to loop back)
|
// output connection (because we are using the same pin to loop back)
|
||||||
let spi = Spi::new(peripherals.SPI2, 10000.kHz(), SpiMode::Mode0)
|
let spi = Spi::new(peripherals.SPI2, 10000.kHz(), SpiMode::Mode0)
|
||||||
|
@ -50,7 +50,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mosi_loopback = mosi.peripheral_input();
|
let (mosi_loopback, mosi) = mosi.split();
|
||||||
|
|
||||||
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
||||||
.with_sck(sclk)
|
.with_sck(sclk)
|
||||||
|
@ -62,7 +62,7 @@ mod tests {
|
|||||||
|
|
||||||
let dma_channel = dma.channel0;
|
let dma_channel = dma.channel0;
|
||||||
|
|
||||||
let mosi_loopback = mosi.peripheral_input();
|
let (mosi_loopback, mosi) = mosi.split();
|
||||||
|
|
||||||
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
||||||
.with_sck(sclk)
|
.with_sck(sclk)
|
||||||
|
@ -11,7 +11,10 @@
|
|||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority},
|
dma::{Dma, DmaPriority},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{interconnect::InputSignal, Io, Level, Output},
|
gpio::{
|
||||||
|
interconnect::{InputSignal, OutputSignal},
|
||||||
|
Io,
|
||||||
|
},
|
||||||
spi::{slave::Spi, SpiMode},
|
spi::{slave::Spi, SpiMode},
|
||||||
Blocking,
|
Blocking,
|
||||||
};
|
};
|
||||||
@ -32,19 +35,32 @@ struct Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct BitbangSpi {
|
struct BitbangSpi {
|
||||||
sclk: Output<'static>,
|
sclk: OutputSignal,
|
||||||
mosi: Output<'static>,
|
mosi: OutputSignal,
|
||||||
miso: InputSignal,
|
miso: InputSignal,
|
||||||
cs: Output<'static>,
|
cs: OutputSignal,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitbangSpi {
|
impl BitbangSpi {
|
||||||
fn new(
|
fn new(
|
||||||
sclk: Output<'static>,
|
mut sclk: OutputSignal,
|
||||||
mosi: Output<'static>,
|
mut mosi: OutputSignal,
|
||||||
miso: InputSignal,
|
mut miso: InputSignal,
|
||||||
cs: Output<'static>,
|
mut cs: OutputSignal,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
// TODO remove this (#2273)
|
||||||
|
// FIXME: devise a public API for signals
|
||||||
|
miso.enable_input(true, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
|
||||||
|
mosi.set_output_high(false, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
mosi.enable_output(true, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
|
||||||
|
cs.set_output_high(true, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
cs.enable_output(true, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
|
||||||
|
sclk.set_output_high(false, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
sclk.enable_output(true, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
sclk,
|
sclk,
|
||||||
mosi,
|
mosi,
|
||||||
@ -54,22 +70,29 @@ impl BitbangSpi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn assert_cs(&mut self) {
|
fn assert_cs(&mut self) {
|
||||||
self.sclk.set_level(Level::Low);
|
self.sclk
|
||||||
self.cs.set_level(Level::Low);
|
.set_output_high(false, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
self.cs
|
||||||
|
.set_output_high(false, unsafe { esp_hal::Internal::conjure() });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deassert_cs(&mut self) {
|
fn deassert_cs(&mut self) {
|
||||||
self.sclk.set_level(Level::Low);
|
self.sclk
|
||||||
self.cs.set_level(Level::High);
|
.set_output_high(false, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
self.cs
|
||||||
|
.set_output_high(true, unsafe { esp_hal::Internal::conjure() });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mode 1, so sampled on the rising edge and set on the falling edge.
|
// Mode 1, so sampled on the rising edge and set on the falling edge.
|
||||||
fn shift_bit(&mut self, bit: bool) -> bool {
|
fn shift_bit(&mut self, bit: bool) -> bool {
|
||||||
self.mosi.set_level(Level::from(bit));
|
self.mosi
|
||||||
self.sclk.set_level(Level::High);
|
.set_output_high(bit, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
self.sclk
|
||||||
|
.set_output_high(true, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
|
||||||
let miso = self.miso.get_level().into();
|
let miso = self.miso.get_level().into();
|
||||||
self.sclk.set_level(Level::Low);
|
self.sclk
|
||||||
|
.set_output_high(false, unsafe { esp_hal::Internal::conjure() });
|
||||||
|
|
||||||
miso
|
miso
|
||||||
}
|
}
|
||||||
@ -105,7 +128,7 @@ mod tests {
|
|||||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
|
|
||||||
let (mosi_pin, miso_pin) = hil_test::i2c_pins!(io);
|
let (mosi_pin, miso_pin) = hil_test::i2c_pins!(io);
|
||||||
let (sclk_pin, sclk_gpio) = hil_test::common_test_pins!(io);
|
let (sclk_pin, _) = hil_test::common_test_pins!(io);
|
||||||
let cs_pin = hil_test::unconnected_pin!(io);
|
let cs_pin = hil_test::unconnected_pin!(io);
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
@ -118,30 +141,22 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let cs = cs_pin.peripheral_input();
|
let (cs, cs_pin) = cs_pin.split();
|
||||||
let mosi = mosi_pin.peripheral_input();
|
let (mosi, mosi_pin) = mosi_pin.split();
|
||||||
let mut miso = miso_pin.peripheral_input();
|
let (miso, miso_pin) = miso_pin.split();
|
||||||
let sclk_signal = sclk_pin.peripheral_input();
|
let (sclk_signal, sclk_pin) = sclk_pin.split();
|
||||||
|
|
||||||
let mosi_gpio = Output::new(mosi_pin, Level::Low);
|
|
||||||
let cs_gpio = Output::new(cs_pin, Level::High);
|
|
||||||
let sclk_gpio = Output::new(sclk_gpio, Level::Low);
|
|
||||||
|
|
||||||
let spi = Spi::new(
|
|
||||||
peripherals.SPI2,
|
|
||||||
sclk_signal,
|
|
||||||
mosi,
|
|
||||||
miso_pin,
|
|
||||||
cs,
|
|
||||||
SpiMode::Mode1,
|
|
||||||
);
|
|
||||||
|
|
||||||
miso.enable_input(true, unsafe { esp_hal::Internal::conjure() });
|
|
||||||
|
|
||||||
Context {
|
Context {
|
||||||
spi,
|
spi: Spi::new(
|
||||||
|
peripherals.SPI2,
|
||||||
|
sclk_signal,
|
||||||
|
mosi,
|
||||||
|
miso_pin,
|
||||||
|
cs,
|
||||||
|
SpiMode::Mode1,
|
||||||
|
),
|
||||||
|
bitbang_spi: BitbangSpi::new(sclk_pin, mosi_pin, miso, cs_pin),
|
||||||
dma_channel,
|
dma_channel,
|
||||||
bitbang_spi: BitbangSpi::new(sclk_gpio, mosi_gpio, miso, cs_gpio),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,10 +32,12 @@ mod tests {
|
|||||||
|
|
||||||
let (loopback_pin, _) = hil_test::common_test_pins!(io);
|
let (loopback_pin, _) = hil_test::common_test_pins!(io);
|
||||||
|
|
||||||
|
let (rx, tx) = loopback_pin.split();
|
||||||
|
|
||||||
let mut config = twai::TwaiConfiguration::new(
|
let mut config = twai::TwaiConfiguration::new(
|
||||||
peripherals.TWAI0,
|
peripherals.TWAI0,
|
||||||
loopback_pin.peripheral_input(),
|
rx,
|
||||||
loopback_pin,
|
tx,
|
||||||
twai::BaudRate::B1000K,
|
twai::BaudRate::B1000K,
|
||||||
TwaiMode::SelfTest,
|
TwaiMode::SelfTest,
|
||||||
);
|
);
|
||||||
|
@ -32,12 +32,9 @@ mod tests {
|
|||||||
|
|
||||||
let (_, pin) = hil_test::common_test_pins!(io);
|
let (_, pin) = hil_test::common_test_pins!(io);
|
||||||
|
|
||||||
let uart = Uart::new(
|
let (rx, tx) = pin.split();
|
||||||
peripherals.UART1,
|
|
||||||
pin.peripheral_input(),
|
let uart = Uart::new(peripherals.UART1, rx, tx).unwrap();
|
||||||
pin.into_peripheral_output(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Context { uart }
|
Context { uart }
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user