Skip to content

drivers/imu/lis2dw12: move config parameters to Kconfig#4

Open
gmarull wants to merge 2084 commits into
mainfrom
lis2dw12-kconfig
Open

drivers/imu/lis2dw12: move config parameters to Kconfig#4
gmarull wants to merge 2084 commits into
mainfrom
lis2dw12-kconfig

Conversation

@gmarull

@gmarull gmarull commented Jun 15, 2026

Copy link
Copy Markdown
Member

Summary

Converts the LIS2DW12 accelerometer's board-level config parameters into Kconfig options. The driver now reads CONFIG_* values directly instead of carrying them as LIS2DW12Config struct fields.

  • src/fw/drivers/imu/Kconfig — adds 7 options under if ACCEL_LIS2DW12: DISABLE_ADDR_PULLUP (bool) plus WK_DUR_DEFAULT, WK_THS_MIN/MAX/DEFAULT, SCALE_MG, FIFO_THRESHOLD (int). Defaults follow the chip power-on-reset values (±2g, thresholds/duration/FIFO = 0).
  • lis2dw12.c / lis2dw12.h — removes the seven scalar fields plus disable_addr_pullup from LIS2DW12Config; usages now reference CONFIG_* directly (bool via #ifdef, ints inline).
  • board_getafix.c / board_obelix.c — drops those initializers; only hardware-wiring fields (i2c, int1, axis map/dir) remain.
  • 6 board defconfigs — each sets its operating values (scale 4000, fifo 32, wk_ths 1/40/16, wk_dur 1), with DISABLE_ADDR_PULLUP=y only on the variants that had it (getafix_evt, obelix_dvt, obelix_bb2).

Behavior is preserved: resolved autoconf.h values match the original board values exactly.

Test plan

  • Verified resolved CONFIG_* values match the original board struct values for getafix_dvt2 and obelix_pvt.
  • Builds clean on getafix_dvt2, obelix_pvt, and getafix_evt.

Notes

  • scale_mg is now a compile-time constant, so the validation switch in the driver (the "Invalid scale" path) is effectively dead code. Could be replaced with a direct CONFIG→register mapping in a follow-up.

🤖 Generated with Claude Code

rojas-claudio and others added 30 commits May 21, 2026 02:07
Signed-off-by: Claudio Rojas <claudio@rojas.tech>
Migrates the lone `#if !RELEASE` check that the broader RELEASE→
CONFIG_RELEASE rename missed (35b17e4). With RELEASE no longer defined
in release builds the check was silently flipping behavior; not the
watchface crash root cause but worth keeping in sync.

Signed-off-by: Joshua Jun <joshuajun@proton.me>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
PBL_LOG_* expands to PBL_MFLT_LOG_SAVE in addition to the syscall'd
async hash log. The Memfault save touches `s_memfault_ram_logger` and
the rest of memfault_log.c's static state, which lives in privileged
kernel BSS. When firmware code runs on an app's stack (e.g. the
PBL_LOG_DBG in app_window_stack_push), the unprivileged MPU view denies
the BSS access and the app traps with DACCVIOL on the very first
window push — bricking every 4.x watchface on release builds where
Memfault is enabled.

This started biting after 35b17e4 dropped `--release`: that flag set
the firmware-side RELEASE macro but never flipped the Kconfig RELEASE
symbol, so `default y if RELEASE && !QEMU` in third_party/memfault left
Memfault off in pre-bisect release builds. `-DCONFIG_RELEASE=y` does set
the symbol, so MEMFAULT now defaults on for non-QEMU release builds —
exposing the pre-existing privilege bug.

Gate the save on mcu_state_is_thread_privileged(); kernel-side logs
still reach Memfault, app-side ones are simply dropped (the async hash
log still records them via the existing syscall path).

Fixes FIRM-1951

Signed-off-by: Joshua Jun <joshuajun@proton.me>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Joshua Jun <lets@throw.rocks>
The ANCS alive-check fires every 15 minutes; if iOS doesn't respond
within 5 seconds, prv_is_ancs_alive_response_timeout_launcher_task_cb
attempts to recover by re-subscribing to the ANCS characteristics. The
timer is only re-armed on the success path, via ancs_handle_subscribe()
when the Data characteristic's CCCD response arrives without error.

