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

H2: enable TWAI, enable delay test #2199

Merged
merged 5 commits into from
Sep 20, 2024
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
1 change: 1 addition & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added APIs to allow connecting signals through the GPIO matrix. (#2128)
- Implement `TryFrom<u32>` for `ledc::timer::config::Duty` (#1984)
- Expose `RtcClock::get_xtal_freq` and `RtcClock::get_slow_freq` publically for all chips (#2183)
- TWAI support for ESP32-H2 (#2199)

### Changed

Expand Down
75 changes: 52 additions & 23 deletions esp-hal/src/twai/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,8 +662,8 @@ impl BaudRate {
/// Convert the BaudRate into the timings that the peripheral needs.
// See: https://github.com/espressif/esp-idf/tree/master/components/hal/include/hal/twai_types.h
const fn timing(self) -> TimingConfig {
#[allow(unused_mut)]
let mut timing = match self {
#[cfg(not(esp32h2))]
let timing = match self {
Self::B125K => TimingConfig {
baud_rate_prescaler: 32,
sync_jump_width: 3,
Expand Down Expand Up @@ -695,11 +695,45 @@ impl BaudRate {
Self::Custom(timing_config) => timing_config,
};

#[cfg(esp32h2)]
let timing = match self {
Self::B125K => TimingConfig {
baud_rate_prescaler: 8,
sync_jump_width: 3,
tseg_1: 23,
tseg_2: 8,
triple_sample: false,
},
Self::B250K => TimingConfig {
baud_rate_prescaler: 8,
sync_jump_width: 3,
tseg_1: 11,
tseg_2: 4,
triple_sample: false,
},
Self::B500K => TimingConfig {
baud_rate_prescaler: 4,
sync_jump_width: 3,
tseg_1: 11,
tseg_2: 4,
triple_sample: false,
},
Self::B1000K => TimingConfig {
baud_rate_prescaler: 2,
sync_jump_width: 3,
tseg_1: 11,
tseg_2: 4,
triple_sample: false,
},
Self::Custom(timing_config) => timing_config,
};

// clock source on ESP32-C6 is xtal (40MHz)
#[cfg(esp32c6)]
{
// clock source on ESP32-C6 is xtal (40MHz)
timing.baud_rate_prescaler /= 2;
}
let timing = TimingConfig {
baud_rate_prescaler: timing.baud_rate_prescaler / 2,
..timing
};

timing
}
Expand Down Expand Up @@ -802,7 +836,7 @@ where
fn set_baud_rate(&mut self, baud_rate: BaudRate) {
// TWAI is clocked from the APB_CLK according to Table 6-4 [ESP32C3 Reference Manual](https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf)
// Included timings are all for 80MHz so assert that we are running at 80MHz.
#[cfg(not(esp32c6))]
#[cfg(not(any(esp32h2, esp32c6)))]
{
let apb_clock = crate::clock::Clocks::get().apb_clock;
assert!(apb_clock == fugit::HertzU32::MHz(80));
Expand All @@ -820,22 +854,17 @@ where
let tseg_2 = timing.tseg_2 - 1;
let triple_sample = timing.triple_sample;

#[cfg(esp32)]
let prescale = prescale as u8;

// Set up the prescaler and sync jump width.
T::register_block()
.bus_timing_0()
.modify(|_, w| unsafe { w.baud_presc().bits(prescale).sync_jump_width().bits(sjw) });
T::register_block().bus_timing_0().modify(|_, w| unsafe {
w.baud_presc().bits(prescale as _);
w.sync_jump_width().bits(sjw)
});

// Set up the time segment 1, time segment 2, and triple sample.
T::register_block().bus_timing_1().modify(|_, w| unsafe {
w.time_seg1()
.bits(tseg_1)
.time_seg2()
.bits(tseg_2)
.time_samp()
.bit(triple_sample)
w.time_seg1().bits(tseg_1);
w.time_seg2().bits(tseg_2);
w.time_samp().bit(triple_sample)
});
}

Expand Down Expand Up @@ -1510,7 +1539,7 @@ impl Instance for crate::peripherals::TWAI0 {
#[cfg(any(esp32, esp32c3, esp32s2, esp32s3))]
impl OperationInstance for crate::peripherals::TWAI0 {}

#[cfg(esp32c6)]
#[cfg(any(esp32h2, esp32c6))]
impl Instance for crate::peripherals::TWAI0 {
const SYSTEM_PERIPHERAL: system::Peripheral = system::Peripheral::Twai0;
const NUMBER: usize = 0;
Expand Down Expand Up @@ -1554,7 +1583,7 @@ impl Instance for crate::peripherals::TWAI0 {
}
}

#[cfg(esp32c6)]
#[cfg(any(esp32h2, esp32c6))]
impl OperationInstance for crate::peripherals::TWAI0 {}

#[cfg(esp32c6)]
Expand Down Expand Up @@ -1641,7 +1670,7 @@ mod asynch {
}
}

const NUM_TWAI: usize = 2;
const NUM_TWAI: usize = 1 + cfg!(twai1) as usize;
#[allow(clippy::declare_interior_mutable_const)]
const NEW_STATE: TwaiAsyncState = TwaiAsyncState::new();
pub(crate) static TWAI_STATE: [TwaiAsyncState; NUM_TWAI] = [NEW_STATE; NUM_TWAI];
Expand Down Expand Up @@ -1768,7 +1797,7 @@ mod asynch {
}
}

#[cfg(esp32c6)]
#[cfg(any(esp32h2, esp32c6))]
#[handler]
pub(super) fn twai0() {
let register_block = TWAI0::register_block();
Expand Down
2 changes: 1 addition & 1 deletion esp-metadata/devices/esp32h2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ peripherals = [
"timg0",
"timg1",
"trace0",
# "twai0",
"twai0",
"uart0",
"uart1",
"uhci0",
Expand Down
24 changes: 12 additions & 12 deletions examples/src/bin/twai.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! This example sends a CAN message to another ESP and receives it back.
//! This example sends a TWAI message to another ESP and receives it back.
//!
//! This example works without CAN Transceivers by:
//! This example works without TWAI transceivers by:
//! * setting the tx pins to open drain
//! * connecting all rx and tx pins together
//! * adding a pull-up to the signal pins
Expand All @@ -17,7 +17,7 @@
//! In case you want to use `self-testing`, get rid of everything related to the aforementioned `IS_FIRST_SENDER`
//! and follow the advice in the comments related to this mode.

//% CHIPS: esp32c3 esp32c6 esp32s2 esp32s3
//% CHIPS: esp32c3 esp32c6 esp32h2 esp32s2 esp32s3

#![no_std]
#![no_main]
Expand All @@ -39,23 +39,23 @@ fn main() -> ! {

let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);

let can_tx_pin = io.pins.gpio0;
let can_rx_pin = io.pins.gpio2;
let tx_pin = io.pins.gpio0;
let rx_pin = io.pins.gpio2;

// The speed of the CAN bus.
const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K;
const TWAI_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K;

// !!! Use `new` when using a transceiver. `new_no_transceiver` sets TX to open-drain
// Self-testing also works using the regular `new` function.

// Begin configuring the TWAI peripheral. The peripheral is in a reset like
// state that prevents transmission but allows configuration.
// For self-testing use `SelfTest` mode of the TWAI peripheral.
let mut can_config = twai::TwaiConfiguration::new_no_transceiver(
let mut twai_config = twai::TwaiConfiguration::new_no_transceiver(
peripherals.TWAI0,
can_rx_pin,
can_tx_pin,
CAN_BAUDRATE,
rx_pin,
tx_pin,
TWAI_BAUDRATE,
TwaiMode::Normal,
);

Expand All @@ -67,12 +67,12 @@ fn main() -> ! {
// A filter that matches StandardId::ZERO.
const FILTER: SingleStandardFilter =
SingleStandardFilter::new(b"00000000000", b"x", [b"xxxxxxxx", b"xxxxxxxx"]);
can_config.set_filter(FILTER);
twai_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();
let mut can = twai_config.start();

if IS_FIRST_SENDER {
// Send a frame to the other ESP
Expand Down
2 changes: 1 addition & 1 deletion hil-test/tests/delay.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Delay Test

//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32s2 esp32s3
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3

#![no_std]
#![no_main]
Expand Down
8 changes: 4 additions & 4 deletions hil-test/tests/twai.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! TWAI test

//% CHIPS: esp32c3 esp32c6 esp32s2 esp32s3
//% CHIPS: esp32c3 esp32c6 esp32h2 esp32s2 esp32s3

#![no_std]
#![no_main]
Expand Down Expand Up @@ -33,12 +33,12 @@ mod tests {

let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);

let (can_tx_pin, can_rx_pin) = hil_test::common_test_pins!(io);
let (tx_pin, rx_pin) = hil_test::common_test_pins!(io);

let mut config = twai::TwaiConfiguration::new(
peripherals.TWAI0,
can_rx_pin,
can_tx_pin,
rx_pin,
tx_pin,
twai::BaudRate::B1000K,
TwaiMode::SelfTest,
);
Expand Down
Loading