esp-hal icon indicating copy to clipboard operation
esp-hal copied to clipboard

[RMT] single shot transmit is continuous.

Open Tnze opened this issue 1 year ago • 3 comments

My testing code is basically same as the RMT example , but remove the final PulseCode::default() from data. And some logging and delay are added.

It turns out that as long as I remove the final PulseCode::default(), the wait() never returned.

#![no_std]
#![no_main]

use esp_backtrace as _;
use esp_hal::{
    clock::ClockControl,
    delay::Delay,
    gpio::Io,
    peripherals::Peripherals,
    prelude::*,
    rmt::{PulseCode, Rmt, TxChannel, TxChannelConfig, TxChannelCreator},
    system::SystemControl,
};

extern crate alloc;
use core::mem::MaybeUninit;

#[global_allocator]
static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();

fn init_heap() {
    const HEAP_SIZE: usize = 32 * 1024;
    static mut HEAP: MaybeUninit<[u8; HEAP_SIZE]> = MaybeUninit::uninit();

    unsafe {
        ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, HEAP_SIZE);
    }
}

#[entry]
fn main() -> ! {
    let peripherals = Peripherals::take();
    let system = SystemControl::new(peripherals.SYSTEM);

    let clocks = ClockControl::max(system.clock_control).freeze();
    let delay = Delay::new(&clocks);
    init_heap();

    esp_println::logger::init_logger_from_env();

    let timg0 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG0, &clocks);
    let _init = esp_wifi::initialize(
        esp_wifi::EspWifiInitFor::Ble,
        timg0.timer0,
        esp_hal::rng::Rng::new(peripherals.RNG),
        peripherals.RADIO_CLK,
        &clocks,
    )
    .unwrap();

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

    let rmt = Rmt::new(peripherals.RMT, 32.MHz(), &clocks).unwrap();

    let tx_config = TxChannelConfig {
        clk_divider: 255,
        ..TxChannelConfig::default()
    };
    let mut channel = rmt.channel0.configure(io.pins.gpio0, tx_config).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();

    delay.delay(5.secs());
    loop {
        log::info!("Hello world!");
        let transaction = channel.transmit(&data);
        channel = transaction.wait().unwrap();
        delay.delay_millis(500);
    }
}

Tnze avatar Sep 08 '24 06:09 Tnze

We probably should check there is a transmission end-marker when starting a one-shot transmission

bjoernQ avatar Sep 09 '24 07:09 bjoernQ

You mean the last element is a terminal marker?

Tnze avatar Sep 09 '24 07:09 Tnze

You mean the last element is a terminal marker?

Yes - from the TRM

The minimum value for the period is zero (0) and is interpreted as a transmission end-marker

bjoernQ avatar Sep 09 '24 07:09 bjoernQ