Commit Graph
23532 Commits
Author SHA1 Message Date
J. Nick Koston 6017ce2c74 Merge branch 'isr-wake-enable-loop-soon' into integration 2026-02-28 14:35:03 -10:00
J. Nick Koston 4cf6376477 Merge remote-tracking branch 'origin/ld2450-atan2f-angle' into integration 2026-02-28 14:07:39 -10:00
J. Nick Koston b83904f533 Merge remote-tracking branch 'origin/ld2450-direction-dedup' into integration 2026-02-28 14:07:30 -10:00
J. Nick Koston d046e3f530 Merge remote-tracking branch 'origin/ld2450-single-pass-zone-counting' into integration 2026-02-28 14:07:20 -10:00
J. Nick Koston 5b3cb1c9d9 Merge remote-tracking branch 'origin/integration' into integration 2026-02-28 13:52:19 -10:00
J. Nick Koston ccf523124c Merge branch 'uart-isr-wake-on-rx' into integration 2026-02-28 13:52:04 -10:00
J. Nick Koston 19016d5296 Merge remote-tracking branch 'origin/pack-entity-strings' into integration 2026-02-28 13:52:01 -10:00
J. Nick Koston 6248177356 Merge branch 'dev' into uart-isr-wake-on-rx 2026-02-28 13:27:56 -10:00
J. Nick Koston b679b04d14 [core] Move CONF_STOP_BITS, CONF_DATA_BITS, CONF_PARITY to const.py (#14379) 2026-02-28 13:27:33 -10:00
J. Nick Koston de71389c14 [ld2450] Use atan2f for angle calculation
Replace acosf(y/distance) + sign flip with atan2f(-x, y) which
computes the angle from the Y axis directly. This eliminates the
division by distance, the acosf call, the sign branch, and the
calculate_angle helper function entirely.

atan2f also handles all quadrants correctly by definition, avoiding
the edge-case guard that silently returned 0 when y was negative.
2026-02-28 13:26:11 -10:00
J. Nick Koston 0c705d7766 [ld2450] Single-pass zone target counting
Merge the two separate count_targets_in_zone_ calls (one for still,
one for moving) into a single pass that counts both simultaneously.
This halves the number of iterations through the target list per zone
(from 6 calls to 3 for 3 zones).
2026-02-28 13:19:16 -10:00
J. Nick Koston 90307f493b Merge branch 'pack-entity-strings' into integration 2026-02-28 13:16:44 -10:00
J. Nick Koston 4ac226dbd5 Merge branch 'dev' into pack-entity-strings 2026-02-28 13:13:35 -10:00
J. Nick Koston 128259870e [ld2450] Use integer dedup for direction text sensor updates
Replace per-frame string comparison with Deduplicator<uint8_t> on
the direction enum value. The previous code called get_state() and
compared std::string against const char* on every frame for each
target (~75 times/sec). The new approach does a single uint8_t
comparison and only looks up the direction string and publishes
when the direction actually changes.

Also use MAX_TARGETS instead of hardcoded 3 for direction_text_sensors_
array size for consistency with all other sensor arrays.
2026-02-28 13:11:18 -10:00
Jonathan SwobodaandCopilot b7d651dd17 [core] Defer entity automation codegen to prevent sibling ID deadlocks (#14381)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 13:10:53 -10:00
J. Nick Koston 2d466c0f85 Merge branch 'uart-isr-wake-on-rx' into integration 2026-02-28 12:26:54 -10:00
J. Nick Koston e7fc69e453 reorder 2026-02-28 12:26:31 -10:00
J. Nick Koston 8a30e74464 Merge remote-tracking branch 'upstream/core-set-status-flag-helper' into integration 2026-02-28 12:08:33 -10:00
J. Nick KostonandJ. Nick Koston 99682f15b7 [core] Extract set_status_flag_ helper to deduplicate status_set methods
The check-and-set pattern for status LED flags was duplicated across
all status_set_warning and status_set_error overloads. Extract a
set_status_flag_ helper that sets the flag on both the component
and the app, returning whether the flag was newly set.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-02-28 12:04:03 -10:00
J. Nick Koston 2d4117f370 [core] Wake main loop from any context in enable_loop_soon_any_context()
enable_loop_soon_any_context() sets volatile flags but does not wake
the main loop from ulTaskNotifyTake() sleep. This means components
using ISR-driven state changes (e.g. GPIO binary sensors) wait up
to ~16ms for the select timeout before their loop runs.

Add wake_loop_any_context() that detects the calling context (ISR vs
task) using xPortInIsrContext() (ESP32) or __get_IPSR() (LibreTiny)
and calls the appropriate FreeRTOS API. This is safe from ISR, thread,
and main loop contexts.

Also relax the wake_loop_isrsafe() guard from requiring both
USE_WAKE_LOOP_THREADSAFE and USE_LWIP_FAST_SELECT to just
USE_LWIP_FAST_SELECT, since the ISR wake path uses
vTaskNotifyGiveFromISR directly and does not depend on the
UDP socket mechanism.
2026-02-28 11:15:26 -10:00
J. Nick Koston 59db01e8d7 Fix IRAM_ATTR not defined on LibreTiny (bk72xx)
IRAM_ATTR is defined by esp_attr.h on ESP32 but not on LibreTiny.
Add a no-op fallback in the C file since hal.h (which defines it
for C++) cannot be included from C.
2026-02-28 11:15:17 -10:00
J. Nick Koston 3f92a4160d Merge remote-tracking branch 'origin/integration' into integration 2026-02-28 10:58:09 -10:00
J. Nick Koston fa579b38ba Merge branch 'isr-wake-enable-loop-soon' into integration 2026-02-28 10:57:42 -10:00
J. Nick Koston 46bff3f3eb [core] Wake main loop from ISR in enable_loop_soon_any_context()
enable_loop_soon_any_context() sets volatile flags but does not wake
the main loop from ulTaskNotifyTake() sleep. This means components
using ISR-driven state changes (e.g. GPIO binary sensors) wait up
to ~16ms for the select timeout before their loop runs.

Add Application::wake_loop_isrsafe(nullptr) to immediately wake the
main loop when called from ISR context on platforms with fast select.

Also relax the wake_loop_isrsafe() guard from requiring both
USE_WAKE_LOOP_THREADSAFE and USE_LWIP_FAST_SELECT to just
USE_LWIP_FAST_SELECT, since the ISR wake path uses
vTaskNotifyGiveFromISR directly and does not depend on the
UDP socket mechanism.
2026-02-28 10:54:00 -10:00
J. Nick Koston 3c5d877d96 Fix clang-tidy naming: snake_case params, no trailing underscore on static method
- pxHigherPriorityTaskWoken → px_higher_priority_task_woken
- uart_rx_isr_callback_ → uart_rx_isr_callback
2026-02-28 10:53:52 -10:00
J. Nick Koston 4a915223a4 Merge remote-tracking branch 'origin/integration' into integration 2026-02-28 10:43:41 -10:00
J. Nick Koston db1a21cb7a Merge remote-tracking branch 'upstream/uart-isr-wake-on-rx' into integration 2026-02-28 10:43:31 -10:00
J. Nick Koston 89c43b49c2 [uart] Replace wake-on-RX task+queue with direct ISR callback
Use the ESP-IDF UART driver's uart_set_select_notif_callback() to wake
the main loop directly from the UART ISR via vTaskNotifyGiveFromISR(),
eliminating the FreeRTOS trampoline task and event queue that were
previously needed when wake_loop_threadsafe() used a UDP loopback socket.

With fast lwip select, the main loop sleeps on ulTaskNotifyTake(), so
the ISR-safe vTaskNotifyGiveFromISR() can wake it directly.

Saves ~2.6KB RAM per UART instance with wake-on-RX enabled:
- 2,240 bytes FreeRTOS task stack
- ~340 bytes event queue (20 entries + control block)
- 8 bytes QueueHandle_t + TaskHandle_t fields

Also adds Application::wake_loop_isrsafe() as the ISR-safe counterpart
to wake_loop_threadsafe(), backed by esphome_lwip_wake_main_loop_from_isr().
2026-02-28 10:40:33 -10:00
J. Nick Koston f3f33be640 Merge remote-tracking branch 'origin/fix-ld2410-ld2412-two-byte-to-int' into integration 2026-02-28 09:15:19 -10:00
J. Nick Koston f383ec7f09 [ld24xx] Make two_byte_to_uint16 constexpr
Enable compile-time evaluation when called with constant arguments.
2026-02-28 09:14:23 -10:00
J. Nick Koston bec07a95e9 Merge remote-tracking branch 'origin/fix-ld2410-ld2412-two-byte-to-int' into integration 2026-02-28 09:12:58 -10:00
J. Nick Koston cfb6c4e9d4 [ld2410/ld2412] Fix two_byte_to_int using signed char causing incorrect values
The two_byte_to_int() function used `char` parameters instead of
`uint8_t`, causing sign extension for byte values >= 0x80. This
produced incorrect sensor values for distances where value % 256 >= 128
(e.g. 128cm reported as -128, 200cm reported as -56).

Changed return type to uint16_t to match protocol spec (unsigned
distances), renamed to two_byte_to_uint16, and moved to shared
ld24xx header to eliminate duplication.
2026-02-28 09:11:10 -10:00
J. Nick Koston b6fb87ae6e Merge remote-tracking branch 'origin/fix-ld2410-ld2412-two-byte-to-int' into integration 2026-02-28 09:02:52 -10:00
J. Nick KostonandClaude Opus 4.6 76690e6900 [ld2410/ld2412] Fix two_byte_to_int using signed char causing incorrect values
The two_byte_to_int() function used `char` parameters instead of
`uint8_t`, causing sign extension for byte values >= 0x80. This
produced incorrect sensor values for distances where value % 256 >= 128
(e.g. 128cm reported as -128, 200cm reported as -56).

Also removed the unnecessary `(int16_t)` cast and switched from `+` to
`|` for proper bitwise assembly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 08:48:18 -10:00
J. Nick Koston 757e8d90e6 [core] Inline set_component_state_ and use it in Application (#14369) 2026-02-28 07:20:34 -10:00
J. Nick Koston 7d52a9587f [api] Outline keepalive ping logic from APIConnection::loop() (#14374) 2026-02-28 07:20:20 -10:00
J. Nick Koston 067d773aac [core] Make register_component protected, remove runtime checks (#14371) 2026-02-28 07:19:55 -10:00
Clyde Stubbs 089d1e55e7 [mipi_dsi] Fix Waveshare P4 7B board config (#14372) 2026-02-28 20:37:04 +11:00
J. Nick Koston 0bf76dbfa0 Merge branch 'api-outline-keepalive' into integration 2026-02-27 23:04:11 -10:00
J. Nick Koston 2e490d9121 [api] Outline keepalive ping logic from APIConnection::loop()
Extract the keepalive ping/disconnect cold path into a separate
noinline check_keepalive_() method. This code only fires once per
minute but was contributing ~110 bytes to the hot loop() body that
runs every ~16ms.

Results on ESP32 (xtensa):
- loop(): 374 → 263 bytes (-111 bytes, -30%)
- check_keepalive_(): 136 bytes (new, cold path)
- Net: +25 bytes total (call overhead), but the hot path icache
  footprint is significantly reduced.
2026-02-27 23:02:30 -10:00
J. Nick Koston 8ebd9113a3 Merge remote-tracking branch 'upstream/dev' into integration 2026-02-27 22:21:26 -10:00
J. Nick Koston 470d6d0537 Merge branch 'remove-register-component-public' into integration 2026-02-27 22:06:30 -10:00
J. Nick Koston 97eba625b9 Revert inline - ESP8266 compiler doesn't outline push_back ISRA 2026-02-27 22:06:05 -10:00
J. Nick Koston 55ffb62571 Inline register_component_ in header for better codegen 2026-02-27 21:59:58 -10:00
J. Nick Koston 2d20986a37 Merge remote-tracking branch 'upstream/remove-register-component-public' into integration 2026-02-27 21:43:30 -10:00
J. Nick KostonandJ. Nick Koston 9967fc54d5 Drop template wrapper, call register_component_ directly
The template wrapper caused the compiler to make different
optimization decisions on setup(), negating the savings.
Calling register_component_ directly was -4 bytes.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-02-27 21:40:03 -10:00
J. Nick KostonandJ. Nick Koston d2af639e71 Keep original template name to preserve compiler optimizations
Using the original register_component name (just moved to protected)
produces identical compiled output to the baseline, avoiding the
symbol name length overhead from renaming.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-02-27 21:32:27 -10:00
J. Nick KostonandJ. Nick Koston ebde654259 Restore template wrapper as protected register_component_
Rename the non-template to register_component_impl_ and add
a protected template register_component_ that wraps it. This
preserves the compiler optimization behavior (isra clones)
while keeping the method inaccessible to external components.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-02-27 21:31:06 -10:00
J. Nick KostonandJ. Nick Koston 6d1a40f210 Mark register_component_ as noinline to prevent setup() bloat
Without the template wrapper, the compiler inlines the 24-byte
function at each of ~92 call sites in setup(), growing setup()
by ~284 bytes. Force a function call instead.

Co-Authored-By: J. Nick Koston <nick@koston.org>
2026-02-27 21:27:41 -10:00
Raymond Richmond 6c0998f220 [gt911] Support for interrupt signal via IO Expander (#14358) 2026-02-28 18:26:06 +11:00