Skip to main content
Built-in Elements

<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>
)

Custom DRC error shown in the PCB viewer

The emitted source_component_misconfigured_error appears in the viewer with the message returned from checkFn.

Props

PropTypeDescription
namestringOptional 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.

HelperDescription
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()