← AXS-015

Circuit review & bench-test guide

AXS-015 — APDS-9960 gesture/proximity/RGB PMOD module

Design-stage — board not yet fabricated

Document purpose#

This document explains the axs-015-apds9960 prototype at component level and turns the design evidence into a practical manual-review and bench-test plan. It is based on the generated schematic (generate_design.py, rev 0.1-schematic), the module README, and the APDS-9960 manufacturer datasheet.

The board is an unfabricated, schematic-only prototype: ERC is clean (0 errors / 0 warnings) and the netlist has been reviewed, but no PCB layout exists, no board has been built, and no bench measurement has ever been taken. Every numeric value in this guide is a verification target taken from the schematic or the datasheet — it is not a measured result and is not proof that an assembled board will work.

1. What the board does#

The board is a 12-pin PMOD (Type 6 extended, I2C) module carrying a Broadcom APDS-9960: gesture engine (four directional photodiodes and a 32-dataset FIFO), proximity engine, and RGBC color/ambient-light engine in one optical package with an integrated 950 nm IR LED and factory-calibrated constant-current LED driver. The module uses the single-supply hookup: LEDA ties to 3V3 and LEDK returns through the internal LDR sink, so IR LED pulses (up to 100 mA at the default drive, more with boost) are drawn from the shared 3.3 V rail, buffered by a 10 µF bulk capacitor. The I2C address is fixed at 0x39. The open-drain interrupt reaches PMOD pin 1 as GESTURE_INT; two solder jumpers make the 4.7 kΩ bus pull-ups removable for chained-module use. All engine configuration and gesture decoding is host firmware.

Functional block diagram#

