Add a new RMT driver (#653)

* Add a new RMT driver

* Add CHANGELOG entry

* Fix typos
This commit is contained in:
Björn Quentin 2023-07-19 19:54:52 +02:00 committed by GitHub
parent fe1965e322
commit 213dde9304
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 2792 additions and 29 deletions

View File

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add initial LP-IO support for ESP32-C6 (#639)
- Implement sleep with some wakeup methods for `esp32` (#574)
- Add a new RMT driver (#653)
### Changed

View File

@ -52,13 +52,13 @@ ufmt-write = { version = "0.1.0", optional = true }
# IMPORTANT:
# Each supported device MUST have its PAC included below along with a
# corresponding feature.
esp32 = { version = "0.24.0", features = ["critical-section"], optional = true }
esp32 = { git = "https://github.com/esp-rs/esp-pacs.git", rev = "c72707e", version = "0.24.0", features = ["critical-section"], optional = true }
esp32c2 = { version = "0.12.0", features = ["critical-section"], optional = true }
esp32c3 = { version = "0.15.0", features = ["critical-section"], optional = true }
esp32c6 = { version = "0.5.0", features = ["critical-section"], optional = true }
esp32h2 = { version = "0.1.0", features = ["critical-section"], optional = true }
esp32c3 = { git = "https://github.com/esp-rs/esp-pacs.git", rev = "c72707e", version = "0.15.0", features = ["critical-section"], optional = true }
esp32c6 = { git = "https://github.com/esp-rs/esp-pacs.git", rev = "c72707e", version = "0.5.0", features = ["critical-section"], optional = true }
esp32h2 = { git = "https://github.com/esp-rs/esp-pacs.git", rev = "c72707e", version = "0.1.0", features = ["critical-section"], optional = true }
esp32s2 = { version = "0.15.0", features = ["critical-section"], optional = true }
esp32s3 = { version = "0.19.0", features = ["critical-section"], optional = true }
esp32s3 = { git = "https://github.com/esp-rs/esp-pacs.git", rev = "c72707e", version = "0.19.0", features = ["critical-section"], optional = true }
[build-dependencies]
basic-toml = "0.1.2"

View File

@ -54,6 +54,8 @@ pub use self::dma::pdma;
pub use self::gpio::IO;
#[cfg(rmt)]
pub use self::pulse_control::PulseControl;
#[cfg(rmt)]
pub use self::rmt::Rmt;
#[cfg(rng)]
pub use self::rng::Rng;
#[cfg(any(lp_clkrst, rtc_cntl))]
@ -114,6 +116,8 @@ pub mod pulse_control;
#[cfg(radio)]
pub mod radio;
pub mod reset;
#[cfg(rmt)]
pub mod rmt;
#[cfg(rng)]
pub mod rng;
pub mod rom;

View File

@ -1116,10 +1116,10 @@ rmt!(
#[cfg(esp32s2)]
rmt!(
apb_conf,
(0, Channel0, channel0, OutputSignal::RMT_SIG_OUT0),
(1, Channel1, channel1, OutputSignal::RMT_SIG_OUT1),
(2, Channel2, channel2, OutputSignal::RMT_SIG_OUT2),
(3, Channel3, channel3, OutputSignal::RMT_SIG_OUT3),
(0, Channel0, channel0, OutputSignal::RMT_SIG_0),
(1, Channel1, channel1, OutputSignal::RMT_SIG_1),
(2, Channel2, channel2, OutputSignal::RMT_SIG_2),
(3, Channel3, channel3, OutputSignal::RMT_SIG_3),
);
#[cfg(esp32)]
@ -1138,8 +1138,8 @@ rmt!(
#[cfg(esp32s3)]
rmt!(
sys_conf,
(0, Channel0, channel0, OutputSignal::RMT_SIG_OUT0),
(1, Channel1, channel1, OutputSignal::RMT_SIG_OUT1),
(2, Channel2, channel2, OutputSignal::RMT_SIG_OUT2),
(3, Channel3, channel3, OutputSignal::RMT_SIG_OUT3),
(0, Channel0, channel0, OutputSignal::RMT_SIG_0),
(1, Channel1, channel1, OutputSignal::RMT_SIG_1),
(2, Channel2, channel2, OutputSignal::RMT_SIG_2),
(3, Channel3, channel3, OutputSignal::RMT_SIG_3),
);

1624
esp-hal-common/src/rmt.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9,4 +9,7 @@ pub mod radio_clocks;
pub(crate) mod constants {
pub const I2S_SCLK: u32 = 160_000_000;
pub const I2S_DEFAULT_CLK_SRC: u32 = 2;
pub const RMT_RAM_START: usize = 0x3ff56800;
pub const RMT_CHANNEL_RAM_SIZE: usize = 64;
}

View File

@ -10,4 +10,9 @@ pub(crate) mod registers {
pub(crate) mod constants {
pub const I2S_SCLK: u32 = 160_000_000;
pub const I2S_DEFAULT_CLK_SRC: u8 = 2;
pub const RMT_RAM_START: usize = 0x60016400;
pub const RMT_CHANNEL_RAM_SIZE: usize = 48;
pub const RMT_CLOCK_SRC: u8 = 1;
pub const RMT_CLOCK_SRC_FREQ: fugit::HertzU32 = fugit::HertzU32::MHz(80);
}

View File

@ -13,4 +13,9 @@ pub(crate) mod constants {
pub const I2S_SCLK: u32 = 160_000_000;
pub const I2S_DEFAULT_CLK_SRC: u8 = 2;
pub const RMT_RAM_START: usize = 0x60006400;
pub const RMT_CHANNEL_RAM_SIZE: usize = 48;
pub const RMT_CLOCK_SRC: u8 = 1;
pub const RMT_CLOCK_SRC_FREQ: fugit::HertzU32 = fugit::HertzU32::MHz(80);
}

View File

@ -12,4 +12,9 @@ pub(crate) mod constants {
pub const I2S_DEFAULT_CLK_SRC: u8 = 1;
pub const I2S_SCLK: u32 = 96_000_000;
pub const RMT_RAM_START: usize = 0x60007400;
pub const RMT_CHANNEL_RAM_SIZE: usize = 48;
pub const RMT_CLOCK_SRC: bool = false;
pub const RMT_CLOCK_SRC_FREQ: fugit::HertzU32 = fugit::HertzU32::MHz(32);
}

View File

@ -128,10 +128,10 @@ pub enum InputSignal {
SPI3_D = 74,
SPI3_HD = 75,
SPI3_CS0 = 76,
RMT_SIG_IN0 = 83,
RMT_SIG_IN1 = 84,
RMT_SIG_IN2 = 85,
RMT_SIG_IN3 = 86,
RMT_SIG_0 = 83,
RMT_SIG_1 = 84,
RMT_SIG_2 = 85,
RMT_SIG_3 = 86,
I2CEXT1_SCL = 95,
I2CEXT1_SDA = 96,
FSPICLK = 108,
@ -202,10 +202,10 @@ pub enum OutputSignal {
LEDC_LS_SIG5 = 84,
LEDC_LS_SIG6 = 85,
LEDC_LS_SIG7 = 86,
RMT_SIG_OUT0 = 87,
RMT_SIG_OUT1 = 88,
RMT_SIG_OUT2 = 89,
RMT_SIG_OUT3 = 90,
RMT_SIG_0 = 87,
RMT_SIG_1 = 88,
RMT_SIG_2 = 89,
RMT_SIG_3 = 90,
I2CEXT1_SCL = 95,
I2CEXT1_SDA = 96,
GPIO_SD0 = 100,

View File

@ -9,4 +9,7 @@ pub mod ulp_core;
pub(crate) mod constants {
pub const I2S_SCLK: u32 = 160_000_000;
pub const I2S_DEFAULT_CLK_SRC: u32 = 2;
pub const RMT_RAM_START: usize = 0x3f416400;
pub const RMT_CHANNEL_RAM_SIZE: usize = 64;
}

View File

@ -93,10 +93,10 @@ pub enum InputSignal {
SPI3_HD = 69,
SPI3_WP = 70,
SPI3_CS0 = 71,
RMT_SIG_IN0 = 81,
RMT_SIG_IN1 = 82,
RMT_SIG_IN2 = 83,
RMT_SIG_IN3 = 84,
RMT_SIG_0 = 81,
RMT_SIG_1 = 82,
RMT_SIG_2 = 83,
RMT_SIG_3 = 84,
I2CEXT0_SCL = 89,
I2CEXT0_SDA = 90,
I2CEXT1_SCL = 91,
@ -195,10 +195,10 @@ pub enum OutputSignal {
LEDC_LS_SIG5 = 78,
LEDC_LS_SIG6 = 79,
LEDC_LS_SIG7 = 80,
RMT_SIG_OUT0 = 81,
RMT_SIG_OUT1 = 82,
RMT_SIG_OUT2 = 83,
RMT_SIG_OUT3 = 84,
RMT_SIG_0 = 81,
RMT_SIG_1 = 82,
RMT_SIG_2 = 83,
RMT_SIG_3 = 84,
I2CEXT0_SCL = 89,
I2CEXT0_SDA = 90,
I2CEXT1_SCL = 91,

View File

@ -10,4 +10,9 @@ pub mod ulp_core;
pub(crate) mod constants {
pub const I2S_SCLK: u32 = 160_000_000;
pub const I2S_DEFAULT_CLK_SRC: u8 = 2;
pub const RMT_RAM_START: usize = 0x60016800;
pub const RMT_CHANNEL_RAM_SIZE: usize = 48;
pub const RMT_CLOCK_SRC: u8 = 1;
pub const RMT_CLOCK_SRC_FREQ: fugit::HertzU32 = fugit::HertzU32::MHz(80);
}

View File

@ -0,0 +1,102 @@
//! Demonstrates decoding pulse sequences with RMT
//! Connect GPIO15 to GPIO4
#![no_std]
#![no_main]
use esp32_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, RxChannel, RxChannelConfig, RxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
use esp_println::println;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.DPORT.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut clock_control = system.peripheral_clock_control;
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt = timer_group0.wdt;
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
// Disable MWDT and RWDT (Watchdog) flash boot protection
wdt.disable();
rtc.rwdt.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let mut out = io.pins.gpio15.into_push_pull_output();
let rmt = Rmt::new(peripherals.RMT, 80u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel0
.configure(
io.pins.gpio4,
RxChannelConfig {
clk_divider: 1,
idle_threshold: 0b111_1111_1111_1111,
..RxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 1,
level2: false,
length2: 1,
}; 48];
loop {
for x in data.iter_mut() {
x.length1 = 0;
x.length2 = 0;
}
let transaction = channel.receive(&mut data).unwrap();
// simulate input
for i in 0u32..5u32 {
out.set_high().unwrap();
delay.delay_us(i * 10 + 20);
out.set_low().unwrap();
delay.delay_us(i * 20 + 20);
}
match transaction.wait() {
Ok(channel_res) => {
channel = channel_res;
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
println!("{} {}", entry.level1, entry.length1);
if entry.length2 == 0 {
break;
}
println!("{} {}", entry.level2, entry.length2);
}
println!();
}
Err((_err, channel_res)) => {
channel = channel_res;
println!("Error");
}
}
delay.delay_ms(1500u32);
}
}

View File

@ -0,0 +1,72 @@
//! Demonstrates generating pulse sequences with RMT
//! Connect a logic analyzer to GPIO4 to see the generated pulses.
#![no_std]
#![no_main]
use esp32_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, TxChannel, TxChannelConfig, TxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.DPORT.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut clock_control = system.peripheral_clock_control;
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt = timer_group0.wdt;
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
// Disable MWDT and RWDT (Watchdog) flash boot protection
wdt.disable();
rtc.rwdt.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let rmt = Rmt::new(peripherals.RMT, 80u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel0
.configure(
io.pins.gpio4,
TxChannelConfig {
clk_divider: 255,
..TxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 200,
level2: false,
length2: 50,
}; 20];
data[data.len() - 2] = PulseCode {
level1: true,
length1: 3000,
level2: false,
length2: 500,
};
data[data.len() - 1] = PulseCode::default();
loop {
let transaction = channel.transmit(&data);
channel = transaction.wait().unwrap();
delay.delay_ms(500u32);
}
}

View File

@ -0,0 +1,115 @@
//! Demonstrates decoding pulse sequences with RMT
//! This uses the boot button as input - press the button a couple of
//! times to generate a pulse sequence and then wait for the idle timeout to see
//! the recorded pulse sequence
#![no_std]
#![no_main]
use esp32c3_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, RxChannel, RxChannelConfig, RxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
use esp_println::{print, println};
const WIDTH: usize = 80;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut clock_control = system.peripheral_clock_control;
// Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT,
// the RTC WDT, and the TIMG WDTs.
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks, &mut clock_control);
let mut wdt1 = timer_group1.wdt;
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let rmt = Rmt::new(peripherals.RMT, 1u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel2
.configure(
io.pins.gpio9,
RxChannelConfig {
clk_divider: 255,
idle_threshold: 10000,
..RxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 1,
level2: false,
length2: 1,
}; 48];
loop {
let transaction = channel.receive(&mut data).unwrap();
channel = transaction.wait().unwrap();
let mut total = 0usize;
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
total += entry.length1 as usize;
if entry.length2 == 0 {
break;
}
total += entry.length2 as usize;
}
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
let count = WIDTH / (total / entry.length1 as usize);
let c = if entry.level1 { '-' } else { '_' };
for _ in 0..count + 1 {
print!("{}", c);
}
if entry.length2 == 0 {
break;
}
let count = WIDTH / (total / entry.length2 as usize);
let c = if entry.level2 { '-' } else { '_' };
for _ in 0..count + 1 {
print!("{}", c);
}
}
println!();
println!();
println!();
delay.delay_ms(500u32);
}
}

View File

@ -0,0 +1,77 @@
//! Demonstrates generating pulse sequences with RMT
//! Connect a logic analyzer to GPIO1 to see the generated pulses.
#![no_std]
#![no_main]
use esp32c3_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, TxChannel, TxChannelConfig, TxChannelCreator},
timer::TimerGroup,
Rmt,
Rtc,
};
use esp_backtrace as _;
use esp_hal_common::Delay;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut clock_control = system.peripheral_clock_control;
// Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT,
// the RTC WDT, and the TIMG WDTs.
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks, &mut clock_control);
let mut wdt1 = timer_group1.wdt;
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let rmt = Rmt::new(peripherals.RMT, 8u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel0
.configure(
io.pins.gpio1.into_push_pull_output(),
TxChannelConfig {
clk_divider: 255,
..TxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 200,
level2: false,
length2: 50,
}; 20];
data[data.len() - 2] = PulseCode {
level1: true,
length1: 3000,
level2: false,
length2: 500,
};
data[data.len() - 1] = PulseCode::default();
loop {
let transaction = channel.transmit(&data);
channel = transaction.wait().unwrap();
delay.delay_ms(500u32);
}
}

View File

@ -0,0 +1,115 @@
//! Demonstrates decoding pulse sequences with RMT
//! This uses the boot button as input - press the button a couple of
//! times to generate a pulse sequence and then wait for the idle timeout to see
//! the recorded pulse sequence
#![no_std]
#![no_main]
use esp32c6_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, RxChannel, RxChannelConfig, RxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
use esp_println::{print, println};
const WIDTH: usize = 80;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.PCR.split();
let mut clock_control = system.peripheral_clock_control;
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
// Disable the watchdog timers. For the ESP32-C6, this includes the Super WDT,
// and the TIMG WDTs.
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks, &mut clock_control);
let mut wdt1 = timer_group1.wdt;
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let rmt = Rmt::new(peripherals.RMT, 1u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel2
.configure(
io.pins.gpio9,
RxChannelConfig {
clk_divider: 255,
idle_threshold: 10000,
..RxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 1,
level2: false,
length2: 1,
}; 48];
loop {
let transaction = channel.receive(&mut data).unwrap();
channel = transaction.wait().unwrap();
let mut total = 0usize;
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
total += entry.length1 as usize;
if entry.length2 == 0 {
break;
}
total += entry.length2 as usize;
}
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
let count = WIDTH / (total / entry.length1 as usize);
let c = if entry.level1 { '-' } else { '_' };
for _ in 0..count + 1 {
print!("{}", c);
}
if entry.length2 == 0 {
break;
}
let count = WIDTH / (total / entry.length2 as usize);
let c = if entry.level2 { '-' } else { '_' };
for _ in 0..count + 1 {
print!("{}", c);
}
}
println!();
println!();
println!();
delay.delay_ms(500u32);
}
}

View File

@ -0,0 +1,77 @@
//! Demonstrates generating pulse sequences with RMT
//! Connect a logic analyzer to GPIO1 to see the generated pulses.
#![no_std]
#![no_main]
use esp32c6_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, TxChannel, TxChannelConfig, TxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.PCR.split();
let mut clock_control = system.peripheral_clock_control;
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
// Disable the watchdog timers. For the ESP32-C6, this includes the Super WDT,
// and the TIMG WDTs.
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks, &mut clock_control);
let mut wdt1 = timer_group1.wdt;
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let rmt = Rmt::new(peripherals.RMT, 8u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel0
.configure(
io.pins.gpio1,
TxChannelConfig {
clk_divider: 255,
..TxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 200,
level2: false,
length2: 50,
}; 20];
data[data.len() - 2] = PulseCode {
level1: true,
length1: 3000,
level2: false,
length2: 500,
};
data[data.len() - 1] = PulseCode::default();
loop {
let transaction = channel.transmit(&data);
channel = transaction.wait().unwrap();
delay.delay_ms(500u32);
}
}

