Skip to content

Commit 129fa96

Browse files
authored
RMT: move more things to esp-metadata, improve HIL test robustness (#4138)
* RMT: use hil_test::assert{,eq}, clarify potential timing issues * RMT: prevent flaky HIL tests by matching pulse codes fuzzily * RMT: add rmt_clock_rate HIL test * RMT: add esp-metadata flags for most hardware features * RMT: move supported clock sources to esp-metadata * RMT: move max_idle_threshold to esp-metadata from a quick glance at the TRMs, it seems that these values are also wrong! e.g. c3 & c6 appear to support up to 0x7FFF -> this should be verified and fixed if correct
1 parent 8e6b591 commit 129fa96

File tree

21 files changed

+673
-58
lines changed

21 files changed

+673
-58
lines changed

esp-hal/src/rmt.rs

Lines changed: 73 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ use crate::{
213213
Async,
214214
Blocking,
215215
asynch::AtomicWaker,
216+
clock::Clocks,
216217
gpio::{
217218
self,
218219
InputConfig,
@@ -788,7 +789,7 @@ impl<'d> Rmt<'d, Blocking> {
788789
/// Create a new RMT instance
789790
pub fn new(peripheral: RMT<'d>, frequency: Rate) -> Result<Self, Error> {
790791
let this = Rmt::create(peripheral);
791-
self::chip_specific::configure_clock(frequency)?;
792+
self::chip_specific::configure_clock(ClockSource::default(), frequency)?;
792793
Ok(this)
793794
}
794795

@@ -1032,13 +1033,7 @@ where
10321033

10331034
let _guard = GenericPeripheralGuard::new();
10341035

1035-
let threshold = if cfg!(any(esp32, esp32s2)) {
1036-
0b111_1111_1111_1111
1037-
} else {
1038-
0b11_1111_1111_1111
1039-
};
1040-
1041-
if config.idle_threshold > threshold {
1036+
if config.idle_threshold > property!("rmt.max_idle_threshold") {
10421037
return Err(Error::InvalidArgument);
10431038
}
10441039

@@ -1661,13 +1656,70 @@ impl DynChannelAccess<Rx> {
16611656
}
16621657
}
16631658

1659+
for_each_rmt_clock_source!(
1660+
(all $(($name:ident, $bits:literal)),+) => {
1661+
#[derive(Clone, Copy, Debug)]
1662+
#[repr(u8)]
1663+
enum ClockSource {
1664+
$(
1665+
#[allow(unused)]
1666+
$name = $bits,
1667+
)+
1668+
}
1669+
};
1670+
1671+
(is_boolean) => {
1672+
impl ClockSource {
1673+
fn bit(self) -> bool {
1674+
match (self as u8) {
1675+
0 => false,
1676+
1 => true,
1677+
_ => unreachable!("should be removed by the compiler!"),
1678+
}
1679+
}
1680+
}
1681+
};
1682+
1683+
(default ($name:ident)) => {
1684+
impl ClockSource {
1685+
fn default() -> Self {
1686+
Self::$name
1687+
}
1688+
1689+
fn bits(self) -> u8 {
1690+
self as u8
1691+
}
1692+
1693+
fn freq(self) -> crate::time::Rate {
1694+
match self {
1695+
#[cfg(rmt_supports_apb_clock)]
1696+
ClockSource::Apb => Clocks::get().apb_clock,
1697+
1698+
#[cfg(rmt_supports_rcfast_clock)]
1699+
ClockSource::RcFast => todo!(),
1700+
1701+
#[cfg(rmt_supports_xtal_clock)]
1702+
ClockSource::Xtal => Clocks::get().xtal_clock,
1703+
1704+
#[cfg(rmt_supports_pll80mhz_clock)]
1705+
ClockSource::Pll80MHz => Rate::from_mhz(80),
1706+
1707+
#[cfg(rmt_supports_reftick_clock)]
1708+
ClockSource::RefTick => todo!(),
1709+
}
1710+
}
1711+
}
1712+
};
1713+
);
1714+
16641715
#[cfg(not(any(esp32, esp32s2)))]
16651716
mod chip_specific {
16661717
use enumset::EnumSet;
16671718

16681719
use super::{
16691720
CHANNEL_INDEX_COUNT,
16701721
ChannelIndex,
1722+
ClockSource,
16711723
Direction,
16721724
DynChannelAccess,
16731725
Error,
@@ -1680,8 +1732,8 @@ mod chip_specific {
16801732
};
16811733
use crate::{peripherals::RMT, time::Rate};
16821734

1683-
pub(super) fn configure_clock(frequency: Rate) -> Result<(), Error> {
1684-
let src_clock = crate::soc::constants::RMT_CLOCK_SRC_FREQ;
1735+
pub(super) fn configure_clock(source: ClockSource, frequency: Rate) -> Result<(), Error> {
1736+
let src_clock = source.freq();
16851737

16861738
if frequency > src_clock {
16871739
return Err(Error::UnreachableTargetFrequency);
@@ -1695,7 +1747,7 @@ mod chip_specific {
16951747
{
16961748
RMT::regs().sys_conf().modify(|_, w| unsafe {
16971749
w.clk_en().clear_bit();
1698-
w.sclk_sel().bits(crate::soc::constants::RMT_CLOCK_SRC);
1750+
w.sclk_sel().bits(source.bits());
16991751
w.sclk_div_num().bits(div);
17001752
w.sclk_div_a().bits(0);
17011753
w.sclk_div_b().bits(0);
@@ -1715,11 +1767,11 @@ mod chip_specific {
17151767
#[cfg(esp32c6)]
17161768
PCR::regs()
17171769
.rmt_sclk_conf()
1718-
.modify(|_, w| unsafe { w.sclk_sel().bits(crate::soc::constants::RMT_CLOCK_SRC) });
1770+
.modify(|_, w| unsafe { w.sclk_sel().bits(source.bits()) });
17191771
#[cfg(not(esp32c6))]
17201772
PCR::regs()
17211773
.rmt_sclk_conf()
1722-
.modify(|_, w| w.sclk_sel().bit(crate::soc::constants::RMT_CLOCK_SRC));
1774+
.modify(|_, w| w.sclk_sel().bit(source.bit()));
17231775

17241776
RMT::regs()
17251777
.sys_conf()
@@ -2097,6 +2149,7 @@ mod chip_specific {
20972149

20982150
use super::{
20992151
ChannelIndex,
2152+
ClockSource,
21002153
Direction,
21012154
DynChannelAccess,
21022155
Error,
@@ -2111,16 +2164,16 @@ mod chip_specific {
21112164
};
21122165
use crate::{peripherals::RMT, time::Rate};
21132166

2114-
pub(super) fn configure_clock(frequency: Rate) -> Result<(), Error> {
2115-
if frequency != Rate::from_mhz(80) {
2167+
pub(super) fn configure_clock(source: ClockSource, frequency: Rate) -> Result<(), Error> {
2168+
if frequency != source.freq() {
21162169
return Err(Error::UnreachableTargetFrequency);
21172170
}
21182171

21192172
let rmt = RMT::regs();
21202173

21212174
for ch_num in 0..NUM_CHANNELS {
21222175
rmt.chconf1(ch_num)
2123-
.modify(|_, w| w.ref_always_on().set_bit());
2176+
.modify(|_, w| w.ref_always_on().bit(source.bit()));
21242177
}
21252178

21262179
rmt.apb_conf().modify(|_, w| w.apb_fifo_mask().set_bit());
@@ -2201,7 +2254,7 @@ mod chip_specific {
22012254
}
22022255

22032256
impl DynChannelAccess<Tx> {
2204-
#[cfg(not(esp32))]
2257+
#[cfg(rmt_has_tx_loop_count)]
22052258
#[inline]
22062259
pub fn set_generate_repeat_interrupt(&self, loopcount: Option<LoopCount>) {
22072260
let rmt = crate::peripherals::RMT::regs();
@@ -2215,7 +2268,7 @@ mod chip_specific {
22152268
.modify(|_, w| unsafe { w.tx_loop_num().bits(repeats) });
22162269
}
22172270

2218-
#[cfg(esp32)]
2271+
#[cfg(not(rmt_has_tx_loop_count))]
22192272
#[inline]
22202273
pub fn set_generate_repeat_interrupt(&self, _loopcount: Option<LoopCount>) {
22212274
// unsupported
@@ -2329,7 +2382,7 @@ mod chip_specific {
23292382
// Returns whether stopping was immediate, or needs to wait for tx end
23302383
// Due to inlining, the compiler should be able to eliminate code in the caller that
23312384
// depends on this.
2332-
#[cfg(esp32s2)]
2385+
#[cfg(rmt_has_tx_immediate_stop)]
23332386
#[inline]
23342387
pub fn stop_tx(&self) -> bool {
23352388
let rmt = crate::peripherals::RMT::regs();
@@ -2338,7 +2391,7 @@ mod chip_specific {
23382391
true
23392392
}
23402393

2341-
#[cfg(esp32)]
2394+
#[cfg(not(rmt_has_tx_immediate_stop))]
23422395
#[inline]
23432396
pub fn stop_tx(&self) -> bool {
23442397
let ptr = self.channel_ram_start();

esp-hal/src/soc/esp32c3/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,10 @@ pub(crate) use esp32c3 as pac;
1919

2020
#[cfg_attr(not(feature = "unstable"), allow(unused))]
2121
pub(crate) mod constants {
22-
use crate::time::Rate;
23-
2422
/// The base clock frequency for the I2S peripheral (Hertz).
2523
pub const I2S_SCLK: u32 = 160_000_000;
2624
/// The default clock source for I2S operations.
2725
pub const I2S_DEFAULT_CLK_SRC: u8 = 2;
28-
29-
/// RMT Clock source value.
30-
pub const RMT_CLOCK_SRC: u8 = 1;
31-
/// RMT Clock source frequency.
32-
pub const RMT_CLOCK_SRC_FREQ: Rate = Rate::from_mhz(80);
3326
}
3427

3528
pub(crate) fn pre_init() {}

esp-hal/src/soc/esp32c6/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,11 @@ pub(crate) use esp32c6 as pac;
2121

2222
#[cfg_attr(not(feature = "unstable"), allow(unused))]
2323
pub(crate) mod constants {
24-
use crate::time::Rate;
25-
2624
/// The clock frequency for the I2S peripheral in Hertz.
2725
pub const I2S_SCLK: u32 = 160_000_000;
2826
/// The default clock source for the I2S peripheral.
2927
pub const I2S_DEFAULT_CLK_SRC: u8 = 2;
3028

31-
/// The default clock source for the RMT peripheral.
32-
pub const RMT_CLOCK_SRC: u8 = 1;
33-
/// The frequency of the RMT clock source in Hertz.
34-
pub const RMT_CLOCK_SRC_FREQ: Rate = Rate::from_mhz(80);
35-
3629
/// The clock frequency for the Parallel IO peripheral in Hertz.
3730
pub const PARL_IO_SCLK: u32 = 240_000_000;
3831
}

esp-hal/src/soc/esp32h2/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,11 @@ pub(crate) use esp32h2 as pac;
2020

2121
#[cfg_attr(not(feature = "unstable"), allow(unused))]
2222
pub(crate) mod constants {
23-
use crate::time::Rate;
24-
2523
/// Default clock source for the I2S peripheral.
2624
pub const I2S_DEFAULT_CLK_SRC: u8 = 1;
2725
/// Clock frequency for the I2S peripheral, in Hertz.
2826
pub const I2S_SCLK: u32 = 96_000_000;
2927

30-
/// Clock source for the RMT peripheral (false = default source).
31-
pub const RMT_CLOCK_SRC: bool = false;
32-
/// Frequency of the RMT clock source, in Hertz.
33-
pub const RMT_CLOCK_SRC_FREQ: Rate = Rate::from_mhz(32);
34-
3528
/// System clock frequency for the parallel I/O (PARL IO) peripheral, in
3629
/// Hertz.
3730
pub const PARL_IO_SCLK: u32 = 96_000_000;

esp-hal/src/soc/esp32s3/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,10 @@ pub use esp32s3 as pac;
2121

2222
#[cfg_attr(not(feature = "unstable"), allow(unused))]
2323
pub(crate) mod constants {
24-
use crate::time::Rate;
25-
2624
/// The base clock frequency for the I2S peripheral (Hertz).
2725
pub const I2S_SCLK: u32 = 160_000_000;
2826
/// The default clock source for I2S operations.
2927
pub const I2S_DEFAULT_CLK_SRC: u8 = 2;
30-
31-
/// RMT Clock source value.
32-
pub const RMT_CLOCK_SRC: u8 = 1;
33-
/// RMT Clock source frequency.
34-
pub const RMT_CLOCK_SRC_FREQ: Rate = Rate::from_mhz(80);
3528
}
3629

3730
#[unsafe(link_section = ".rwtext")]

0 commit comments

Comments
 (0)