Zephyr Sparse Keypads: Apply the Physical Key Mask Before Ghost Detection

Consider a hypothetical sparse control panel whose three-button maintenance chord is rejected even though all three switches are fitted. Removing the absent fourth coordinate from the application’s keymap may not fix it: the scan can be rejected before keycode mapping occurs.

Zephyr v4.2.0’s keyboard-matrix library provides a physical-key mask for this boundary. It filters scanned row bits before testing for an ambiguous rectangle. Understanding that order helps distinguish an electrical-population description from a user-interface mapping and prevents a sparse keypad from being treated like a fully populated matrix.

A hypothetical sparse two-column keypad produces raw row masks 11 and 11. Physical masks 11 and 10 produce filtered masks 11 and 10, leaving one common row bit rather than the two required for the ghost predicate.

Identify what the ghost check actually tests

The pinned matrix implementation represents each column as a bitset of active rows. For every pair of columns, the ghost detector computes their bitwise intersection. If that intersection contains at least two set bits, it declares ghosting.

The columns need not be adjacent. A layout that looks harmless when inspected as neighboring physical buttons can still contain an electrical rectangle across distant column assignments. Review the row/column net assignments, not only the printed arrangement of labels on the enclosure.

When ghost checking is enabled and that predicate is true, input_kbd_matrix_check_key_events() returns before calling the state-update routine. It does not simply delete one guessed phantom key and process everything else normally. That distinction is the reason to examine scan-level behavior when an otherwise valid chord appears to suppress other input changes.

Describe switches that physically exist

The pinned GPIO keyboard guide describes actual-key-mask for incompletely populated matrices. This is a description of which row/column intersections contain real keys, not a list of actions currently enabled by the product UI.

The matrix configuration header requires one mask entry per column. Within that entry, the bits identify rows. Its configuration macros also derive ghostkey_check from the inverse of no-ghostkey-check.

Transposing the mask can silently describe another board. Build it from an explicit electrical inventory: column index, row index, populated switch, and board revision. Keep the application’s mapping from that coordinate to a keycode as a separate artifact. A physically fitted key that is temporarily forbidden by a product state is still physically fitted.

Work through one sparse rectangle

Consider a hypothetical two-row, two-column board with switches at column zero/row zero, column zero/row one, and column one/row one. Column one/row zero is unpopulated. Its column masks are therefore binary 11 and 10, or hexadecimal 0x03 and 0x02.

Suppose a simultaneous press produces raw scanned masks 11 and 11, including an apparent bit at the absent intersection. Without population filtering, the two columns share two row bits and meet the ghost predicate.

With the correct physical mask, the scan stores 11 and 10. Their intersection is 10, containing only one set bit, so this particular pair no longer triggers ghost rejection. This is a constructed bit-level fixture illustrating the algorithm, not a measurement of a real keyboard’s electrical behavior.

For a fully populated two-by-two rectangle, both masks remain 11. Filtering does not remove the ambiguity. Do not falsify the population description by pretending that a fitted switch is absent simply to make a desired chord pass; that also prevents legitimate events from that switch and misrepresents the circuit.

A missing keycode is too late in the path

The scanner applies the physical mask to the sampled row value before storing its new-state column. Ghost detection consumes that filtered state. Accepted updates then proceed through debouncing and event reporting. The guide describes a later input-keymap layer that translates matrix-coordinate events into normal key events.

Consequently, omitting an unused coordinate from the keymap cannot undo a ghost rejection that has already prevented state processing. That omission changes interpretation of reported coordinates; it does not change the earlier electrical scan predicate.

Keep a diagnostic trace at both boundaries. Capture raw or instrumented scan state and filtered state for the chord, then record the resulting input events. If events never emerge, changing keycodes or UI bindings is unlikely to address the blocking stage.

Do not confuse debounce with ambiguity

Debounce asks whether a transition has persisted long enough to accept. Ghost detection asks whether the current matrix pattern is ambiguous under its rule. Increasing debounce time does not remove an electrical rectangle from the scanned bitsets.

Because the ghosting branch skips the complete state-update routine, that scan also skips its normal press/release processing and debounce bookkeeping. A release elsewhere in the matrix can therefore remain unreported during an ambiguous scan. Do not promise a fixed release delay from this source observation: later scans, configured timings, and actual electrical states determine what follows.

Include an already-held key in the qualification sequence, create a rejected chord, and release that earlier key while the ambiguous pattern remains. Observe when the application receives its release after ambiguity clears. A control application should not assume that every physical release becomes an immediate event during ghost suppression.

Qualify the board description with the chord set

Start with individual-key tests that verify every populated intersection and every intentionally empty position. Then exercise the product’s required chords, including combinations spanning nonadjacent columns. Compare the expected population mask with the generated configuration instead of relying on a copied overlay.

Add software fixtures for two columns sharing zero, one, and two row bits. Repeat the sparse example with the correct mask and with the mask omitted. Include a deliberately wrong mask to confirm that the test detects lost real keys rather than celebrating fewer ghost reports.

The guide permits disabling ghost detection for appropriately isolated diode matrices. That is a separate hardware-backed configuration, not a general workaround for a missing chord. Review diode presence, orientation, GPIO polarity, and scanning behavior before using that option. This article does not establish electrical rollover capability for any particular keypad.

No keypad scan, debounce measurement, or hardware test was executed here. The release artifact should be a board-specific population map plus a tested chord/release matrix. Its purpose is to make physical topology enter the decision before ambiguous scans are rejected, without claiming that software masking resolves every ghosting condition.

Trend context

The preserved Google Trends “embedded os” export, worldwide web search across all categories from July 19 to October 19, 2026, lists “zephyr os” rising +300% and “zephyr” rising +40%. This is parent related-query evidence for Zephyr coverage, not measured demand for sparse-keypad masking or this article’s title.

Similar Posts