View File

@ -0,0 +1,115 @@
//! Demonstrates decoding pulse sequences with RMT
//! This uses the boot button as input - press the button a couple of
//! times to generate a pulse sequence and then wait for the idle timeout to see
//! the recorded pulse sequence
#![no_std]
#![no_main]
use esp32h2_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, RxChannel, RxChannelConfig, RxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
use esp_println::{print, println};
const WIDTH: usize = 80;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.PCR.split();
let mut clock_control = system.peripheral_clock_control;
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
// Disable the watchdog timers. For the ESP32-C6, this includes the Super WDT,
// and the TIMG WDTs.
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks, &mut clock_control);
let mut wdt1 = timer_group1.wdt;
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let rmt = Rmt::new(peripherals.RMT, 1u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel2
.configure(
io.pins.gpio9,
RxChannelConfig {
clk_divider: 255,
idle_threshold: 10000,
..RxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 1,
level2: false,
length2: 1,
}; 48];
loop {
let transaction = channel.receive(&mut data).unwrap();
channel = transaction.wait().unwrap();
let mut total = 0usize;
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
total += entry.length1 as usize;
if entry.length2 == 0 {
break;
}
total += entry.length2 as usize;
}
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
let count = WIDTH / (total / entry.length1 as usize);
let c = if entry.level1 { '-' } else { '_' };
for _ in 0..count + 1 {
print!("{}", c);
}
if entry.length2 == 0 {
break;
}
let count = WIDTH / (total / entry.length2 as usize);
let c = if entry.level2 { '-' } else { '_' };
for _ in 0..count + 1 {
print!("{}", c);
}
}
println!();
println!();
println!();
delay.delay_ms(500u32);
}
}

