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