Skip to content
binho.io (opens in a new tab)Contact Us

Target Voltage (VTARG)

The target voltage (VTARG) pin on each port sets the logic level of the bus. It works in one of two ways:

  • The adapter powers the target. The adapter drives VTARG at the set voltage, and the target runs from it.
  • The target powers itself. The adapter stops driving VTARG, reads the target’s own supply on that pin, and matches its logic levels to it.

Never let both happen at once. Two supplies on one rail is how a target gets damaged. This page shows how to pick the right mode, what changes across firmware versions, and how to recover when something looks wrong.

Each adjustable rail is a 500 mA LDO whose output voltage is set by a DAC, followed by a load switch to the VTARG pin. Setting 0 V opens the switch. The adapter measures VTARG on the connector side of that switch, so a reading shows whatever is on the pin, whoever supplies it.

AdapterPortRailVoltage rangeOutput current (recommended max)Saved across power cycles
SupernovaMultifunction + Dedicated I2C (I2C, SPI, UART, GPIO)Multifunction1.2–3.3 V200 mAYes, optional
SupernovaI3C High-VoltageI3C HV1.2–3.3 V200 mANo
SupernovaI3C Low-VoltageI3C LV0.8–1.2 V350 mANo
PulsarMultifunction + Dedicated I2C (I2C, SPI, UART, GPIO)Multifunction1.2–3.3 V200 mAYes, optional
PulsarRS-485 + CAN-FDDifferentialFixed 5 V, not configurable200 mANot applicable

Sources: Supernova datasheet rev 1.6 and Pulsar datasheet rev 1.3, Recommended Operating Conditions.

  • The multifunction rail is shared. I2C, SPI, UART and GPIO all use it. Setting the voltage from any of them moves all four.
  • The two I3C ports are exclusive. When the HV port is in use, the LV port is not available, and the reverse.
  • I3C voltage is never saved. The I3C rails are set by DACs with no memory, so the I3C ports start unpowered every time the adapter starts. Set the I3C voltage in every session.
  • Pulsar’s 1-Wire port (Nova compatibility mode, firmware 4.4.0 and later) runs at 3.3 V or 5 V, independent of the multifunction rail.

Absolute maximum ratings (Supernova datasheet rev 1.6, Pulsar datasheet rev 1.3): 4.2 V on VTARG and any signal pin of the multifunction ports, on both adapters (the Pulsar 1-Wire pin: 5.5 V). Supernova only: on the I3C HV port, 5.5 V on the power input (VTARG) and 3.6 V on SCL and SDA; 2.5 V on the I3C LV port, power input and signal pins. An external supply above the operating range is not refused by the adapter, so keep it within the ranges in the table.

TargetUsePyCosmicSDK call
Has no supply of its ownThe adapter powers itset_voltage(voltage_mv)
Has its own supply, battery or bench supplyThe target powers itselfuse_external_voltage()
Is powered by another Binho adapter on the same busOne adapter powers, the other uses externalset_voltage on one, use_external_voltage on the other

The calls exist on each interface that owns a rail:

InterfaceSetUse the target’s supplyRead
dev.i2c()set_voltage(voltage_mv, persist=False)use_external_voltage(persist=False)get_bus_voltage() → mV
dev.spi()set_voltage(voltage_mv, persist=False)use_external_voltage(persist=False)get_bus_voltage() → mV
dev.uart()set_voltage(voltage_mv, persist=False)use_external_voltage(persist=False)get_bus_voltage() → mV
dev.gpio()set_voltage(voltage_mv, persist=False)use_external_voltage(persist=False)get_voltage() → mV
dev.i3c() (Supernova)set_voltage(voltage_mv)use_external_voltage(persist=False)get_bus_voltage() → (hv_mv, lv_mv)

The four multifunction readers return the same number: they all read the one shared rail. For I3C, the voltage selects the port: 800–1199 mV drives the LV port, 1200–3300 mV the HV port. 0 switches the rail off on any interface.

