Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ jobs:
run: cd esp-hal-smartled/ && cargo +nightly check --features=esp32c3
- name: check (esp32c6)
run: cd esp-hal-smartled/ && cargo +nightly check --features=esp32c6
# - name: check (esp32h2)
# run: cd esp-hal-smartled/ && cargo +nightly check --features=esp32h2
- name: check (esp32h2)
run: cd esp-hal-smartled/ && cargo +nightly check --features=esp32h2
# Check all Xtensa targets:
- name: check (esp32)
run: cd esp-hal-smartled/ && cargo +esp check --features=esp32,esp32_40mhz
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add initial support for MCPWM in ESP32-H2 (#544)
- Add some miscellaneous examples for the ESP32-H2 (#548)
- Add initial support for PCNT in ESP32-H2 (#551)
- Add initial support for RMT in ESP32-H2 (#556)

### Fixed

Expand Down
2 changes: 1 addition & 1 deletion esp-hal-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ esp32 = { version = "0.23.0", features = ["critical-section"], optional = true
esp32c2 = { version = "0.11.0", features = ["critical-section"], optional = true }
esp32c3 = { version = "0.14.0", features = ["critical-section"], optional = true }
esp32c6 = { version = "0.4.0", features = ["critical-section"], optional = true }
esp32h2 = { git = "https://github.com/esp-rs/esp-pacs", rev = "4fe0791", package = "esp32h2", features = ["critical-section"], optional = true }
esp32h2 = { git = "https://github.com/esp-rs/esp-pacs", rev = "d22c06a", package = "esp32h2", features = ["critical-section"], optional = true }
esp32s2 = { version = "0.14.0", features = ["critical-section"], optional = true }
esp32s3 = { version = "0.18.0", features = ["critical-section"], optional = true }

Expand Down
2 changes: 1 addition & 1 deletion esp-hal-common/devices/esp32h2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ peripherals = [
"pcnt",
"pcr",
# "pmu",
# "rmt",
"rmt",
# "rng",
"rsa",
"sha",
Expand Down
66 changes: 49 additions & 17 deletions esp-hal-common/src/pulse_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,16 @@ pub enum ClockSource {
XTAL = 3,
}

/// Specify the clock source for the RMT peripheral on the ESP32-H2
#[cfg(esp32h2)]
#[derive(Debug, Copy, Clone)]
pub enum ClockSource {
/// External clock source
XTAL = 0,
/// 20 MHz internal oscillator
RTC20M = 1,
}

/// Specify the clock source for the RMT peripheral on the ESP32 and ESP32-S3
/// variants
#[cfg(any(esp32s2, esp32))]
Expand All @@ -155,7 +165,7 @@ pub enum ClockSource {
// to the RMT channel
#[cfg(any(esp32s2, esp32))]
const CHANNEL_RAM_SIZE: u8 = 64;
#[cfg(any(esp32c3, esp32c6, esp32s3))]
#[cfg(any(esp32c3, esp32c6, esp32s3, esp32h2))]
const CHANNEL_RAM_SIZE: u8 = 48;

// Specifies where the RMT RAM section starts for the particular ESP32 variant
Expand All @@ -165,6 +175,8 @@ const RMT_RAM_START: usize = 0x3f416400;
const RMT_RAM_START: usize = 0x60016400;
#[cfg(esp32c6)]
const RMT_RAM_START: usize = 0x60006400;
#[cfg(esp32h2)]
const RMT_RAM_START: usize = 0x60007400;
#[cfg(esp32)]
const RMT_RAM_START: usize = 0x3ff56800;
#[cfg(esp32s3)]
Expand Down Expand Up @@ -290,7 +302,7 @@ macro_rules! channel_instance {
let mut channel = $cxi { mem_offset: 0 };

cfg_if::cfg_if! {
if #[cfg(any(esp32c3, esp32c6, esp32s3))] {
if #[cfg(any(esp32c3, esp32c6, esp32s3, esp32h2))] {
// Apply default configuration
unsafe { &*RMT::PTR }.ch_tx_conf0[$num].modify(|_, w| unsafe {
// Configure memory block size
Expand Down Expand Up @@ -466,7 +478,7 @@ macro_rules! channel_instance {
}
}

#[cfg(any(esp32c3, esp32c6, esp32s3))]
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
conf_reg.modify(|_, w| {
// Set config update bit
w.conf_update().set_bit()
Expand Down Expand Up @@ -547,14 +559,14 @@ macro_rules! channel_instance {
}

// always enable tx wrap
#[cfg(any(esp32c3, esp32c6, esp32s3))]
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
unsafe { &*RMT::PTR }.ch_tx_conf0[$num].modify(|_, w| {
w.mem_tx_wrap_en()
.set_bit()
});

// apply configuration updates
#[cfg(any(esp32c3, esp32c6, esp32s3))]
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
unsafe { &*RMT::PTR }.ch_tx_conf0[$num].modify(|_, w| {
w.conf_update()
.set_bit()
Expand All @@ -577,18 +589,28 @@ macro_rules! channel_instance {
let interrupts = unsafe { &*RMT::PTR }.int_raw.read();

match (
#[cfg(not(esp32h2))]
unsafe { interrupts.ch_tx_end_int_raw($num).bit() },
#[cfg(esp32h2)]
interrupts.[<ch $num _tx_end_int_raw>]().bit(),
// The ESP32 variant does not support the loop functionality
#[cfg(not(esp32))]
unsafe {interrupts.ch_tx_loop_int_raw($num).bit()},
#[cfg(esp32)]
false,
#[cfg(esp32h2)]
interrupts.[<ch $num _tx_loop_int_raw>]().bit(),
#[cfg(not(any(esp32, esp32h2)))]
unsafe {interrupts.ch_tx_loop_int_raw($num).bit()},
// The C3/S3 have a slightly different interrupt naming scheme
#[cfg(any(esp32, esp32s2))]
unsafe { interrupts.ch_err_int_raw($num).bit() },
#[cfg(any(esp32c3, esp32c6, esp32s3))]
unsafe { interrupts.ch_tx_err_int_raw($num).bit() },
#[cfg(not(esp32h2))]
unsafe { interrupts.ch_tx_thr_event_int_raw($num).bit() },
#[cfg(esp32h2)]
interrupts.[<ch $num _tx_err_int_raw>]().bit(),
#[cfg(esp32h2)]
interrupts.[<ch $num _tx_thr_event_int_raw>]().bit(),
) {
// SingleShot completed and no error -> success
(true, false, false, _) => break,
Expand All @@ -612,18 +634,28 @@ macro_rules! channel_instance {
// Anything else constitutes an error state
_ => {
return Err(TransmissionError::Failure(
#[cfg(not(esp32h2))]
unsafe { interrupts.ch_tx_end_int_raw($num).bit() },
#[cfg(esp32h2)]
interrupts.[<ch $num _tx_end_int_raw>]().bit(),
// The ESP32 variant does not support the loop functionality
#[cfg(not(esp32))]
unsafe {interrupts.ch_tx_loop_int_raw($num).bit()},
#[cfg(esp32)]
false,
#[cfg(esp32h2)]
interrupts.[<ch $num _tx_loop_int_raw>]().bit(),
#[cfg(not(any(esp32, esp32h2)))]
unsafe {interrupts.ch_tx_loop_int_raw($num).bit()},
// The C3/S3 have a slightly different interrupt naming scheme
#[cfg(any(esp32, esp32s2))]
unsafe { interrupts.ch_err_int_raw($num).bit() },
#[cfg(any(esp32c3, esp32c6, esp32s3))]
unsafe { interrupts.ch_tx_err_int_raw($num).bit() },
#[cfg(not(esp32h2))]
unsafe { interrupts.ch_tx_thr_event_int_raw($num).bit() },
#[cfg(esp32h2)]
interrupts.[<ch $num _tx_err_int_raw>]().bit(),
#[cfg(esp32h2)]
interrupts.[<ch $num _tx_thr_event_int_raw>]().bit(),
))
}
}
Expand All @@ -639,7 +671,7 @@ macro_rules! channel_instance {
/// previously a sequence was sent with `RepeatMode::Forever`.
fn stop_transmission(&self) {
cfg_if::cfg_if! {
if #[cfg(any(esp32c3, esp32c6, esp32s3))] {
if #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] {
unsafe { &*RMT::PTR }
.ch_tx_conf0[$num]
.modify(|_, w| w.tx_stop().set_bit());
Expand Down Expand Up @@ -673,7 +705,7 @@ macro_rules! output_channel {
#[inline(always)]
fn set_idle_output_level(&mut self, level: bool) -> &mut Self {
cfg_if::cfg_if! {
if #[cfg(any(esp32c3, esp32c6, esp32s3))] {
if #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] {
unsafe { &*RMT::PTR }
.ch_tx_conf0[$num]
.modify(|_, w| w.idle_out_lv().bit(level));
Expand All @@ -690,7 +722,7 @@ macro_rules! output_channel {
#[inline(always)]
fn set_idle_output(&mut self, state: bool) -> &mut Self {
cfg_if::cfg_if! {
if #[cfg(any(esp32c3, esp32c6, esp32s3))] {
if #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] {
unsafe { &*RMT::PTR }
.ch_tx_conf0[$num]
.modify(|_, w| w.idle_out_en().bit(state));
Expand All @@ -707,7 +739,7 @@ macro_rules! output_channel {
#[inline(always)]
fn set_channel_divider(&mut self, divider: u8) -> &mut Self {
cfg_if::cfg_if! {
if #[cfg(any(esp32c3, esp32c6, esp32s3))] {
if #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] {
unsafe { &*RMT::PTR }
.ch_tx_conf0[$num]
.modify(|_, w| unsafe { w.div_cnt().bits(divider) });
Expand All @@ -724,7 +756,7 @@ macro_rules! output_channel {
#[inline(always)]
fn set_carrier_modulation(&mut self, state: bool) -> &mut Self {
cfg_if::cfg_if! {
if #[cfg(any(esp32c3, esp32c6, esp32s3))] {
if #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] {
unsafe { &*RMT::PTR }
.ch_tx_conf0[$num]
.modify(|_, w| w.carrier_en().bit(state));
Expand Down Expand Up @@ -852,7 +884,7 @@ macro_rules! rmt {

impl<'d> PulseControl<'d> {
/// Create a new pulse controller instance
#[cfg(any(esp32c3, esp32c6, esp32s3))]
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
pub fn new(
instance: impl Peripheral<P = RMT> + 'd,
peripheral_clock_control: &mut PeripheralClockControl,
Expand Down Expand Up @@ -909,7 +941,7 @@ macro_rules! rmt {
/// clock is calculated as follows:
///
/// divider = absolute_part + 1 + (fractional_part_a / fractional_part_b)
#[cfg(any(esp32c3, esp32c6, esp32s3))]
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
fn config_global(
&self,
clk_source: ClockSource,
Expand Down Expand Up @@ -1047,7 +1079,7 @@ macro_rules! rmt {
};
}

#[cfg(any(esp32c3, esp32c6))]
#[cfg(any(esp32c3, esp32c6, esp32h2))]
rmt!(
sys_conf,
(0, Channel0, channel0, OutputSignal::RMT_SIG_0),
Expand Down
8 changes: 4 additions & 4 deletions esp-hal-common/src/soc/esp32h2/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ pub enum InputSignal {
FSPICS0 = 68,
PARL_RX_CLK = 69,
PARL_TX_CLK = 70,
RMT_SIG0 = 71,
RMT_SIG1 = 72,
RMT_SIG_0 = 71,
RMT_SIG_1 = 72,
TWAI0_RX = 73,
PWM0_SYNC0 = 87,
PWM0_SYNC1 = 88,
Expand Down Expand Up @@ -170,8 +170,8 @@ pub enum OutputSignal {
FSPICS0 = 68,
PARL_RX_CLK = 69,
PARL_TX_CLK = 70,
RMT_SIG_OUT0 = 71,
RMT_SIG_OUT1 = 72,
RMT_SIG_0 = 71,
RMT_SIG_1 = 72,
TWAI0_TX = 73,
TWAI0_BUS_OFF_ON = 74,
TWAI0_CLKOUT = 75,
Expand Down
2 changes: 1 addition & 1 deletion esp-hal-common/src/soc/esp32h2/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ crate::peripherals! {
PCNT => true,
PCR => true,
// PMU => true,
// RMT => true,
RMT => true,
// RNG => true,
RSA => true,
SHA => true,
Expand Down
13 changes: 10 additions & 3 deletions esp32-hal/examples/pulse_control.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
//! This demos basic usage of RMT / PulseControl
//! Use a logic analyzer to see the generated pulses.
//! The correct output is only achieved when running in release mode.
//! RMT / PulseControl
//!
//! Folowing pins are used:
//! GPIO4 (RMT channel 0)
//!
//! Depending on your target and the board you are using you have to change the
//! pins.
//!
//! This is an example of generating pulses. Attach a Logic Analyzer to the RTM
//! channel 0 pin to see the gerated signal.

#![no_std]
#![no_main]
Expand Down
13 changes: 10 additions & 3 deletions esp32c3-hal/examples/pulse_control.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
//! This demos basic usage of RMT / PulseControl
//! Use a logic analyzer to see the generated pulses.
//! The correct output is only achieved when running in release mode.
//! RMT / PulseControl
//!
//! Folowing pins are used:
//! GPIO4 (RMT channel 0)
//!
//! Depending on your target and the board you are using you have to change the
//! pins.
//!
//! This is an example of generating pulses. Attach a Logic Analyzer to the RTM
//! channel 0 pin to see the gerated signal.

#![no_std]
#![no_main]
Expand Down
13 changes: 10 additions & 3 deletions esp32c6-hal/examples/pulse_control.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
//! This demos basic usage of RMT / PulseControl
//! Use a logic analyzer to see the generated pulses.
//! The correct output is only achieved when running in release mode.
//! RMT / PulseControl
//!
//! Folowing pins are used:
//! GPIO4 (RMT channel 0)
//!
//! Depending on your target and the board you are using you have to change the
//! pins.
//!
//! This is an example of generating pulses. Attach a Logic Analyzer to the RTM
//! channel 0 pin to see the gerated signal.

#![no_std]
#![no_main]
Expand Down
Loading