If anything in that recovery path fails -- characteristics already
invalidated, gatt_client_subscriptions_subscribe() returns non-OK
synchronously, or iOS never sends a CCCD response -- the alive-check
timer stays stopped permanently. The watch then appears connected
but silently drops every notification until reboot, which is the
symptom in this bug and the related FIRM-1692 / FIRM-951 reports.

Always re-schedule the next alive check at the end of the timeout
handler. On the happy path ancs_handle_subscribe() will cancel and
reschedule via prv_ancs_is_alive_start_tracking(); on the failure
paths we still tick again in 15 minutes and get another shot at
recovery instead of dying silently.

Fixes FIRM-1936

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
If some path leaks s_user_controlled_state set to true (e.g. a voice
window that disappears before its exit handler resets the light), the
backlight ends up pinned in LIGHT_STATE_ON: button release skips the
auto-off timer transition because the flag is honored, and the only
ways out are light_enable(false), light_reset_user_controlled(), or a
reboot.

Users hit this by toggling the backlight setting off and back on, which
is exactly the workaround the FIRM-1874 reporter described. But
light_toggle_enabled() only drives the state machine
(LIGHT_STATE_OFF -> LIGHT_STATE_ON_TIMED) and never clears
s_user_controlled_state, so the flag survives the round-trip and the
next button release still skips the fade-out timer. The user thinks
they fixed it because the light went off, but the underlying state is
still wrong.

Clear s_user_controlled_state at the top of light_toggle_enabled() and
light_toggle_ambient_sensor_enabled() so the user's escape hatch
actually restores normal behavior. This is defense-in-depth: it does
not address whatever upstream path leaked the flag, but it guarantees
that the documented recovery procedure works.

Fixes FIRM-1874

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
prv_mic_window_appear() pins the backlight via
sys_light_enable_respect_settings(true) for the duration of the
dictation session. The light is released by prv_exit_and_send_result_event()
(back button, errors, success), the StateTransitionToText branch,
and voice_window_pop() (external pop / destroy). prv_mic_window_disappear()
itself, however, only calls prv_cancel_dictation() and leaves the
backlight held on, even though the window is no longer visible.

In normal flows a later exit path runs and resets the light, so this
is harmless. The hole is that disappear can fire on its own when the
mic window is interrupted (modal preempt, voice_window_lose_focus,
StateError) and the owning context goes away without a subsequent
voice_window_pop -- the light stays pinned until something else
clears s_user_controlled_state.

Call sys_light_reset_to_timed_mode() at the top of the disappear
handler so the appear/disappear pair is symmetric. If a later
exit path also resets the light, that's a no-op; if no later path
runs, the backlight no longer leaks.

Fixes FIRM-1874

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
prv_handle_timezone_set() ran a one-shot "pivot RTC from localtime to
UTC" block whenever clock_is_timezone_set() was false. That migration
was meant for the era when classic Pebbles stored wall-clock localtime
in the RTC; modern firmware always stores UTC, and on Asterix/Obelix
the RTC has never held anything else.

The pivot re-arms on every dead-battery boot, because retained RAM is
wiped and rtc_is_timezone_set() goes back to returning false. When a
subsequent timezone-only update comes in (e.g.
clock_set_timezone_by_region_id() triggered by the BlobDB watch-prefs
sync of timezoneSource shortly after reconnect), there is no UTC time
in the same call to overwrite the pivot's result, so it adds the
timezone offset (+7h for PDT) to an already-correct UTC value and
leaves the RTC permanently shifted.

Drop the pivot. The migration has been a no-op on every supported
platform for years, and removing it eliminates the double-offset path.

Fixes FIRM-2000

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
It looks like Claude loves to write lots of text to often explain simple
changes. Ask agents to use Git history for that, instead of comments in
the code.

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Commit 499b9e1 made the status bar clock bold across the whole UI by
keying off StatusBarLayerModeClock. Add an opt-in style preference
that only affects the notification window so the rest of the UI goes
back to the regular weight default.

