Commit Graph

15 Commits

Author SHA1 Message Date
Jakub
f5b3213f80 Merge upstream/main (v1.16.0) into wio-unified
Merge 254 upstream commits. Highlights relevant to the Wio fork: native
NRF52 companion power-saving (sleep when !hasPendingWork), preamble 16->32
for SF<9, generic sensor-registration model, CMD_SEND_RAW_PACKET, isEink()
display abstraction, KEEP_DISPLAY_ON_USB, contacts-sync/transient fixes.

Conflicts resolved (11 files):
- buzzer.h/.cpp: keep NRF52 include guard + our begin()->startup(); fold in
  upstream doc comment.
- platformio (wio + eink): keep our slim env layout, add upstream kiss_modem
  env (+ debug_tool=stlink on eink ble).
- GxEPDDisplay.h: take upstream isEink() override.
- EnvironmentSensorManager.h: take upstream's wider #if guard.
- DataStore.cpp: take upstream saveContacts(filter) signature, keep our
  ::openWrite (member openWrite would shadow the global 2-arg overload).
- main.cpp: keep our watchdog init + add board.onBootComplete(); adopt
  upstream's `if(!hasPendingWork()) sleep` loop.
- MyMesh.h: version -> v1.16-solo.0, build date 6 Jun 2026.
- MyMesh.cpp: keep both CMD codes (SCREENSHOT 66 + RAW_PACKET 65), both field
  inits, both handlers, our screenshot fns + upstream saveContacts/save_filter,
  upstream hasPendingWork() + our MyMeshBot include.
