Circuit review & bench-test guide
AXL-009 — GPIO expander lab PMOD module (MCP23017)
Document purpose#
This document explains the axl-009-gpio-expander module at component level and turns its schematic into a manual-review and bench-test plan. It is based on the implemented schematic (generate_design.py), the module README.md, and the Microchip MCP23017 datasheet. The board has never been fabricated. Every value below is a verification target, not a measured result.
1. What the board does#
A 16-bit I2C GPIO expander: two 8-bit ports (GPA, GPB) reached over the PMOD I2C bus. Port A drives 8 on-board LEDs; port B reads 8 on-board tactile buttons using the chip's internal pull-ups. It multiplies 2 host data pins into 16 IO and teaches the canonical I2C register-map workflow.
PMOD J1 ── SDA/SCL ──> [4.7k pull-ups behind JP1/JP2] ──> U1 MCP23017
INTA/INTB <── R12/R14 100R <── U1 INTA/INTB (open-drain, R11/R13 10k PU)
U1 GPA0..7 ──> 330R ──> 8x LED ──> GND
U1 GPB0..7 <── 8x button ──> GND (internal GPPU)
2. Safety and scope boundaries#
- 3.3 V logic only. On a PMOD host the rail comes from the socket; standalone, feed 3.3 V into the 3V3/GND header from a current-limited bench supply (set ~100 mA — the whole board draws well under that).
- LEDs and buttons are harmless, but a wrong VCC polarity will destroy U1; verify 3V3/GND orientation before power.
- This is an unreleased prototype: no EMC, no ESD qualification.
3. Power and control sequence#
- Apply 3.3 V. U1 powers up with all pins as inputs (
IODIRA/B = 0xFF), pull-ups off, so no LED lights and the bus is idle-high. - Host scans I2C, finds U1 at its strapped address, then configures ports.
IODIRA = 0x00makes port A outputs; writingOLATAwalks the LEDs.GPPUB = 0xFFenables port B pull-ups; readingGPIOBreturns buttons active-low.GPINTEN/INTCON/DEFVALarm interrupt-on-change to INTA/INTB.
4. Interfaces#
- J1 PMOD I2C (Type 6 extended): 1 INTA, 2 INTB, 3 SCL, 4 SDA, 9/10 bus repeat, 5/11 GND, 6/12 3V3.
- JP1/JP2 solder jumpers connecting the 4.7 k SDA/SCL pull-ups; cut when another module on the bus supplies pull-ups.
- JP3 address strap: A0 to GND (0x20, default) or VDD (0x21); A1/A2 are tied GND on-board.
5. Component-by-component review#
5.1 Expander and bus#
- U1 MCP23017-E/SS (SSOP-28): the expander. 16 IO, two interrupt outputs, I2C up to 1.7 MHz. If absent/dead: no bus ACK at the address — the first bring-up failure symptom. Verify VDD 1.8–5.5 V, all three address pins strapped, and
~RESEThigh (see R-note below). - R9, R10 4.7 kΩ (SDA, SCL pull-ups): set I2C rise time. If absent: bus stuck low or no ACK; too large: rounded edges, failed reads at speed. Behind JP1/JP2 so they can be removed on a shared bus.
- JP1/JP2: pull-up disconnects. If both cut with no other pull-ups: dead bus.
- JP3 + address strap: picks 0x20/0x21. If mis-strapped: device answers at an unexpected address (scan finds it, but your driver won't).
5.2 Interrupts#
- R11, R13 10 kΩ: pull-ups on the open-drain INTA/INTB outputs. If absent: interrupt line floats, false edges. (INT can be push-pull via IOCON — document that if you reconfigure.)
- R12, R14 100 Ω: series protection on the two chip-driven interrupt lines to the PMOD (line rule for module-driven signals). If absent: a host miswire shorts INTA/INTB directly.
5.3 ~RESET and decoupling#
- ~RESET is held high by a 10 kΩ pull-up (see the generator's reset net); if it floats or is tied low the chip sits in reset and never ACKs.
- C1 100 nF + C2 10 µF: VDD decoupling. If absent: I2C glitches under LED switching load; the 10 µF steadies the rail as 8 LEDs turn on together.
5.4 LEDs and buttons#
- 8× LED + 330 Ω (port A): visible outputs; ~3.7 mA each at 3.3 V. If the resistor is absent: LED over-current and possible GPA pin damage.
- 8× tactile button (port B) to GND: read via internal GPPU. If GPPU is not enabled in firmware: inputs float and read randomly — a classic first-bring-up gotcha, not a hardware fault.
6. Datasheet summary (MCP23017)#
- Supply 1.8–5.5 V; I2C 0/100/400 k and 1.7 MHz. Address 0x20–0x27 via A2:A0.
- Registers (IOCON.BANK=0 default): IODIR 0x00/0x01, GPPU 0x0C/0x0D, GPIO 0x12/0x13, OLAT 0x14/0x15, GPINTEN 0x04/0x05, INTCAP 0x10/0x11.
- INT pins open-drain by default, active-driver/polarity set in IOCON.
- Per-pin source/sink 25 mA max; total device 150 mA — 8 LEDs at 3.7 mA is fine.
7. Expected values before bench testing#
- Idle SDA/SCL: 3.3 V. Address ACK at 0x20 (JP3 default) or 0x21.
- After
IODIRA=0x00,OLATA=0x01: LED0 lit, ~3.7 mA;OLATA=0xFF: all lit, ~30 mA added to VDD current. - Port B button pressed (GPPUB=0xFF): corresponding
GPIOBbit reads 0.
8. Manual review checklist#
- [ ] U1 pin 1 orientation and all three address pins strapped as intended.
- [ ] R9/R10 present, JP1/JP2 bridged (default).
- [ ] ~RESET pulled high, not floating.
- [ ] Every LED has its 330 Ω; LED polarity (cathode to GND).
- [ ] INTA/INTB each have 10 k pull-up + 100 Ω series.
- [ ] C1/C2 close to U1 VDD.
9. Ordered bench-test procedure#
A. Unpowered: continuity 3V3↔U1 VDD, GND↔U1 VSS; confirm no VDD-GND short; verify address straps with an ohmmeter (A0 to GND or VDD per JP3).
B. Power, idle: apply 3.3 V (≤100 mA limit). Confirm ~idle current (<1 mA), SDA/SCL at 3.3 V, no LED lit.
C. Bus bring-up: I2C scan → expect ACK at 0x20. Read IOCON to confirm comms.
D. LED walk: IODIRA=0x00; loop OLATA through 0x01,0x02,…,0x80; watch a single LED step across. Then OLATA=0xFF (all on), 0x00 (all off).
E. Button read: GPPUB=0xFF, IODIRB=0xFF; poll GPIOB; press each button, confirm the matching bit drops to 0.
F. Interrupt-on-change: GPINTEN B=0xFF, INTCONB=0x00 (compare to previous); press a button, verify INTB asserts low and INTCAPB latches the state; confirm INTB releases after the read.
10. Troubleshooting map#
- No ACK: check ~RESET high, address straps, JP1/JP2 bridged, VDD present.
- LEDs won't light: IODIRA not set to output, or OLAT vs GPIO confusion.
- Buttons read random: GPPU not enabled (firmware), not a board fault.
- INT never fires: GPINTEN/INTCON not configured, or 10 k pull-up missing.
11. Bench record template#
Board: axl-009 S/N:____ Date:____ Operator:____
Idle current @3.3V: ____ mA
ACK address: 0x____ IOCON readback: 0x____
LED walk pass: [ ] All-on current: ____ mA
Button map (1-8) correct: [ ]
INTB asserts on change: [ ] releases after INTCAP read: [ ]
Notes:
12. Review conclusion#
A low-risk L3 board: one I2C device, visible outputs, no power hazards. The only real failure modes are the universal I2C ones (address, pull-ups, reset) and the firmware-side GPPU gotcha. Bench value is confirming the register workflow end to end before it becomes the reference for the register-map lesson.