Modeled as an enum (Default / Bold) so an upcoming larger-status-bar
mode can slot in without another schema bump. The notification window
flips its status bar to a new StatusBarLayerModeClockBold when the
pref selects Bold; everywhere else keeps the existing Clock mode and
renders non-bold. The mode-checking call sites accept either clock
mode via a small helper.

Settings -> Notifications gains a "Status Bar" row that opens a
submenu mirroring the Banner Style pattern.

Test goldens touched by 499b9e1 are restored to their pre-bold
versions since none of them go through the bold path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Shashvat Prabhu <shashvatprabhu2006@gmail.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Shashvat Prabhu <shashvatprabhu2006@gmail.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Shashvat Prabhu <shashvatprabhu2006@gmail.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Shashvat Prabhu <shashvatprabhu2006@gmail.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Shashvat Prabhu <shashvatprabhu2006@gmail.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Shashvat Prabhu <shashvatprabhu2006@gmail.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Joshua Jun <lets@throw.rocks>
The periodic flush iterated all sessions under s_list_mutex on
KernelBG. Each session's comm_session_send_buffer_begin_write can
stall up to 500 ms, so once DLS_MAX_NUM_SESSIONS slots fill up the
worst case is ~10 s -- well past the KernelBG watchdog threshold.
Because sessions persist across reboots, hitting this once puts the
device in an unrecoverable boot loop until a factory reset clears
flash.

Snapshot the session list under the mutex, then chain one send per
system task callback (mirroring prv_reopen_next_session_system_task_cb)
so KernelBG yields between sends and the watchdog gets fed.

Fixes FIRM-1860

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
prv_refill_bg (system task) and the public speaker_service APIs
(KernelMain / app threads) had no synchronization. The observed
fallout was a PBL_ASSERTN in stop_mode_enable: two callers of
prv_stop_internal both passed the state==Idle guard before either
cleared state, so audec_stop()->stop_mode_enable(InhibitorAudio) ran
twice and underflowed s_num_items_disallowing_stop_mode. The same
race also lets a stop on one thread interleave with a play on
another — both touching the AUDCODEC HAL, DMA buffers and
pcm_stream lifecycle.

Add s_lock (PebbleMutex *) and take it on every public entry point
that mutates state or audio HW, plus prv_refill_bg's system-task
callback. prv_refill_bg becomes a lock-take wrapper around
prv_refill_locked; the priming callers (play_note_seq / play_tone /
play_tracks) already hold the lock and call prv_refill_locked
directly. Keep state-first ordering inside prv_stop_internal so it
stays idempotent if called twice.

Trivial single-word getters (get_state, is_muted, set_owner_task)
are left unlocked.

No ISR enters speaker_service.c directly (DMA ISR posts via
system_task_add_callback_from_isr), so a plain PebbleMutex matches
the pattern used by voice.c.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
…e is not Started

The idempotency guard in bt_driver_start() short-circuited whenever
ble_hs_is_enabled() reported true, regardless of our own driver state,
and returned without running ble_hs_util_ensure_addr(0). After a prior
ble_hs_stop (e.g. an err-path stop) had run ble_hs_id_reset(), the
identity addresses were left empty, and the next call to
bt_driver_id_copy_local_identity_address from bt_local_id_configure_driver
tripped PBL_ASSERTN(rc == 0) on the return value of ble_hs_id_infer_auto.

Split the guard: keep the no-op only when our driver state already says
Started. If NimBLE thinks the host is on but our state disagrees, drive
a clean stop and fall into the fresh-start path so ble_hs_util_ensure_addr
runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
The caller-id text layer's frame was pinned to the style's static
caller_id_height (60px), while only its bounds grew to fit the chosen
font. At PreferredContentSizeLarge the title font (GOTHIC_28_BOLD) plus
the forced second line needed ~66px, so the layer's frame clipped the
bottom of the rendered phone number.

Set the frame height alongside the bounds so it scales with the font
instead of relying on a per-style magic number. The frame never shrinks
below the style's caller_id_height, preserving the existing single-line
top margin.

