-
Notifications
You must be signed in to change notification settings - Fork 370
Description
I was switching my project from manual interrupt handling to using embassy. In the process I also switched from blocking to async RMT. Before, I was sending about 150*24=3000 PulseCodes on each transmission without issues to control an LED strip. With the async implementation, the strip wasnt getting any input apparently. I used parts of the embassy_rmt example to reproduce this and check for which array sizes the RMT would stop working completely. At 65 PulseCodes, my example stopped working, so 64 seems to be the sweet spot.
This makes some sense as the RAM blocks for each RMT channel hold up to 64 data points according to the ESP32 documentation. So, I guess, something which the Blocking implementation is doing right is going wrong on the Async side. I haven't had the time to look into the implementation further. Maybe someone has an insight on this?
Here are some snippets of the program:
#[main]
async fn main(spawner: Spawner) {
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let clocks = ClockControl::max(system.clock_control).freeze();
esp_println::logger::init_logger_from_env();
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
esp_hal_embassy::init(&clocks, timg0);
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let channel = transmit::init_rmt(peripherals.RMT, io.pins.gpio26, &clocks);
spawner.spawn(test_rmt(channel)).ok();
}
pub fn init_rmt<'d, P: esp_hal::gpio::OutputPin>(
rmt: impl Peripheral<P = RMT> + 'd,
pin: impl Peripheral<P = P> + 'd,
clocks: &Clocks,
) -> Channel<Async, 0> {
let _rmt = Rmt::new_async(rmt, HertzU32::MHz(80), clocks).unwrap();
_rmt.channel0
.configure(
pin,
TxChannelConfig {
clk_divider: 1,
idle_output_level: false,
idle_output: false,
carrier_modulation: false,
carrier_high: 1,
carrier_low: 1,
carrier_level: false,
},
)
.unwrap()
}
#[embassy_executor::task]
async fn test_rmt(mut channel: Channel<Async, 0>) {
loop {
let on = 10000 / NS_PER_CLOCK_CYCLE;
let off = 10000 / NS_PER_CLOCK_CYCLE;
let mut sequence = [PulseCode {
level1: true,
length1: on,
level2: false,
length2: off,
}; 65];
sequence.last_mut().unwrap().length2 = 0;
channel.transmit(&sequence).await.ok();
Timer::after_secs(1).await;
}
}Metadata
Metadata
Assignees
Labels
Type
Projects
Status