Full reference: PyCosmicSDK I2C guide, I3C guide, GPIO guide.

  1. Disconnect the target, or make sure its own supply is off.
  2. Set the voltage, then read it back.
  3. Configure the bus and start talking.
from pycosmicsdk import Device, I2cPullUp
with Device.open() as dev:
i2c = dev.i2c()
i2c.set_voltage(1800) # 1.8 V on the shared rail
print("VTARG:", i2c.get_bus_voltage(), "mV") # expect about 1800
i2c.initialize(400_000, I2cPullUp.KOHM_2_2)
print("Found:", sorted(i2c.scan().addresses_7bit))

If the reading does not match the voltage set, stop. Another source is on the rail: see Troubleshooting.

  1. Power the target from its own supply.
  2. Call use_external_voltage() before any set_voltage. Never call set_voltage on this port.
  3. Read the voltage the adapter measured. It should match the target’s supply.
from pycosmicsdk import Device, I2cPullUp
with Device.open() as dev:
i2c = dev.i2c()
i2c.use_external_voltage() # adapter stops driving VTARG
print("Target supply:", i2c.get_bus_voltage(), "mV")
i2c.initialize(400_000, I2cPullUp.KOHM_2_2)

For I3C on the Supernova, exactly one I3C port must be powered by the target when dev.i3c().use_external_voltage() is called. With neither powered the adapter answers FW_I3C_PORTS_NOT_POWERED (0x0104); with both, FW_BOTH_I3C_PORTS_POWERED (0x0105).

Handle a Self-Powered Target on Firmware 4.7.0 and Later (Coming Soon)

Section titled “Handle a Self-Powered Target on Firmware 4.7.0 and Later (Coming Soon)”

From firmware 4.7.0, the adapter measures the port before it powers it. If the pin already reads above 500 mV with the adapter’s switch open, the set is refused with FW_EXTERNAL_VOLTAGE_DETECTED (0x0102) and VTARG stays off. A refused persist=True set stores nothing. This applies to the multifunction rail on both adapters and to both I3C ports.

Scripts that used to set a voltage over a self-powered target now get this error. Catch it and switch to the target’s supply:

from pycosmicsdk import Device, StatusCode, SystemFirmwareError
with Device.open() as dev:
i2c = dev.i2c()
try:
i2c.set_voltage(3300)
except SystemFirmwareError as exc:
if exc.status_code is not StatusCode.FW_EXTERNAL_VOLTAGE_DETECTED:
raise
i2c.use_external_voltage() # the target already powers VTARG
print("VTARG:", i2c.get_bus_voltage(), "mV")

Setting 0 V and then the working voltage again power-cycles a target that the adapter powers. Use it to recover a peripheral that holds SDA low.

i2c.set_voltage(0)
i2c.set_voltage(3300)

This works only when nothing else drives the rail. On a bench with two adapters sharing the rail, call use_external_voltage() on the other adapter first, then read the rail back.

set_voltage(voltage_mv, persist=True) on the multifunction rail stores the voltage in the adapter. The adapter then powers the target as soon as it gets USB power, before any software connects. Use it for a target that must come up on its own.

  • Only the multifunction rail can be saved. I3C cannot.
  • use_external_voltage(persist=True) stores the voltage measured at that moment, not “external”. After a power cycle the rail state is not defined; do not use this with a self-powered target.
  • To stop powering the target at startup, call set_voltage(0, persist=True).

Firmware 4.7.0 and later

After a reboot, a firmware update or a DFU, the rail comes up at the saved voltage. If a target supply is present on the pin at startup, the adapter leaves VTARG off.

Firmware 4.6.x and earlier

Until the update:

  • Disconnect the target before rebooting the adapter or updating its firmware.
  • Unplug and replug USB instead of a software reboot. A full power cycle loads the saved voltage correctly.
  • Or save the voltage actually wanted before rebooting, so the saved and current values match.
FirmwareSPI, UART, GPIO pins at 0 VI2C pull-ups at 0 V
4.5.1 and earlierKeep driving. A GPIO output or an idle chip select at 3.3 V can power an unpowered target through its I/O.Stay powered
4.6.xStop driving. They come back with the configuration when the rail returns.Stay powered
4.7.0 and laterStop drivingDisconnected while the rail is off, restored when it returns

