From 34454e23fed4ca5b8b32af94b4b3c4fc4de4d523 Mon Sep 17 00:00:00 2001 From: dimi Date: Tue, 29 Nov 2022 13:53:03 +0100 Subject: [PATCH 1/2] enable TWAI on ESP32-S3 --- esp-hal-common/src/gpio/esp32s3.rs | 2 ++ esp-hal-common/src/lib.rs | 2 +- esp-hal-common/src/peripherals/esp32s3.rs | 1 + esp-hal-common/src/system.rs | 4 ++-- esp-hal-common/src/twai/mod.rs | 2 +- esp32s3-hal/Cargo.toml | 3 ++- esp32s3-hal/src/lib.rs | 1 + 7 files changed, 10 insertions(+), 5 deletions(-) diff --git a/esp-hal-common/src/gpio/esp32s3.rs b/esp-hal-common/src/gpio/esp32s3.rs index e51df318e41..1861da55242 100644 --- a/esp-hal-common/src/gpio/esp32s3.rs +++ b/esp-hal-common/src/gpio/esp32s3.rs @@ -95,6 +95,7 @@ pub enum InputSignal { FSPIIO6 = 108, FSPIIO7 = 109, FSPICS0 = 110, + TWAI_RX = 116, SUBSPIQ = 120, SUBSPID = 121, SUBSPIHD = 122, @@ -209,6 +210,7 @@ pub enum OutputSignal { FSPICS3 = 113, FSPICS4 = 114, FSPICS5 = 115, + TWAI_TX = 116, SUBSPICLK = 119, SUBSPIQ = 120, SUBSPID = 121, diff --git a/esp-hal-common/src/lib.rs b/esp-hal-common/src/lib.rs index 89070691f34..f5a2f812121 100644 --- a/esp-hal-common/src/lib.rs +++ b/esp-hal-common/src/lib.rs @@ -73,7 +73,7 @@ pub mod system; #[cfg(systimer)] pub mod systimer; pub mod timer; -#[cfg(any(esp32c3))] +#[cfg(any(esp32s3, esp32c3))] pub mod twai; pub mod uart; #[cfg(usb_serial_jtag)] diff --git a/esp-hal-common/src/peripherals/esp32s3.rs b/esp-hal-common/src/peripherals/esp32s3.rs index 92248e320e3..035b1cac305 100644 --- a/esp-hal-common/src/peripherals/esp32s3.rs +++ b/esp-hal-common/src/peripherals/esp32s3.rs @@ -89,6 +89,7 @@ mod peripherals { RTC_CNTL, TIMG0, TIMG1, + TWAI, APB_SARADC, SENS, } diff --git a/esp-hal-common/src/system.rs b/esp-hal-common/src/system.rs index bce01d8178d..cab6e6df415 100644 --- a/esp-hal-common/src/system.rs +++ b/esp-hal-common/src/system.rs @@ -42,7 +42,7 @@ pub enum Peripheral { I2s1, #[cfg(usb_otg)] Usb, - #[cfg(any(esp32c3))] + #[cfg(any(esp32s3, esp32c3))] Twai, } @@ -151,7 +151,7 @@ impl PeripheralClockControl { perip_clk_en0.modify(|_, w| w.usb_clk_en().set_bit()); perip_rst_en0.modify(|_, w| w.usb_rst().clear_bit()); } - #[cfg(any(esp32c3))] + #[cfg(any(esp32s3, esp32c3))] Peripheral::Twai => { perip_clk_en0.modify(|_, w| w.can_clk_en().set_bit()); perip_rst_en0.modify(|_, w| w.can_rst().clear_bit()); diff --git a/esp-hal-common/src/twai/mod.rs b/esp-hal-common/src/twai/mod.rs index 8bf7dc08d6c..4d76006d7b2 100644 --- a/esp-hal-common/src/twai/mod.rs +++ b/esp-hal-common/src/twai/mod.rs @@ -705,7 +705,7 @@ pub trait Instance { fn register_block(&self) -> &RegisterBlock; } -#[cfg(any(esp32c3))] +#[cfg(any(esp32s3, esp32c3))] impl Instance for crate::peripherals::TWAI { #[inline(always)] fn register_block(&self) -> &RegisterBlock { diff --git a/esp32s3-hal/Cargo.toml b/esp32s3-hal/Cargo.toml index 97e19edcd0b..67a3e1ce654 100644 --- a/esp32s3-hal/Cargo.toml +++ b/esp32s3-hal/Cargo.toml @@ -31,6 +31,7 @@ embedded-hal = { version = "0.2.7", features = ["unproven"] } embedded-hal-1 = { version = "=1.0.0-alpha.9", optional = true, package = "embedded-hal" } embedded-hal-async = { version = "0.1.0-alpha.3", optional = true } embedded-hal-nb = { version = "=1.0.0-alpha.1", optional = true } +embedded-can = { version = "0.4.1", optional = true } esp-hal-common = { version = "0.4.0", features = ["esp32s3"], path = "../esp-hal-common" } r0 = { version = "1.0.0", optional = true } xtensa-lx = { version = "0.7.0", features = ["esp32s3"] } @@ -52,7 +53,7 @@ static_cell = "1.0.0" [features] default = ["rt", "vectored"] direct-boot = ["r0"] -eh1 = ["esp-hal-common/eh1", "dep:embedded-hal-1", "dep:embedded-hal-nb"] +eh1 = ["esp-hal-common/eh1", "dep:embedded-hal-1", "dep:embedded-hal-nb", "dep:embedded-can"] rt = ["xtensa-lx-rt/esp32s3"] smartled = ["esp-hal-common/smartled"] ufmt = ["esp-hal-common/ufmt"] diff --git a/esp32s3-hal/src/lib.rs b/esp32s3-hal/src/lib.rs index 1025c82d5b4..870ada55901 100644 --- a/esp32s3-hal/src/lib.rs +++ b/esp32s3-hal/src/lib.rs @@ -28,6 +28,7 @@ pub use esp_hal_common::{ system, systimer, timer, + twai, uart, utils, Cpu, From e257f334707c931f1f08b70a5a0f415cf4f35c77 Mon Sep 17 00:00:00 2001 From: dimi Date: Thu, 22 Dec 2022 20:36:59 +0100 Subject: [PATCH 2/2] add esp32-s3 TWAI example --- esp32s3-hal/examples/twai.rs | 110 +++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 esp32s3-hal/examples/twai.rs diff --git a/esp32s3-hal/examples/twai.rs b/esp32s3-hal/examples/twai.rs new file mode 100644 index 00000000000..5a05da0a1a7 --- /dev/null +++ b/esp32s3-hal/examples/twai.rs @@ -0,0 +1,110 @@ +//! This example sends a CAN message to another ESP and receives it back. +//! +//! Wiring: +//! This example works without CAN Transceivers by: +//! * setting the tx pins to open drain +//! * connecting all rx and tx pins together +//! * adding a pull-up to the signal pins +//! +//! ESP1/GND --- ESP2/GND +//! ESP1/IO2 --- ESP1/IO3 --- ESP2/IO2 --- ESP2/IO3 --- 4.8kOhm --- ESP1/5V +//! +//! `IS_FIRST_SENDER` below must be set to false on one of the ESP's + +#![no_std] +#![no_main] + +const IS_FIRST_SENDER: bool = true; + +// Run this example with the eh1 feature enabled to use embedded-can instead of +// embedded-hal-0.2.7. embedded-can was split off from embedded-hal before it's +// upgrade to 1.0.0. cargo run --example twai --features eh1 --release +#[cfg(feature = "eh1")] +use embedded_can::{nb::Can, Frame, StandardId}; +// Run this example without the eh1 flag to use the embedded-hal 0.2.7 CAN traits. +// cargo run --example twai --release +#[cfg(not(feature = "eh1"))] +use embedded_hal::can::{Can, Frame, StandardId}; +use esp32s3_hal::{ + clock::ClockControl, + gpio::IO, + peripherals::Peripherals, + prelude::*, + timer::TimerGroup, + twai, + Rtc, +}; +use esp_backtrace as _; +use esp_println::println; +use nb::block; +use xtensa_lx_rt::entry; + +#[entry] +fn main() -> ! { + let peripherals = Peripherals::take(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks); + let mut wdt = timer_group0.wdt; + let mut rtc = Rtc::new(peripherals.RTC_CNTL); + + // Disable watchdog timer + wdt.disable(); + rtc.rwdt.disable(); + + let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); + + // Set the tx pin as open drain. Skip this if using transceivers. + let can_tx_pin = io.pins.gpio2.into_open_drain_output(); + let can_rx_pin = io.pins.gpio3; + + // The speed of the CAN bus. + const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K; + + // Begin configuring the TWAI peripheral. The peripheral is in a reset like + // state that prevents transmission but allows configuration. + let mut can_config = twai::TwaiConfiguration::new( + peripherals.TWAI, + can_tx_pin, + can_rx_pin, + &mut system.peripheral_clock_control, + &clocks, + CAN_BAUDRATE, + ); + + // Partially filter the incoming messages to reduce overhead of receiving + // undesired messages. Note that due to how the hardware filters messages, + // standard ids and extended ids may both match a filter. Frame ids should + // be explicitly checked in the application instead of fully relying on + // these partial acceptance filters to exactly match. + // A filter that matches StandardId::ZERO. + const FILTER: twai::filter::SingleStandardFilter = + twai::filter::SingleStandardFilter::new(b"00000000000", b"x", [b"xxxxxxxx", b"xxxxxxxx"]); + can_config.set_filter(FILTER); + + // Start the peripheral. This locks the configuration settings of the peripheral + // and puts it into operation mode, allowing packets to be sent and + // received. + let mut can = can_config.start(); + + if IS_FIRST_SENDER { + // Send a frame to the other ESP + let frame = Frame::new(StandardId::ZERO, &[1, 2, 3]).unwrap(); + block!(can.transmit(&frame)).unwrap(); + println!("Sent a frame"); + } + + // Wait for a frame to be received. + let frame = block!(can.receive()).unwrap(); + + println!("Received a frame: {frame:?}"); + + if !IS_FIRST_SENDER { + // Transmit the frame back to the other ESP + block!(can.transmit(&frame)).unwrap(); + println!("Sent a frame"); + } + + loop {} +}