<drccheck />
Overview
The <drccheck /> element lets you add a custom design rule check close to the
components it applies to. Use it for project-specific rules that tscircuit does
not check automatically, such as "these two I2C devices must not share the same
address."
A custom DRC uses a checkFn. The function can return:
- a single circuit-json error object
- an array of circuit-json error objects
undefined,null, or nothing when the rule passes
TMP117MAIDRVR I2C Address Conflict
This example detects two TMP117MAIDRVR temperature sensors on the same I2C bus
with the same address configuration. Both sensors have ADD0 pulled down
through a 10k resistor, and both share SDA and SCL, so they would respond at
the same I2C address.
import React from "react"
export default () => (
<board width="35mm" height="22mm" routingDisabled>
<chip
name="U1"
footprint="sot23_6"
manufacturerPartNumber="TMP117MAIDRVR"
pinLabels={{
pin1: "SCL",
pin2: "GND",
pin3: "ALERT",
pin4: "ADD0",
pin5: "VCC",
pin6: "SDA",
}}
pcbX={-8}
pcbY={0}
/>
<chip
name="U2"
footprint="sot23_6"
manufacturerPartNumber="TMP117MAIDRVR"
pinLabels={{
pin1: "SCL",
pin2: "GND",
pin3: "ALERT",
pin4: "ADD0",
pin5: "VCC",
pin6: "SDA",
}}
pcbX={8}
pcbY={0}
/>
<resistor
name="R_ADD0_U1"
resistance="10k"
footprint="0402"
pcbX={-8}
pcbY={-8}
/>
<resistor
name="R_ADD0_U2"
resistance="10k"
footprint="0402"
pcbX={8}
pcbY={-8}
/>
<trace from=".U1 > .VCC" to="net.VCC" />
<trace from=".U2 > .VCC" to="net.VCC" />
<trace from=".U1 > .GND" to="net.GND" />
<trace from=".U2 > .GND" to="net.GND" />
<trace from=".U1 > .SDA" to="net.SDA" />
<trace from=".U2 > .SDA" to="net.SDA" />
<trace from=".U1 > .SCL" to="net.SCL" />
<trace from=".U2 > .SCL" to="net.SCL" />
<trace from=".U1 > .ADD0" to=".R_ADD0_U1 > .pin1" />
<trace from=".R_ADD0_U1 > .pin2" to="net.GND" />
<trace from=".U2 > .ADD0" to=".R_ADD0_U2 > .pin1" />
<trace from=".R_ADD0_U2 > .pin2" to="net.GND" />
<drccheck
name="tmp117maidrvr-i2c-address-conflict"
checkFn={({ selectAll, isConnected, isPulledDown }) => {
const chips = selectAll("chip[manufacturerPartNumber='TMP117MAIDRVR']")
const [chipA, chipB] = chips
if (!chipA || !chipB) return
const aSda = chipA.getPort("SDA")
const bSda = chipB.getPort("SDA")
const aScl = chipA.getPort("SCL")
const bScl = chipB.getPort("SCL")
const aAdd0 = chipA.getPort("ADD0")
const bAdd0 = chipB.getPort("ADD0")
if (!aSda || !bSda || !aScl || !bScl || !aAdd0 || !bAdd0) return
if (
isConnected(aSda, bSda) &&
isConnected(aScl, bScl) &&
isPulledDown(aAdd0) &&
isPulledDown(bAdd0)
) {
return {
error_type: "source_component_misconfigured_error",
message: "Two TMP117MAIDRVR chips share the same I2C address",
source_component_ids: [
chipA.getSourceComponent()!.source_component_id,
chipB.getSourceComponent()!.source_component_id,
],
source_port_ids: [
aSda.getSourcePort()!.source_port_id,
bSda.getSourcePort()!.source_port_id,
aScl.getSourcePort()!.source_port_id,
bScl.getSourcePort()!.source_port_id,
aAdd0.getSourcePort()!.source_port_id,
bAdd0.getSourcePort()!.source_port_id,
],
}
}
}}
/>
</board>
)

The emitted source_component_misconfigured_error appears in the viewer with
the message returned from checkFn.
Props
| Prop | Type | Description |
|---|---|---|
name | string | Optional name for the DRC rule. Use a stable, descriptive name such as "tmp117maidrvr-i2c-address-conflict". |
checkFn | (ctx) => error | error[] | void | Promise<error | error[] | void> | Function that runs after the circuit renders. Return circuit-json errors when the rule fails. |
Check Function Context
The checkFn receives helpers for selecting elements and checking connectivity.
| Helper | Description |
|---|---|
select(selector) | Select one component, port, or net using familiar tscircuit selectors such as "U1.ADD0" or "net.GND". |
selectAll(selector) | Select multiple components, ports, or nets. |
isConnected(a, b) | Returns true when two selected items share connectivity. |
isPulledUp(a) | Returns true when the item is connected or resistor-connected to net.VCC or net.VDD. |
isPulledDown(a) | Returns true when the item is connected or resistor-connected to net.GND. |
getResistanceBetween(a, b) | Returns 0 for a direct connection, a resistance value for a resistor path, or null when no resistor-only path is found. |
Selection Results
select and selectAll return small wrapper objects instead of raw
circuit-json. This lets the check function stay close to normal tscircuit
concepts.
Component selections support:
getPort(name)getPorts()getSourceComponent()getPcbComponent()
Port selections support:
getSourcePort()getPcbPort()
Net selections support:
getSourceNet()