I2C pull-ups on 4.6.x and earlier: with the rail at 0 V, the adapter’s I2C pull-ups stay powered and feed an unpowered target through SDA and SCL. The target’s supply pin then lifts VTARG. Measured on a Supernova with a sensor board on the I2C port, rail off: 645 mV with 2.2 kΩ pull-ups, 1089 mV with 470 Ω, 1496 mV with 150 Ω, 1 mV with pull-ups disabled. Before switching the rail off, either disconnect the target or disable the pull-ups:

i2c.set_pull_up(I2cPullUp.DISABLE) # needs dev.capabilities.i2c_runtime_reconfigurable
i2c.set_voltage(0)

On 4.5.1 and earlier, also return GPIO outputs to inputs before switching the rail off.

Mission Control 3 sets the target voltage when a tool connects.

  1. Choose the voltage before clicking Connect. The SPI, GPIO and Serial Terminal tools show a Voltage setting; the I3C tool has a VOLTAGE field with presets and a Set button.
  2. The multifunction rail is shared: a voltage set in the SPI tool also applies to I2C, UART and GPIO on the same adapter.
  3. With a self-powered target:
    • In the I3C tool, use Switch to external bus voltage.
    • On firmware 4.7.0 and later, if the target already powers the pin, the adapter refuses the voltage and Mission Control 3 reports bus voltage was not applied: an external supply on VTARG defines the rail. The tool keeps working on the target’s supply.
    • On firmware 4.6.x and earlier, Mission Control 3 connects the adapter’s supply to the pin. Update the firmware first. See Updating Firmware.
SymptomCauseFix
The target gets about 3.3 V after a reboot, firmware update or DFUFirmware 4.6.x and earlier, with a saved voltage and a different unsaved value set laterUpdate to 4.7.0. Until then, disconnect the target before rebooting or updating, or replug USB instead.
A self-powered target is pulled toward the adapter’s voltageFirmware 4.6.x and earlier: a voltage set connected both suppliesDisconnect, then use use_external_voltage() and never set_voltage on that port. Update to 4.7.0.
set_voltage raises SystemFirmwareError with FW_EXTERNAL_VOLTAGE_DETECTED (0x0102)Firmware 4.7.0 and later found more than 500 mV on the pin: the target, or a second adapter, already powers itCall use_external_voltage(). If the target should be unpowered, find what powers the pin: its own supply, a second adapter, or a USB cable to the target.
set_voltage succeeds but get_bus_voltage() does not changeAnother source on the rail: a powered target or a second adapter. The adapter’s regulator sources current but does not sink it, so the other source wins.Turn the other source off, or hand it over with use_external_voltage() on the other adapter. Firmware 4.7.0 reports this as 0x0102.
VTARG reads several hundred mV to 1.5 V with the rail at 0 VFirmware 4.6.x and earlier: I2C pull-ups feeding an unpowered targetDisable the pull-ups or disconnect the target before switching off. Update to 4.7.0.
An unpowered target stays partly alive with the rail at 0 VFirmware 4.5.1 and earlier: SPI, UART or GPIO pins still drivingReturn outputs to inputs first, or update to 4.6.0 or later.
set_voltage raises FW_VOLTAGE_OUT_OF_RANGE (0x0101)Value outside the port’s rangeUse 0 or 1200–3300 mV on the multifunction rail; 0 or 800–3300 mV on I3C.
dev.i3c().use_external_voltage() raises 0x0104 or 0x0105No I3C port, or both, powered by the targetPower exactly one I3C port from the target.
The I3C port is unpowered after replugging the adapterI3C voltage is never savedSet the I3C voltage again in each session.
A peripheral holds SDA low and the bus stays stuckThe peripheral is hungIf the adapter powers it, power-cycle it with set_voltage(0) and back.

Still stuck? Send the adapter’s serial number, firmware version, the calls made and the voltages read to [email protected]. See Adapter Stops Responding for how to collect them.