Skip to content

feat(mixer): add buzzer to unified PWM/PINIO/LED output selection#2654

Open
sensei-hacker wants to merge 10 commits into
iNavFlight:maintenance-10.xfrom
sensei-hacker:feature-buzzer-unified-output
Open

feat(mixer): add buzzer to unified PWM/PINIO/LED output selection#2654
sensei-hacker wants to merge 10 commits into
iNavFlight:maintenance-10.xfrom
sensei-hacker:feature-buzzer-unified-output

Conversation

@sensei-hacker

@sensei-hacker sensei-hacker commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

Adds buzzer (PWM beeper) pads to the Output Mapping table in the Mixer tab, making them visible alongside motor, servo, LED, and PINIO outputs and allowing them to be reassigned at runtime.

image

Works on 1024 width screens, looks better on 1280 or higher.

Changes

  • js/outputMapping.js

    • Added TIMER_OUTPUT_MODE_BEEPER = 5 constant
    • getOutputCount() and getFirstOutputOffset() now include pads with TIM_USE_BEEPER
    • getTimerMap() assigns OUTPUT_TYPE_BEEPER for beeper-flagged pads in AUTO mode
    • getOutputTableDirect() maps firmware-reported beeper assignments to "Buzzer"
    • New: isBeeperPin(outputIndex) — detects beeper pads for label display
    • New: isTimerDefaultLed(timerId) / isTimerDefaultBeeper(timerId) — detect compile-time default timer assignments for dropdown pre-selection
  • tabs/mixer.html

    • Output Mapping table restructured to three rows: timer-mode dropdowns (colspan per timer group), pad labels, function assignments — gives uniform cell heights across all pads
  • tabs/mixer.js

    • Timer mode selectors moved from a separate box into the Output Mapping table
    • Colspan groups span pads sharing the same timer, with one dropdown per group
    • renderOutputTable(): LED pads labeled S13/LED, buzzer pads labeled S14/Buzzer
    • Timer dropdowns pre-select LED or BEEPER (not AUTO) for timers whose compile-time default is LED or buzzer, using getTimerOverride() ?? AUTO to correctly handle timers with no stored override
    • renderOutputMapping(): fills LED/buzzer function cells from the JS-computed map when the firmware direct-assignment response (which only reports motors, servos, and explicitly-overridden buzzers) leaves them as "-"

Testing

Tested on BrotherHobby H743 hardware (INAV 9.1.0, DEF_TIM(TIM2, CH1, PA15, TIM_USE_BEEPER, 0, 0)):

  • S14/Buzzer (Timer 2) column appears in Output Mapping table ✅
  • Timer 2 dropdown pre-selects BEEPER ✅
  • Function row shows "Buzzer" for the buzzer pad ✅
  • Timer 1 (LED) dropdown pre-selects LED, function row shows "Led" ✅
  • Motor assignments (Motor 1–4) unaffected ✅
  • No JavaScript console errors ✅

Boards with GPIO-only buzzers (e.g. SDMODELH7V1, PC13 not in timerHardware[]) show no extra column — correct behavior.

Code Review

Two rounds of review with inav-code-review agent. All critical and important findings addressed, including the ?? AUTO fallback fix and gap-fill guard.

- Add TIMER_OUTPUT_MODE_BEEPER = 5 to OutputMappingCollection, matching
  OUTPUT_MODE_BEEPER in firmware mixer.h
- In getOutputTableDirect(), compare entry.type against TIM_USE_*
  bit-index constants (already defined in the file) instead of magic
  numbers; use TIM_USE_BEEPER for the new buzzer assignment type
- Add BEEPER option to the per-timer output mode selector in mixer tab
…is set

Add OUTPUT_TYPE_BEEPER and a pre-pass in getTimerMap() so that timers
explicitly overridden to TIMER_OUTPUT_MODE_BEEPER are assigned before the
flag-based motor/servo/LED passes run. Add the corresponding display case
in getOutputTable(). Without this, a BEEPER-overridden LED pad would
fall through to the TIM_USE_LED flag check and incorrectly show "Led".
Each timer's mode dropdown now appears in the first pad cell of that
timer's column group, co-located with the output labels it controls.
The separate "Output Groups (Timers)" box is removed.
…ight

Timer mode dropdowns move to a dedicated row above the pad labels,
with each cell spanning the number of pads in that timer group.
This eliminates the unequal cell heights caused by embedding the
dropdown only in the first pad of each group.
getOutputCount(), getFirstOutputOffset(), and the getTimerMap()
non-dedicated pass now recognise TIM_USE_BEEPER so that targets
whose buzzer pin is a timer-capable pad (e.g. BROTHERHOBBYH743)
display it as a reassignable column alongside motors/servos/LEDs.
GPIO-only buzzer pins are not in timerHardware[] and are unaffected.
… dropdowns

Compile-time LED and buzzer pads now show /LED and /Buzzer suffixes in the
Output Mapping table. Their timer dropdowns pre-select LED or BEEPER instead
of AUTO. The function row fills in Led/Buzzer via JS fallback for pads the
firmware does not report in direct assignments.
Use ?? instead of || when reading timer override so undefined timers
correctly fall back to AUTO (0 is a valid override value). Tighten the
direct-assignment gap-fill to skip jsMap entries that are also '-'.
Rename private isTimerDefault helper for clarity.
@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

Use for-of loops and Array.at(-1) as suggested by static analysis.
Split renderOutputTable() into buildTimerGroups() and buildTimerSelectHtml()
helpers. Replace repeated ternary-per-option pattern with a [value, label]
array and map(). Also address SonarQube minor suggestions: for-of loops and
Array.at(-1).
…shorten PINIO option

Move timer number from each pad label into the timer-row dropdown cell
so it appears once per group rather than repeating on every pad. Add
padding-right to visually separate adjacent timer groups. Shorten
'PINIO / DUTY CYCLE' to 'PINIO / PWM' to reduce select box width.
@sonarqubecloud

sonarqubecloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant