{
  "family": "Drive",
  "name": "DC.H",
  "rev": "a",
  "tile_id": 14,
  "json_version": "0.14",
  "updated_at": "2026-06-21T18:27:33.093Z",
  "headline": "11V/2A H-bridge DC-motor driver",
  "description": "The Drive.DC.I is a single-channel H-bridge motor driver built around the DRV8214. It can deliver up to 4 A peak (2 A RMS continuous) and operates from a 1.65 V to 11 V supply, making it suitable for a wide range of small brushed DC motors in robotics, haptics, and actuation applications.\n\nThe DRV8214 features sensorless ripple counting, which tracks motor commutation ripples in the current waveform to determine relative position and speed — eliminating the need for external encoders. Integrated speed regulation maintains constant motor speed across varying supply voltages, while voltage regulation allows driving the motor at a programmable lower terminal voltage to save energy.\n\nMotor speed can be controlled via either PWM at frequencies up to 200 kHz or via the I2C interface, which is also used for register-based configuration and diagnostics, including soft-start/stop, stall detection, and various limits.",
  "application_notes": [
    {
      "sort": 0,
      "details": "Integrated current sensing via an internal current mirror provides an analog output (NPROP) proportional to load current, with selectable gain for accurate sensing down to 10 mA. Current regulation limits motor current autonomously during stall or high-load events.",
      "heading": "Integrated Current Sensing",
      "image_url": ""
    },
    {
      "sort": 1,
      "details": "Four different order-time variants exist for this tile, representing the four possible I2C addresses (0x30, 0x31, 0x33, 0x34), allowing up to four motors to be independently controlled on the same bus. ",
      "heading": "I2C address variants",
      "image_url": ""
    }
  ],
  "package": {
    "pads": 10,
    "type": "T44",
    "size_x": 4000,
    "size_y": 4000,
    "size_z": 0
  },
  "power": [
    {
      "max": 5,
      "min": 1.8,
      "type": "system",
      "notes": "",
      "gnd_pad": [
        "1"
      ],
      "function": "",
      "direction": "input",
      "is_required": true,
      "max_current": "",
      "positive_pad": [
        "10"
      ]
    },
    {
      "max": 11,
      "min": 1.8,
      "type": "drive",
      "notes": "",
      "gnd_pad": [
        "1"
      ],
      "function": "",
      "direction": "input",
      "is_required": true,
      "max_current": "",
      "positive_pad": [
        "9"
      ]
    }
  ],
  "components": [
    {
      "url": "https://www.ti.com/product/DRV8214",
      "part": "DRV8214",
      "datasheet": "https://mosaic-component-datasheets.s3.eu-north-1.amazonaws.com/14/Texas_Instruments-DRV8214.pdf",
      "manufacturer": "Texas Instruments"
    }
  ],
  "pads": [
    {
      "pad": "1",
      "geometry": {
        "size_x": 1000,
        "size_y": 400,
        "center_x": -1500,
        "center_y": 1600
      },
      "functions": [
        {
          "note": "",
          "type": "power",
          "function": "GND",
          "direction": "input"
        }
      ]
    },
    {
      "pad": "2",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": 800
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "EN",
          "direction": "input"
        },
        {
          "note": "",
          "type": "digital",
          "function": "IN1",
          "direction": "input"
        }
      ]
    },
    {
      "pad": "3",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": 0
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "PH",
          "direction": "input"
        },
        {
          "note": "",
          "type": "digital",
          "function": "IN2",
          "direction": "input"
        }
      ]
    },
    {
      "pad": "4",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": -800
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "I2C.CLK",
          "direction": "bidirectional",
          "interface": "I2C"
        }
      ]
    },
    {
      "pad": "5",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": -1600
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "I2C.DAT",
          "direction": "bidirectional",
          "interface": "I2C"
        }
      ]
    },
    {
      "pad": "6",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": -1600
      },
      "functions": [
        {
          "note": "analog current output proportional to motor current",
          "type": "analog",
          "function": "NPROP",
          "direction": "output"
        }
      ]
    },
    {
      "pad": "7",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": -800
      },
      "functions": [
        {
          "note": "",
          "type": "drive",
          "function": "OUT2",
          "direction": "output"
        }
      ]
    },
    {
      "pad": "8",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": 0
      },
      "functions": [
        {
          "note": "",
          "type": "drive",
          "function": "OUT1",
          "direction": "output"
        }
      ]
    },
    {
      "pad": "9",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": 800
      },
      "functions": [
        {
          "note": "1.8-11V drive supply",
          "type": "power",
          "function": "VM",
          "direction": "input"
        }
      ]
    },
    {
      "pad": "10",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": 1600
      },
      "functions": [
        {
          "note": "1.8-5.0V",
          "type": "power",
          "function": "V+",
          "direction": "input"
        }
      ]
    }
  ],
  "interfaces": [
    {
      "name": "I2C",
      "type": "I2C",
      "parameters": {
        "modes": [
          "slave"
        ],
        "addresses": [
          {
            "address": "variant",
            "is_default": true
          }
        ]
      },
      "pad_assignments": [
        {
          "pad": "4",
          "role": "bus",
          "function": "I2C.CLK",
          "is_required": true
        },
        {
          "pad": "5",
          "role": "bus",
          "function": "I2C.DAT",
          "is_required": true
        }
      ]
    }
  ],
  "twin": {
    "score": 1,
    "source": "// Digital twin for Drive.DC.H — TI DRV8214 brushed-DC H-bridge motor driver.\n//\n// 11 V / 2 A H-bridge with integrated current sense (IPROPI/NPROP), voltage &\n// current regulation, stall detection, and sensorless ripple counting (speed +\n// position without an encoder). I²C control on pads 4/5; the H-bridge drives a\n// motor across OUT1 (pad 8) / OUT2 (pad 7) — per the tile schematic, which is\n// authoritative; NPROP (pad 6) mirrors motor current. (The tile JSON currently\n// lists pad 7=OUT1 / 8=OUT2 — swapped; correct it at the product DB.)\n// Address 0x34 = A1/A0 both Hi-Z — the dual-NP (unpopulated-resistor) default;\n// alternate SKUs would populate the address resistors.\n//\n// The motor is external, so its current/speed are MODELED from a load control\n// (the VM draw is dominated by motor current, like a piezo's reactive draw is\n// the whole story for Drive.P). The chip's own currents are canonical from the\n// datasheet (VM active 1.3 mA / sleep ~0.1 µA; VCC active 1.5 mA), and the\n// readback conversions match the driver: Vmtr = raw·FS/255 (FS 15.7 V or 3.92 V),\n// Imtr = raw·Imax/192, 8-bit speed, 16-bit ripple count, FAULT bit masks.\nimport type { TileSim } from '../tileSim';\n\nconst I2C_ADDR = 0x34; // A1/A0 Hi-Z (dual-NP default)\n\n// CS_GAIN_SEL → max current (mA), matching the driver's cs_max_ma table\nconst CS_MAX_MA = [4000, 2000, 1000, 500, 250, 125, 250, 125];\n\n// bridge state\nconst COAST = 0;\nconst FORWARD = 1;\nconst REVERSE = 2;\nconst BRAKE = 3;\n\n// FAULT register bits\nconst FLT_FAULT = 0x80;\nconst FLT_STALL = 0x20;\nconst FLT_OCP = 0x10;\n\n// chip supply currents (µA), datasheet Table 7.5\nconst IVM_ACTIVE_UA = 1300; // VM active quiescent\nconst IVM_SLEEP_UA = 0.1; // VM sleep (OVP enabled)\nconst IVCC_ACTIVE_UA = 1500; // VCC/V+ active\n\nconst UVLO_MV = 1800; // VM minimum\n\ninterface State {\n  // ── inputs (controls) ──\n  vm_mv: number; // motor supply (VM)\n  vplus_mv: number; // logic supply (V+)\n  bridge: number; // 0 coast, 1 forward, 2 reverse, 3 brake\n  target: number; // WSET_VSET duty/voltage target, 0..255\n  load: number; // mechanical load 0..100 % (→ current ↑, speed ↓)\n  stall: number; // rotor stalled\n  fault: number; // inject overcurrent fault\n  sleeping: number; // EN_OUT = 0\n\n  // ── config (tracked) ──\n  vm_gain: number; // 0 = 0-15.7 V range, 1 = 0-3.92 V\n  cs_gain: number; // CS_GAIN_SEL 0..5\n  control_mode: number; // 0 I2C, 1 PAD_PHEN, 2 PAD_IN1IN2\n  reg_mode: number; // 0 open, 1 cycle-by-cycle, 2 speed, 3 voltage\n  imode: number; // current-regulation mode\n  stall_enabled: number;\n  inrush_ms: number;\n  stall_recovery: number;\n  ripple_thr: number;\n  filter_gain: number;\n\n  // ── evolving ──\n  ripple_count: number; // accumulates while running\n\n  [field: string]: number;\n}\n\nconst pick = (args: number[], i: number, cur: number) =>\n  args.length > i && Number.isFinite(args[i]) ? args[i] : cur;\nconst clamp = (v: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, v));\n\nconst csMax = (s: State) => CS_MAX_MA[clamp(Math.round(s.cs_gain), 0, 7)];\nconst voltFs = (s: State) => (s.vm_gain === 1 ? 3920 : 15700);\nconst running = (s: State) =>\n  s.sleeping !== 1 && s.vm_mv >= UVLO_MV && (s.bridge === FORWARD || s.bridge === REVERSE);\n\n// Regulated motor terminal voltage (mV): target maps onto the voltage range,\n// clamped to the available supply. Zero unless actively driving.\nfunction appliedMv(s: State): number {\n  if (!running(s)) return 0;\n  return Math.min(Math.round((s.target / 255) * voltFs(s)), s.vm_mv);\n}\n\n// Motor current (mA): a stalled rotor draws the gain's max (locked-rotor); a\n// running motor scales with duty and mechanical load. External motor ⇒ modeled.\nfunction motorMa(s: State): number {\n  if (!running(s)) return 0;\n  if (s.stall === 1) return csMax(s);\n  const i = (0.15 + 0.85 * (s.load / 100)) * (s.target / 255) * csMax(s);\n  return Math.round(clamp(i, 0, csMax(s)));\n}\n\n// Speed estimate (0..255, the chip's RC_STATUS1 scale): rises with duty, falls\n// with load; zero when stalled or not driving.\nfunction speed(s: State): number {\n  if (!running(s) || s.stall === 1) return 0;\n  return Math.round(clamp((s.target / 255) * (1 - 0.6 * (s.load / 100)) * 255, 0, 255));\n}\n\nfunction faultByte(s: State): number {\n  let b = 0;\n  if (s.stall === 1) b |= FLT_STALL;\n  if (s.fault === 1) b |= FLT_OCP;\n  return b ? b | FLT_FAULT : 0;\n}\n\nconst sim: TileSim<State> = {\n  tile: 'Drive.DC.H',\n\n  defaultState: {\n    vm_mv: 5000,\n    vplus_mv: 3300,\n    bridge: COAST,\n    target: 255,\n    load: 30,\n    stall: 0,\n    fault: 0,\n    sleeping: 0,\n\n    vm_gain: 1,\n    cs_gain: 0,\n    control_mode: 0,\n    reg_mode: 3,\n    imode: 1,\n    stall_enabled: 1,\n    inrush_ms: 0,\n    stall_recovery: 1,\n    ripple_thr: 0,\n    filter_gain: 1,\n\n    ripple_count: 0,\n  },\n\n  controls: [\n    { type: 'slider', field: 'bridge', label: 'Bridge (0c 1f 2r 3b)', min: 0, max: 3, step: 1 },\n    { type: 'slider', field: 'target', label: 'Target (duty)', min: 0, max: 255, step: 1 },\n    {\n      type: 'slider',\n      field: 'load',\n      label: 'Mechanical load',\n      min: 0,\n      max: 100,\n      step: 1,\n      unit: '%',\n    },\n    {\n      type: 'slider',\n      field: 'vm_mv',\n      label: 'VM (motor supply)',\n      min: 1800,\n      max: 11000,\n      step: 100,\n      unit: 'mV',\n    },\n    { type: 'slider', field: 'cs_gain', label: 'Current-sense gain', min: 0, max: 5, step: 1 },\n    { type: 'toggle', field: 'vm_gain', label: 'Low-V range (3.92 V)' },\n    { type: 'toggle', field: 'stall', label: 'Stall rotor' },\n    { type: 'toggle', field: 'fault', label: 'Overcurrent fault' },\n    { type: 'toggle', field: 'sleeping', label: 'Sleep' },\n  ],\n\n  // Ripple counter accumulates while the motor turns (8-bit speed → counts).\n  deriveState(state) {\n    if (!running(state) || state.stall === 1) return {};\n    return { ripple_count: clamp(state.ripple_count + Math.round(speed(state) / 16), 0, 0xffff) };\n  },\n\n  hostCalls: {\n    // ── lifecycle ──\n    tile_drive_dc_h_find: () => ({ scalar: I2C_ADDR }),\n    tile_drive_dc_h_init: () => ({\n      scalar: 0,\n      nextState: { bridge: COAST, sleeping: 0, reg_mode: 3, control_mode: 0, ripple_count: 0 },\n    }),\n    tile_drive_dc_h_sleep: () => ({ nextState: { sleeping: 1 } }),\n    tile_drive_dc_h_wake: () => ({ nextState: { sleeping: 0 } }),\n\n    // ── bridge control ──\n    tile_drive_dc_h_forward: () => ({ nextState: { bridge: FORWARD, sleeping: 0 } }),\n    tile_drive_dc_h_reverse: () => ({ nextState: { bridge: REVERSE, sleeping: 0 } }),\n    tile_drive_dc_h_brake: () => ({ nextState: { bridge: BRAKE } }),\n    tile_drive_dc_h_coast: () => ({ nextState: { bridge: COAST } }),\n    tile_drive_dc_h_set_target: ({ args }) => ({\n      nextState: { target: clamp(pick(args, 0, 255), 0, 255) },\n    }),\n\n    // ── configuration ──\n    tile_drive_dc_h_set_control_mode: ({ args }) => ({\n      nextState: { control_mode: pick(args, 0, 0) },\n    }),\n    tile_drive_dc_h_set_regulation_mode: ({ args }) => ({\n      nextState: { reg_mode: pick(args, 0, 3) },\n    }),\n    tile_drive_dc_h_set_current_regulation_mode: ({ args }) => ({\n      nextState: { imode: pick(args, 0, 1) },\n    }),\n    tile_drive_dc_h_set_current_sense_gain: ({ args }) => ({\n      nextState: { cs_gain: clamp(pick(args, 0, 0), 0, 7) },\n    }),\n    tile_drive_dc_h_set_stall_enabled: ({ args }) => ({\n      nextState: { stall_enabled: pick(args, 0, 1) ? 1 : 0 },\n    }),\n    tile_drive_dc_h_set_inrush_time_ms: ({ args }) => ({\n      nextState: { inrush_ms: pick(args, 0, 0) },\n    }),\n    tile_drive_dc_h_set_stall_recovery: ({ args }) => ({\n      nextState: { stall_recovery: pick(args, 0, 1) },\n    }),\n    tile_drive_dc_h_set_ripple_threshold: ({ args }) => ({\n      nextState: { ripple_thr: pick(args, 0, 0) },\n    }),\n    tile_drive_dc_h_set_ripple_filter_gain: ({ args }) => ({\n      nextState: { filter_gain: pick(args, 0, 1) },\n    }),\n\n    // ── status / readback ──\n    tile_drive_dc_h_get_fault: ({ state }) => ({ scalar: faultByte(state) }),\n    tile_drive_dc_h_clear_fault: () => ({ nextState: { fault: 0, stall: 0 } }),\n    tile_drive_dc_h_is_stalled: ({ state }) => ({ scalar: state.stall }),\n    tile_drive_dc_h_get_voltage_mv: ({ state }) => ({ scalar: appliedMv(state) }),\n    tile_drive_dc_h_get_current_ma: ({ state }) => ({ scalar: motorMa(state) }),\n    tile_drive_dc_h_get_speed: ({ state }) => ({ scalar: speed(state) }),\n    tile_drive_dc_h_get_ripple_count: ({ state }) => ({ scalar: state.ripple_count }),\n    tile_drive_dc_h_clear_ripple_count: () => ({ nextState: { ripple_count: 0 } }),\n    tile_drive_dc_h_is_running: ({ state }) => ({ scalar: running(state) ? 1 : 0 }),\n    tile_drive_dc_h_wait_for_stop: () => ({ scalar: 1 }), // can't block in the sim\n\n    // ── tier-2 helpers ──\n    tile_drive_dc_h_set_speed_rpm: ({ args }) => ({\n      nextState: { bridge: pick(args, 1, 0) === 1 ? REVERSE : FORWARD, reg_mode: 2, sleeping: 0 },\n    }),\n    tile_drive_dc_h_move_distance: ({ args }) => ({\n      nextState: {\n        bridge: pick(args, 1, 0) === 1 ? REVERSE : FORWARD,\n        sleeping: 0,\n        ripple_count: 0,\n      },\n    }),\n  },\n\n  provenance: {\n    // canonical — datasheet/driver-accurate\n    tile_drive_dc_h_find: 'canonical', // I2C 0x34 (Hi-Z/Hi-Z)\n    tile_drive_dc_h_get_voltage_mv: 'canonical', // Vmtr = raw·FS/255\n    tile_drive_dc_h_get_current_ma: 'canonical', // Imtr scale (CS_GAIN_SEL)\n    tile_drive_dc_h_get_fault: 'canonical', // FAULT bit masks\n    tile_drive_dc_h_forward: 'canonical', // OUT1=H, OUT2=L\n    tile_drive_dc_h_reverse: 'canonical', // OUT1=L, OUT2=H\n    tile_drive_dc_h_brake: 'canonical', // both low\n    tile_drive_dc_h_coast: 'canonical', // both Hi-Z\n    tile_drive_dc_h_set_current_sense_gain: 'canonical', // CS_GAIN_SEL codes\n    tile_drive_dc_h_set_control_mode: 'canonical',\n    tile_drive_dc_h_set_regulation_mode: 'canonical',\n    // inferred — behavior obvious from the driver; motor response modeled\n    tile_drive_dc_h_init: 'inferred',\n    tile_drive_dc_h_sleep: 'inferred',\n    tile_drive_dc_h_wake: 'inferred',\n    tile_drive_dc_h_set_target: 'inferred',\n    tile_drive_dc_h_set_current_regulation_mode: 'inferred',\n    tile_drive_dc_h_set_stall_enabled: 'inferred',\n    tile_drive_dc_h_set_inrush_time_ms: 'inferred',\n    tile_drive_dc_h_set_stall_recovery: 'inferred',\n    tile_drive_dc_h_set_ripple_threshold: 'inferred',\n    tile_drive_dc_h_set_ripple_filter_gain: 'inferred',\n    tile_drive_dc_h_clear_fault: 'inferred',\n    tile_drive_dc_h_is_stalled: 'inferred',\n    tile_drive_dc_h_get_speed: 'inferred', // modeled from duty × load\n    tile_drive_dc_h_get_ripple_count: 'inferred', // accumulated from modeled speed\n    tile_drive_dc_h_clear_ripple_count: 'inferred',\n    tile_drive_dc_h_is_running: 'inferred',\n    tile_drive_dc_h_set_speed_rpm: 'inferred',\n    tile_drive_dc_h_move_distance: 'inferred',\n    // hallucinated — not really modeled\n    tile_drive_dc_h_wait_for_stop: 'hallucinated', // always reports stopped\n    power: 'inferred', // motor current modeled; chip quiescent canonical\n  },\n\n  // H-bridge terminals (drive level 0..1) + NPROP current mirror.\n  padOutputs(state) {\n    const d = running(state) ? state.target / 255 : 0;\n    const out1 = state.bridge === FORWARD ? d : 0;\n    const out2 = state.bridge === REVERSE ? d : 0;\n    const nprop = motorMa(state) / csMax(state);\n    return { OUT1: out1, OUT2: out2, NPROP: nprop };\n  },\n\n  // Electrical. V+ logic (pad 10) + VM motor supply (pad 9, carries the motor\n  // current — the dominant draw); H-bridge terminals OUT1 (pad 8) / OUT2 (pad 7).\n  power(state) {\n    const asleep = state.sleeping === 1;\n    const uvlo = state.vm_mv < UVLO_MV;\n    const vccUa = asleep || uvlo ? 0 : IVCC_ACTIVE_UA;\n    const vmChipUa = asleep ? IVM_SLEEP_UA : uvlo ? 0 : IVM_ACTIVE_UA;\n    const motorUa = motorMa(state) * 1000;\n    const vmUa = vmChipUa + motorUa;\n    const av = appliedMv(state);\n\n    return {\n      draw_ua: Math.round(vccUa + vmUa),\n      rails: [\n        {\n          name: 'V+',\n          role: 'supply',\n          v_mv: state.vplus_mv,\n          i_ua: vccUa,\n          pads: ['10'],\n          note: 'logic supply',\n        },\n        {\n          name: 'VM',\n          role: 'supply',\n          v_mv: state.vm_mv,\n          i_ua: Math.round(vmUa),\n          pads: ['9'],\n          note: asleep\n            ? 'motor supply — sleep'\n            : motorUa > 0\n              ? 'motor supply + motor current'\n              : 'motor supply — idle',\n        },\n        {\n          name: 'OUT1',\n          role: 'output',\n          v_mv: state.bridge === FORWARD ? av : 0,\n          pads: ['8'],\n          note: 'H-bridge terminal 1 (chip OUT1 → tile pad 8)',\n        },\n        {\n          name: 'OUT2',\n          role: 'output',\n          v_mv: state.bridge === REVERSE ? av : 0,\n          pads: ['7'],\n          note: 'H-bridge terminal 2 (chip OUT2 → tile pad 7)',\n        },\n      ],\n    };\n  },\n};\n\nexport default sim;\n",
    "status": "validated",
    "updated_at": "2026-06-21 18:29:40"
  },
  "config": {
    "inputMode": {
      "kind": "select",
      "group": "Drive",
      "label": "Motor control mode",
      "default": "i2c-only",
      "options": [
        {
          "label": "I2C only (pads 2, 3 unused)",
          "value": "i2c-only",
          "states": {
            "2": "open",
            "3": "open"
          },
          "firmware_contract": [
            {
              "via": "i2c",
              "type": "register",
              "value": "I2C_ONLY",
              "register": "BRIDGE_CONTROL"
            }
          ]
        },
        {
          "label": "EN/PH (PWM enable + direction)",
          "value": "en-ph",
          "netlist": {
            "expects": [
              {
                "to": {
                  "kind": "matchFunction",
                  "function": "GPIO",
                  "capabilities": [
                    "output",
                    "pwm"
                  ]
                },
                "tag": "inputMode.en-ph.en.attached",
                "from": {
                  "pad": "2",
                  "kind": "tile"
                },
                "role": "data"
              },
              {
                "to": {
                  "kind": "matchFunction",
                  "function": "GPIO",
                  "capabilities": [
                    "output"
                  ]
                },
                "tag": "inputMode.en-ph.ph.attached",
                "from": {
                  "pad": "3",
                  "kind": "tile"
                },
                "role": "data"
              }
            ]
          },
          "firmware_contract": [
            {
              "via": "i2c",
              "type": "register",
              "value": "EN_PH",
              "register": "BRIDGE_CONTROL"
            }
          ]
        },
        {
          "label": "IN1/IN2 (independent half-bridge PWM)",
          "value": "in1-in2",
          "netlist": {
            "expects": [
              {
                "to": {
                  "kind": "matchFunction",
                  "function": "GPIO",
                  "capabilities": [
                    "output",
                    "pwm"
                  ]
                },
                "tag": "inputMode.in1-in2.in1.attached",
                "from": {
                  "pad": "2",
                  "kind": "tile"
                },
                "role": "data"
              },
              {
                "to": {
                  "kind": "matchFunction",
                  "function": "GPIO",
                  "capabilities": [
                    "output",
                    "pwm"
                  ]
                },
                "tag": "inputMode.in1-in2.in2.attached",
                "from": {
                  "pad": "3",
                  "kind": "tile"
                },
                "role": "data"
              }
            ]
          },
          "firmware_contract": [
            {
              "via": "i2c",
              "type": "register",
              "value": "IN1_IN2",
              "register": "BRIDGE_CONTROL"
            }
          ]
        }
      ]
    },
    "currentSense": {
      "kind": "boolean",
      "group": "Sidebands",
      "label": "Use NPROP analog current output",
      "binding": {
        "pad": "6",
        "kind": "output"
      },
      "default": false,
      "options": [
        {
          "value": false,
          "firmware_contract": [
            {
              "via": "i2c",
              "type": "register",
              "value": "disabled",
              "register": "CURRENT_MIRROR"
            }
          ]
        },
        {
          "value": true,
          "netlist": {
            "expects": [
              {
                "to": {
                  "kind": "matchFunction",
                  "function": "ADC",
                  "capabilities": [
                    "analog-input"
                  ]
                },
                "tag": "currentSense.attached",
                "from": {
                  "pad": "6",
                  "kind": "tile"
                },
                "role": "data"
              }
            ]
          },
          "firmware_contract": [
            {
              "via": "i2c",
              "type": "register",
              "value": "enabled",
              "register": "CURRENT_MIRROR"
            },
            {
              "via": "i2c",
              "type": "register",
              "value": "<configured>",
              "register": "VREF"
            }
          ]
        }
      ]
    }
  },
  "variants": {
    "varies": [
      {
        "type": "i2c-address",
        "description": "I2C address"
      }
    ],
    "options": {
      "A30": {
        "i2c-address": "0x30"
      },
      "A31": {
        "i2c-address": "0x31"
      },
      "A33": {
        "i2c-address": "0x33"
      },
      "A34": {
        "default": true,
        "i2c-address": "0x34"
      }
    }
  }
}