PMOD J1 (2x6, Type 6 ext.)
  6/12  3V3 ───┬──────────┬─────────┬─────────┬────────┬───────────────┐
               │          │         │         │        │               │
          C1 100nF   C2 10uF    R1 4.7k   R2 4.7k   R3 10k             │
          (VDD HF)  (IR LED       │ SDA_PU   │ SCL_PU   │              │
                     pulse       JP1 ═╗     JP2 ═╗      │              │
  5/11  GND ───┐     reservoir)  (cut to    (cut to     │              │
               │                  unchain)   unchain)   │              │
   3/9  SCL ───┼──────────────────────┼─────────┘       │              │
   4/10 SDA ───┼──────────────────────┘                 │              │
               v                                        │              │
        ┌─────────────────┐ VDD ── 3V3                  │              │
        │    APDS-9960    │ LEDA ─ 3V3 ─────────────────┼──────────────┘
        │       U1        │ LEDK ─┬─ LDR (internal      │
        │ fixed I2C 0x39  │       │   current sink,     │   R4 100R
        │ gesture+prox+   │      net LED_K              │      │
        │ RGBC + IR LED   │ INT (open drain) ── GST_INT ┴──────┴─> pin 1
        └─────────────────┘                                  GESTURE_INT

2. Safety and scope boundaries#

3. Power and control sequence#

  1. The PMOD host (or bench supply) applies 3.3 V (pins 6/12) and ground (pins 5/11). VDD and LEDA power up together; LEDK returns through the internal LDR sink (constant-current driver), per the single-supply reference hookup. Datasheet ranges: VDD 2.4–3.6 V, VLEDA 3.0–4.5 V — 3.3 V satisfies both, with only 0.3 V of VLEDA margin at the bottom if the rail sags.
  2. After POR the device initializes (≈5.7 ms) and enters SLEEP: ~1 µA typical (10 µA max). I2C access temporarily wakes the core even with PON = 0.
  3. R1/R2 (through JP1/JP2) hold SDA/SCL at 3.3 V; R3 holds the open-drain INT high.
  4. Host sets PON (ENABLE 0x80 bit 0). The oscillator runs; the first engine enable after sleep incurs a ≈7 ms exit-sleep delay.
  5. Enabling AEN runs the color/ALS engine (no IR LED, ~200 µA typical). Enabling PEN pulses the IR LED per PPULSE/PPLEN and CONTROL<LDRIVE> (default 100 mA, 8 µs — LED off-chip current flows 3V3 → LEDA → LED → LEDK/LDR → internal sink → GND, drawn from C2). Device-side current ~790 µA plus LED duty-cycle average.
  6. Gesture mode arms when GEN is set and PDATA crosses GPENTH (or GMODE is forced to 1): the engine streams 4-byte U/D/L/R datasets into the 32-deep FIFO, asserting INT when GFLVL reaches the GFIFOTH threshold. The engine exits when all unmasked channels fall below GEXTH for GEXPERS cycles (GMODE clears).
  7. INT is open-drain, active low, shared by all engines' maskable interrupt sources; R3/R4 deliver it to PMOD pin 1. Non-gesture interrupts clear via special "address-accessing" commands (PICLEAR 0xE5, CICLEAR 0xE6, AICLEAR 0xE7); gesture flags clear by draining the FIFO.

4. Interfaces#

PMOD pin map (J1, Type 6 extended)#

PMOD pin123456789101112
NetGESTURE_INTNCSCLSDAGND3V3NCNCSCLSDAGND3V3

Pins 9/10 duplicate SCL/SDA for chaining a second I2C module.

Jumpers#

Ref.TypeFactory stateFunction
JP12-pad solder jumper, bridgedBridgedConnects R1 (4.7 kΩ) to SDA. Cut when another module in the chain provides the bus pull-ups.
JP22-pad solder jumper, bridgedBridgedConnects R2 (4.7 kΩ) to SCL. Cut together with JP1.

There is no address jumper: the APDS-9960 supports the single 7-bit address 0x39. Chain buses (JP1/JP2) for multiple modules.

Test points#

None are defined in the rev 0.1 schematic. Probe SCL/SDA/INT at the J1 pins and 3V3/GND at pins 6/5. A test pad on the LED_K net would make the LED pulse train directly observable — worth adding at layout.

5. Component-by-component review#

Every reference designator in the generated schematic is listed.

Ref.Part / valueFunction and why neededIf absent / openIf shorted, wrong, or misassembledKey datasheet parameters
J12x6 right-angle PMOD male header (Conn_02x06_Odd_Even)Host connection: power, ground, I2C, INT, chained-bus pinsNo power/communication; single open pin loses that functionReversed/offset insertion puts 3.3 V on signal pins; adjacent-pin bridges short SDA/SCL or powerPMOD Type 6 extended; 3.3 V rail defined by host
U1Broadcom APDS-9960, 8-pin optical moduleThe whole sensor: gesture/proximity/RGBC engines, IR LED + calibrated driver, I2C, interruptBoard is inert; no ACK at 0x39Rotated part misconnects VDD/GND/LED pins and can destroy it; an open LEDA or LEDK-LDR joint silently kills proximity/gesture (ALS still works — a distinctive signature); solder on either optical window degrades that functionVDD 2.4–3.6 V, VLEDA 3.0–4.5 V, abs max 3.8 V; sleep 1 µA typ; ALS 200 µA typ; prox/gesture 790 µA typ + LED; LED 100/50/25/12.5 mA (LDRIVE), boost to 300%; I2C 0x39, ≤400 kHz; ID reg 0x92 = 0xAB
C1100 nF 16 V X7R 0603 (Murata GRM188R71C104KA01D)U1 VDD high-frequency decouplingSupply bounce during engine switching; noisy counts, flaky I2CShorted C1 = 3V3–GND short, rail collapseLow-ESR ceramic close to the package
C210 µF 10 V X5R 0805 (Murata GRM21BR61A106KE19L)Bulk reservoir for IR LED pulses on the shared railLED pulses (100 mA, 4–32 µs bursts) sag the rail/PMOD wiring; proximity/gesture counts become noisy or the device browns out mid-burstShorted C2 = rail short; a far-away placement (layout risk) defeats its purpose — keep adjacent to U1's LEDA100 mA × 8 µs from 10 µF ≈ 80 mV droop; datasheet recommends split supplies only for LED_BOOST ≥ 200%
R14.7 kΩ 0603 (Yageo RC0603FR-074K7L)SDA bus pull-up (via JP1)With JP1 cut / R1 open and no external pull-up, SDA floats: no trafficShort 3V3→SDA jams the bus; too-low value overloads drivers~0.7 mA sink per line at 3.3 V
R24.7 kΩ 0603 (Yageo RC0603FR-074K7L)SCL bus pull-up (via JP2)Clock floats; no transactionsAs R1As R1
R310 kΩ 0603 (Yageo RC0603FR-0710KL)Pull-up for U1's open-drain INT (net GST_INT)INT floats; host sees noise/stuck level; gesture interrupt-driven FIFO draining impossibleShort to 3V3 masks all interruptsVOL ≤ 0.4 V at 3 mA sink
R4100 Ω 0603 (Yageo RC0603FR-07100RL)Series protection between GST_INT and PMOD pin 1Pin 1 disconnected: interrupt never reaches hostShorted = functional but unprotected; large wrong value slows edgesLimits contention current if the host mis-drives pin 1
JP12-pad solder jumper, factory bridgedMakes the SDA pull-up removable for chained busesCut: relies on external pull-ups — correct only in a chainSloppy re-bridge can short SDA to adjacent copperSee section 4
JP22-pad solder jumper, factory bridgedMakes the SCL pull-up removableAs JP1, for SCLAs JP1See section 4
#FLG01PWR_FLAG on 3V3ERC-only artifact marking 3V3 as power-drivenNot a physical part; only ERC warningsNot applicable — never fitted, not in BOM/POS
#FLG02PWR_FLAG on GNDERC-only artifact for GNDAs #FLG01Not applicable

Wiring note: the schematic ties U1's LEDK (pin 4) and LDR (pin 3) together on net LED_K, and LEDA (pin 5) to 3V3 — exactly the datasheet's "connect LEDK to LDR pin when using internal LED driver circuit" hookup.

6. Datasheet summary and design interpretation#

Primary reference: APDS-9960 datasheet (Avago/Broadcom AV02-4191EN). Passives: Yageo RC thick-film series, Murata GRM188R71C104KA01D / GRM21BR61A106KE19L via murata.com capacitor search.

Manufacturer fact (AV02-4191EN)Board-specific interpretation
VDD 2.4–3.6 V; VLEDA 3.0–4.5 V; abs max 3.8 VShared 3.3 V rail satisfies both; VLEDA has only 0.3 V of low-side margin, so rail sag under LED pulses matters — hence C2
IDD: sleep 1.0 µA typ / 10 µA max; wait 38 µA; ALS active 200 µA typ / 250 µA max; prox or gesture with LDR pulses 790 µA typ (LED current not included)Bench sanity currents in section 7
LED drive (CONTROL 0x8F LDRIVE / GCONF2 GLDRIVE bits): 100 / 50 / 25 / 12.5 mA; LED_BOOST (CONFIG2 0x90 bits 5:4): 100/150/200/300%Default LDRIVE=0 → 100 mA pulses from the 3.3 V rail. Datasheet note: at LED_BOOST 200/300% "it is recommended to separate the VDD and VLEDA supplies" — not possible on this board; cap firmware at ≤150%
Simplified power examples: 100 mA / 8 pulses / 16 µs / GWTIME=2 → 3.76 mA average; 300 mA case → 16.14 mA averageAverage bench current stays small; only the instantaneous pulse threatens tight current limits
Single fixed I2C address 0x39, ≤400 kHzACK scan must show 0x39 only; no variants
ID register (0x92) = 0xAB = APDS-9960The only ID value this datasheet documents. Community driver reports exist of parts returning 0x9C or 0xA8 (later silicon or compatible clones); treat a non-0xAB ID as "identify part provenance and re-verify against the current datasheet," not as an automatic pass
ENABLE (0x80): bit0 PON, bit1 AEN, bit2 PEN, bit3 WEN, bit4 AIEN, bit5 PIEN, bit6 GEN; configure engine registers before setting enablesPower-on sequence in section 9; init 5.7 ms after POR, ≈7 ms exit-sleep on first engine enable
Proximity: PDATA (0x9C) 8-bit; no-object count 10 typ / 25 max; 100 mm 90% grey card 96–144 counts (calibrated conditions)Section 7 proximity targets
Gesture: entry when PDATA ≥ GPENTH (0xA0); exit below GEXTH (0xA1); GCONF1 (0xA2) FIFO threshold/exit mask/persistence; GCONF2 (0xA3) GGAIN/GLDRIVE/GWTIME; GPULSE (0xA6, resets 0x40 = 8 µs, 1 pulse; 8 pulses recommended); GCONF4 (0xAB) GIEN/GMODE/GFIFO_CLR; GFLVL (0xAE) = datasets available; GSTATUS (0xAF) GVALID/GFOV; FIFO data at GFIFO_U/D/L/R 0xFC/0xFD/0xFE/0xFFGesture bring-up procedure in section 9F; FIFO holds 32 four-byte datasets and overflows (GFOV) if not drained
Gesture direction decoding: the diode opposite the motion sees the reflection first/larger on entry; compare amplitude and phase between U/D and L/R waveformsExpected FIFO signatures in section 9F
RGBC: ATIME (0x81, resets 0xFF = 2.78 ms) sets integration; 16-bit CDATA/RDATA/GDATA/BDATA at 0x94–0x9B, low-byte-first latched readsQuick ALS check in section 9E
STATUS (0x93): PGSAT/CPSAT saturation, PINT/AINT/GINT flags, PVALID/AVALIDPoll points during bring-up

7. Expected values before bench testing#

All values are targets to verify, not measurements.

QuantityTarget / calculatedBasis
Bus idle level, SDA and SCL3.3 V through R1/R2Pull-ups via JP1/JP2
SDA→3V3 / SCL→3V3 resistance, unpowered, jumpers fitted≈ 4.7 kΩ eachR1 / R2
SDA/SCL→3V3 after cutting JP1/JP2Open (>1 MΩ) on the bus side; SDA_PU/SCL_PU pads still ≈4.7 kΩJumper cut isolates R1/R2
GESTURE_INT (pin 1)→3V3 resistance≈ 10.1 kΩ (R4 + R3 in series)Pin1–R4–R3–3V3 path
Address-ACK scanACK at exactly 0x39; NACK everywhere else (no jumper variants exist)Fixed-address device
Module supply current, POR sleep≤ ~15 µA (U1 1 µA typ / 10 µA max)Sleep spec
Supply current, PON + AEN (ALS only)~200–250 µA — no LED activity in ALS modeALS-state spec; color engine does not use the IR LED
Supply current step when PEN or gesture runsDevice ~790 µA plus LED average: ~3.8 mA at defaults-plus-8-pulses (datasheet case 1); instantaneous pulses 100 mA × 4–32 µsOperating characteristics + power table
ID register (0x92)0xAB per datasheet; 0x9C/0xA8 are community-reported variants — investigate, don't silently acceptID register definition
PDATA, no object above sensor~10 counts typical, ≤25 (open view, calibrated conditions)Proximity characteristics
PDATA, hand/90% card at 100 mm96–144 counts (120 typ) at 100 mA / 8 pulses / 8 µs / PGAIN 4×Proximity characteristics
Gesture FIFO, hand wave at a few cmGFLVL climbs 1→32; each dataset four bytes U/D/L/R from ~10 (no object) toward 100–255 near the hand; GFOV sets if not drainedGesture engine description
Rail droop during an LED pulse (at C2)≈ 80 mV calculated (100 mA × 8 µs / 10 µF) — layout-dependentCharge arithmetic on C2
RGBC clear channel, room light, ATIME defaultNonzero, well below 1025 (2.78 ms full scale is only 1025 counts — lengthen ATIME for real ALS use)ATIME/count relationship (CountMAX = 1025 × cycles)

8. Manual schematic and assembly review checklist#

9. Ordered bench-test procedure#

Assume a PMOD host (FPGA board) or a 3.3 V bench supply current-limited to about 200 mA (see section 2 — pulsed LED current can trip an aggressive limit) wired to J1 pins 6/12 and 5/11, plus an I2C master on pins 3/4. Stop at the first abnormal result and record everything.

A. Unpowered inspection and resistance tests#

  1. Complete the section 8 checklist under magnification.
  2. Measure 3V3→GND resistance in both meter polarities; investigate anything under ~10 kΩ before power.
  3. Verify SDA→3V3 ≈ 4.7 kΩ, SCL→3V3 ≈ 4.7 kΩ, pin 1→3V3 ≈ 10.1 kΩ.

B. First power, no I2C traffic#

  1. Apply 3.3 V at a 200 mA limit.
  2. Confirm sleep current ≤ ~15 µA and SDA/SCL/pin 1 idle at 3.3 V.

C. Address-ACK scan#

  1. Wait ≥10 ms after power-up (5.7 ms init), then scan all 7-bit addresses.
  2. Expect an ACK only at 0x39. No ACK: U1 power/orientation/bus. Extra ACKs: another device on the chain.

D. First-transaction bring-up (ID and power-on)#

  1. Read the ID register: START, 0x39+W, register 0x92, repeated START, 0x39+R, read one byte — expect 0xAB. If 0x9C or 0xA8 appears, record it, identify the part's provenance (these values are reported in the field for later silicon and clones but are not in the datasheet), and continue only with that caveat logged.
  2. Write ENABLE (0x80) = 0x01 (PON). Wait ≥7 ms.
  3. Read STATUS (0x93); expect the power-up pattern (0x04 reset value, PVALID/AVALID clear until engines run).
  4. Confirm supply current is now in the idle/oscillator-on range (tens of µA, below the ALS-active 200 µA).

E. ALS engine and proximity engine (with LED-current check)#

  1. Write ENABLE = 0x03 (PON | AEN). After ≥ one ATIME period (2.78 ms default; write ATIME 0x81 = 0xDB for 100 ms first for usable range), read CDATAL/H (0x94/0x95, low byte first) — expect nonzero room-light counts that fall when the sensor is covered. Supply current ~200 µA: the color engine must not produce LED pulses.
  2. Enable proximity: write ENABLE = 0x05 (PON | PEN). Defaults give LDRIVE = 100 mA, PPULSE reset 0x40 = 8 µs / 1 pulse; optionally write PPULSE (0x8E) = 0x87 (8 µs, 8 pulses) for the datasheet's recommended condition.
  3. IR LED current check: watch the supply. Expect a measurable average step (device ~0.8 mA plus LED duty average, order 1–4 mA depending on pulse settings) and, on a scope across the supply or at C2, brief ~100 mA pulse-train droop events (~80 mV calculated at C2). A phone camera (no IR filter) pointed at the module should show the LED flashing. If the bench supply folds back or the device resets here, raise the current limit — this is the anticipated aggressive-limit trip point.
  4. Read PDATA (0x9C): expect ~10 counts (≤25) with nothing above the module, rising toward 96–144 with a hand/90% card at ~100 mm and saturating toward 255 as the hand approaches.
  5. Verify the CONTROL (0x8F) LDRIVE field: write LDRIVE = 3 (12.5 mA, 0xC0 in bits 7:6) and confirm both the supply-current step and PDATA sensitivity drop; restore LDRIVE = 0. Do not test LED_BOOST above 150% on this shared-rail board (datasheet recommends split supplies for 200/300%).

F. Gesture-engine bring-up and FIFO behavior#

  1. Configure before enabling (datasheet requirement):
  1. Write ENABLE = 0x4D (PON | PEN | WEN | GEN). The engine now arms via proximity: nothing should happen with no object present (GFLVL = 0, INT high).
  2. Wave a hand a few centimeters above the module. Expect: GMODE sets (GCONF4 bit 0 reads 1), STATUS (0x93) GINT (bit 2) asserts, pin 1 falls, and GFLVL (0xAE) reads a climbing dataset count (1–32).
  3. Drain the FIFO: for each GFLVL count read four bytes GFIFO_U/D/L/R = 0xFC/0xFD/0xFE/0xFF (a 4-byte burst per dataset). Expect all four channels to rise from the ~10-count no-object floor toward 100–255 and fall again as the hand leaves; for an up-to-down swipe the U and D waveforms are time-shifted copies (D leads on entry from the down side), and L/R shift for sideways swipes. GINT/GVALID clear once the FIFO is empty.
  4. Leave the FIFO undrained during a long wave: GFLVL should peg at 32 and GSTATUS (0xAF) GFOV (bit 1) must set — confirming overflow detection. Clear with GCONF4 GFIFO_CLR (bit 2).
  5. Confirm the engine exits after the hand leaves (GMODE clears) and that supply current returns to the idle level — a stuck GMODE (e.g. GEXTH = 0) keeps the LED pulsing indefinitely.

G. Interrupt line and pull-up chain configuration#

  1. During F3, verify pin 1 (GESTURE_INT) falls below 0.4 V and recovers to 3.3 V after the FIFO is drained. For proximity interrupts, set PILT/PIHT (0x89/0x8B) around PDATA, set PIEN, and clear with the PICLEAR (0xE5) address-access command.
  2. Power off. Cut JP1/JP2; verify SDA→3V3 and SCL→3V3 read open on this module alone; operate behind a pull-up-fitted module and repeat C–D; re-bridge and re-verify ≈4.7 kΩ.

10. Troubleshooting map#

SymptomFirst measurementsLikely areas
No ACK at 0x393V3 at U1, idle levels, JP1/JP2 continuityU1 unpowered/rotated, cut jumpers without external pull-ups, J1 solder
ID not 0xABRe-read, scope the transactionBus corruption; else silicon variant/clone (0x9C/0xA8 field reports) — identify provenance before proceeding
ALS works, proximity/gesture always ~0LEDA voltage, LED_K continuity, phone-camera IR checkOpen LEDA or LEDK–LDR joint, LED aperture blocked — the classic signature of the LED path failing
Device resets/browns out when PEN setRail at C2 on a scope, supply limit settingBench current limit folding back on 100 mA pulses; C2 missing/far away; rail wiring too thin
PDATA stuck at 255Surroundings, offset registersReflective surface too close, crosstalk (no barrier), POFFSET_UR/DL (0x9D/0x9E) need calibration
PDATA noisyRail droop, ambient IR (sunlight)C2 placement, strong IR ambient, lower PGAIN
Gesture never enters (GFLVL always 0)PDATA vs GPENTH, ENABLE bitsGPENTH too high, GEN/PEN not both set, configuration written after enabling
Gesture never exits (LED keeps pulsing)GMODE bit, GEXTH valueGEXTH = 0 prevents exit by design; write GMODE = 0 or set a nonzero GEXTH
GFLVL pegged at 32 / data staleGSTATUS GFOVHost draining too slowly — FIFO overflow; drain in 4-byte bursts per dataset
INT never assertsR3/R4 path, GIEN/PIEN/AIEN bitsInterrupt enables clear, R3 open, thresholds not bracketing
INT stuck lowGFLVL, STATUS flagsFIFO not emptied (gesture flags clear only on empty), PICLEAR/AICLEAR never issued, shorted R4/pin 1
Supply current mA-range in sleepThermal check U1/C1/C2Shorted capacitor, damaged U1

11. Bench record template#

FieldRecord
Board revision / serial
JP1/JP2 state audit
Host / supply, current-limit setting and response behavior
DMM / scope / IR-viewer equipment and calibration
Unpowered resistance results (A)
Sleep current and idle levels (B)
Address-scan result (C)
ID register value (D1) — flag if not 0xAB
ALS counts, uncovered/covered (E1)
Supply current: ALS vs proximity states; LED pulse observation (E3)
PDATA no-object / 100 mm / near values (E4)
LDRIVE-step check result (E5)
Gesture entry, GFLVL fill, FIFO waveforms, overflow test (F)
Interrupt assert/clear result (G1)
Chained-bus / jumper-cut result (G2)
Deviations, photos, raw-file paths
Reviewer / date / disposition

12. Review conclusion#

The schematic implements the standard single-supply APDS-9960 hookup (LEDA to 3V3, LEDK joined to the internal LDR sink) with the decoupling the arrangement demands: 100 nF for VDD plus a 10 µF reservoir for the 100 mA IR LED pulse train, and datasheet-conformant pull-ups on the bus and interrupt. The design's defining constraint is the shared rail: LED pulses draw from the same 3.3 V that powers the sensor core and the PMOD host, so C2's placement is the single most important layout decision still ahead, LED_BOOST above 150% is out of scope for this hardware, and bench supplies need a generous current limit despite the small average draw. The principal open risks are pre-fabrication: no PCB exists (optical apertures, LED-to-sensor crosstalk barrier, and C2 placement unverified), no board has ever been powered, and the gesture engine — the most stateful peripheral in the sensor line — has an entirely unwritten host driver whose FIFO-draining discipline this guide's section 9F is designed to prove out. The ID-register ambiguity (datasheet 0xAB versus field-reported 0x9C/0xA8) should be resolved against the actual purchased lot at incoming inspection.