View File

@ -0,0 +1,77 @@
//! Demonstrates generating pulse sequences with RMT
//! Connect a logic analyzer to GPIO1 to see the generated pulses.
#![no_std]
#![no_main]
use esp32h2_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, TxChannel, TxChannelConfig, TxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let mut system = peripherals.PCR.split();
let mut clock_control = system.peripheral_clock_control;
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
// Disable the watchdog timers. For the ESP32-C6, this includes the Super WDT,
// and the TIMG WDTs.
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks, &mut clock_control);
let mut wdt1 = timer_group1.wdt;
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let rmt = Rmt::new(peripherals.RMT, 8u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel0
.configure(
io.pins.gpio1,
TxChannelConfig {
clk_divider: 255,
..TxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 200,
level2: false,
length2: 50,
}; 20];
data[data.len() - 2] = PulseCode {
level1: true,
length1: 3000,
level2: false,
length2: 500,
};
data[data.len() - 1] = PulseCode::default();
loop {
let transaction = channel.transmit(&data);
channel = transaction.wait().unwrap();
delay.delay_ms(500u32);
}
}

View File

@ -0,0 +1,102 @@
//! Demonstrates decoding pulse sequences with RMT
//! Connect GPIO15 to GPIO4
#![no_std]
#![no_main]
use esp32s2_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, RxChannel, RxChannelConfig, RxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
use esp_println::println;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut clock_control = system.peripheral_clock_control;
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt = timer_group0.wdt;
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
// Disable MWDT and RWDT (Watchdog) flash boot protection
wdt.disable();
rtc.rwdt.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let mut out = io.pins.gpio15.into_push_pull_output();
let rmt = Rmt::new(peripherals.RMT, 80u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel0
.configure(
io.pins.gpio4,
RxChannelConfig {
clk_divider: 1,
idle_threshold: 0b111_1111_1111_1111,
..RxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 1,
level2: false,
length2: 1,
}; 48];
loop {
for x in data.iter_mut() {
x.length1 = 0;
x.length2 = 0;
}
let transaction = channel.receive(&mut data).unwrap();
// simulate input
for i in 0u32..5u32 {
out.set_high().unwrap();
delay.delay_us(i * 10 + 20);
out.set_low().unwrap();
delay.delay_us(i * 20 + 20);
}
match transaction.wait() {
Ok(channel_res) => {
channel = channel_res;
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
println!("{} {}", entry.level1, entry.length1);
if entry.length2 == 0 {
break;
}
println!("{} {}", entry.level2, entry.length2);
}
println!();
}
Err((_err, channel_res)) => {
channel = channel_res;
println!("Error");
}
}
delay.delay_ms(1500u32);
}
}

