ports/esp32/components/woz_uwb/port/dw3000_hw.c
openaliro/openaliro
Module

dw3000_hw.c

ESP-IDF GPIO/IRQ backend for the DW3000 decadriver — implements dw3000_hw.h.

ports/esp32/components/woz_uwb/port/dw3000_hw.c14 documented symbols

Overview

ESP-IDF GPIO/IRQ backend for the DW3000 decadriver — implements dw3000_hw.h. Replaces the Zephyr deps/dw3000/platform/dw3000_hw.c (not compiled here). IRQ mirrors the Zephyr design: the GPIO ISR wakes a dedicated high-priority task that calls dwt_isr() while the IRQ line stays high — dwt_isr does SPI, so it cannot run in true ISR context. Dual-core targets pin the worker to core 1; single-core targets run it on core 0. Also provides the cycle-counter diag symbols that the decadriver references via esp_cpu_get_cycle_count().

depends on board_pins.h

API

Fuint32_t dw3000_dwt_cyccnt(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:46

Return the current CPU cycle count, used as the DW3000 driver's cycle-counter timebase on this port.

Fvoid dw3000_hw_mark_asleep(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:54

Mark the DW3000 as asleep. Does not itself put the chip to sleep; only updates local state.

Fbool dw3000_hw_is_asleep(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:56

Return whether the DW3000 is currently marked asleep.

Fint dw3000_hw_init(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:61

Initialize the DW3000 hardware port: configure the reset line as input (relying on an external pull-up, driven low only when active) and the wakeup line as output held high, then initialize SPI. Returns the result of dw3000_spi_init(); 0 on success.

Fstatic void IRAM_ATTR dw3000_gpio_isr(void *arg)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:84

GPIO interrupt handler for the DW3000 IRQ line. Runs in IRAM. Latches the cycle count at interrupt time into g_dw_cyc_gpio, then signals s_irq_sem; yields to a higher-priority task if the semaphore give woke one.

Fstatic void dw3000_isr_task(void *arg)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:99

Background task that services DW3000 interrupts: blocks on the IRQ semaphore, then calls dwt_isr() in a loop for as long as the IRQ line stays asserted. Records cycle-count timestamps (g_dw_cyc_work, g_dw_cyc_isrdone) around the service loop for latency diagnostics. Runs for the lifetime of the program; never returns.

Fint dw3000_hw_init_interrupt(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:121

Configure the DW3000 IRQ GPIO, install the shared ISR service, and start the pinned ISR worker task. Idempotent: safe to call more than once, the ISR service and worker task are each created only once. The worker task runs at priority 23 (above esp_timer and Thread) so DS-TWR slot callbacks (RX/TX-done) are not delayed by preemption; it is bursty and mostly blocked on the IRQ semaphore. It uses core 1 when available and core 0 on single-core targets such as ESP32-C6. Leaves the interrupt enabled. Returns 0 on success, -1 if the ISR service failed to install.

Fvoid dw3000_hw_interrupt_enable(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:169

Re-enable the DW3000 IRQ GPIO interrupt after a prior disable. No-op if already enabled.

Fvoid dw3000_hw_interrupt_disable(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:178

Disable the DW3000 IRQ GPIO interrupt. No-op if already disabled.

Fbool dw3000_hw_interrupt_is_enabled(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:187

Return whether the DW3000 IRQ GPIO interrupt is currently enabled.

Fvoid dw3000_hw_reset(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:191

Hardware-reset the DW3000 by pulsing the RESET pin low then releasing it to hi-Z. Blocks for about 3 ms total to let the chip climb to IDLE_RC. Clears the asleep flag.

Fvoid dw3000_hw_wakeup(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:206

Wake the DW3000 from sleep if marked asleep; no-op otherwise. Drives the wake sequence over SPI, waits for the INIT_RC-to-IDLE_RC startup delay, clears the asleep flag, then polls dwt_checkidlerc() (up to ~5 ms) and logs an error if the chip never reaches IDLE_RC.

Fvoid dw3000_hw_wakeup_pin_low(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:227

Drive the DW3000 WAKEUP pin low.

Fvoid dw3000_hw_fini(void)

ports/esp32/components/woz_uwb/port/dw3000_hw.c:234

Tear down the DW3000 hardware port: disable the IRQ line if enabled and finalize the SPI bus. Safe to call after dw3000_hw_init; leaves s_irq_enabled cleared.