Fixes FIRM-1944

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
The ANCS alive-check fires a Control Point write every 15 minutes and
treats iOS' reply as proof the watch is still receiving notifications.
That probe only verifies the CP path. iOS can wedge in a state where it
keeps responding to CP requests but its Notification Source push has
been silently dropped (commonly after airplane-mode toggles and timezone
swings during travel), so the watch reports itself healthy while no
notifications arrive. Re-opening the iOS Pebble app is currently the
only way to recover, which is what the FIRM-1692 reporter had to do
after a 7-day silent outage.

Track how many consecutive alive-check intervals pass without any NS
traffic. After ANCS_NO_NS_TIMEOUT_HOURS (6 h, derived from the
alive-check interval so the two don't desync) we force a CCCD
re-subscribe to nudge iOS into pushing again, skip the CP probe that
round to avoid interleaving with the CCCD writes, and schedule the
next alive check as a backup in case the CCCD response never lands.
Any NS event (add/modify/remove) resets the counter, so users with
normal notification volume never see the refresh fire; users with
genuinely quiet phones absorb at most one harmless CCCD rewrite per
6 h window.

Fixes FIRM-1692

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Add a 32-entry ring buffer (s_lcdc_irq_log) to record LCDC IRQs with
timestamp, IRQ before/after, JDI_PAR_CTRL, STATUS and per-interrupt
flags.
Register the buffer as the Memfault extra region "lcdc_irq_log" so it
appears in coredumps. Mark EOF completions via s_lcdc_eof_cb_fired in
the
HAL callback so the logger can detect interrupts that saw EOF but never
hit the completion path.

Add tools/extract_irq_log.py to decode the ring buffer from a firmware
ELF and core file and highlight lost-EOF interrupts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Joshua Jun <lets@throw.rocks>
…p resets

The AW2016 LED driver on Obelix can spontaneously reset (PUIS=1) when
VBAT briefly dips below 1.25V or its I2C watchdog trips on SCL held low
>130ms. After such a reset the chip comes up with CHIPEN=0 and all
registers cleared, but there's no INT line wired back to the MCU so the
firmware has no way to notice.

Today the AW2016 driver only writes GCR1 CHIPEN_EN + LCTR/LCFG on the
0->nonzero brightness transition. Once it's cached s_brightness>0,
subsequent writes only touch PWM registers, which silently do nothing
while CHIPEN=0.

Expose a new backlight_refresh() driver entry point that re-applies the
chip-enable, configures the LED registers, and re-emits the current
color. On AW2016 it's a real recovery path; on the PWM, AW9364E, QEMU,
and stub backends it's a harmless no-op since those drivers can't desync
from cached state in the same way.

Signed-off-by: Joshua Jun <joshuajun@proton.me>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
The light-service state machine short-circuits in prv_change_state when
the target brightness matches the cached value, so a tap or wrist-flick
arriving while we're already in ON_TIMED never reaches the backlight
driver. That's normally fine, but on AW2016-equipped boards (Obelix) the
chip can silently reset on a VBAT dip or I2C watchdog with no signal
back to firmware, leaving the chip stuck off while we still believe the
light is on. The user then sees the backlight fail to respond to taps,
and each new tap just re-arms the fade-out timer -- extending the
outage from a single fade cycle (~3-5s) to multiple minutes if they
keep trying.

Call backlight_refresh() on the no-brightness-change branch when the
target state is ON or ON_TIMED. backlight_refresh() is a no-op on
drivers that can't desync, and on AW2016 it re-enables the chip and
re-applies the configured color, so user-initiated wake actions always
heal a previously-reset chip.

Fixes FIRM-1929

Signed-off-by: Joshua Jun <joshuajun@proton.me>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Mearman and others added 28 commits June 12, 2026 12:41
A bare tentative definition (e.g. `enum { X } Name;` at file scope in a
header included by multiple TUs) is silently merged by macOS ld64 but
rejected by GNU ld. That asymmetry means a duplicate-symbol bug can
pass on macOS CI and only surface on Linux, or vice versa.

-fno-common makes both toolchains reject the collision at link time, so
the bug is caught on whichever host runs the tests first.

GCC has defaulted to -fno-common since GCC 10 (released 2020), so this
flag is a no-op on any current Linux host. It only changes behaviour on
macOS, where Clang still accepts tentative definitions unless told not to.

The flag is placed in the 'local' env CFLAGS block (wscript lines
237-251) which applies to every host unit test; it has no effect on
firmware builds, which use a separate cross-compilation environment.

Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On glibc, including <math.h> after <pblibc_private.h> breaks
compilation: pblibc_private.h does `#undef floor; #define floor
pblibc_floor` before glibc's <math.h> is processed, so glibc sees
`floor` already redefined when it tries to emit its __DECL_SIMD_*
declarations.

Move <math.h>, <stdbool.h>, and <stdint.h> above the
<pblibc_private.h> include in floor.c, matching the safe pattern
already used by pow.c, scalbn.c, and sqrt.c (system headers first,
pblibc_private.h last). The rename still takes effect for the
function definition that follows.

Remove test_floor.c and test_pow.c from BROKEN_TESTS: test_floor.c
uses only literal expected values and passes once floor.c compiles
correctly; test_pow.c's newlib implementation is deterministic across
hosts.

Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add -ffile-prefix-map and -fdebug-prefix-map to the firmware CFLAGS and
ASFLAGS, mapping the absolute source root to '.'.  This removes
machine-specific paths from debug info and __FILE__ strings, making
firmware binaries byte-reproducible across different checkout paths.

-ffile-prefix-map is the preferred flag (covers both debug info and
macros); -fdebug-prefix-map is included as well for compatibility with
older toolchain versions that pre-date -ffile-prefix-map.

Also set ARFLAGS to 'rcsD' (deterministic mode) for the firmware ar
step.  Without the 'D' modifier, gcc-ar embeds timestamps and UIDs in
.a files, producing non-reproducible archives even when object files
are identical.  'D' suppresses those fields.

Both flags apply to the firmware env only; host-test compilation is
unaffected.

Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add -ffp-contract=off and -fexcess-precision=standard to the host
unit-test CFLAGS (alongside -fno-common in the local test env).

-ffp-contract=off stops the compiler contracting multiply-add pairs
into FMA instructions, which macOS clang does by default but Linux
clang typically does not. This contraction changes intermediate
precision and is the classic source of last-ULP float differences
between platforms, so floating-point test results are now reproducible
across hosts without changing any test assertions.

-fexcess-precision=standard is a no-op on SSE-only x86-64 (where
the compiler already uses 64-bit SSE registers), but it future-proofs
any 32-bit or x87 host path where the compiler might otherwise keep
80-bit intermediates in registers between operations.

Neither flag affects firmware builds; they are applied only to the
host test environment configured in the 'local' waf conf block.

Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
test_pow compared pblibc_pow against the host libm at runtime: it
defined pow_theirs() before the pblibc_private.h rename so it called the
host pow, then compared pblibc_pow within 1 ulp. glibc and Apple's libm
disagree in the last ulp, so the expected values were host-specific.

Precompute correctly-rounded reference values off-host instead.
gen_pow_reference.py evaluates pow(2, v) as exp(v * ln 2) in the stdlib
decimal module at 80 significant digits and rounds to the nearest double
(round-half-to-even), for v = i * 0.001, i in [0, 10000), matching the
inputs the test exercises. It emits input and expected IEEE-754 bit
patterns into pow_reference.h so no decimal round-trip loss occurs. The
table is identical on every host and the script is checked in so it is
regenerable.

The test now compares pblibc_pow against the table within 1 ulp.
pow.c (newlib) documents its result as "nearly rounded"; measured
against the correctly-rounded reference it is within 1 ulp, so 1 ulp is
the justified tolerance, not an invented one. The host libm is no longer
called.

Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
test_log compared pblibc_log against the host libm at runtime: it
defined log_theirs() before the pblibc_private.h rename so it called the
host log, then compared pblibc_log within 1 ulp. glibc and Apple's libm
disagree in the last ulp, so the expected values were host-specific.

Precompute correctly-rounded reference values off-host instead.
gen_log_reference.py evaluates log(v) in the stdlib decimal module at 80
significant digits and rounds to the nearest double (round-half-to-even),
for v = i * 0.001, i in [1, 10000), matching the inputs the test
exercises. It emits input and expected IEEE-754 bit patterns into
log_reference.h so no decimal round-trip loss occurs. The table is
identical on every host and the script is checked in so it is
regenerable.

The test now compares pblibc_log against the table within 1 ulp.
log.c (newlib) documents its error as always less than 1 ulp relative to
the true value, so 1 ulp against the correctly-rounded reference is the
justified tolerance, not an invented one. The host libm is no longer
called.

Also rename the fixture from test_pow__initialize to
test_log__initialize so clar actually runs it for this suite; the old
name meant the rounding-mode setup never fired here.

Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Batch-migrate every service and driver area that logs and has its own
Kconfig (~70 areas) to the per-module logging macros: each area gains
a log level Kconfig choice sourced from Kconfig.template.log_level,
logs carry the module name and verbosity can be tuned per module.

Naming conventions:

- Services use service_<name> with module = SERVICE_<NAME>, matching
  the existing gating symbol (the merged activity module is renamed
  accordingly). PBL_LOG_MODULE_DEFINE goes in the main unit,
  PBL_LOG_MODULE_DECLARE in the remaining units.
- Drivers use driver_<category>_<model> per concrete driver (e.g.
  driver_ambient_opt3001, driver_mic_nrf5) with module =
  DRIVER_<CATEGORY>, each defining its own module while sharing the
  area-wide log level. Common units use the plain area name
  (driver_vibe, driver_i2c, driver_flash). The merged lis2dw12 module
  is renamed to driver_accel_lis2dw12, and the remaining IMU drivers
  join as driver_accel_lsm6dso and driver_mag_mmc5603nj under
  CONFIG_DRIVER_IMU_LOG_LEVEL.

Verified on asterix, obelix_dvt, getafix_dvt2 and all QEMU boards;
unit tests pass. The PRF variant link failure is pre-existing on main
and unrelated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Replace the LOG_DOMAIN_TOUCH-gated TOUCH_DEBUG macro with plain PBL_LOG
level macros. The on/off domain flag is subsumed by the service_touch
module level. Position updates log at verbose level since they fire
continuously while a finger is down.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Replace the LOG_DOMAIN_VOICE-gated wrappers with plain PBL_LOG level
macros; the voice service files are gated by the service_voice module
level. Messages with ERROR:/WARNING: text prefixes move to the proper
error/warning levels and per-frame encoder logs move to verbose.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Replace the LOG_DOMAIN_ACCEL-gated wrapper with plain PBL_LOG macros.
Per-sample and per-batch logs move to verbose level, matching the
previous off-by-default behavior while remaining selectable through
the module log levels. The qemu accel driver adopts the imu module,
and the prev_timestamp_ms bookkeeping in AccelServiceState becomes
unconditional (the compiler drops the dead computation when verbose
logging is compiled out).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Replace the LOG_DOMAIN_QEMU_COMM-gated wrappers with plain PBL_LOG
macros. Packet parsing and send-path logs (including the outgoing data
hexdump) move to verbose level to match the previous off-by-default
behavior; host event messages log at debug. QEMU_LOG_ERROR was unused.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Replace the ble_log.h wrapper macros with plain PBL_LOG level macros,
level for level (LOG_DOMAIN_BT was always on, so behavior at the
default level is unchanged). The files with converted call sites
declare the bt log module so they are now gated by CONFIG_BT_LOG_LEVEL
alongside the nimble backend. Files that only included ble_log.h for
its transitive includes now include system/logging.h directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
LOG_DOMAIN_BT, LOG_DOMAIN_ACCEL, LOG_DOMAIN_VOICE, LOG_DOMAIN_TOUCH and
LOG_DOMAIN_QEMU_COMM have no users left after the wrapper macro
removals; the per-module log levels replace them. The LOG_DOMAIN_ALL
block only covered LOG_DOMAIN_BT, so it goes too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Now that debug chatter is controllable per module, default builds log
at info level; debug/verbose logging is opt-in via the per-module
Kconfig log level options or DEFAULT_LOG_LEVEL_DEBUG.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
gap_le_advert_workaround.h existed to assist with a bug in the TI
Bluetooth chips, which are no longer supported. The three getters it
declared have had no callers since the original import, so remove the
header and their definitions.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Joshua Jun <lets@throw.rocks>
clang_multi bundles an i686 multilib sysroot (for -m32 unit-test
builds), and nixpkgs throws when evaluating the i686 package set on
non-x86 hosts, so the aarch64-linux dev shell never evaluated. Use
clang_multi only on x86_64 and fall back to plain clang on other
Linux systems; -m32 builds are not possible there anyway.

The x86_64-linux and aarch64-darwin shell derivations are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Replace the drivers/hal/*.c glob with per-module HAL_SIFLI_* Kconfig
options, mirroring Zephyr's modules/hal_sifli/Kconfig. Granularity is
purely at the source-list level: the SDK conf header keeps every
HAL_x_MODULE_ENABLED macro defined, so no SDK changes are needed.

The always-built core is bf0_hal, adc, cortex, dma, efuse, hlp, pmu,
rcc and bf0_sys_cfg: HAL_Init() calls HAL_ADC_HwInit() which in turn
needs DMA, PMU pulls BSP_CONFIG_get() from bf0_sys_cfg.c, and HLP
provides the backup registers and HAL_DBG_printf used by core code.

Intra-HAL dependencies are encoded as selects (AON->RTC, GPIO->AON,
LRC_CAL->LCPU_CONFIG/MAILBOX, IPC_QUEUE->MAILBOX). Consumers select
what they use: the SF32LB52 drivers select their HAL modules, NimBLE
selects IPC_QUEUE and the new LCPU boot support on SF32LB52, and
HAL_SIFLI_SF32LB52 selects the modules required by unconditional
SoC/kernel/system code (AON, GPT, IPC_QUEUE, LPTIM, LRC_CAL, MPI,
PINMUX, RTC).

Verified on obelix_pvt that the set of hal_sifli objects pulled into
the link is identical before and after; getafix_dvt2, obelix PRF and
asterix also build. hal_sifli compiles drop from 74 to 41 TUs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Fixes FIRM-2450
Fixes FIRM-2507

Signed-off-by: Joshua Jun <lets@throw.rocks>
Signed-off-by: Joshua Jun <lets@throw.rocks>
Fixes FIRM-2475

Signed-off-by: Joshua Jun <lets@throw.rocks>
The service-changed path was an empty stub at both layers. The service layer
now sends an indication when the GATT database changes, and the NimBLE driver
emits it over the Service Changed characteristic (0x1801/0x2a05) via
ble_gatts_indicate_custom with the affected handle range.

Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…akes

Port the test off the deleted SS1 fakes onto fake_bt_driver_gatt, which records
the indications the driver emits, and take it out of BROKEN_TESTS.

Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Use PBL_LOG_MODULE_DECLARE / PBL_LOG_ERR matching the pattern in
gatt_client_operations.c and other bluetooth-fw files. LOG_DOMAIN_BT
was removed from logging.h in 5483b6d; the new per-module logging
doesn't need a domain argument.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Change the driver signature from (connection_id, range) to (device,
range) so the NimBLE implementation resolves the connection handle
through its own connection table (ble_gap_conn_find_by_addr) instead
of reaching back into fw/comm/ble under bt_lock.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Joseph Mearman <joseph@mearman.co.uk>
Expose the LIS2DW12 tuning parameters (wake duration/threshold, scale,
FIFO threshold, ADDR pull-up) as Kconfig options instead of board struct
fields. The driver now reads the CONFIG_* values directly, dropping the
corresponding fields from LIS2DW12Config.

Kconfig defaults follow the chip power-on-reset values; each board sets
the values it needs in its defconfig, preserving current behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
@github-actions

Copy link
Copy Markdown

This pull request has been marked as stale because it has been open (more than) 30 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 7 days. Note, that you can always re-open a closed pull request at any time.

@github-actions github-actions Bot added the stale label Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.