View File

@ -0,0 +1,71 @@
//! Demonstrates generating pulse sequences with RMT
//! Connect a logic analyzer to GPIO4 to see the generated pulses.
#![no_std]
#![no_main]
use esp32s2_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, TxChannel, TxChannelConfig, TxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut clock_control = system.peripheral_clock_control;
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt = timer_group0.wdt;
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
// Disable MWDT and RWDT (Watchdog) flash boot protection
wdt.disable();
rtc.rwdt.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let mut delay = Delay::new(&clocks);
let rmt = Rmt::new(peripherals.RMT, 80u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel2
.configure(
io.pins.gpio4,
TxChannelConfig {
clk_divider: 255,
..TxChannelConfig::default()
},
)
.unwrap();
let mut data = [PulseCode {
level1: true,
length1: 200,
level2: false,
length2: 50,
}; 20];
data[data.len() - 2] = PulseCode {
level1: true,
length1: 3000,
level2: false,
length2: 500,
};
data[data.len() - 1] = PulseCode::default();
loop {
let transaction = channel.transmit(&data);
channel = transaction.wait().unwrap();
delay.delay_ms(500u32);
}
}

View File

@ -0,0 +1,110 @@
//! Demonstrates decoding pulse sequences with RMT
//! This uses the boot button as input - press the button a couple of
//! times to generate a pulse sequence and then wait for the idle timeout to see
//! the recorded pulse sequence
#![no_std]
#![no_main]
use esp32s3_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
rmt::{PulseCode, RxChannel, RxChannelConfig, RxChannelCreator},
timer::TimerGroup,
Delay,
Rmt,
Rtc,
};
use esp_backtrace as _;
use esp_println::{print, println};
const WIDTH: usize = 80;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut clock_control = system.peripheral_clock_control;
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt = timer_group0.wdt;
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
// Disable MWDT and RWDT (Watchdog) flash boot protection
wdt.disable();
rtc.rwdt.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let rmt = Rmt::new(peripherals.RMT, 1u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel7
.configure(
io.pins.gpio0,
RxChannelConfig {
clk_divider: 255,
idle_threshold: 10000,
..RxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 1,
level2: false,
length2: 1,
}; 48];
loop {
let transaction = channel.receive(&mut data).unwrap();
channel = transaction.wait().unwrap();
let mut total = 0usize;
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
total += entry.length1 as usize;
if entry.length2 == 0 {
break;
}
total += entry.length2 as usize;
}
for entry in &data[..data.len()] {
if entry.length1 == 0 {
break;
}
let count = WIDTH / (total / entry.length1 as usize);
let c = if entry.level1 { '-' } else { '_' };
for _ in 0..count + 1 {
print!("{}", c);
}
if entry.length2 == 0 {
break;
}
let count = WIDTH / (total / entry.length2 as usize);
let c = if entry.level2 { '-' } else { '_' };
for _ in 0..count + 1 {
print!("{}", c);
}
}
println!();
println!();
println!();
delay.delay_ms(500u32);
}
}

