Commit Graph
27448 Commits
Author SHA1 Message Date
J. Nick Koston 222626eb8c Merge remote-tracking branch 'upstream/fast-millis-esp32' into integration
# Conflicts:
#	esphome/core/application.cpp
#	esphome/core/time_64.cpp
2026-04-14 15:04:47 -10:00
J. Nick Koston 80e29bc7b2 Merge remote-tracking branch 'upstream/optimize-value-accuracy' into integration 2026-04-14 15:01:45 -10:00
J. Nick Koston 256385bb09 Merge remote-tracking branch 'upstream/dev' into fast-millis-esp32
# Conflicts:
#	esphome/core/scheduler.h
2026-04-14 15:00:40 -10:00
J. Nick Koston f891ea3752 add tests 2026-04-14 14:54:51 -10:00
J. Nick Koston 2ccd94e1ad add tests 2026-04-14 14:54:42 -10:00
J. Nick Koston 82232d8c74 Merge remote-tracking branch 'origin/optimize-value-accuracy' into integration
# Conflicts:
#	esphome/core/application.cpp
#	esphome/core/application.h
#	tests/components/core/test_helpers.cpp
2026-04-14 14:45:20 -10:00
J. Nick Koston efba0f5fd6 handle 0 2026-04-14 14:44:12 -10:00
Edward Firmoandpre-commit-ci-lite[bot] 2db2b89eb1 [nextion] Fix command spacing pacer never throttling sends (#15664)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-04-15 07:47:44 +12:00
J. Nick Koston e48c7165c5 [light] Avoid addressable transition stall at low gamma-corrected values (#15726) 2026-04-15 07:45:42 +12:00
J. Nick KostonandCopilot 506edaadd5 [core] Inline feed_wdt hot path with out-of-line slow path (#15656)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 19:08:30 +00:00
J. Nick Koston 5ae9ddc46a buf_append_sep_str: always null-terminate when remaining >= 1 2026-04-14 08:41:43 -10:00
J. Nick Koston 5066171a9d Address Copilot review: uint32 overflow guard, docstring, test namespace/include 2026-04-14 08:36:09 -10:00
3f82a3a519 [core] Inline Millis64Impl::compute() on single-threaded platforms (#15684)
Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-04-14 08:20:31 -10:00
J. Nick Koston 79cee864cb [esphome][ota] Disable loop while idle, wake on listening-socket activity (#15636) 2026-04-14 08:20:14 -10:00
J. Nick Koston 57d9e508ea merge 2026-04-14 08:09:00 -10:00
J. Nick Koston f4f56cfaaa Merge remote-tracking branch 'upstream/dev' into optimize-value-accuracy
# Conflicts:
#	esphome/core/helpers.h
#	tests/components/core/test_helpers.cpp
2026-04-14 08:07:44 -10:00
Alexey SpirkovandAlexey Spirkov 9f5ed938e5 [i2s_audio] Add PDM mics support for ESP32-P4 (#15333)
Co-authored-by: Alexey Spirkov <dev@alsp.net>
2026-04-14 14:07:16 -04:00
J. Nick Koston 4729efbd04 [light] Deduplicate color_uncorrect channel math via shared helper (#15727) 2026-04-14 07:50:28 -10:00
J. Nick Koston da9fbb8044 [core] Fix app_state_ status bits clobbered for non-looping components (#15658) 2026-04-14 07:50:11 -10:00
J. Nick Koston cf01163c8c [core] Add uint32_to_str helper and use in preferences (#15597) 2026-04-14 07:49:44 -10:00
J. Nick Koston 5ba8c644e4 [ld24xx] Replace heap-allocated SensorWithDedup with inline SensorWithDedup (#15676) 2026-04-14 07:49:27 -10:00
Kevin AhrendtandCopilot c833ff4a84 [audio] Add/configure microDecoder library in preparation for use in future PRs (#15679)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-14 13:49:18 -04:00
J. Nick Koston 2a530a4bf4 [core] Optimize format_hex_internal by splitting separator loop (#15594) 2026-04-14 07:48:33 -10:00
J. Nick Koston 6b4b653462 [globals] Fix TemplatableFn deprecation warning for globals.set (#15733) 2026-04-14 09:18:38 -04:00
J. Nick Koston 651e37dcdc Merge branch 'light-addressable-gamma-transition-stall' into integration 2026-04-13 22:57:50 -10:00
J. Nick Koston 111e2cc9ed cleanups 2026-04-13 22:56:32 -10:00
J. Nick Koston a60631a599 Merge remote-tracking branch 'upstream/light-addressable-gamma-transition-stall' into integration 2026-04-13 22:42:36 -10:00
J. Nick Koston c7b4ee5c60 fix when on_boot at 800 2026-04-13 22:40:17 -10:00
J. Nick Koston 8255afaa60 Merge remote-tracking branch 'origin/globals-set-lambda-return-type' into integration 2026-04-13 22:21:25 -10:00
J. Nick Koston 503e299d15 [globals] Use value_type alias instead of stashing type in CORE.data 2026-04-13 22:10:24 -10:00
J. Nick Koston a325df98da [globals] Emit globals.set value lambda with declared global type
Pass the global's declared C++ type as the lambda return type so
TemplatableFn stores a direct function pointer instead of hitting the
deprecated converting trampoline when the value expression deduces to a
different type (e.g. an int literal or int-returning lambda assigned to
a float global).
2026-04-13 21:59:54 -10:00
J. Nick Koston fa1391ac54 Merge branch 'light-force-inline-set-flag' into integration 2026-04-13 17:27:22 -10:00
J. Nick Koston a0286616f7 [light] Force-inline LightCall::set_flag_/clear_flag_
Both are trivial bit operations on a uint16_t (one or/and on flags_),
but without ESPHOME_ALWAYS_INLINE each call costs a call0/call8 plus
the return/register-window rotation — more work than the body itself.
validate_() invokes these ~8 times and transform_parameters_() adds
more, so runtime benchmarks should reflect the elimination of the
call overhead.

Note: a previous attempt at this (#15402) was closed based on flash
size deltas alone. This reopens the question with CodSpeed in-loop
to measure actual runtime impact.
2026-04-13 17:16:49 -10:00
J. Nick Koston bd97a3ef85 Merge remote-tracking branch 'origin/light-gamma-uncorrect-outline' into integration 2026-04-13 17:03:36 -10:00
J. Nick Koston 1ee28e210a Merge remote-tracking branch 'upstream-ssh/light-validate-clamp-loop' into integration 2026-04-13 17:03:20 -10:00
J. Nick Koston c9b6253d24 [light] Fix stale comments on float_out_of_unit_range / clamp_unit_float 2026-04-13 17:01:11 -10:00
J. Nick KostonandCopilot Autofix powered by AI edb16a27d3 [esphome] Skip missing extra flash images in upload_using_esptool (#15723)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-04-13 16:58:48 -10:00
J. Nick Koston 674fb1d3f6 [light] Drop redundant is_standard_layout asserts (offsetof no longer used)
Since validate_() now accesses unit_fields_[] directly via the union
alias, there's no offsetof arithmetic to guard. The FieldFlags bit
layout assert is all that's needed.
2026-04-13 16:57:58 -10:00
J. Nick Koston 58885c2090 [light] Rename log_value_out_of_range_ to drop trailing underscore (clang-tidy) 2026-04-13 16:55:25 -10:00
J. Nick Koston 6491072a77 [light] Alias clamp fields via anonymous-union float[8] to eliminate pointer UB
Replaces the previous `float *p = &this->brightness_; p[bit]` pattern
(flagged by Copilot as pointer-into-scalar UB) with a shared anonymous
union that exposes brightness_..warm_white_ as unit_fields_[8] in both
LightCall and LightColorValues. validate_() now indexes the real array
directly — defined behavior — while the named members stay accessible
to getters/setters. Code generation is unchanged.

The union is declared once via ESPHOME_LIGHT_UNIT_FIELDS_UNION() in
light_color_values.h and expanded in both structs. The per-field
offsetof static_asserts collapse to a single FieldFlags bit-layout
assert since the union guarantees member ↔ array-index alignment.

Caught by Copilot on PR review.
2026-04-13 16:54:43 -10:00
J. Nick Koston 8ef1057674 [light] Treat -0.0f as in range in float_out_of_unit_range
-0.0f has bit pattern 0x80000000 which exceeds ONE_F_BITS as unsigned,
so the check previously flagged it and emitted a spurious out-of-range
warning. Add an explicit compare against NEG_ZERO_F_BITS (declared as
a named constexpr for readability) so -0.0f takes the in-range fast
path. clamp_unit_float() already returned 0.0f for it via the sign-bit
branch, so behavior on clamp is unchanged.

Caught by Copilot on PR review.
2026-04-13 16:48:00 -10:00
J. Nick Koston bdd1c413de [light] Eliminate static-local guard variables by hoisting names to PROGMEM_STRING_TABLE
The PROGMEM_STRING_TABLE expansion is entirely constexpr-initialized, so it doesn't require the per-static thread-safe-init guard variables that the previous `static const LogString *const FIELD_NAMES[8] PROGMEM = { LOG_STR(...) }` form emitted inside validate_() (LOG_STR contains a GCC statement-expression, which is not a constant expression, so GCC fell back to dynamic init with an 8-byte guard).

Combined the 8 clamp-field names and "Color temperature" into a single ValidateFieldNames table; index 8 is reserved for CT. log_value_out_of_range_() now takes the resolved `const LogString *` directly, so the helper no longer needs its internal progmem_read_ptr dereference.

Impact vs. prior commit (isolated light build):

  ESP8266 .irom0.text: 267912 -> 267784  (-128 B)

  ESP8266 .bss guard vars on light symbols: 16 -> 0 (-16 B RAM)

  ESP32-IDF .flash.text: 136988 -> 136996 (+8 B, marginal)
2026-04-13 16:38:44 -10:00
J. Nick Koston de44b8e859 [light] Tighten comments in validate_ clamp loop and LightColorValues helpers 2026-04-13 16:31:50 -10:00
J. Nick Koston 8eb8b3dc0f [light] Promote bit-pattern clamp to LightColorValues setters and add layout asserts
Move `float_out_of_unit_range()` / add `clamp_unit_float()` to
light_color_values.h so the nine `set_*(float)` setters can use the
unsigned bit-pattern clamp instead of `std::clamp(x, 0.0f, 1.0f)`.
`std::clamp` expands to two soft-float `__ltsf2`/`__gtsf2` calls per
invocation on ESP8266 — replacing it with a single unsigned compare
saves code across every caller of these setters (StrobeLightEffect,
the 11-arg LightColorValues constructor, external components).

Split the cold-path helper: `log_value_out_of_range_()` now only logs,
and each caller applies the clamp strategy appropriate to its range
(`clamp_unit_float` for the 8-field loop, `std::clamp` for color
temperature's runtime-variable range).

Add layout/format assertions:
- std::is_standard_layout_v on LightCall and LightColorValues so the
  offsetof arithmetic in the clamp loop is well-defined.
- sizeof(float) == 4 and is_iec559 so the bit-pattern trick is valid.
  A direct __builtin_bit_cast check would be cleaner but is not
  available on the ESP8266 xtensa toolchain.

Text-section delta vs. prior commit (isolated light build):
  ESP32-IDF: .flash.text  137760 -> 136988 (-772 B)
  ESP8266:   .irom0.text  268440 -> 267912 (-528 B)
2026-04-13 16:27:09 -10:00
J. Nick Koston 36881166a8 [light] Replace soft-float range check with union bit-cast + unsigned compare
The inlined `value < 0.0f || value > 1.0f` check in the clamp loop costs
~50 B per iteration on ESP8266 (two libgcc soft-float calls with register
spills). IEEE 754 floats in [0.0f, 1.0f] have bit patterns in
[0x00000000, 0x3F800000]; anything out of range — values > 1.0f, negatives
(sign bit set → huge unsigned interpretation), NaN, Infinity — has a
strictly larger unsigned interpretation. A single `pun.u > 0x3F800000u`
covers every case.

Using a union for the type-pun rather than memcpy/bit_cast because those
don't optimize to a no-op on xtensa-gcc (same reason api/proto.h's
float_to_raw() uses a union).

The loop body is now two instructions for the range check:
  l32i a2, a9, 0    ; load raw u32
  bgeu a10, a2, ... ; compare against pre-hoisted 1.0f bits

Size delta vs. the prior float-compare form:
  ESP32-IDF: validate_ -16 B, net -12 B
  ESP8266:   validate_ -20 B, net -20 B

vs. dev baseline (isolated light build, matched funcs):
  ESP32-IDF: -103 B code, +32 B PROGMEM table = -71 B net
  ESP8266:    -42 B code, +32 B PROGMEM table = -10 B net
2026-04-13 16:16:44 -10:00
J. Nick Koston cdde0abec7 [light] Refine validate_ clamp loop: ctz iteration, per-field asserts, typed pointers
Follow-up to edb2145a addressing three points:

1. Hoist the in-range check out of the logging helper. The loop now tests
   `value < 0.0f || value > 1.0f` inline and only calls the out-of-line
   log_out_of_range_and_clamp_ helper on the cold path. Hot path (value in
   range) skips the call8 and the register spill/reload around it, which
   matters because HA automations can drive perform() at high frequency.

2. Iterate only set bits with __builtin_ctz + (active & active-1). Common
   calls with one or two flags set now exit the loop after one or two
   iterations instead of always scanning all eight slots.

3. Replace the uint8_t* pointer arithmetic with typed float arrays aliasing
   &brightness_ in each struct. Per-field static_asserts (expanded via a
   local macro) now catch reorders of any single member in either struct,
   not just reorders at the endpoints. Compiles to the same machine code as
   the uint8_t* version.

Size delta vs. prior commit (isolated light build):
  ESP32-IDF: validate_ +60 B, helper -29 B, net +31 B
  ESP8266:   validate_ +72 B, helper -42 B, net +30 B
Still a net win vs. dev on both targets (ESP32-IDF -91 B, ESP8266 -22 B).
2026-04-13 16:07:34 -10:00
J. Nick Koston edb2145aca [light] Collapse 8 clamp-and-copy blocks in LightCall::validate_ into a loop
Reorder FieldFlags so the eight [0.0, 1.0]-clamped float fields occupy
bits 0-7 in the same order as they appear in LightCall and
LightColorValues, and move color_temperature_ to the end of both
structs. Under that layout the LightCall offset for clamp field i is
`offsetof(LightCall, brightness_) + i * 4`, and the LightColorValues
offset is exactly 12 bytes lower for every field. validate_() now
iterates the active clamp bits in a small loop that computes these
offsets from the bit position instead of expanding eight nearly
identical inline blocks via macro.

The field-name PROGMEM pointer is passed to clamp_and_log_if_invalid as
`const LogString *const *`; progmem_read_ptr only runs on the cold
(out-of-range) path, so the hot path performs no flash reads for the
name. The eight invariants the loop relies on (flag-bit layout,
field contiguity, and the constant 12-byte delta) are enforced by
static_asserts so any future reshuffle fails loudly at compile time.

Size deltas for the isolated light component build (vs dev):
  ESP32-IDF:  -118 B code, +32 B PROGMEM name table = -86 B net
  ESP8266:     -56 B code, +32 B PROGMEM name table = -24 B net
0 B RAM impact on both targets.
2026-04-13 15:55:50 -10:00
J. Nick Koston 76c8eeede9 [light] Fix uint16_t overflow in color_uncorrect_channel_
When max_brightness and local_brightness_ are small but non-zero, the
intermediate (uncorrected / max_brightness) * 255 can exceed 65535
before the std::min(255) clamp runs, producing an incorrect low result.
Widen intermediates to uint32_t. Copilot review catch on #15727.
2026-04-13 15:08:36 -10:00
J. Nick Koston 10412ac2c5 Merge remote-tracking branch 'origin/light-gamma-uncorrect-outline' into integration 2026-04-13 15:04:11 -10:00
J. Nick Koston 4696d70b8a Merge remote-tracking branch 'origin/light-addressable-gamma-transition-stall' into integration 2026-04-13 15:04:07 -10:00