Circuit review & bench-test guide
AXO-012 — 4×4 matrix keypad interface PMOD module
Document purpose#
Component-level explanation and bench-test plan for the axo-012-keypad interface, from generate_design.py, the module README.md, and the CDSOT236-0504C (SRV05-4 family) TVS-array datasheet. Never fabricated; all values are targets. The 4×4 membrane keypad plugs into J2 — its ribbon order is verified before use (Section 4a).
1. What the board does#
An interface for the ubiquitous 8-pin 4×4 membrane keypad: 4 row drives + 4 column reads brought to the PMOD, each with a 100 Ω series resistor, columns pulled up, and DNP TVS arrays for optional ESD hardening. Scanning happens in FPGA fabric (keypad_scan core).
PMOD J1 ROW1-4 ──> 100R ──> J2 rows ── [membrane] ── J2 cols ──> 100R ──> J1 COL1-4
cols also <── 10k pull-ups to 3V3
D1 (rows) / D2 (cols): CDSOT236 TVS arrays, DNP
2. Safety and scope boundaries#
- 3.3 V only. PMOD host supplies the rail; standalone, 3.3 V into 3V3/GND at a low current limit (this board sinks microamps).
- A membrane keypad is harmless; the only failure risk is a shifted ribbon plug shorting a row driver to 3V3 through a pressed key — the 100 Ω series resistors bound that current (~33 mA worst case).
- Unreleased prototype; TVS arrays are DNP by default.
4. Interfaces#
- J1 PMOD Type 1 GPIO: 1–4 ROW1–4, 7–10 COL1–4, 5/11 GND, 6/12 3V3.
- J2 1×8 socket for the keypad ribbon (R1 R2 R3 R4 C1 C2 C3 C4 in the common order — verify per Section 4a).
4a. PLUG-IN VERIFICATION#
The 8-pin membrane ribbon is unkeyed and its row/column order varies by supplier. A shifted or reversed plug maps keys wrongly (harmless, just confusing) but can also tie a driven row to a column. Before relying on the map:
- With the keypad unplugged, ohm out the keypad itself: pressing key "1" shorts its row-1 pin to its col-1 pin. Build the actual pin→(row,col) table.
- Compare to J2's silkscreen labels; note any offset in your HDL constants rather than forcing the ribbon.
5. Component-by-component review#
- J2 (1×8 socket): keypad interface. If mis-plugged: wrong key map; series R's prevent damage.
- 8× 100 Ω series (all lines): on both rows (driven) and columns (read). The design deliberately puts 100 Ω on all 8 lines, not just the four module-driven ones, because the ribbon is unkeyed — a reversed plug could make any line a driven line. If absent: a shifted plug + pressed key shorts a host output to 3V3/GND.
- 4× 10 kΩ column pull-ups: define the idle-high read level. If absent: columns float; scanning reads garbage. (Rows are driven, so no pull needed.)
- D1, D2 CDSOT236-0504C (SOT-23-6 TVS arrays, DNP): optional ESD clamp on the keypad side. Human finger + long ribbon = ESD path; populate for field use. If absent (default): fine on a bench, less robust in a classroom.
- C1 100 nF: rail decoupling. Minimal load, but standard.
6. Datasheet summary (CDSOT236-0504C / SRV05-4)#
- 4-channel + 1 common TVS array, SOT-23-6. Working voltage 5 V, clamps ESD to ±8 kV contact / ±15 kV air (IEC 61000-4-2). Low capacitance (~few pF) so it does not slow the scan.
- Placed on the keypad side of the 100 Ω resistors so a strike is clamped before the series R and never reaches the FPGA directly.
7. Expected values before bench testing#
- All columns idle at 3.3 V (pull-ups), rows driven by the host.
- Drive ROW1 low, press key "1": COL1 reads 0, COL2–4 stay high.
- No key pressed: all columns high regardless of row drive.
8. Manual review checklist#
- [ ] J2 order vs the actual keypad map (Section 4a).
- [ ] 100 Ω on all 8 lines (count them — the point of this board).
- [ ] 10 k pull-ups on the four column lines only.
- [ ] D1/D2 footprints present (DNP is acceptable for bench).
9. Ordered bench-test procedure#
A. Unpowered: ohm the keypad to build its true map (Section 4a). Buzz J2 → 100 Ω → J1 for all 8 lines. Confirm 10 k from each column net to 3V3.
B. Power, idle: 3.3 V. All four column PMOD pins read high; rows follow whatever the host drives.
C. Static scan by hand: drive one row low (others high/hi-Z per your scan scheme), press each key in that row, confirm exactly the expected column drops. Repeat for all four rows → full 16-key map.
D. Scope the scan (with HDL): run keypad_scan at ~1 kHz; scope a row line and a column line. Confirm the row pulses low in sequence and a pressed key pulls its column low only during that row's active window.
E. Ghosting demo: press three keys forming an "L" (same row + same column overlap); observe the phantom fourth key — the diode-less-matrix limitation the lesson teaches. (Populating per-key diodes would remove it; membrane keypads can't.)
F. Debounce check: scope a column on a single press; confirm several ms of bounce — motivating the fabric debounce core.
10. Troubleshooting map#
- All columns stuck low: a row driven low + missing column pull-ups, or a ribbon short.
- No key ever detected: ribbon offset (rebuild map), or rows not being driven.
- Phantom keys: expected on 3-key combos (ghosting), not a fault.
11. Bench record template#
Board: axo-012 Keypad P/N:____ True map built: [ ]
Idle columns high: [ ] 16-key map correct: [ ]
Bounce duration observed: ____ ms
TVS populated: [ ]
Notes:
12. Review conclusion#
A deliberately minimal board whose engineering content is the "100 Ω on every line because the ribbon is unkeyed" decision and the honest ghosting limitation. No power hazards. Bench work is mostly building the true key map and confirming the scan waveform before it becomes the keypad_scan reference.