Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable TWAI on ESP32-S3 #325

Merged
merged 2 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions esp-hal-common/src/gpio/esp32s3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub enum InputSignal {
FSPIIO6 = 108,
FSPIIO7 = 109,
FSPICS0 = 110,
TWAI_RX = 116,
SUBSPIQ = 120,
SUBSPID = 121,
SUBSPIHD = 122,
Expand Down Expand Up @@ -209,6 +210,7 @@ pub enum OutputSignal {
FSPICS3 = 113,
FSPICS4 = 114,
FSPICS5 = 115,
TWAI_TX = 116,
SUBSPICLK = 119,
SUBSPIQ = 120,
SUBSPID = 121,
Expand Down
2 changes: 1 addition & 1 deletion esp-hal-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
1 change: 1 addition & 0 deletions esp-hal-common/src/peripherals/esp32s3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ mod peripherals {
RTC_CNTL,
TIMG0,
TIMG1,
TWAI,
APB_SARADC,
SENS,
}
Expand Down
4 changes: 2 additions & 2 deletions esp-hal-common/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub enum Peripheral {
I2s1,
#[cfg(usb_otg)]
Usb,
#[cfg(any(esp32c3))]
#[cfg(any(esp32s3, esp32c3))]
Twai,
}

Expand Down Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion esp-hal-common/src/twai/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion esp32s3-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
Expand All @@ -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"]
Expand Down
110 changes: 110 additions & 0 deletions esp32s3-hal/examples/twai.rs
Original file line number Diff line number Diff line change
@@ -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 {}
}
1 change: 1 addition & 0 deletions esp32s3-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub use esp_hal_common::{
system,
systimer,
timer,
twai,
uart,
utils,
Cpu,
Expand Down