diff --git a/docs/elements/drccheck.mdx b/docs/elements/drccheck.mdx new file mode 100644 index 00000000..5ee34e04 --- /dev/null +++ b/docs/elements/drccheck.mdx @@ -0,0 +1,184 @@ +--- +title: +sidebar_position: 5.5 +description: >- + The `` element lets you add a custom design rule check that runs + against a circuit and emits circuit-json errors. +--- + +## Overview + +The `` 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. + +```tsx +import React from "react" + +export default () => ( + + + + + + + + + + + + + + + + + + + + + + + { + 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, + ], + } + } + }} + /> + +) +``` + +![Custom DRC error shown in the PCB viewer](/img/drc-check-error.png) + +*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` | 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()` diff --git a/static/img/drc-check-error.png b/static/img/drc-check-error.png new file mode 100644 index 00000000..95577a1a Binary files /dev/null and b/static/img/drc-check-error.png differ