unstable
only.Expand description
§Event Task Matrix (ETM)
§Overview
Normally, if a peripheral X needs to notify peripheral Y of a particular event, this could only be done via a CPU interrupt from peripheral X, where the CPU notifies peripheral Y on behalf of peripheral X. However, in time-critical applications, the latency introduced by CPU interrupts is non-negligible.
With the help of the Event Task Matrix (ETM) module, some peripherals can directly notify other peripherals of events through pre-set connections without the intervention of CPU interrupts. This allows precise and low latency synchronization between peripherals, and lessens the CPU’s workload as the CPU no longer needs to handle these events.
The ETM module has multiple programmable channels, they are used to connect a particular Event to a particular Task. When an event is activated, the ETM channel will trigger the corresponding task automatically.
For more information, please refer to the ESP-IDF documentation
§Examples
§Control LED by the button via ETM
let mut led = peripherals.GPIO1;
let button = peripherals.GPIO9;
// setup ETM
let gpio_ext = Channels::new(peripherals.GPIO_SD);
let led_task = gpio_ext.channel0_task.toggle(
&mut led,
OutputConfig {
open_drain: false,
pull: Pull::None,
initial_state: Level::Low,
},
);
let button_event = gpio_ext
.channel0_event
.falling_edge(button, InputConfig { pull: Pull::Down });
let etm = Etm::new(peripherals.SOC_ETM);
let channel0 = etm.channel0;
// make sure the configured channel doesn't get dropped - dropping it will
// disable the channel
let _configured_channel = channel0.setup(&button_event, &led_task);
// the LED is controlled by the button without involving the CPU
loop {}
§Control LED by the systimer via ETM
use esp_hal::time::Duration;
let syst = SystemTimer::new(peripherals.SYSTIMER);
let mut alarm0 = syst.alarm0;
let mut timer = PeriodicTimer::new(&mut alarm0);
timer.start(Duration::from_secs(1));
let mut led = peripherals.GPIO1;
// setup ETM
let gpio_ext = Channels::new(peripherals.GPIO_SD);
let led_task = gpio_ext.channel0_task.toggle(
&mut led,
OutputConfig {
open_drain: false,
pull: Pull::None,
initial_state: Level::Low,
},
);
let timer_event = Event::new(&mut alarm0);
let etm = Etm::new(peripherals.SOC_ETM);
let channel0 = etm.channel0;
// make sure the configured channel doesn't get dropped - dropping it will
// disable the channel
let _configured_channel = channel0.setup(&timer_event, &led_task);
// the LED is controlled by the timer without involving the CPU
loop {}
Structs§
- Etm
- ETM Instance
- EtmChannel
- Unconfigured EtmChannel.
- EtmConfigured
Channel - A readily configured channel