- UITask.cpp: keep our solo splash/clock page/snprintf/buzzer init; merge
  auto-off (+ opt-in KEEP_DISPLAY_ON_USB); merge low-batt shutdown (our EMA +
  prefs threshold + upstream's !isExternalPowered() guard and eink-aware delay).

Post-merge drift fixes (upstream API/architecture changes, not conflicts):
- applyTxPower(): radio_set_tx_power() removed upstream -> radio_driver.setTxPower().
- Sensor refactor dropped the per-sensor *_initialized flags our
  getAvailableLPPTypes() relied on; removed that override and the SENSORS page
  now derives available LPP types from the populated sensors_lpp buffer.

README kept ours via .gitattributes merge=ours. Builds verified on all 5 Wio
envs (dual, eink dual, radio_ble, dual_dev, eink_dual_dev). Not yet
hardware-verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 17:21:41 +02:00
Jakub
bf724ce692 perf(bot): lower body once and strstr instead of O(n*m) per-offset tolower
For a 140-byte channel msg with a 64-byte trigger, the old loop did
~8960 tolower() calls per inbound message; now it's 140 tolower calls
plus one strstr.

perf(buzzer): skip nRF52 STOPPED wait when PWM was not running

TASKS_STOP on a disabled PWM never fires EVENTS_STOPPED, so the wait
always timed out at 2 ms. Gating on _pwm_on removes the wait on the
first note of a melody and after pauses, where there's nothing to wait
for.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 19:59:21 +02:00
Jakub
6399df1f4a fix: improve buzzer volume control on nRF52
- Use inverted PWM polarity (0x8000) with PCT {2,5,12,25,50} giving
  ~6-8 dB perceptual steps (-24/-16/-9/-3/0 dB) vs the original
  uneven steps where levels 4 and 5 were only 1 dB apart
- Guard against cmp=0 truncation in both _nrfStartPwm and applyVolume:
  at level 1 with high notes (freq > ~2.5 kHz) integer math gives
  cmp=0 which with inverted polarity means 100% HIGH → complete silence
- Change volume preview note from C5 (523 Hz) to C6 (1047 Hz) to better
  match the piezo resonant frequency range and actual notification sounds

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 09:06:00 +02:00
Jakub
bf05a13549 fix: implement nRF52 RTTTL player using direct NRF_PWM2 control for working volume
tone() dynamically computes seq_refresh so the DMA repeats 50% duty for
~13-30ms per note before re-reading its buffer — volume cannot take effect
until that delay passes, producing a staircase artifact.

Replace tone()/NonBlockingRtttl with a custom RTTTL parser that drives
NRF_PWM2 directly using REFRESH=0. DMA now re-reads _duty_buf every
PWM period so:
- Duty is set before SEQSTART fires → no initial full-volume burst
- applyVolume() writes to _duty_buf and takes effect within one period (<2.3ms at A4)
- setVolume() during playback adjusts loudness immediately and smoothly

Non-nRF52 platforms continue to use NonBlockingRtttl + analogWrite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 13:09:38 +02:00
Jakub
b3c6416874 feat: melody assignment per channel/DM, dual ringtone slots, volume cleanup
Add second ringtone slot (ringtone2_*) to NodePrefs and DataStore.
Add per-channel and per-DM melody assignment (built-in / melody 1 / 2)
stored in NodePrefs bitmasks and DmMelodyEntry table.
Settings screen exposes DM/CH sound items; RingtoneEditorScreen supports
switching between slots. notify() uses buildMelodyFromPrefs() to select
the correct RTTTL string per contact.

Remove broken nRF52 volume control from buzzer.cpp: tone() uses
NRF_PWM2 with DECODER.MODE=Auto so TASKS_NEXTSTEP has no effect and
duty cannot be changed before the first DMA read without patching the
Arduino core. applyVolume() is now a no-op on nRF52.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:43:38 +02:00
Jakub
4891a36c72 Add ringtone editor, buzzer volume, unread fixes and buzzer notification fixes
- RingtoneEditorScreen: 32-note step sequencer accessible via new Tools page on home screen. U/D=pitch, ENTER=octave cycle, L/R=cursor, MENU=options (play, duration, BPM, insert/delete, save). Notes stored packed in NodePrefs and persisted via DataStore.
- ToolsScreen: new "Tools" home page entry launching the editor
- Buzzer volume: 0-4 bar control in Settings > Sound, persisted to prefs
- Buzzer notifications: fixed notify() firing inside wrong serial-guard branch and before addChannelMsg set the channel index
- Unread counter: fixed newest-first index direction; watermark formula now correct
- OLED brightness: wider range via pre-charge register 0xD9 combined with contrast

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
ffa568938f Settings: add buzzer volume control (5 levels, like brightness)
- NodePrefs: add buzzer_volume field (0=min..4=max, default 4)
- DataStore: persist buzzer_volume at end of prefs file (backward-compat)
- buzzer: setVolume()/getVolume(); applyVolume() sets PWM duty cycle via
  analogWrite() after each rtttl::play() call to control output amplitude
- Settings UI: new BzrVol bar item in Sound section (left/right to adjust)
- UITask: apply saved volume on startup alongside brightness

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
9d92fb62df Buzzer: add playForced(); fix per-channel force-on notification ignoring global mute
buzzer.play() was returning early when _is_quiet=true, so channels with
explicit notification=ON were silent even though the logic correctly set
play=true. playForced() bypasses the quiet check for these overrides.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:47 +02:00
Jakub
c3846ba9f5 feat(wio-tracker-l1): add settings screen and companion radio improvements
Settings screen (UI_HAS_JOYSTICK_UPDOWN build variant):
- Display brightness (5 levels, contrast curve tuned for SH1106 non-linearity)
- Buzzer on/off (respected at startup, no more forced unmute)
- TX power (2–22 dBm)
- Auto-off delay (5s / 15s / 30s / 60s / never)
- GPS update interval (off / 30s / 1min / 5min / 15min / 30min)
- Timezone offset (UTC-12..+14) for clock screen
- Low battery auto-shutdown threshold (off / 3.0–3.5V, default 3.4V)
- Battery display mode (icon / % / voltage)

Battery:
- EMA filter (alpha=0.2) on ADC readings to smooth voltage spikes from uneven load
- Battery % calculated using low_batt_mv as 0% anchor
- Mute icon repositions dynamically based on battery display width

Clock screen on HomeScreen showing time/date with timezone support.

Build:
- _settings variants added for USB and BLE companion radio builds
- Automatic UF2 generation on every build via create-uf2.py post-script
- UI_HAS_JOYSTICK_UPDOWN flag guards joystick_up/down to avoid breaking other boards

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:46 +02:00
Quency-D
6d3b71eed9 add heltec-mesh-node-t1 2026-05-11 15:11:07 +08:00
liamcottle
5a509752a7 don't play startup tune if buzzer pref disabled 2026-05-02 01:47:35 +12:00
Florent
1c7c5ecb2b buzzer: disable when quiet 2025-07-08 14:01:31 +02:00
liamcottle
4b9eac81c6 fix 150mA power draw on ThinkNode M1 2025-06-06 21:55:03 +12:00
seagull9000
7507f889a5 fix location and naming of enum 2025-05-20 19:33:21 +12:00
Scott Powell
7e90d386e2 * refactored buzzer concept to UITask
* moved buzzer.h/cpp to helpers/ui
2025-05-20 11:52:55 +10:00