In-Circuit Conflicts
practicalIn-Circuit Conflicts
In-circuit reading means the flash chip is still soldered to the board, still electrically connected to the SoC and every other component on the SPI bus. This creates problems the previous lessons didn't cover. The flash chip doesn't exist in isolation β it's part of a live system, and that system will fight you.
Why In-Circuit Reads Fail
When you clip onto a flash chip that is still connected to a running (or even powered-off-but-not-isolated) SoC, you are sharing the SPI bus with everything the SoC has connected to it.
The SoC is still connected. Even with board power off, the SoC's SPI controller I/O pins are connected to the same MOSI, MISO, SCK, and CS lines. The SoC's I/O pins, even when the core is unpowered, present impedance to the bus. In some cases, they actively pull lines to defined states through internal clamp circuits or pull resistors.
When the board is powered on: The SoC is the bus master. It controls CS, drives SCK and MOSI, and reads MISO. Your programmer also wants to be bus master. Two bus masters fighting over the same wires produce unpredictable signal levels β neither device sees valid transactions.
Symptoms of bus contention:
- flashrom hangs during the identification phase (no JEDEC ID response)
- flashrom returns a chip ID of 0xFFFFFF or 0x000000
- flashrom detects a chip but reads are unreliable (hashes differ between reads)
- Erratic reads with repeating patterns (the programmer and SoC alternating control)
- The board behaves abnormally (SoC crashes, reboots) during the read attempt
Solution 1: Hold the SoC in Reset
If the SoC has an accessible reset pin (RESET#, nRESET, or similar), holding it low keeps the CPU and peripherals in reset state. In reset, the SoC's SPI controller is inactive and its I/O pins are typically high-impedance.
How to do it:
- Find the reset pin. Check the SoC datasheet for the pin name and location. On many boards, the reset line is also connected to a reset button or an external supervisor chip.
- Power the board normally.
- Ground the reset pin (connect it to GND through a 100-470 ohm resistor to limit current β some reset pins are driven by output stages that don't tolerate hard shorts).
- With the SoC held in reset, attach the clip and run flashrom.
Limitations: - Some SoCs don't fully tri-state their I/O in reset β check the datasheet for the I/O state during reset - Some boards have external pull-up resistors on CS or other SPI lines that remain active regardless of reset state - Some reset pins are not accessible without removing components
Solution 2: Disconnect VCC to the SoC Only
If the SoC can be powered independently of the flash chip, you can cut power to the SoC while leaving the flash chip accessible.
Surgical approach:
- Trace the VCC line from the SoC's power input on the PCB. Identify whether the SoC and flash chip share a power rail or use separate rails.
- If they share a rail, look for a series resistor or ferrite bead between the SoC's VCC and the rail β this is a common EMI filter. Bridging across it or lifting one end cuts SoC power while maintaining rail voltage for the flash chip (if powered by the programmer's VCC instead).
- Power the flash chip from the programmer's VCC pin. Do not power the board.
- Read.
This is more complex than it sounds. Tracing power rails on a multi-layer board requires continuity probing and sometimes X-ray or delamination. Approach this only when simpler methods fail.
Solution 3: Clip with No Board Power (Programmer-Powered)
This works when the SoC's I/O pins are truly high-impedance with no board power applied.
Method: 1. Remove all power from the board (disconnect everything) 2. Attach the SOIC clip 3. Connect the CH341A. The programmer powers the flash chip via the VCC pin on the clip 4. Run flashrom
The flash chip receives VCC and all signals from the programmer only. The SoC's pins, with no power to the SoC, should be floating or weakly pulled by any pull resistors on the board.
Problem: Pull-up resistors remain active even without board power if they're tied to the programmer's VCC through the clip. A pull-up on CS tied to the programmer's VCC means CS never goes low β the chip never enables. You'll see "No EEPROM/flash device found."
Diagnosis: Probe CS with a multimeter after connecting the programmer but before running flashrom. CS should be at logic-high (VCC) when idle and drop to near 0V when flashrom actively selects the chip. If CS never drops, there's a pull-up holding it high that the programmer cannot overcome.
Pull-Up Resistors on CS
Many SoC SPI controllers include internal pull-ups on the CS line, or the board has an external pull-up resistor. This is by design β a floating CS could accidentally enable the chip during power-up glitches.
When pull-ups cause problems: - Programmer-powered reads: the pull-up (tied to VCC through the clip) prevents CS from going low - Some board designs use unusually strong pull-ups (1k-2.2k ohm) that the programmer's CS driver struggles to overcome
Diagnosis:
# Use a multimeter: probe CS relative to GND with programmer connected but flashrom not running
# Expected: CS at VCC (high) β this is correct, CS idles high
# Then probe while flashrom is running
# Expected: CS toggling (visible as ~VCC/2 on a multimeter due to switching, or use a logic analyzer)
# Problem: CS stays at VCC the entire time flashrom is running β pull-up winning
Fix: Identify the pull-up resistor (typically 4.7k-10k ohm, between CS and VCC somewhere on the board). Lift one leg of the resistor or cut the trace to VCC. Re-test.
The Unknown Chip Problem
Your chip is not in flashrom's database. This happens with GigaDevice parts, some Macronix variants, and newer Winbond revisions.
# flashrom detects something but can't identify it:
# "Found unknown SPI flash chip (JEDEC ID: 0xC8 0x40 0x17)"
# Try forcing with unknown
flashrom -p ch341a_spi -c unknown --force -r dump.bin
The --force flag tells flashrom to proceed even without a known chip definition. The -c unknown uses a generic read routine. Results may vary β some chips work fine, others have timing or command differences that produce garbage.
Better approach: Decode the JEDEC ID yourself.
The 3-byte JEDEC ID (returned by command 0x9F) encodes: - Byte 1: Manufacturer ID - Byte 2: Memory type - Byte 3: Capacity
0xC8 = GigaDevice
0x40 = SPI NOR Flash (standard)
0x17 = 2^23 bytes = 8 MB = 64 Mbit β GD25Q64
Look up the manufacturer ID in the JEDEC JEP106 standard. Cross-reference the capacity byte against the manufacturer's datasheet. Then find the closest equivalent in flashrom's database and force it with -c "GD25Q64B" or the matching part.
Bus Conflict Detection Summary
| Symptom | Likely Cause |
|---|---|
| flashrom hangs at probe | SoC driving SCK/MOSI, contention on bus |
Chip ID 0xFFFFFF |
MISO pulled high β no chip driving it, or contention |
Chip ID 0x000000 |
MISO pulled low β short or severe contention |
| Reads differ hash | Intermittent contention or bad clip contact |
Repeating 0xFF blocks |
VCC to chip insufficient; chip in internal reset |
| CS never toggles (multimeter) | Pull-up on CS preventing chip select |
Decision Tree
Attach clip β flashrom probe
Chip detected + hashes match?
YES β Done, proceed to L5
NO β
Hashes differ?
β Reseat clip β retry with --spispeed 512
Still failing?
β Board power off, programmer powers chip (Solution 3)
Chip not detected?
β Check CS toggling
CS stuck high? β pull-up problem, locate and lift resistor
CS toggling? β contention from SoC
Contention confirmed?
β Try reset pin hold (Solution 1)
β Or cut SoC VCC (Solution 2)