Bus Pirate 6 · Volume 5
Bus Pirate 6 Volume 5 — Power and Probing: PSU, Pull-ups, Voltage Measurement, Pin Discovery
0–5 V / 0–500 mA programmable supply, individually-toggleable pull-ups, per-pin ADC, the auxiliary pin AUX, frequency counter, PWM
Contents
1. About this volume
This volume covers the mode-agnostic capabilities of the BP6 — the things you can do regardless of which protocol mode is active. Power supply control, per-pin pull-up management, voltage measurement, frequency counting, PWM generation, and JTAG/SWD pin discovery via blueTag are all available from any mode (HiZ, UART, I²C, SPI, whatever) because they don’t depend on the bus protocol; they depend on the hardware around the probe pins that Vol 2 walked.
Read this volume as your discovery toolkit — the things you do when you sit down at a board you don’t yet understand. Power the target, read its rails, find its clock, identify its debug interface — all before you commit to a specific protocol mode.
2. The Programmable Power Supply (PPSU)
The BP6’s 1.0-5.0 V / 0-500 mA programmable supply is the unit’s single most useful “I’m interfacing an unknown target” feature. Most embedded targets need exactly one specific rail voltage to come alive, and getting it wrong (or absent) is the most common reason “the chip isn’t responding.”
2.1 Setting a voltage and enabling the rail
Set the voltage and enable the rail with W <voltage>:
W 3.3 set PSU to 3.3 V and enable
W 1.8 set to 1.8 V and enable
W 5 set to 5 V and enable
Decimal values are accepted; the firmware quantizes to the regulator’s actual achievable set points (roughly 100 mV steps). Voltage clamps at the 1.0-5.0 V range — W 0.5 errors, W 6 errors.
The rail is delivered to VOUT on the probe header (Pin 1, red cable). It also becomes the VCCB rail of every per-pin 74LVC1T45 level translator (Vol 2 § 4) — so when you do W 3.3, the entire BP6’s “target side” is now 3.3 V logic. Connect the VOUT red lead to the target’s positive rail (with the GND black lead to the target’s GND), and the target’s rails are now driven by the BP6.
Disable the rail with w (lowercase): output goes to 0 V, the buck regulator shuts off, and the per-pin level translators go into a state where their B-side is floating.
2.2 Reading the actual output voltage
The PSU’s output voltage isn’t always what you commanded — under load it can droop. To read it:
v— one-shot voltage read. Prints the current VOUT voltage measured at the rail.V— continuous voltage read. Prints the voltage and updates the display as it changes. Press Enter (or any character) to exit.
Use V when you’re about to connect a target and want to see what happens to the rail. If it droops below your set point, you’ve either hit the 500 mA current limit or there’s a downstream short.
2.3 Measuring target current draw
The PSU output has a 200 mΩ shunt + ×32 op-amp current sense (Vol 2 § 6.2). The VT100 status bar shows live current draw at the bottom — you don’t have to do anything to see it; it’s always there.
For an explicit numeric readout, the BP6 firmware exposes the current sense in the same v / V commands (the output line shows both voltage and current). When connecting a new target:
W 3.3— enable PSU at the target’s rail voltage.- Watch the status bar’s current readout.
- Healthy connection: current draw climbs to whatever the target normally consumes — often 5-50 mA for small MCUs at idle.
- Short: current immediately spikes to the limit (~500 mA), the rail droops to near-0, and the buck regulator goes into current-limit mode. Disconnect immediately.
- Open: current stays near 0 mA. Either you haven’t actually connected to the rail, or the target has no quiescent current path.
2.4 Failure modes and the 500 mA hard limit
The buck regulator hard-limits at 500 mA. Beyond that, the regulator enters fold-back mode — the output voltage sags to whatever maintains the 500 mA limit. The firmware monitors current and surfaces a warning on screen if current exceeds the user-configurable soft threshold (default ~400 mA, see Vol 2 § 6.4).
The BP6 will not let the PSU output overcurrent under normal circumstances. The PFET ideal-diode + hFE-matched PNP-pair back-flow protection (Vol 2 § 6.3) also prevents an external rail from back-feeding into the BP through VOUT.
This means: connecting the BP6’s VOUT to a target that’s already powered from elsewhere doesn’t blow up the BP6 — the back-flow protection holds. But it does prevent the BP6 from being able to read or control the rail’s voltage cleanly. Best practice: either the BP6 powers the target or the target powers itself, not both.
2.5 Sanity-checking before you connect a target
Before clipping probes onto an unknown board:
- Disable the BP6 PSU (
wif it’s on). - Connect just GND (black lead) first. This establishes a common ground.
- Read the target’s rail voltage by probing it with a single IO pin — see § 4.2 below.
- Decide whether the BP6 should provide the rail (target is powered-off and you want to drive it) or not (target is powered and you just want to talk to it).
- If powering:
W <target_voltage>and clip VOUT to the target’s V+. - If not powering: leave PSU off. The per-pin level translators will track whatever voltage the target itself puts on the probe pins (VCCB floats with the target’s rail).
This is the disciplined sequence. Skipping it works fine on familiar boards and bites you on unfamiliar ones.
3. Pull-ups
The 10 kΩ pull-ups on each IO pin (Vol 2 § 4.2-4.3) are essential for some protocols, useless for others, and harmful for none. Default state: off.
3.1 Per-pin enable / disable from the prompt
Top-level commands (Vol 4 § 2.6):
P— enable pull-ups on the pins currently assigned by the active mode.p— disable pull-ups globally.
The mode decides which pins should have pull-ups. For I²C, that’s both SDA and SCL. For 1-Wire, just the data line. For UART, neither. For SPI, neither (the CS pin is sometimes pulled up but the BP6 firmware drives it explicitly, no pull-up needed).
For per-pin granularity beyond what the mode picks, drop into the mode’s setup wizard (m → re-enter mode → answer the prompts) and choose pull-ups during the wizard. This isn’t a one-key shortcut.
3.2 When you need them (I²C, 1-Wire) and when you don’t (SPI, UART)
| Protocol | Pull-ups? | Why |
|---|---|---|
| I²C | Yes | Open-drain bus — both SDA and SCL are pulled high by external resistance when no driver is active. Without pull-ups, the lines float and the protocol breaks. |
| 1-Wire | Yes | Same open-drain model on a single data line. The parasite-power mode also relies on the pull-up. |
| 2-Wire (SLE4442 smart card) | Yes | Open-drain, like I²C. |
| 3-Wire (Microwire) | Optional | Some 93-series EEPROMs work with active push-pull; pull-up is a safety. |
| SPI | No | Push-pull bus; the BP6 drives MOSI / SCK / CS actively. MISO is driven by the target. No pull-up needed. |
| UART | No | Idle state is held by the line driver. Pull-ups would actively interfere with the framing. |
| JTAG / SWD | No | Driven actively. (External pulldowns on the target may be needed — see § 7.6.) |
| HDUART | Maybe | LIN / K-Line are open-collector on the target side; some targets have their own pull-up, some need the BP6’s. |
| IR | No | The carrier modulation drives actively. |
| LED | No | The WS2812/SK6812 chain has its own protocol; pull-ups don’t apply. |
| I²S | No | Synchronous push-pull. |
When in doubt, let the mode’s setup wizard pick. The firmware author knew what each mode needs.
3.3 Pull-up value vs target capacitance
The 10 kΩ pull-up is a compromise. Too weak (say, 50 kΩ) and the rising edge is too slow for fast I²C (above 400 kHz) on a heavily-loaded bus. Too strong (say, 1 kΩ) and you waste power and may exceed the target’s drive capability.
10 kΩ at 3.3 V across typical 10-100 pF of bus capacitance gives a τ ~ 0.1-1 µs rise time. Adequate for standard-mode I²C (100 kHz), fine for fast-mode (400 kHz), marginal for fast-mode-plus (1 MHz). If you’re working with 1 MHz I²C and seeing weird ACK / NACK issues, add external 2.2-4.7 kΩ pull-ups on the bus and disable the BP6’s internal ones (the math is “parallel resistance”; you don’t want both fighting).
For most workflows you ignore this. It only surfaces when you’re at the speed edge.
4. Per-pin voltage measurement
Every probe pin can be voltage-read via the CD4067 mux (Vol 2 § 7). This is the BP6’s “what’s actually on this wire?” feature.
4.1 The v snapshot vs V continuous read
Two commands:
v— single voltage snapshot, all pins (or the relevant ones for the current mode). Prints once and returns to prompt.V— continuous voltage display. The terminal scrolls live voltage values; Ctrl-C or Enter exits.
These commands span both VOUT and IO0-IO7 in one shot — you see PSU voltage and every probe-pin voltage on one display.
4.2 Reading rail voltage on an unknown board
Workflow for “what voltage is this rail?”:
- BP6 PSU disabled (
w). - Connect IO0 to the unknown rail; connect GND to the board’s GND.
vat the prompt. Read the IO0 voltage from the output.- Now you know the target’s rail voltage. Configure the PSU accordingly (
Wto match) or just leave it disabled and read at the target’s voltage.
Range: 0-6.6 V (Vol 2 § 7.2). Above that, the input clamp diodes engage and the per-pin 120 Ω series resistor takes the brunt — you can over-volt by a few volts without damage, but don’t make a habit of it.
Resolution: roughly 1.6 mV per ADC count. Plenty to tell 1.8 V from 3.3 V from 5 V.
4.3 Per-pin reads in the status bar (it’s already happening)
The VT100 status bar (Vol 4 § 7.1) and the LCD mirror (Vol 4 § 8) show live per-pin voltage at ~10 Hz without you having to ask. When you’re in any mode with probes connected, the status line shows what each pin is reading.
This is the way most BP6 voltage measurement happens: ambient. You don’t run v to read a pin; you glance at the status bar.
V (continuous) is useful when you want full-precision streaming readout (the status bar is rounded for display); v (snapshot) is useful in scripts where you want the exact value captured to a log.
5. The frequency counter
A PIO-based frequency counter on the AUX pin (or any IO pin, configurable). Counts edges over a known interval.
5.1 f one-shot vs F continuous
f— one-shot frequency measurement. Prints once.F— continuous measurement, updating display.
Both prompt for the input pin if it isn’t already configured. The frequency counter consumes one PIO state machine (Vol 3 § 6.3) while running; turn it off when done so it’s available for other PIO needs.
5.2 Practical range and accuracy
| Range | Accuracy | Notes |
|---|---|---|
| < 100 Hz | ±1 Hz | Long sample window needed; slow to settle. |
| 100 Hz - 10 kHz | ±0.5% | Decent for hobby use. |
| 10 kHz - 1 MHz | ±0.1% | Typical sweet spot. |
| 1 MHz - 100 MHz | ±1% | The BP6 PIO clock is 150 MHz; counter saturates approaching that. |
| > 100 MHz | Don’t trust | Aliasing and edge-rate limitations. |
Better-than-1% accuracy across most of the range is enough for “is this clock around 32.768 kHz, 16 MHz, or 25 MHz?” identification, which is the main use case.
5.3 Worked example: identifying an unknown clock
Unknown 8-pin SOIC chip on a target board has a pin that looks like it might be the crystal feedback. You want to know its frequency.
- Connect IO4 to the suspect pin, GND to board GND.
- PSU off; target powered from its own supply.
f— read the frequency one-shot.- Reads, say,
8.0001 MHz. That’s almost certainly an 8 MHz crystal.
Or it reads 32.768 kHz — the watch-crystal frequency. Or 48.000 MHz — a common USB-clock value. Or 25 MHz — common Ethernet PHY clock.
These quick identifications save real time when reverse-engineering unknown boards.
6. PWM generation
The BP6 can output a PWM signal on the AUX pin (or any IO pin, configurable).
6.1 g to start, G to stop
g— start PWM. Prompts for output pin, frequency, and duty cycle.G— stop PWM.
Once started, the PWM runs autonomously (PIO-driven, no CPU load) until you G. It keeps running across mode changes, so you can configure a PWM in HiZ mode and then enter I²C mode to talk to a device that needs the PWM as a clock source.
6.2 Frequency and duty cycle ranges
- Frequency: roughly 1 Hz to 150 kHz (PIO-derived; finer resolution at lower frequencies). Higher frequencies are possible but resolution degrades.
- Duty cycle: 0-100% in 1% steps.
The output is a sharp-edged digital signal — clean square wave from the 1T45 buffer at whatever VCCB is currently set. For analog control, this needs an external RC filter to integrate.
6.3 Use cases (clock injection, motor control, LED dim)
- Clock injection: drive a target’s CLK input when it doesn’t have its own oscillator. Useful for bringing up bare MCUs without a crystal.
- Motor control: 1-10 kHz PWM into a transistor or motor driver. Vary duty cycle to vary speed.
- LED dimming: 100-1000 Hz PWM through a current-limiting resistor.
- Tone generation: audio-frequency PWM into a piezo for “did the board respond?” beeps.
This is one of those “rarely used but invaluable when you need it” features. The BP6’s PWM is part of why it’s a one-tool-on-the-bench answer for so many bring-up tasks.
7. Pin discovery — the bluetag JTAG/SWD pin-finder
The most powerful BP6 feature for unknown-board recon. bluetag is a command in JTAG mode that scans up to 8 pins, identifying which subset (if any) forms a working JTAG TAP or SWD interface — and reads back the chip’s IDCODE.
7.1 Why pin-find matters
When you sit down at an unfamiliar board, you can usually find a debug header — 4, 6, 8, or 10 pins in a row, sometimes with silkscreen labels but often not. Even when there are labels, vendor pinouts vary: STM32’s SWD is on one set of pins, NXP’s on different ones, Espressif’s on different again. And the de-facto JTAG order (TCK, TDI, TDO, TMS) can be silkscreened in any rotation.
Manual pin-find is tedious: clip onto an unknown pin combination, configure OpenOCD or your debugger to expect that combination, try to read IDCODE, get garbage, try another combination, repeat. Eight unknown pins is 8! = 40,320 possible orderings if you’re being thorough. Even narrowing to the right 4-of-8 is C(8,4) × 4! = 1680 trials.
bluetag automates this. The BP6 tries every plausible pin combination, looks for a JTAG-or-SWD response, and reports which combination worked.
7.2 What blueTag actually does
The algorithm:
- Drive a known TAP-reset sequence out one candidate pin (treating it as TCK), with another candidate pin (treating it as TMS) held in the appropriate state.
- Sample the response on a third candidate pin (treating it as TDO).
- If a recognizable TAP state machine responds (the IR length is non-zero, IDCODE returns a non-0xFF / non-0x00 value), record the candidate combination.
- Iterate through enough combinations to find the working one.
- For SWD: try driving SWCLK + SWDIO on candidate pairs and listen for a valid DPIDR response.
The BP6 firmware (commands/jtag/bluetag.c, derived from Aedan Cullen’s original blueTag project) prunes the search space using heuristics — pins held permanently low or permanently high during initial sampling are skipped as obvious non-candidates, drastically reducing the brute-force count.
Total scan time on 8 pins: typically 5-30 seconds to find a working JTAG/SWD interface. Faster on boards where the interface is clean; slower on noisy boards.
7.3 Running bluetag — the procedure
- Enter JTAG mode:
m→ select JTAG → answer the setup wizard (or accept defaults). - Connect probes IO0-IO7 to the candidate pins on the target board. Skip pins you’re confident aren’t debug (power rails, GPIO-with-LED, etc.).
- Connect GND to the board’s GND.
- Target must be powered — either by the BP6 PSU (
W 3.3or whatever the target needs) or by its own supply. - At the JTAG prompt, type
bluetagand press Enter. - Wait. The LCD and status bar update as the scan progresses.
7.4 Reading the output: IDCODE, TAP states, candidate maps
A successful scan output looks like:
bluetag scan complete
JTAG interface found:
TCK = IO3
TMS = IO5
TDI = IO2
TDO = IO4
TRST = (not found, optional)
IR length: 4
IDCODE: 0x3BA02477
Vendor: ARM Ltd.
Part: Cortex-M3
Revision: 3
TAP state: RUN-TEST-IDLE (idle)
The IDCODE decode (vendor / part / revision) comes from the firmware’s built-in IDCODE database — a list of known vendor codes that translates the raw 32-bit IDCODE into a human-readable chip identification. The database covers common ARM Cortex-M parts, common MIPS / RISC-V / Xtensa cores, and many SoCs that ship with embedded JTAG.
If bluetag finds SWD instead of JTAG:
bluetag scan complete
SWD interface found:
SWCLK = IO3
SWDIO = IO5
DPIDR: 0x2BA01477
Vendor: ARM Ltd.
Part: Cortex-M4 + FPU
If bluetag finds nothing:
bluetag scan complete
No JTAG or SWD interface found on IO0-IO7.
Possible causes:
- Target not powered (check VOUT)
- Pull-down resistors needed on candidate pins (see Vol 5 § 7.6)
- Pins are debug-locked / fuse-disabled on the target chip
- Pins are not actually JTAG/SWD on this board
7.5 The handoff to OpenOCD
Once bluetag has identified the pinout, the BP6’s JTAG mode can act as an OpenOCD bridge — i.e., OpenOCD on the host talks JTAG via the BP6 to the target chip.
The bridge command (commands/jtag/openocd.c) puts the BP6 into a special mode where it speaks the OpenOCD buspirate interface protocol over USB-CDC. OpenOCD configuration on the host:
# openocd.cfg
adapter driver buspirate
buspirate port /dev/ttyUSB0 # or COMN on Windows
buspirate speed normal
buspirate vreg 1 # enable VREG (PSU)
buspirate mode normal
buspirate pullup 1 # not usually needed for JTAG
Then OpenOCD finds the BP6, the BP6 relays commands to the target’s JTAG TAP, and OpenOCD does the rest — flash programming, register inspection, breakpoint insertion, the whole debugger workflow.
This is the BP6’s “I’m a JTAG adapter” mode. The bit-banging is slow (Vol 3 § 5.3 — JTAG is C-loop-bit-banged, not PIO) so flash programming is much slower than a dedicated J-Link or Black Magic Probe. But for occasional debug sessions on rarely-debugged targets, it’s plenty.
7.6 When blueTag fails: errata E9 and external pulldowns
The RP2350 errata E9 (Vol 2 § 2.4) causes the internal pulldowns to behave more like bus-keepers than strong ground biases. The BP6 mitigates this with 100 kΩ external pulldowns on each IO pin, but some JTAG/SWD targets expect stronger pulldowns (10 kΩ class) on SWDIO / TDI to distinguish “no chip there” from “chip is there and floating SWDIO”.
If bluetag returns “no interface found” on a board where you’re confident there’s a chip with debug pins:
- Try a stronger external pulldown. Wire a 4.7-10 kΩ resistor from the suspect SWDIO/TDI pin to GND on a separate probe wire (don’t put it through the BP6 — just an external resistor on the breadboard).
- Re-run
bluetag. - If still nothing, the pins may not be debug at all, or the chip’s debug interface may be fuse-disabled (some production chips lock JTAG / SWD with a one-time fuse). The chip is intentionally un-debuggable in that case.
The vast majority of bluetag runs work first time. The edge cases above account for the rare “I know it’s there but it isn’t seeing it” symptom.
8. The AUX pin (BP6’s spare GPIO)
The BP6 has one auxiliary I/O pin on the AUX header (separate from IO0-IO7). It’s a single-bit GPIO that exists outside the protocol modes — useful for “I need one more signal” cases.
Commands (Vol 4 § 2.7):
A— drive AUX pin higha— drive AUX pin low@— read AUX pin
The AUX pin can also be configured as the frequency counter input (§ 5) or the PWM output (§ 6) — those features use it by default. When neither is active, AUX is a plain GPIO under A/a/@ control.
Use cases:
- Oscilloscope trigger: drive AUX low for the duration of a long transaction, scope-triggers on the falling edge.
- External-event sync: read AUX (
@) before/after a transaction to capture timing relative to some target event. - Enable line: drive a target’s chip-enable separately from the bus pins.
The AUX pin uses one of the BP6’s free RP2350B GPIOs and has its own level translator (not one of the IO0-IO7 chain). It’s 3.3 V output only; not VCCB-tracking like the main probe pins. Take that into account when interfacing — a 1.8 V or 5 V target may need an external level shifter for AUX-driven signals.
9. Operational hygiene
The patterns that distinguish “I always have working sessions” from “I sometimes brick targets.”
9.1 Always start in HiZ
The BP6’s default boot mode is HiZ — all outputs disabled, all level translators in high-impedance, no PSU, no pull-ups. This is the safe state.
After boot, don’t change mode until you’ve configured the target side (target voltage known, probe connections planned). Switching from HiZ to a mode that drives 8 pins at 3.3 V into an unknown target is how chips die.
If you’re returning to a board mid-session and want to be sure you’re safe: m → HiZ. Probe re-checks the rails. Then re-enter the working mode.
9.2 Configure mode and pins before connecting
The mode entry wizard (Vol 4 § 2.2) asks for:
- Mode-specific config (baud rate, I²C speed, SPI mode/CPOL/CPHA, etc.)
- Pin assignments (which IO is SDA, which is SCL, etc.)
- Whether to enable pull-ups
Answer all of these before clipping probes to the target. Mid-transaction reconfiguration is when accidents happen.
9.3 Voltage-check the target before driving
Before enabling the PSU at 3.3 V on a target you think is 3.3 V:
- Connect just GND.
- Connect IO0 to one of the target’s rails.
v— read the rail voltage.- Set PSU to match.
This 30-second sanity check has caught many “wait, it’s actually a 1.8 V part” mistakes.
9.4 Disconnect between mode changes
When changing modes (I²C → SPI, for example), the pin assignments change. IO5 might have been SCL; now it’s MISO. The target sees the same probe but with different signaling.
Disconnect probes (or go to HiZ first) when changing modes if the target is still powered. This avoids transient signals as the BP6 reconfigures its drivers.
9.5 The shutdown sequence
End-of-session:
- Stop the protocol — any active transaction completes; the bus goes idle.
- Disable PWM, frequency counter —
G, exitFif running. - Disable PSU —
w(lowercase). - Mode → HiZ —
m→ HiZ. - Disconnect probes from the target.
- Then unplug the USB-C from the BP6, if you’re packing up.
Going in the wrong order (disconnect USB → probes still on target with mode active → PSU sags as the BP6 loses USB power) can put weird transient signals on the target. Habits in this order, like any bench discipline, prevent half the symptoms you’d otherwise spend time debugging.
10. Cheatsheet updates for Vol 12
Items from this volume that belong on the laminate cheatsheet:
- PSU:
W <V>to set+enable;wto disable; range 1.0-5.0 V; 500 mA hard limit. - Voltage measurement:
vsnapshot,Vcontinuous; 0-6.6 V range; status bar shows live values. - Pull-ups:
Penable,pdisable; needed for I²C / 1-Wire / 2-Wire; off for SPI / UART / JTAG / SWD. - Frequency counter:
fone-shot,Fcontinuous; useful range 100 Hz - 100 MHz. - PWM:
gstart,Gstop; range 1 Hz - 150 kHz, 0-100% duty. - AUX pin:
Ahigh,alow,@read; also configurable as freq-in or PWM-out. bluetagrecipe:- Enter JTAG mode (
m→ JTAG) - Connect probes IO0-IO7 to candidate pins
- Power target (
Wor external) - Type
bluetag - Read IDCODE from output
- Hand off to OpenOCD with the discovered pinout
- Enter JTAG mode (
- Shutdown sequence: stop protocol → disable PWM/freq →
wPSU →mHiZ → disconnect probes → unplug.
End of Volume 5. Volume 6 picks up with the four daily-driver protocols — UART, HDUART, I²C, SPI — and their core workflows (baud hunt, listen-mode HDUART, I²C scan + EEPROM, SPI flash dump).