mohan-bee/stm32-mini-dev-board-v1-a-2

A diagnostic STM32G031 development board with USB‑C 3.3V power, SWD/GPIO/UART/SPI headers, reset, potentiometer, buttons, LEDs, buzzer, I²C EEPROM, MCP23008 GPIO expansion, filtered inputs, and multiple I²C sensor ports.

Version
1.0.1
License
unset
Stars
0

stress-v6.circuit.tsx

import { Children, Fragment, cloneElement, isValidElement, type ReactElement, type ReactNode } from "react"
import StressV5Board from "./stress-v5.circuit"

// Flatten containers only; preserve footprints and all electrical components.
function flattenSheets(children: ReactNode): ReactElement<Record<string, any>>[] {
  return Children.toArray(children).flatMap((child) => {
    if (!isValidElement<Record<string, any>>(child)) return []
    if (child.type === Fragment || child.type === "schematicsheet") {
      return flattenSheets(child.props.children)
    }
    return [child]
  })
}

const sheets = [
  ["power", "USB power and regulator"],
  ["mcu", "STM32 and reset"],
  ["io", "User controls and buzzer"],
  ["headers", "Programming and serial headers"],
  ["peripherals", "EEPROM and peripheral buses"],
  ["expander", "GPIO expander and LED bank"],
  ["filters", "Filtered GPIO outputs"],
  ["buttons", "Button input bank"],
  ["sensor_ports", "Four I2C expansion ports"],
] as const

export default function StressV6Board() {
  const original = StressV5Board()
  const additions = Array.from({ length: 4 }, (_, channel) => {
    const x = -42 + channel * 28
    const sx = -18 + channel * 12
    const header = `J${9 + channel}`
    const scl = `R${43 + channel * 2}`
    const sda = `R${44 + channel * 2}`
    return <Fragment key={channel}>
      <pinheader name={header} displayName={`3V3 I2C PORT ${channel + 1}`} pinCount={4}
        schSectionName="sensor_ports" schX={sx + 4} schY={0} pcbX={x} pcbY={54} />
      <resistor name={scl} resistance="100" footprint="0603"
        schSectionName="sensor_ports" schX={sx} schY={2} pcbX={x - 3} pcbY={43} />
      <resistor name={sda} resistance="100" footprint="0603"
        schSectionName="sensor_ports" schX={sx} schY={-2} pcbX={x + 3} pcbY={43} />
      <capacitor name={`C${26 + channel}`} capacitance="100nF" footprint="0603"
        schSectionName="sensor_ports" schX={sx + 7} schY={-3} schRotation={90}
        pcbX={x} pcbY={47} />
      <testpoint name={`TP${13 + channel * 2}`} footprintVariant="pad" padDiameter="1.5mm"
        schSectionName="sensor_ports" schX={sx + 2} schY={3} pcbX={x - 3} pcbY={49} />
      <testpoint name={`TP${14 + channel * 2}`} footprintVariant="pad" padDiameter="1.5mm"
        schSectionName="sensor_ports" schX={sx + 2} schY={-3} pcbX={x + 3} pcbY={49} />
      <trace from={`.${header} > .pin1`} to="net.VCC_3V3" thickness="0.4mm" />
      <trace from={`.${header} > .pin2`} to="net.GND" thickness="0.3mm" />
      <trace from={`.${scl} > .pin1`} to="net.I2C_SCL" />
      <trace from={`.${sda} > .pin1`} to="net.I2C_SDA" />
      <trace from={`.${scl} > .pin2`} to={`.${header} > .pin3`} />
      <trace from={`.${sda} > .pin2`} to={`.${header} > .pin4`} />
      <trace from={`.TP${13 + channel * 2} > .pin1`} to={`.${header} > .pin3`} />
      <trace from={`.TP${14 + channel * 2} > .pin1`} to={`.${header} > .pin4`} />
      <trace from={`.C${26 + channel} > .pin1`} to="net.VCC_3V3" thickness="0.4mm" />
      <trace from={`.C${26 + channel} > .pin2`} to="net.GND" thickness="0.3mm" />
    </Fragment>
  })
  const elements = flattenSheets([original.props.children, additions]).map((element, index) => cloneElement(element, { key: `v6-${index}` }))
  const sectionByName = new Map(elements.filter(e => e.props.schSectionName).map(e => [e.props.name, e.props.schSectionName]))
  const sectionOf = (element: ReactElement<Record<string, any>>): string | undefined => {
    if (element.type === "schematicsection") return element.props.name
    if (element.props.schSectionName) return element.props.schSectionName
    if (element.type !== "trace") return undefined
    const sections = [element.props.from, element.props.to]
      .map((selector: string) => sectionByName.get(selector?.match(/^\.([^ >]+)/)?.[1]))
      .filter(Boolean)
    return new Set(sections).size === 1 ? sections[0] : undefined
  }
  return <board {...original.props} title="STM32 Expansion Lab V6 — multi-sheet diagnostic" width="140mm" height="120mm">
    {elements.filter(element => !sectionOf(element))}
    {sheets.map(([name, title], index) =>
      <Fragment key={name}><schematicsheet name={name} displayName={title} sheetIndex={index}
        sheetWidth={["filters", "buttons", "sensor_ports", "expander"].includes(name) ? "600mm" : "400mm"}
        sheetHeight={["filters", "buttons", "sensor_ports"].includes(name) ? "160mm" : "300mm"}>
        {elements.filter(element => sectionOf(element) === name)}
      </schematicsheet></Fragment>
    )}
  </board>
}