Circuit review & bench-test guide
AXC-004 — RFM95W LoRa radio PMOD module
Document purpose#
This document explains the axc-004-lora PMOD module at component level and turns the design evidence into a practical manual-review and bench-test plan. It is based on generate_design.py, README.md, and the ERC report in reports/.
This board has never been fabricated. Repository status is schematic generated, ERC clean (0 errors / 0 warnings), netlist reviewed; PCB layout not started; not released. There is no PCB, no BOM export, no DRC record, and no first-article bench result. Every number below is a target to verify against real hardware, not a proven result.
1. What the board does#
The board carries a HopeRF RFM95W module (a Semtech SX1276 LoRa transceiver with the SPI+FIFO front end) as a 915 MHz long-range packet radio: the FPGA is the brain, the RFM95W is the radio. LoRa trades bitrate for kilometres of range via spreading factor and bandwidth. It is a PMOD Type 2A "expanded SPI" module — SPI mode 0 at ≤ 10 MHz plus two interrupt lines: DIO0 fires on TX-done / RX-done and DIO1 on RX-timeout, both routed to PMOD pins per the platform interrupt rule. The antenna reaches the outside world through a JP1 solder-jumper choice of a u.FL receptacle (J2) or a bare wire-solder pad (J3). The 915 MHz build fits the RFM95W-915S2; fit the RFM95W-868S2 for the EU 868 MHz band (same footprint).
Functional block diagram#
PMOD host (3.3 V) Module
┌────────────────┐ ┌───────────────────────────────────────────┐
│ 1 CS_N ────────┼──>│ U1 NSS U1 RFM95W-915S2 (SX1276) │
│ 2 MOSI ────────┼──>│ U1 MOSI │
│ 3 MISO <──R1───┼───│ U1 MISO 3V3 ─ C1 100n + C2 10µ │
│ 4 SCK ─────────┼──>│ U1 SCK RST_N ─ R4 10k PU │
│ 7 DIO0 <──R2───┼───│ U1 DIO0 (TX/RX done) │
│ 8 RST_N ───────┼──>│ U1 RESET │
│ 9 DIO1 <──R3───┼───│ U1 DIO1 (RX timeout) │
│ 6/12 3V3 ──────┼──>│ ANT ─ JP1 ─┬─ 1-2 J2 u.FL (default) │
│ 5/11 GND ──────┼───│ └─ 2-3 J3 wire pad (~78 mm ¼λ) │
└────────────────┘ └───────────────────────────────────────────┘
2. Safety and scope boundaries#
- ANTENNA-FIRST RULE — read before every transmit. This is an intentional radio transmitter with a real power amplifier (up to +20 dBm ≈ 100 mW). Never key the transmitter without a 50 Ω antenna (or lab load) connected at J2 or J3. Transmitting into an open or shorted antenna port reflects the PA's power back into the die and can degrade or destroy the output stage. Confirm the JP1 route matches the connected antenna before the first
RegOpModeTX command. - Regulatory. 915 MHz is the US/ITU-Region-2 ISM band; 868 MHz is the EU band. Fit the matching module variant and antenna, and observe the band's duty-cycle and channel limits (EU 868 has strict duty-cycle caps; US 915 has FHSS/dwell rules). Operating the wrong-band variant, or ignoring duty-cycle, is a regulatory violation — this is a lab tool, not a type-approved product.
- Everything on the board is 3.3 V; hazard to people is negligible. The supply range for the module is 1.8–3.7 V but the board is a 3.3 V PMOD — never feed 5 V; there is no regulator here.
- Standalone bench work must use a current-limited 3.3 V supply set to ~300 mA. The PA draws ~120 mA in bursts at +20 dBm; a 100 mA limit will brown the module out mid-transmit and produce misleading failures.
- RF keep-out is a layout promise, not a schematic fact: no ground pour or copper under the antenna pin/50 Ω feed, and the antenna edge faces off the PMOD plug. ERC-clean says nothing about this.
- A working link is not regulatory certification. Do not radiate beyond the band plan or without confirming local licensing/exemption rules.
3. Power and control sequence#
- 3.3 V arrives on PMOD pins 6/12; C1 (100 nF) + C2 (10 µF) buffer the PA's TX-burst current. There is no enable pin — the module powers up with the rail.
- RESET must be released for POR to complete. R4 (10 k) pulls RST_N to 3V3 so the SX1276 finishes power-on reset with the pin idle-high; the host pulses RST_N low to force a hard reset. The SX1276 boots into STDBY (LoRa or FSK per
RegOpMode). - The host selects the module with CS_N low and clocks SPI mode 0. The address byte's MSB is the R/W flag (1 = write, 0 = read).
- Bring-up handshake: read
RegVersion(address 0x42). It must return 0x12 (the SX1276 silicon revision). A wrong or zero value means the SPI wiring, CS_N, reset state, or the module itself is bad — do not proceed to RF work until 0x12 is stable. - The host configures frequency, spreading factor, bandwidth, coding rate, and PA (
RegPaConfig— select PA_BOOST for the RFM95W, since the module's antenna path is wired to PA_BOOST, not RFO). - On transmit, the SX1276 raises DIO0 = TxDone when the packet has left the PA; on receive, DIO0 = RxDone and DIO1 = RxTimeout. Both reach the host through 100 Ω series resistors.
4. Interfaces#
| Reference | Pins/signals | Intended use |
|---|---|---|
| J1 | 12-pin PMOD plug, Type 2A | 1 ~CS(NSS), 2 MOSI, 3 MISO (via R1), 4 SCK, 7 DIO0 (via R2), 8 ~RST, 9 DIO1 (via R3), 5/11 GND, 6/12 3V3, 10 NC |
| J2 | Hirose U.FL-R-SMT-1 receptacle | Default antenna path (JP1 1-2); mates a u.FL pigtail to a 915 MHz whip/patch |
| J3 | Wire solder pad | Alternate antenna path (JP1 2-3); a ~78 mm quarter-wave wire at 915 MHz |
| JP1 | 3-pad solder jumper, 1-2 default | Antenna route select: u.FL (1-2) or wire pad (2-3). Exactly one may be bridged |
There are no dedicated test points; bench probing is at J1 pins, JP1, the 100 Ω resistors, and the RFM95W castellations. Probe DIO/SPI, never the antenna node with an ordinary scope probe while transmitting.
5. Component-by-component review#
5.1 Radio and antenna path#
| Ref. | Part | Function and why needed | If absent/open | If shorted, wrong, or misassembled |
|---|---|---|---|---|
| U1 | HopeRF RFM95W-915S2 (SX1276), RF_Module:HOPERF_RFM9XW_SMD (footprint assigned explicitly — the stock symbol ships with none) | LoRa/FSK transceiver, SPI+FIFO, +20 dBm PA on PA_BOOST | Board inert | Castellation opens on 3V3/GND/SPI give partial or dead SPI; copper/pour under the antenna feed (layout) wrecks RF; an 868S2 fitted where 915 is intended radiates out of band |
| J2 | Hirose U.FL-R-SMT-1(10) | Default RF output to a u.FL antenna | No radiated output if JP1 is on 1-2 | A damaged centre pin or bad solder reflects PA power — the antenna-first hazard; never key TX into it unmated |
| J3 | Wire solder pad (SolderWire) | Alternate ¼λ wire antenna | No output if JP1 is on 2-3 | A stray/wrong-length wire detunes the PA and reflects power; treat an unterminated pad as no-antenna |
| JP1 | 3-pad solder jumper (DNP in BOM/POS; a build-time strap) | Chooses u.FL vs wire pad | ANT floats — both open = transmitting into an open port, the classic PA-killer | Both bridged shorts the two antenna paths together; verify exactly one route before any TX |
5.2 Interrupt/data conditioning and reset#
| Refs. | Value | Function | If omitted or wrong |
|---|---|---|---|
| R1 | 100 Ω | Series protection on the module-driven MISO line (only driven when CS_N is low) | Open = host sees no SPI read data: RegVersion reads as 0x00/0xFF and the module looks dead though it is fine |
| R2 | 100 Ω | Series protection on the module-driven DIO0 (TxDone/RxDone) line | Open = host never sees the done interrupt: TX/RX appears to hang forever |
| R3 | 100 Ω | Series protection on the module-driven DIO1 (RxTimeout) line | Open = RX-timeout events never reach the host |
| R4 | 10 kΩ to 3V3 | ~RST idle pull-up so POR completes with the pin released | Missing = reset may float; intermittent boot, or the host must always drive RST_N |
5.3 Decoupling#
| Refs. | Value | Function | If omitted or wrong |
|---|---|---|---|
| C1 | 100 nF 16 V X7R | Module HF decoupling at the 3V3 pin | Rail noise into the synthesiser/PA; spurs and unstable RF |
| C2 | 10 µF 10 V X5R | TX-burst bulk (PA ~120 mA at +20 dBm) | Rail droop on TX keying: resets, truncated packets, reduced output power |
| #FLG01–02 | ERC power flags (3V3, GND) | Bookkeeping only | — |
Every ref-des is covered: U1, J1, J2, J3, JP1, R1–R4, C1–C2.
6. Datasheet summary and design interpretation#
| Device | Key manufacturer facts used here | Board-specific interpretation |
|---|---|---|
| RFM95W / SX1276 (RFM95W datasheet) | SPI mode 0 ≤ 10 MHz; address MSB = R/W; RegVersion 0x42 reads 0x12; DIO mapping (RegDioMapping) puts TxDone/RxDone on DIO0, RxTimeout on DIO1; PA output on PA_BOOST for the RFM95W; ~120 mA PA burst at +20 dBm; POR needs RESET released | The 0x12 read is the first bring-up gate. The 100 Ω on DIO0/DIO1/MISO and the 10 k on RESET follow the platform rules. PA_BOOST is the only wired antenna path — configure RegPaConfig accordingly |
| LoRa modulation | Spreading factor + bandwidth trade bitrate for link budget; TxDone/RxDone are interrupt-driven | The DIO0/DIO1 routing is what makes an interrupt-driven RX/TX state machine possible on this PMOD |
| Regulatory (915/868 ISM) | 915 MHz = US Region 2; 868 MHz = EU with duty-cycle limits | Fit the matching variant and antenna; the duty-cycle note is an explicit open README item for the lesson text |
| Hirose U.FL-R-SMT-1 | 50 Ω u.FL receptacle | Verified stock footprint; the wire-pad J3 is the low-cost alternative |
Official reference: RFM95W datasheet (and the Semtech SX1276 datasheet for register detail). Check the exact orderable variant (915S2 vs 868S2) before procurement.
7. Expected values before bench testing#
All values are design targets for a board that does not yet exist.
| Quantity | Target | How to measure |
|---|---|---|
| 3V3-to-GND, unpowered | High (caps only), both polarities | DMM |
| MISO/DIO0/DIO1 series | ~100 Ω to the respective PMOD pin | DMM at R1/R2/R3 |
| RST_N idle | ≈3.3 V (R4 pull-up) after power | DMM/scope |
RegVersion (0x42) | 0x12 | SPI transaction, logic analyzer |
| Idle current (STDBY, not transmitting) | ~1.5–10 mA class | Bench supply |
| RX current | ~10–12 mA class | Bench supply |
| TX current burst (+20 dBm PA_BOOST) | ~120 mA peaks; record actual | Current probe or 0.1 Ω shunt + scope — a DMM will not catch the burst |
| Rail droop at module during TX | 3V3 stays > 3.0 V | Scope, AC-coupled, at C2 |
| DIO0 TxDone | Rising edge at end of a transmit | Scope at R2 / PMOD pin 7 |
| Two-node link | Second AXC-004 (or any SX127x) receives the packet with plausible RSSI/SNR | RegRssiValue/RegPktSnr on the RX node |
8. Manual schematic and assembly review checklist#
- Confirm the RFM95W variant marking matches the intended band (915S2 vs 868S2) and that
RF_Module:HOPERF_RFM9XW_SMDis the assigned footprint. - Verify JP1 is bridged on exactly one side and that the connected antenna (u.FL at J2 or wire at J3) matches it. An open JP1 is a transmit-into-open hazard.
- Confirm R1/R2/R3 sit in the module-driven MISO/DIO0/DIO1 paths and that SCK/MOSI/CS_N are direct.
- Confirm R4 pulls RST_N to 3V3; verify C1/C2 sit at the module 3V3 pin.
- Layout (future): antenna edge overhangs off-board, no copper/pour under the antenna pin or 50 Ω feed, controlled-impedance feed to J2/J3.
- Confirm host gateware idles CS_N high and RST_N high/high-Z except during deliberate reset.
9. Ordered bench-test procedure#
Stop at the first abnormal result. Record board serial, module marking/band, antenna identity, and supply identity. Confirm an antenna is connected and JP1 matches it before any command that could key the PA.
A. Unpowered inspection and resistance tests#
- Visual: module castellations, JP1 route, antenna connector/pad, passives.
- DMM: 3V3-to-GND both polarities; MISO/DIO0/DIO1 series ≈ 100 Ω; RST_N to 3V3 ≈ 10 k; confirm exactly one JP1 side bridged and the matching antenna fitted.
B. Standalone power-on and SPI identity (bench supply, 3.3 V, 300 mA)#
- Power the module; expect a few mA idle, no heating.
- With a logic analyzer or the host in a safe (RX/STDBY only) mode, read
RegVersion(0x42) and confirm 0x12. A wrong value stops the test — debug SPI/CS/reset before anything else. - Read/write a scratch register (e.g.
RegFrfMsb) to confirm write access and the address-MSB R/W convention.
C. Receive-first RF bring-up#
- With an antenna connected, put the module in continuous RX (LoRa) on the target channel. Confirm no fault, sane current (~10 mA).
- Bring up a second SX127x node (another AXC-004 is ideal for the two-node test) as the transmitter, or use a known LoRa beacon; confirm RxDone on DIO0 and a plausible RSSI/SNR on this node.
D. Transmit at minimum power (antenna connected)#
- Set the PA to its minimum output (
RegPaConfiglow output power) for first transmit — verify the TX chain before commanding +20 dBm. - Insert a current probe/shunt in the 3.3 V feed; scope it and 3V3 (at C2) during a transmit. Command a single packet; capture the current burst and the DIO0 TxDone rising edge. 3V3 must stay > 3.0 V.
- Step the PA up toward +20 dBm; record peak current (~120 mA target) and confirm the second node receives with rising RSSI. Never remove the antenna between transmits.
E. Link and interrupt characterisation#
- Two-node link: send/receive N packets, log RSSI/SNR/PER at a few spreading factors and TX powers.
- Confirm DIO1 RxTimeout fires when no packet arrives in the RX window.
- Exercise a full interrupt-driven TX→RX turnaround from gateware.
F. Host (PMOD) bring-up and robustness#
- On the FPGA PMOD host, repeat B–D through the fabric SPI; compare against a logic-analyzer tap.
- Measure PMOD 3V3 droop at the module during a TX burst before trusting long sessions.
- Duty-cycle/thermal soak within the band's regulatory limits; log any resets or output-power drift.
10. Troubleshooting map#
| Symptom | First measurements | Likely areas |
|---|---|---|
RegVersion ≠ 0x12 | SPI lines, CS_N, RST_N level | R1 open, SCK/MOSI/CS wiring, reset held, dead module |
| Reads all 0x00 or 0xFF | MISO at R1, CS_N timing | R1 open, CS_N not asserting, SPI mode wrong |
| TX "hangs", no completion | DIO0 at R2 | R2 open, DioMapping wrong, PA not keying |
| RX never times out | DIO1 at R3 | R3 open, RegDioMapping, wrong RX mode |
| Resets/truncates on TX | Shunt + 3V3 droop at C2 | Supply limit too low, C2 missing, thin rail |
| No link / terrible range | Antenna route, RSSI | JP1 wrong side, antenna unmated (PA damage risk), wrong band, detuned feed |
| PA output low/dead after a test | — | Suspect a prior transmit into an open/shorted antenna port — inspect and replace U1 if confirmed |
11. Bench record template#
| Field | Record |
|---|---|
| Board revision / serial; module marking + band | |
| Antenna type + JP1 route confirmed | |
| Supply / shunt / analyzer IDs and calibration | |
| Unpowered resistance results (9.A) | |
RegVersion read | |
| Idle / RX / TX peak current, min 3V3 | |
| DIO0 TxDone capture reference | |
| Two-node link RSSI/SNR/PER | |
| Spreading factor / bandwidth / TX power tested | |
| Regulatory band + duty-cycle observed | |
| Deviations, photos, raw-file paths | |
| Reviewer / date / disposition |
12. Review conclusion#
The schematic is small and every part earns its place: the 10 k holds RESET so POR completes, three 100 Ω resistors protect the module-driven MISO/DIO0/ DIO1 lines, and 10 µF of bulk keeps the +20 dBm PA burst from browning out the rail. The single most important operating discipline is the antenna-first rule — JP1 must select a real antenna at J2 or J3 before the PA is ever keyed, or a reflected transmit can destroy the output stage. The first bench gate is the RegVersion = 0x12 read; RF work only begins after that is stable. Open risks: no PCB exists (RF keep-out and the 50 Ω feed are layout promises), the band/duty-cycle regulatory note is an open README item, and the u.FL-vs-wire antenna choice must be verified on every built board before transmit.