View File

@ -0,0 +1,75 @@
//! Demonstrates generating pulse sequences with RMT
//! Connect a logic analyzer to GPIO1 to see the generated pulses.
#![no_std]
#![no_main]
use esp32s3_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
timer::TimerGroup,
Delay,
Rtc,
};
use esp_backtrace as _;
use esp_hal_common::{
rmt::{PulseCode, TxChannel, TxChannelConfig, TxChannelCreator},
Rmt,
};
use esp_println::println;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let mut clock_control = system.peripheral_clock_control;
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks, &mut clock_control);
let mut wdt = timer_group0.wdt;
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
// Disable MWDT and RWDT (Watchdog) flash boot protection
wdt.disable();
rtc.rwdt.disable();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let rmt = Rmt::new(peripherals.RMT, 8u32.MHz(), &mut clock_control, &clocks).unwrap();
let mut channel = rmt
.channel0
.configure(
io.pins.gpio1,
TxChannelConfig {
clk_divider: 255,
..TxChannelConfig::default()
},
)
.unwrap();
let mut delay = Delay::new(&clocks);
let mut data = [PulseCode {
level1: true,
length1: 200,
level2: false,
length2: 50,
}; 20];
data[data.len() - 2] = PulseCode {
level1: true,
length1: 3000,
level2: false,
length2: 500,
};
data[data.len() - 1] = PulseCode::default();
loop {
let transaction = channel.transmit(&data);
channel = transaction.wait().unwrap();
delay.delay_ms(500u32);
}
}