← AXL-009

Circuit review & bench-test guide

AXL-009 — GPIO expander lab PMOD module (MCP23017)

Design-stage — board not yet fabricated

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. Power and control sequence#

  1. 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.
  2. Host scans I2C, finds U1 at its strapped address, then configures ports.
  3. IODIRA = 0x00 makes port A outputs; writing OLATA walks the LEDs.
  4. GPPUB = 0xFF enables port B pull-ups; reading GPIOB returns buttons active-low. GPINTEN/INTCON/DEFVAL arm interrupt-on-change to INTA/INTB.

4. Interfaces#

5. Component-by-component review#

5.1 Expander and bus#

5.2 Interrupts#

5.3 ~RESET and decoupling#

5.4 LEDs and buttons#

6. Datasheet summary (MCP23017)#

7. Expected values before bench testing#

8. Manual review checklist#

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#

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.