Connecting LPCOMP CROSS event to TWO DPPI-driven tasks (GPIOTE toggle + TIMER count) simultaneously — only the last-configured one fires

Subject: Connecting LPCOMP CROSS event to TWO DPPI-driven tasks (GPIOTE toggle + TIMER count) simultaneously — only the last-configured one fires

Chip: nRF54L15
SDK: nRF Connect SDK v2.9.0 (Zephyr 3.7.99)
Board: nrf54l15dk/nrf54l15/cpuapp

Hello,

I'm trying to connect the LPCOMP CROSS event, via DPPI, to TWO different tasks at the same time:
1) A GPIOTE OUT task (to toggle a pin — closed-loop drive)
2) A TIMER COUNT task (to count the crossings — frequency measurement)

Goal: whenever LPCOMP's CROSS event fires, it should BOTH toggle a GPIO pin AND increment a TIMER — simultaneously, from the same single event.

I tried two approaches and both gave the same result: only the LAST configured task actually fires; the other one is silently never triggered.

Approach A — two separate DPPI channels, both publishing from the same event:

uint32_t evt_cross = nrf_lpcomp_event_address_get(NRF_LPCOMP, NRF_LPCOMP_EVENT_CROSS);
uint32_t task_tgl = nrfx_gpiote_out_task_address_get(&gpiote, DRIVE_PIN);
uint32_t task_cnt = nrfx_timer_task_address_get(&sense_tmr, NRF_TIMER_TASK_COUNT);

nrfx_gppi_channel_alloc(&dppi_drive);
nrfx_gppi_channel_endpoints_setup(dppi_drive, evt_cross, task_tgl); // configured 1st

nrfx_gppi_channel_alloc(&dppi_count);
nrfx_gppi_channel_endpoints_setup(dppi_count, evt_cross, task_cnt); // configured 2nd

// in engine_wake():
nrfx_gppi_channels_enable(BIT(dppi_drive) | BIT(dppi_count));

Result: only dppi_count (configured 2nd) actually works. If I reverse the order (configure count first, then drive second), only drive works instead — the last one configured always "wins". It looks like evt_cross's PUBLISH register only holds a single channel, and the second call to channel_endpoints_setup silently overwrites the first.

Approach B — a single DPPI channel, with two tasks subscribed to it:

nrfx_gppi_channel_alloc(&dppi_cross);
nrfx_gppi_event_endpoint_setup(dppi_cross, evt_cross); // publish: once
nrfx_gppi_task_endpoint_setup(dppi_cross, task_tgl); // subscribe #1
nrfx_gppi_task_endpoint_setup(dppi_cross, task_cnt); // subscribe #2

nrfx_gppi_channels_enable(BIT(dppi_cross));

Result: with this approach, NEITHER task seems to fire at all (the TIMER count consistently reads back 0, even when I isolate-test LPCOMP by shorting its input to a pin I toggle in software with a known square wave).

My questions:

1. On nRF54L15, does an event's PUBLISH register really only support a single DPPI channel (i.e., can one event only ever publish to one channel at a time)?

2. Should Approach B (one channel, two tasks subscribed) be supported in hardware? If so, is there a step I might be missing in my code (e.g. correct ordering of ENABLE/SUBSCRIBE register writes, or a domain/instance mismatch)?

3. Could there be a DPPI domain mismatch between LPCOMP (which, per the datasheet block diagram, appears to sit alongside DPPIC30 in that domain) and GPIOTE20/TIMER20/TIMER21 (a different instance/domain number)? In other words, is it possible LPCOMP's event simply cannot reach the DPPI bus that GPIOTE20/TIMER20 are on, and a PPIB (domain-to-domain bridge) is required?

4. If "one event fanning out to multiple tasks" is genuinely not supported on this chip/peripheral combination, what is the recommended approach? (For example: drive one task via DPPI and handle the other via a CPU interrupt instead?)

My end goal: use the LPCOMP CROSS event to both drive a GPIO pin (for closed-loop excitation) and count the same crossings with a TIMER — ideally both handled fully in hardware via DPPI, without CPU involvement.

Thank you in advance for any guidance.

Related