From 8a1d02bbfdcaf1a360728559e624923797a402f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Wed, 16 Oct 2024 17:53:15 +0200 Subject: [PATCH] Erase TWAI instance --- esp-hal/CHANGELOG.md | 4 ++ esp-hal/MIGRATING-0.21.md | 1 + esp-hal/src/twai/mod.rs | 71 +++++++++++++++++++++++++++++--- examples/src/bin/embassy_twai.rs | 17 +------- hil-test/tests/twai.rs | 3 +- 5 files changed, 73 insertions(+), 23 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 66f7aea0e6c..b908b8563d2 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -14,12 +14,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add burst transfer support to DMA buffers (#2336) - `AnyPin` now implements `From>`. (#2326) - Added `AnySpi` and `AnySpiDmaChannel`. (#2334) +- Added `degrade` function for SPI instances (SPI2, SPI3) to obtain `AnySpi`. (#2334) +- Added `degrade` function for TWAI instances (TWAI0, TWAI1) to obtain `AnyTwai`. (#?) + - `Pins::steal()` to unsafely obtain GPIO. (#2335) - `TwaiConfiguration::into_async` (#?) ### Changed - Peripheral type erasure for SPI (#2334) +- Peripheral type erasure for TWAI (#?) ### Fixed diff --git a/esp-hal/MIGRATING-0.21.md b/esp-hal/MIGRATING-0.21.md index 7cc08b54c4a..f7a6123b524 100644 --- a/esp-hal/MIGRATING-0.21.md +++ b/esp-hal/MIGRATING-0.21.md @@ -49,6 +49,7 @@ You no longer have to specify the peripheral instance in the driver's type for t peripherals: - SPI (both master and slave) +- TWAI ```diff -Spi<'static, SPI2, FullDuplexMode> diff --git a/esp-hal/src/twai/mod.rs b/esp-hal/src/twai/mod.rs index 4ac3c85a8d8..d9863983ad3 100644 --- a/esp-hal/src/twai/mod.rs +++ b/esp-hal/src/twai/mod.rs @@ -743,7 +743,7 @@ impl BaudRate { } /// An inactive TWAI peripheral in the "Reset"/configuration state. -pub struct TwaiConfiguration<'d, DM: crate::Mode, T> { +pub struct TwaiConfiguration<'d, DM: crate::Mode, T = AnyTwai> { twai: PeripheralRef<'d, T>, phantom: PhantomData, mode: TwaiMode, @@ -1021,6 +1021,36 @@ where } } +impl<'d> TwaiConfiguration<'d, crate::Blocking> { + /// Create a new instance of [TwaiConfiguration] + /// + /// You will need to use a transceiver to connect to the TWAI bus + pub fn new( + peripheral: impl Peripheral

> + 'd, + rx_pin: impl Peripheral

+ 'd, + tx_pin: impl Peripheral

+ 'd, + baud_rate: BaudRate, + mode: TwaiMode, + ) -> Self { + Self::new_typed(peripheral.map_into(), rx_pin, tx_pin, baud_rate, mode) + } + + /// Create a new instance of [TwaiConfiguration] meant to connect two ESP32s + /// directly + /// + /// You don't need a transceiver by following the description in the + /// `twai.rs` example + pub fn new_no_transceiver( + peripheral: impl Peripheral

> + 'd, + rx_pin: impl Peripheral

+ 'd, + tx_pin: impl Peripheral

+ 'd, + baud_rate: BaudRate, + mode: TwaiMode, + ) -> Self { + Self::new_no_transceiver_typed(peripheral.map_into(), rx_pin, tx_pin, baud_rate, mode) + } +} + impl<'d, T> TwaiConfiguration<'d, crate::Blocking, T> where T: Instance, @@ -1028,7 +1058,7 @@ where /// Create a new instance of [TwaiConfiguration] /// /// You will need to use a transceiver to connect to the TWAI bus - pub fn new( + pub fn new_typed( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -1043,7 +1073,7 @@ where /// /// You don't need a transceiver by following the description in the /// `twai.rs` example - pub fn new_no_transceiver( + pub fn new_no_transceiver_typed( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -1080,7 +1110,7 @@ where /// /// In this mode, the TWAI controller can transmit and receive messages /// including error signals (such as error and overload frames). -pub struct Twai<'d, DM: crate::Mode, T> { +pub struct Twai<'d, DM: crate::Mode, T = AnyTwai> { twai: PeripheralRef<'d, T>, tx: TwaiTx<'d, DM, T>, rx: TwaiRx<'d, DM, T>, @@ -1198,7 +1228,7 @@ where } /// Interface to the TWAI transmitter part. -pub struct TwaiTx<'d, DM: crate::Mode, T> { +pub struct TwaiTx<'d, DM: crate::Mode, T = AnyTwai> { twai: PeripheralRef<'d, T>, phantom: PhantomData, } @@ -1240,7 +1270,7 @@ where } /// Interface to the TWAI receiver part. -pub struct TwaiRx<'d, DM: crate::Mode, T> { +pub struct TwaiRx<'d, DM: crate::Mode, T = AnyTwai> { twai: PeripheralRef<'d, T>, phantom: PhantomData, } @@ -1659,6 +1689,35 @@ impl Instance for crate::peripherals::TWAI1 { } } +crate::any_peripheral! { + /// Any TWAI peripheral. + pub peripheral AnyTwai { + #[cfg(twai0)] + Twai0(crate::peripherals::TWAI0), + #[cfg(twai1)] + Twai1(crate::peripherals::TWAI1), + } +} + +impl Instance for AnyTwai { + delegate::delegate! { + to match &self.0 { + #[cfg(twai0)] + AnyTwaiInner::Twai0(twai) => twai, + #[cfg(twai1)] + AnyTwaiInner::Twai1(twai) => twai, + } { + fn number(&self) -> usize; + fn input_signal(&self) -> InputSignal; + fn output_signal(&self) -> OutputSignal; + fn interrupt(&self) -> crate::peripherals::Interrupt; + fn async_handler(&self) -> InterruptHandler; + fn register_block(&self) -> &RegisterBlock; + fn async_state(&self) -> &asynch::TwaiAsyncState; + } + } +} + mod asynch { use core::{future::poll_fn, task::Poll}; diff --git a/examples/src/bin/embassy_twai.rs b/examples/src/bin/embassy_twai.rs index 1c051ad471a..2d28ddb04f2 100644 --- a/examples/src/bin/embassy_twai.rs +++ b/examples/src/bin/embassy_twai.rs @@ -37,7 +37,6 @@ use esp_backtrace as _; use esp_hal::{ gpio::Io, interrupt, - peripherals::{self, TWAI0}, timer::timg::TimerGroup, twai::{self, EspTwaiFrame, StandardId, TwaiMode, TwaiRx, TwaiTx}, }; @@ -47,10 +46,7 @@ use static_cell::StaticCell; type TwaiOutbox = Channel; #[embassy_executor::task] -async fn receiver( - mut rx: TwaiRx<'static, esp_hal::Async, TWAI0>, - channel: &'static TwaiOutbox, -) -> ! { +async fn receiver(mut rx: TwaiRx<'static, esp_hal::Async>, channel: &'static TwaiOutbox) -> ! { loop { let frame = rx.receive_async().await; @@ -72,10 +68,7 @@ async fn receiver( } #[embassy_executor::task] -async fn transmitter( - mut tx: TwaiTx<'static, TWAI0, esp_hal::Async>, - channel: &'static TwaiOutbox, -) -> ! { +async fn transmitter(mut tx: TwaiTx<'static, esp_hal::Async>, channel: &'static TwaiOutbox) -> ! { loop { let frame = channel.receive().await; let result = tx.transmit_async(&frame).await; @@ -142,12 +135,6 @@ async fn main(spawner: Spawner) { // Get separate transmit and receive halves of the peripheral. let (rx, tx) = twai.split(); - interrupt::enable( - peripherals::Interrupt::TWAI0, - interrupt::Priority::Priority1, - ) - .unwrap(); - static CHANNEL: StaticCell = StaticCell::new(); let channel = &*CHANNEL.init(Channel::new()); diff --git a/hil-test/tests/twai.rs b/hil-test/tests/twai.rs index ac30b564b8f..da41f1dc258 100644 --- a/hil-test/tests/twai.rs +++ b/hil-test/tests/twai.rs @@ -8,7 +8,6 @@ use embedded_hal_02::can::Frame; use esp_hal::{ gpio::Io, - peripherals::TWAI0, prelude::*, twai::{self, filter::SingleStandardFilter, EspTwaiFrame, StandardId, TwaiMode}, Blocking, @@ -17,7 +16,7 @@ use hil_test as _; use nb::block; struct Context { - twai: twai::Twai<'static, Blocking, TWAI0>, + twai: twai::Twai<'static, Blocking>, } #[cfg(test)]