MustafaMulla29/rp2040-bldc-motor-controller-new
A USB‑C PD–powered RP2040 BLDC motor controller PCB with 3.3 V logic, MCT8329A sensorless commutation, three MOSFET half-bridges, protected power switching, USB data, controls, and motor connectors.
- Version
- 0.3.82
- License
- unset
- Stars
- 0
circuit/helpers.tsx
import { type ReactNode } from "react"
import type { ChipProps } from "@tscircuit/props"
import { assemblyProps } from "./assembly-parts"
import placement from "./placement.json"
import schematicLayout from "./schematic-layout.json"
import { MMBT3904_7_F } from "../imports/MMBT3904_7_F"
export const net = (name: string) => `net.${name}`
// Component origins are ordinary native pcbX/pcbY props, centralized for layout review.
const locations = Object.fromEntries(placement.pcb_placements.map(p => [p.selector, p.center]))
const pcbOverrides: Record<string, {rotation?: number; layer?: "top" | "bottom"}> = Object.fromEntries(placement.pcb_placements.map(p => {
const { rotation, layer } = p
if (layer !== undefined && layer !== "top" && layer !== "bottom") throw new Error(`Invalid placement layer for ${p.selector}: ${layer}`)
return [p.selector, { rotation, layer }]
}))
const schematicLocations: Record<string, { x: number; y: number; sheet: string; section: string; rotation?: number; width?: number; height?: number; showRatings?: boolean; pinArrangement?: unknown; pinStyle?: ChipProps["schPinStyle"] }> = schematicLayout.components
export const schAt = (name: string, schX: number, schY: number) => {
const p = locations[name]
if (!p) throw new Error(`No PCB placement for ${name}`)
const s = schematicLocations[name]
if (!s) throw new Error(`No schematic placement for ${name}`)
return { ...assemblyProps(name), pcbX: p.x, pcbY: p.y, ...(pcbOverrides[name]?.rotation === undefined ? {} : { pcbRotation: pcbOverrides[name].rotation }), ...(pcbOverrides[name]?.layer === undefined ? {} : { layer: pcbOverrides[name].layer }), schX: s.x, schY: s.y,
schSheetName: s.sheet,
// Native sections keep local circuits wired and use named nets between functions.
// This only controls the schematic representation; PCB props come from placement.json.
schSectionName: s.section,
...(s.rotation === undefined ? {} : { schRotation: s.rotation }),
...(s.width === undefined ? {} : { schWidth: s.width }),
...(s.height === undefined ? {} : { schHeight: s.height }),
...(s.pinArrangement === undefined ? {} : { schPinArrangement: s.pinArrangement as ChipProps["schPinArrangement"] }),
...(s.pinStyle === undefined ? {} : { schPinStyle: s.pinStyle }),
}
}
export const pcbRotations: Record<string, number> = Object.fromEntries(
Object.entries(pcbOverrides).filter(([,p]) => p.rotation !== undefined).map(([name,p]) => [name,p.rotation!])
)
export type Passive = {
name: string
kind: "R" | "C"
value: string
a: string
b: string
x: number
y: number
layer?: "top" | "bottom"
footprint?: string
volts?: number
note?: string
maxDecouplingTraceLength?: number
connections?: { pin1?: string; pin2?: string }
}
// Schematic placement is independent of the retained PCB placement and copper.
export function Passives({ parts, sx, sy }: { parts: Passive[]; sx: number; sy: number }) {
return <>{parts.map(p => {
const pos = { ...schAt(p.name, sx, sy), layer: pcbOverrides[p.name]?.layer ?? p.layer,
pcbRotation: pcbRotations[p.name] ?? 0,
schRotation: schematicLocations[p.name].rotation ?? -90 }
return p.kind === "R"
? <resistor key={p.name} name={p.name} resistance={p.value} tolerance="1%"
footprint={p.footprint ?? "0603"} {...pos}
connections={{ pin1: net(p.a), pin2: net(p.b) }} />
: <capacitor key={p.name} name={p.name} capacitance={p.value}
maxVoltageRating={p.volts ?? 25} schShowRatings={schematicLocations[p.name].showRatings ?? true}
maxDecouplingTraceLength={p.maxDecouplingTraceLength}
footprint={p.footprint ?? "0603"} {...pos}
connections={p.connections ?? { pin1: net(p.a), pin2: net(p.b) }} />
})}</>
}
export function Npn({ name, base, collector, emitter = "GND", x, y, sx, sy }: {
name: string; base: string; collector: string; emitter?: string; x: number; y: number; sx: number; sy: number
}) {
return <MMBT3904_7_F name={name} pcbRotation={pcbRotations[name] ?? 0} {...schAt(name, sx, sy)}
connections={{ pin1: net(base), pin2: net(emitter), pin3: net(collector) }} />
}
export function BlockTitle({ x, y, children }: { x: number; y: number; children: ReactNode }) {
// Titles now come from the native schematic sheets and sections.
return null
}