0hmX/robocraze-ov7670-camera-module-clone
This code defines and generates a 4-layer PCB hardware layout featuring an OV7670 VGA camera sensor module with fixed component placement, power regulation using ME6211 voltage regulators, a 2x9 header interface, and associated signal routing and mechanical footprints, designed for manufacturing and assembly.
- Version
- 1.0.7
- License
- MIT
- Stars
- 0
dist/index.js
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import { Fragment as Fragment$1 } from 'react';
import { AutoroutingPipelineSolver } from '@tscircuit/capacity-autorouter';
const pz254v1218pPinLabels = {
pin1: ["3V3"],
pin2: ["GND"],
pin3: ["SIO_C"],
pin4: ["SIO_D"],
pin5: ["VSYNC"],
pin6: ["HREF"],
pin7: ["PCLK"],
pin8: ["XCLK"],
pin9: ["D7"],
pin10: ["D6"],
pin11: ["D5"],
pin12: ["D4"],
pin13: ["D3"],
pin14: ["D2"],
pin15: ["D1"],
pin16: ["D0"],
pin17: ["RESET"],
pin18: ["PWDN"],
};
const PZ254V_12_18P_Footprint = () => (jsxs("footprint", { insertionDirection: "from_above", children: [jsx("platedhole", { portHints: ["pin1"], pcbX: "-10.16mm", pcbY: "-1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin2"], pcbX: "-10.16mm", pcbY: "1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin3"], pcbX: "-7.62mm", pcbY: "-1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin4"], pcbX: "-7.62mm", pcbY: "1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin5"], pcbX: "-5.08mm", pcbY: "-1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin6"], pcbX: "-5.08mm", pcbY: "1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin7"], pcbX: "-2.54mm", pcbY: "-1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin8"], pcbX: "-2.54mm", pcbY: "1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin9"], pcbX: "-0mm", pcbY: "-1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin10"], pcbX: "-0mm", pcbY: "1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin11"], pcbX: "2.54mm", pcbY: "-1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin12"], pcbX: "2.54mm", pcbY: "1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin13"], pcbX: "5.08mm", pcbY: "-1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin14"], pcbX: "5.08mm", pcbY: "1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin15"], pcbX: "7.62mm", pcbY: "-1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin16"], pcbX: "7.62mm", pcbY: "1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin17"], pcbX: "10.16mm", pcbY: "-1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("platedhole", { portHints: ["pin18"], pcbX: "10.16mm", pcbY: "1.27mm", outerDiameter: "1.6999966mm", holeDiameter: "1.1000232mm", shape: "circle" }), jsx("silkscreenpath", { route: [{ "x": -8.8900000000001, "y": 0.03997960000003786 }, { "x": -11.429974600000037, "y": 0.03997960000003786 }] }), jsx("silkscreenpath", { route: [{ "x": -8.8900000000001, "y": -2.4999950000000126 }, { "x": -8.8900000000001, "y": 0.03997960000003786 }] }), jsx("silkscreenpath", { route: [{ "x": -11.429974600000037, "y": -2.4999950000000126 }, { "x": 11.429974599999923, "y": -2.4999950000000126 }] }), jsx("silkscreenpath", { route: [{ "x": -11.429974600000037, "y": 2.4999950000001263 }, { "x": -11.429974600000037, "y": -2.4999950000000126 }] }), jsx("silkscreenpath", { route: [{ "x": 11.429974599999923, "y": 2.4999950000001263 }, { "x": -11.429974600000037, "y": 2.4999950000001263 }] }), jsx("silkscreenpath", { route: [{ "x": 11.429974599999923, "y": -2.4999950000000126 }, { "x": 11.429974599999923, "y": 2.4999950000001263 }] }), jsx("silkscreentext", { text: "{NAME}", pcbX: "-0.0127mm", pcbY: "3.54mm", anchorAlignment: "center", fontSize: "1mm" }), jsx("courtyardoutline", { outline: [{ "x": -11.705400000000054, "y": 2.7899999999999636 }, { "x": 11.679999999999836, "y": 2.7899999999999636 }, { "x": 11.679999999999836, "y": -2.7899999999999636 }, { "x": -11.705400000000054, "y": -2.7899999999999636 }, { "x": -11.705400000000054, "y": 2.7899999999999636 }] })] }));
const PZ254V_12_18P = (props) => {
return (jsx("chip", { pinLabels: pz254v1218pPinLabels, supplierPartNumbers: {
"jlcpcb": [
"C492426"
]
}, manufacturerPartNumber: "PZ254V-12-18P", footprint: jsx(PZ254V_12_18P_Footprint, {}), cadModel: {
objUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C492426.obj?uuid=944d3afa7415492585fb90fdc37a5397",
stepUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C492426.step?uuid=944d3afa7415492585fb90fdc37a5397",
pcbRotationOffset: 0,
modelOriginPosition: { x: 0, y: 0, z: -5999999999950489e-21 },
}, ...props }));
};
const ov7670ModulePinLabels = {
pin1: "3V3",
pin2: "GND",
pin3: "SIO_C",
pin4: "SIO_D",
pin5: "VSYNC",
pin6: "HREF",
pin7: "PCLK",
pin8: "XCLK",
pin9: "D7",
pin10: "D6",
pin11: "D5",
pin12: "D4",
pin13: "D3",
pin14: "D2",
pin15: "D1",
pin16: "D0",
pin17: "RESET",
pin18: "PWDN",
};
const OV7670ModuleHeader = (props) => (jsx("connector", { ...props, pinCount: 18, pinLabels: ov7670ModulePinLabels, pinAttributes: {
pin1: { requiresPower: true },
pin2: { requiresGround: true },
}, manufacturerPartNumber: "PZ254V-12-18P", supplierPartNumbers: { jlcpcb: ["C492426"] }, footprint: jsx(PZ254V_12_18P_Footprint, {}), cadModel: {
objUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C492426.obj?uuid=944d3afa7415492585fb90fdc37a5397",
stepUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C492426.step?uuid=944d3afa7415492585fb90fdc37a5397",
pcbRotationOffset: 0,
modelOriginPosition: { x: 0, y: 0, z: -6e-6 },
} }));
/**
* OV7670 24-ball CSP2 land pattern from the OmniVision package drawing.
*
* The array is 5 columns by 6 rows on 0.62 mm pitch. Rows C and D only
* contain balls 1 and 2. The 0.30 mm circular lands match the nominal ball
* diameter; a fabricator should still validate mask/paste rules for its CSP
* process before this is released to production.
*/
const balls = [
[1, "A1", -1.24, 1.55],
[2, "A2", -0.62, 1.55],
[3, "A3", 0, 1.55],
[4, "A4", 0.62, 1.55],
[5, "A5", 1.24, 1.55],
[6, "B1", -1.24, 0.93],
[7, "B2", -0.62, 0.93],
[8, "B3", 0, 0.93],
[9, "B4", 0.62, 0.93],
[10, "B5", 1.24, 0.93],
[11, "C1", -1.24, 0.31],
[12, "C2", -0.62, 0.31],
[13, "D1", -1.24, -0.31],
[14, "D2", -0.62, -0.31],
[15, "E1", -1.24, -0.93],
[16, "E2", -0.62, -0.93],
[17, "E3", 0, -0.93],
[18, "E4", 0.62, -0.93],
[19, "E5", 1.24, -0.93],
[20, "F1", -1.24, -1.55],
[21, "F2", -0.62, -1.55],
[22, "F3", 0, -1.55],
[23, "F4", 0.62, -1.55],
[24, "F5", 1.24, -1.55],
];
const OV7670BallArray = () => (jsx(Fragment, { children: balls.map(([pin, ball, pcbX, pcbY]) => (jsx(Fragment$1, { children: jsx("smtpad", { portHints: [`pin${pin}`], pcbX: pcbX, pcbY: pcbY, shape: "circle", radius: "0.15mm" }) }, ball))) }));
/** Bare CSP2 package footprint, centered on the optical axis. */
const OV7670CSP2Footprint = () => (jsxs("footprint", { children: [jsx(OV7670BallArray, {}), jsx("courtyardoutline", { outline: [
{ x: -2.15, y: 2.35 },
{ x: 2.15, y: 2.35 },
{ x: 2.15, y: -2.35 },
{ x: -2.15, y: -2.35 },
{ x: -2.15, y: 2.35 },
] }), jsx("silkscreenpath", { route: [
{ x: -2.05, y: 1.65 },
{ x: -2.05, y: 2.15 },
{ x: -1.55, y: 2.15 },
], strokeWidth: "0.12mm" }), jsx("silkscreencircle", { pcbX: -2.2, pcbY: 2.25, radius: "0.16mm", strokeWidth: "0.1mm" })] }));
/**
* Assembly footprint used by the photographed module.
*
* The CSP geometry is datasheet-derived. The 19 mm holder courtyard and the
* two 2.0 mm mounting holes are photo-scaled placeholders because the seller
* does not publish the holder drawing. Verify them against the selected lens
* holder before fabrication.
*/
const OV7670CameraAssemblyFootprint = () => (jsxs("footprint", { children: [jsx(OV7670BallArray, {}), jsx("hole", { pcbX: 0, pcbY: 7, diameter: "2mm" }), jsx("hole", { pcbX: 0, pcbY: -7, diameter: "2mm" }), jsx("keepout", { shape: "circle", pcbX: 0, pcbY: 7, radius: "1.3mm", layers: ["top", "inner1", "inner2", "bottom"] }), jsx("keepout", { shape: "circle", pcbX: 0, pcbY: -7, radius: "1.3mm", layers: ["top", "inner1", "inner2", "bottom"] }), jsx("courtyardoutline", { outline: [
{ x: -9.5, y: 9.5 },
{ x: 9.5, y: 9.5 },
{ x: 9.5, y: -9.5 },
{ x: -9.5, y: -9.5 },
{ x: -9.5, y: 9.5 },
] }), jsx("silkscreenrect", { width: "16mm", height: "16mm", strokeWidth: "0.15mm" }), jsx("silkscreencircle", { radius: "5.5mm", strokeWidth: "0.15mm" }), jsx("silkscreencircle", { pcbX: -2.2, pcbY: 2.25, radius: "0.16mm", strokeWidth: "0.1mm" })] }));
const ov7670PinLabels = {
pin1: ["AVDD", "A1"],
pin2: ["SIO_D", "A2"],
pin3: ["SIO_C", "A3"],
pin4: ["D1", "A4"],
pin5: ["D3", "A5"],
pin6: ["PWDN", "B1"],
pin7: ["VREF2", "B2"],
pin8: ["AGND", "B3"],
pin9: ["D0", "B4"],
pin10: ["D2", "B5"],
pin11: ["DVDD", "C1"],
pin12: ["VREF1", "C2"],
pin13: ["VSYNC", "D1_BALL"],
pin14: ["HREF", "D2_BALL"],
pin15: ["PCLK", "E1"],
pin16: ["STROBE", "E2"],
pin17: ["XCLK", "E3"],
pin18: ["D7", "E4"],
pin19: ["D5", "E5"],
pin20: ["DOVDD", "F1"],
pin21: ["RESET_N", "RESET", "F2"],
pin22: ["DOGND", "F3"],
pin23: ["D6", "F4"],
pin24: ["D4", "F5"],
};
const ov7670PinAttributes = {
AVDD: { requiresPower: true, requiresVoltage: "2.8V" },
DOVDD: { requiresPower: true, requiresVoltage: "2.8V" },
DVDD: { requiresPower: true, requiresVoltage: "1.8V" },
AGND: { requiresGround: true },
DOGND: { requiresGround: true },
SIO_C: { capabilities: ["i2c_scl"], needsExternalPullup: true },
SIO_D: { capabilities: ["i2c_sda"], needsExternalPullup: true },
};
const OV7670Sensor = (props) => (jsx("chip", { ...props, pinLabels: ov7670PinLabels, pinAttributes: ov7670PinAttributes, manufacturerPartNumber: "OV7670-VL2A", datasheetUrl: "https://web.mit.edu/6.111/www/f2015/tools/OV7670_2006.pdf", footprint: jsx(OV7670CameraAssemblyFootprint, {}), doNotPlace: true }));
const pinLabels$1 = {
pin1: ["VIN"],
pin2: ["VSS"],
pin3: ["CE"],
pin4: ["NC"],
pin5: ["VOUT"]
};
const pinAttributes$1 = {
pin1: { requiresPower: true },
pin2: { requiresGround: true },
pin4: { doNotConnect: true }
};
const ME6211C18M5G_N = (props) => {
return (jsx("chip", { pinLabels: pinLabels$1, pinAttributes: pinAttributes$1, supplierPartNumbers: {
"jlcpcb": [
"C236671"
]
}, manufacturerPartNumber: "ME6211C18M5G-N", datasheetUrl: "https://datasheet.lcsc.com/datasheet/pdf/2079c21a565bb18f68c1d4daad5e823a.pdf?productCode=C236671", footprint: jsxs("footprint", { children: [jsx("smtpad", { portHints: ["pin5"], pcbX: "-1.300099mm", pcbY: "-0.94996mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("smtpad", { portHints: ["pin4"], pcbX: "-1.300099mm", pcbY: "0.94996mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("smtpad", { portHints: ["pin3"], pcbX: "1.300099mm", pcbY: "0.94996mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("smtpad", { portHints: ["pin2"], pcbX: "1.300099mm", pcbY: "-0mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("smtpad", { portHints: ["pin1"], pcbX: "1.300099mm", pcbY: "-0.94996mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("silkscreenpath", { route: [{ "x": 0.8999728000000005, "y": -1.404111999999941 }, { "x": 0.8999728000000005, "y": -1.5500604000000067 }] }), jsx("silkscreenpath", { route: [{ "x": 0.8999728000000005, "y": -0.45412660000010874 }, { "x": 0.8999728000000005, "y": -0.4958079999998972 }] }), jsx("silkscreenpath", { route: [{ "x": 0.8999728000000005, "y": 0.4958079999998972 }, { "x": 0.8999728000000005, "y": 0.45415200000002187 }] }), jsx("silkscreenpath", { route: [{ "x": 0.8999728000000005, "y": 1.5499587999998994 }, { "x": 0.8999728000000005, "y": 1.404111999999941 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": -1.404111999999941 }, { "x": -0.9000489999999672, "y": -1.5500604000000067 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": 0.4958079999998972 }, { "x": -0.9000489999999672, "y": -0.4958334000000377 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": 1.5499587999998994 }, { "x": -0.9000489999999672, "y": 1.4040866000000278 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": 1.5499587999998994 }, { "x": 0.8999728000000005, "y": 1.5499587999998994 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": -1.5500604000000067 }, { "x": 0.8999728000000005, "y": -1.5500604000000067 }] }), jsx("silkscreentext", { text: "{NAME}", pcbX: "0.012319mm", pcbY: "2.562354mm", anchorAlignment: "center", fontSize: "1mm" }), jsx("courtyardoutline", { outline: [{ "x": -2.091880999999944, "y": 1.8123540000000276 }, { "x": 2.1165190000000393, "y": 1.8123540000000276 }, { "x": 2.1165190000000393, "y": -1.786446000000069 }, { "x": -2.091880999999944, "y": -1.786446000000069 }, { "x": -2.091880999999944, "y": 1.8123540000000276 }] })] }), cadModel: {
objUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C236671.obj?uuid=460193f9bf2d42e58cf3c2f675b07dc6",
stepUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C236671.step?uuid=460193f9bf2d42e58cf3c2f675b07dc6",
pcbRotationOffset: 180,
modelOriginPosition: { x: 0, y: -12700000070253736e-21, z: -0.049083 },
}, ...props }));
};
const pinLabels = {
pin1: ["VIN"],
pin2: ["VSS"],
pin3: ["CE"],
pin4: ["NC"],
pin5: ["VOUT"]
};
const pinAttributes = {
pin1: { requiresPower: true },
pin2: { requiresGround: true },
pin4: { doNotConnect: true }
};
const ME6211C28M5G_N = (props) => {
return (jsx("chip", { pinLabels: pinLabels, pinAttributes: pinAttributes, supplierPartNumbers: {
"jlcpcb": [
"C53099"
]
}, manufacturerPartNumber: "ME6211C28M5G-N", datasheetUrl: "https://datasheet.lcsc.com/datasheet/pdf/2079c21a565bb18f68c1d4daad5e823a.pdf?productCode=C53099", footprint: jsxs("footprint", { children: [jsx("smtpad", { portHints: ["pin5"], pcbX: "-1.300099mm", pcbY: "-0.94996mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("smtpad", { portHints: ["pin4"], pcbX: "-1.300099mm", pcbY: "0.94996mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("smtpad", { portHints: ["pin3"], pcbX: "1.300099mm", pcbY: "0.94996mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("smtpad", { portHints: ["pin2"], pcbX: "1.300099mm", pcbY: "-0mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("smtpad", { portHints: ["pin1"], pcbX: "1.300099mm", pcbY: "-0.94996mm", width: "1.0999978mm", height: "0.5999988mm", shape: "rect" }), jsx("silkscreenpath", { route: [{ "x": 0.8999728000000005, "y": -1.404111999999941 }, { "x": 0.8999728000000005, "y": -1.5500604000000067 }] }), jsx("silkscreenpath", { route: [{ "x": 0.8999728000000005, "y": -0.45412660000010874 }, { "x": 0.8999728000000005, "y": -0.4958079999998972 }] }), jsx("silkscreenpath", { route: [{ "x": 0.8999728000000005, "y": 0.4958079999998972 }, { "x": 0.8999728000000005, "y": 0.45415200000002187 }] }), jsx("silkscreenpath", { route: [{ "x": 0.8999728000000005, "y": 1.5499587999998994 }, { "x": 0.8999728000000005, "y": 1.404111999999941 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": -1.404111999999941 }, { "x": -0.9000489999999672, "y": -1.5500604000000067 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": 0.4958079999998972 }, { "x": -0.9000489999999672, "y": -0.4958334000000377 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": 1.5499587999998994 }, { "x": -0.9000489999999672, "y": 1.4040866000000278 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": 1.5499587999998994 }, { "x": 0.8999728000000005, "y": 1.5499587999998994 }] }), jsx("silkscreenpath", { route: [{ "x": -0.9000489999999672, "y": -1.5500604000000067 }, { "x": 0.8999728000000005, "y": -1.5500604000000067 }] }), jsx("silkscreentext", { text: "{NAME}", pcbX: "0.012319mm", pcbY: "2.562354mm", anchorAlignment: "center", fontSize: "1mm" }), jsx("courtyardoutline", { outline: [{ "x": -2.091880999999944, "y": 1.8123540000000276 }, { "x": 2.1165190000000393, "y": 1.8123540000000276 }, { "x": 2.1165190000000393, "y": -1.786446000000069 }, { "x": -2.091880999999944, "y": -1.786446000000069 }, { "x": -2.091880999999944, "y": 1.8123540000000276 }] })] }), cadModel: {
objUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C53099.obj?uuid=460193f9bf2d42e58cf3c2f675b07dc6",
stepUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C53099.step?uuid=460193f9bf2d42e58cf3c2f675b07dc6",
pcbRotationOffset: 180,
modelOriginPosition: { x: 0, y: -12700000070253736e-21, z: -0.049083 },
}, ...props }));
};
const INPUT_POWER = "input_and_2v8_power";
const CORE_POWER = "core_1v8_power";
const SENSOR = "ov7670_sensor";
const ANALOG_RAILS = "sensor_analog_and_reference";
const IO_RAIL = "sensor_io_power";
const INTERFACE = "camera_interface";
const DNP = "dnp";
const parts = {
c100n: { jlcpcb: ["C14663"], mpn: "CC0603KRX7R9BB104" },
c1u: { jlcpcb: ["C15849"], mpn: "CL10A105KB8NNNC" },
c4u7: { jlcpcb: ["C19666"], mpn: "CL10A475KO8NNNC" },
c10u: { jlcpcb: ["C19702"], mpn: "CL10A106KP8NNNC" },
r10: { jlcpcb: ["C22859"], mpn: "0603WAF100JT5E" },
r0: { jlcpcb: ["C21189"], mpn: "0603WAF0000T5E" },
r1k: { jlcpcb: ["C21190"], mpn: "0603WAF1001T5E" },
r10k: { jlcpcb: ["C2906982"], mpn: "FRC0603F1002TS" },
ledRed: { jlcpcb: ["C2286"], mpn: "KT-0603R" },
};
const headerPairs = [
["3V3", "GND"],
["SIOC", "SIOD"],
["VSYNC", "HREF"],
["PCLK", "XCLK"],
["D7", "D6"],
["D5", "D4"],
["D3", "D2"],
["D1", "D0"],
["RESET#", "PWDN"],
];
const directSignals = [
"SIO_C",
"VSYNC",
"HREF",
"PCLK",
"XCLK",
"D7",
"D6",
"D5",
"D4",
"D3",
"D2",
"D1",
"D0",
"PWDN",
];
const schematicSignalLabels = {
SIO_C: "SCCB_SCL",
VSYNC: "VSYNC",
HREF: "HREF",
PCLK: "PCLK",
XCLK: "XCLK",
D7: "D7",
D6: "D6",
D5: "D5",
D4: "D4",
D3: "D3",
D2: "D2",
D1: "D1",
D0: "D0",
PWDN: "PWDN",
};
/**
* Reserve the demonstrated 0.10 mm CSP escapes before whole-board routing.
* XCLK and VREF1 hand off to the router after a through-via. HREF uses a fixed
* 0.15 mm bottom route after its 0.10 mm ball-field escape because the automatic
* HREF route otherwise misses the neighboring DOVDD clearance by 0.006 mm.
*/
const prepareReservedCspRoutes = (simpleRouteJson) => {
const input = structuredClone(simpleRouteJson);
const xclkConnection = input.connections.find((connection) => connection.pointsToConnect.some((point) => Math.hypot(point.x - 3, point.y + 0.93) < 0.2));
const sensorPoint = xclkConnection?.pointsToConnect.find((point) => Math.hypot(point.x - 3, point.y + 0.93) < 0.2);
if (!xclkConnection || !sensorPoint) {
return {
input,
preexistingTraces: [],
};
}
const breakoutPointId = "XCLK_CSP_BREAKOUT_BOTTOM";
const originalPortId = sensorPoint.pcb_port_id;
xclkConnection.pointsToConnect = xclkConnection.pointsToConnect.map((point) => point === sensorPoint
? {
x: 6,
y: -2.5,
layer: "bottom",
pointId: breakoutPointId,
}
: point);
const xclkDogbone = {
type: "pcb_trace",
pcb_trace_id: "XCLK_CSP_DOGBONE",
connection_name: xclkConnection.name,
connectsTo: [originalPortId, breakoutPointId].filter((value) => Boolean(value)),
route: [
{
route_type: "wire",
x: 3,
y: -0.93,
width: 0.1,
layer: "top",
start_pcb_port_id: originalPortId,
},
{ route_type: "wire", x: 3, y: -0.31, width: 0.1, layer: "top" },
{ route_type: "wire", x: 6, y: -0.31, width: 0.1, layer: "top" },
{ route_type: "wire", x: 6, y: -2.5, width: 0.1, layer: "top" },
{
route_type: "via",
x: 6,
y: -2.5,
from_layer: "top",
to_layer: "bottom",
via_diameter: 0.45,
via_hole_diameter: 0.2,
},
{ route_type: "wire", x: 6, y: -2.5, width: 0.1, layer: "bottom" },
],
};
const vref1Connection = input.connections.find((connection) => connection.pointsToConnect.some((point) => Math.hypot(point.x - 2.38, point.y - 0.31) < 0.2));
const vref1SensorPoint = vref1Connection?.pointsToConnect.find((point) => Math.hypot(point.x - 2.38, point.y - 0.31) < 0.2);
const reservedTraces = [xclkDogbone];
if (vref1Connection && vref1SensorPoint) {
const vref1BreakoutPointId = "VREF1_CSP_BREAKOUT_BOTTOM";
const vref1PortId = vref1SensorPoint.pcb_port_id;
vref1Connection.pointsToConnect = vref1Connection.pointsToConnect.map((point) => point === vref1SensorPoint
? {
x: 5.2,
y: 0.5,
layer: "bottom",
pointId: vref1BreakoutPointId,
}
: point);
reservedTraces.push({
type: "pcb_trace",
pcb_trace_id: "VREF1_CSP_DOGBONE",
connection_name: vref1Connection.name,
connectsTo: [vref1PortId, vref1BreakoutPointId].filter((value) => Boolean(value)),
route: [
{
route_type: "wire",
x: 2.38,
y: 0.31,
width: 0.1,
layer: "top",
start_pcb_port_id: vref1PortId,
},
{ route_type: "wire", x: 2.69, y: 0, width: 0.1, layer: "top" },
{ route_type: "wire", x: 5.2, y: 0, width: 0.1, layer: "top" },
{ route_type: "wire", x: 5.2, y: 0.5, width: 0.1, layer: "top" },
{
route_type: "via",
x: 5.2,
y: 0.5,
from_layer: "top",
to_layer: "bottom",
via_diameter: 0.45,
via_hole_diameter: 0.2,
},
{ route_type: "wire", x: 5.2, y: 0.5, width: 0.1, layer: "bottom" },
],
});
}
const hrefConnection = input.connections.find((connection) => connection.pointsToConnect.some((point) => Math.hypot(point.x - 2.38, point.y + 0.31) < 0.2));
const hrefSensorPoint = hrefConnection?.pointsToConnect.find((point) => Math.hypot(point.x - 2.38, point.y + 0.31) < 0.2);
const hrefHeaderPoint = hrefConnection?.pointsToConnect.find((point) => point !== hrefSensorPoint);
if (hrefConnection && hrefSensorPoint && hrefHeaderPoint) {
const hrefPortId = hrefSensorPoint.pcb_port_id;
const hrefHeaderPortId = hrefHeaderPoint.pcb_port_id;
input.connections = input.connections.filter((connection) => connection !== hrefConnection);
reservedTraces.push({
type: "pcb_trace",
pcb_trace_id: "HREF_CSP_ESCAPE_AND_HEADER_ROUTE",
connection_name: hrefConnection.name,
connectsTo: [hrefPortId, hrefHeaderPortId].filter((value) => Boolean(value)),
route: [
{
route_type: "wire",
x: 2.38,
y: -0.31,
width: 0.1,
layer: "top",
start_pcb_port_id: hrefPortId,
},
{ route_type: "wire", x: 2.07, y: -0.62, width: 0.1, layer: "top" },
{ route_type: "wire", x: 0.5, y: -0.62, width: 0.1, layer: "top" },
{
route_type: "via",
x: 0.5,
y: -0.62,
from_layer: "top",
to_layer: "bottom",
via_diameter: 0.45,
via_hole_diameter: 0.2,
},
{ route_type: "wire", x: 0.5, y: -0.62, width: 0.15, layer: "bottom" },
{ route_type: "wire", x: 0.5, y: -8.5, width: 0.15, layer: "bottom" },
{ route_type: "wire", x: -9.5, y: -8.5, width: 0.15, layer: "bottom" },
{
route_type: "wire",
x: -9.5,
y: hrefHeaderPoint.y,
width: 0.15,
layer: "bottom",
},
{
route_type: "wire",
x: hrefHeaderPoint.x,
y: hrefHeaderPoint.y,
width: 0.15,
layer: "bottom",
end_pcb_port_id: hrefHeaderPortId,
},
],
});
}
input.traces = [
...(input.traces ?? []),
...reservedTraces,
];
return { input, preexistingTraces: reservedTraces };
};
class ThroughViaOnlyAutorouter {
constructor(simpleRouteJson) {
this.isRouting = false;
this.eventHandlers = {
complete: [],
error: [],
progress: [],
};
this.runCycle = () => {
if (!this.isRouting)
return;
try {
const startedAt = Date.now();
const startingIterations = this.solver.iterations;
while (Date.now() - startedAt < 200 &&
!this.solver.solved &&
!this.solver.failed) {
this.solver.step();
}
if (this.solver.failed) {
this.isRouting = false;
const error = new Error(this.solver.error ?? "Through-via-only autorouting failed");
for (const handler of this.eventHandlers.error) {
handler({ type: "error", error });
}
return;
}
if (this.solver.solved) {
this.isRouting = false;
const traces = [
...this.preexistingTraces,
...(this.solver.getOutputSimpleRouteJson().traces ??
[]),
];
for (const handler of this.eventHandlers.complete) {
handler({ type: "complete", traces });
}
return;
}
const elapsedMs = Math.max(1, Date.now() - startedAt);
const iterationsPerSecond = ((this.solver.iterations - startingIterations) / elapsedMs) * 1000;
for (const handler of this.eventHandlers.progress) {
handler({
type: "progress",
steps: this.solver.iterations,
progress: this.solver.progress,
phase: this.solver.getCurrentPhase(),
iterationsPerSecond,
});
}
this.timeoutId = setTimeout(this.runCycle, 0);
}
catch (caught) {
this.isRouting = false;
const error = caught instanceof Error ? caught : new Error(String(caught));
for (const handler of this.eventHandlers.error) {
handler({ type: "error", error });
}
}
};
const prepared = prepareReservedCspRoutes(simpleRouteJson);
this.preexistingTraces = prepared.preexistingTraces;
this.input = {
...prepared.input,
// Preserve inner1/inner2 as uninterrupted power/ground plane layers.
// The automatic router may use top and bottom and ordinary through-vias.
layerCount: 2,
allowViaInPad: false,
// Leave manufacturing margin around CSP lands. The core checker requires
// 0.10 mm; asking the router for 0.15 mm prevents borderline rounded
// geometry from being emitted below that limit.
minViaEdgeToPadEdgeClearance: 0.15,
};
this.solver = new AutoroutingPipelineSolver(this.input);
}
start() {
if (this.isRouting)
return;
this.isRouting = true;
this.runCycle();
}
stop() {
this.isRouting = false;
if (this.timeoutId !== undefined)
clearTimeout(this.timeoutId);
}
on(event, callback) {
this.eventHandlers[event].push(callback);
}
solveSync() {
this.solver.solve();
if (this.solver.failed) {
throw new Error(this.solver.error ?? "Through-via-only autorouting failed");
}
return [
...this.preexistingTraces,
...(this.solver.getOutputSimpleRouteJson().traces ?? []),
];
}
getOutputSimpleRouteJson() {
const output = this.solver.getOutputSimpleRouteJson();
return {
...output,
traces: [
...this.preexistingTraces,
...(output.traces ?? []),
],
};
}
}
const createThroughViaOnlyAutorouter = async (simpleRouteJson) => new ThroughViaOnlyAutorouter(simpleRouteJson);
function NamedTrace({ from, to, label, routingPhaseIndex, maxLength, width, }) {
const clean = (value) => value.replace(/[^a-zA-Z0-9]+/g, "_");
const connectedNet = [from, to].find((value) => value.startsWith("net."));
const schematicLabel = label ?? connectedNet?.slice(4);
// Perimeter placement intentionally makes several reference and decoupling
// connections longer than the JSX default. Physical quality is validated
// after autorouting instead of using a pre-route straight-line veto.
const effectiveMaxLength = maxLength ?? "100mm";
return (jsx("trace", { name: `${clean(from)}_TO_${clean(to)}`, from: from, to: to, schDisplayLabel: schematicLabel, routingPhaseIndex: routingPhaseIndex, maxLength: effectiveMaxLength, width: width }));
}
/**
* Standalone FIFO-less OV7670 module matching the B0FDRCHSFW interface.
* Component placement is fixed; PCB traces are generated by the autorouter.
*/
function RobocrazeOV7670CameraModuleBoard() {
return (jsxs("board", { name: "ROBOCRAZE_OV7670_CAMERA_MODULE", title: "Electrobot OV7670 VGA Camera Module Interface Clone", width: "35.16mm", height: "34.29mm", layers: 4, thickness: "1.6mm", borderRadius: "0.5mm", solderMaskColor: "blue", silkscreenColor: "white", doubleSidedAssembly: true, autorouter: { local: true, algorithmFn: createThroughViaOnlyAutorouter }, schTraceAutoLabelEnabled: true, defaultTraceWidth: "0.15mm", nominalTraceWidth: "0.15mm", minTraceWidth: "0.1mm", minTraceToPadEdgeClearance: "0.1mm", minViaEdgeToPadEdgeClearance: "0.1mm", minViaHoleEdgeToViaHoleEdgeClearance: "0.2mm", minViaHoleDiameter: "0.2mm", minViaPadDiameter: "0.45mm", minBoardEdgeClearance: "0.3mm", children: [jsxs("schematicsheet", { name: "main", displayName: "OV7670 standalone camera module", sheetIndex: 0, children: [jsx("schematicsection", { name: INPUT_POWER, displayName: "POWER INPUT + 2.8 V ANALOG / I/O SUPPLY" }), jsx("schematicsection", { name: CORE_POWER, displayName: "1.8 V SENSOR CORE SUPPLY" }), jsx("schematicsection", { name: SENSOR, displayName: "OV7670 IMAGE SENSOR" }), jsx("schematicsection", { name: ANALOG_RAILS, displayName: "AVDD + ANALOG REFERENCE FILTERING" }), jsx("schematicsection", { name: IO_RAIL, displayName: "DOVDD 2.8 V SENSOR I/O FILTERING" }), jsx("schematicsection", { name: INTERFACE, displayName: "CAMERA HEADER / DVP / SCCB CONTROL" }), jsx("schematicsection", { name: DNP, displayName: "OPTIONAL POWER INDICATOR \u2014 DO NOT POPULATE" })] }), jsxs("group", { name: "MAIN_SHEET_CONTENT", schSheetName: "main", children: [[
"V3V3",
"V2V8",
"AVDD",
"DOVDD",
"AGND",
"GND",
"RESET_N",
"VREF1",
"VREF2",
"DNP_LED_A",
].map((name) => (jsx(Fragment$1, { children: jsx("net", { name: name }) }, name))), jsx("copperpour", { name: "V2V8_POUR_INNER1", layer: "inner1", connectsTo: "net.V2V8", clearance: "0.3mm", padMargin: "0.3mm", traceMargin: "0.3mm", boardEdgeMargin: "0.3mm", cutoutMargin: "0.3mm", useThermalReliefs: true, coveredWithSolderMask: true }), jsx("copperpour", { name: "GND_POUR_INNER2", layer: "inner2", connectsTo: "net.GND", clearance: "0.3mm", padMargin: "0.3mm", traceMargin: "0.3mm", boardEdgeMargin: "0.3mm", cutoutMargin: "0.3mm", useThermalReliefs: true, coveredWithSolderMask: true }), jsx("hole", { name: "H1", pcbX: -14.765, pcbY: 14.235, diameter: "2.5mm" }), jsx("hole", { name: "H2", pcbX: 14.765, pcbY: 14.235, diameter: "2.5mm" }), jsx("hole", { name: "H3", pcbX: -14.765, pcbY: -14.235, diameter: "2.5mm" }), jsx("hole", { name: "H4", pcbX: 14.765, pcbY: -14.235, diameter: "2.5mm" }), jsx(OV7670ModuleHeader, { name: "J1", displayName: "2x9 CAMERA HEADER", layer: "bottom", pcbX: -12.5, pcbY: 0, pcbRotation: -90, schSectionName: INTERFACE, schX: 11, schY: 2, schWidth: 2.15, schHeight: 2, schPinArrangement: {
leftSide: {
pins: ["3V3", "SIO_C", "VSYNC", "PCLK", "D7", "D5", "D3", "D1", "RESET"],
direction: "top-to-bottom",
},
rightSide: {
pins: ["GND", "SIO_D", "HREF", "XCLK", "D6", "D4", "D2", "D0", "PWDN"],
direction: "top-to-bottom",
},
} }), jsx(ME6211C28M5G_N, { name: "U1", displayName: "2.8 V LDO", layer: "bottom", pcbX: -4, pcbY: 12, pcbRotation: 90, schSectionName: INPUT_POWER, schX: -9, schY: 5.5, schWidth: 1.6, schHeight: 0.6, schPinArrangement: {
leftSide: { pins: ["VIN", "CE"], direction: "top-to-bottom" },
rightSide: { pins: ["VOUT", "VSS"], direction: "top-to-bottom" },
} }), jsx(ME6211C18M5G_N, { name: "U2", displayName: "1.8 V LDO", layer: "bottom", pcbX: 6.5, pcbY: -12, pcbRotation: 90, schSectionName: CORE_POWER, schX: -9, schY: -4.5, schWidth: 1.6, schHeight: 0.6, schPinArrangement: {
leftSide: { pins: ["VIN", "CE"], direction: "top-to-bottom" },
rightSide: { pins: ["VOUT", "VSS"], direction: "top-to-bottom" },
} }), jsx("capacitor", { name: "C1", displayName: "3V3 input bulk", capacitance: "4.7uF", footprint: "0603", manufacturerPartNumber: parts.c4u7.mpn, supplierPartNumbers: { jlcpcb: parts.c4u7.jlcpcb }, layer: "bottom", pcbX: -7.5, pcbY: 10.7, schSectionName: INPUT_POWER, schX: -12, schY: 2.5, schOrientation: "vertical" }), jsx("capacitor", { name: "C2", displayName: "2V8 output bulk", capacitance: "10uF", footprint: "0603", manufacturerPartNumber: parts.c10u.mpn, supplierPartNumbers: { jlcpcb: parts.c10u.jlcpcb }, layer: "bottom", pcbX: -0.5, pcbY: 13.3, pcbRotation: 180, schSectionName: INPUT_POWER, schX: -8, schY: 2.5, schOrientation: "vertical" }), jsx("capacitor", { name: "C3", displayName: "2V8 output bypass", capacitance: "1uF", footprint: "0603", manufacturerPartNumber: parts.c1u.mpn, supplierPartNumbers: { jlcpcb: parts.c1u.jlcpcb }, layer: "bottom", pcbX: 2.8, pcbY: 13.3, pcbRotation: 180, schSectionName: INPUT_POWER, schX: -5.5, schY: 2.5, schOrientation: "vertical" }), jsx("capacitor", { name: "C5", displayName: "1V8 regulator input", capacitance: "10uF", footprint: "0603", manufacturerPartNumber: parts.c10u.mpn, supplierPartNumbers: { jlcpcb: parts.c10u.jlcpcb }, layer: "bottom", pcbX: 10, pcbY: -13.3, pcbRotation: 180, schSectionName: CORE_POWER, schX: -12.5, schY: -7, schOrientation: "vertical" }), jsx("capacitor", { name: "C6", displayName: "1V8 output bypass", capacitance: "1uF", footprint: "0603", manufacturerPartNumber: parts.c1u.mpn, supplierPartNumbers: { jlcpcb: parts.c1u.jlcpcb }, layer: "bottom", pcbX: 3, pcbY: -10.7, schSectionName: CORE_POWER, schX: -9.3, schY: -7, schOrientation: "vertical" }), jsx(OV7670Sensor, { name: "U3", displayName: "OV7670 image sensor (CSP2)", pcbX: 3, pcbY: 0, schSectionName: SENSOR, schX: 1, schY: 1.5, schWidth: 2.245, schHeight: 2.6, schPinArrangement: {
leftSide: {
pins: ["AVDD", "DOVDD", "DVDD", "AGND", "DOGND", "VREF1", "VREF2", "SIO_C", "SIO_D", "XCLK", "RESET_N", "PWDN"],
direction: "top-to-bottom",
},
rightSide: {
pins: ["PCLK", "VSYNC", "HREF", "D7", "D6", "D5", "D4", "D3", "D2", "D1", "D0", "STROBE"],
direction: "top-to-bottom",
},
}, noConnect: ["STROBE"] }), jsx("resistor", { name: "R1", displayName: "AVDD 10\u03A9 filter", resistance: "10ohm", footprint: "0603", manufacturerPartNumber: parts.r10.mpn, supplierPartNumbers: { jlcpcb: parts.r10.jlcpcb }, layer: "bottom", pcbX: 9.4, pcbY: 10.7, pcbRotation: 180, schSectionName: ANALOG_RAILS, schX: -3, schY: 6.2 }), jsx("resistor", { name: "R2", displayName: "DOVDD 10\u03A9 filter", resistance: "10ohm", footprint: "0603", manufacturerPartNumber: parts.r10.mpn, supplierPartNumbers: { jlcpcb: parts.r10.jlcpcb }, layer: "bottom", pcbX: -6.9, pcbY: -10.7, pcbRotation: 180, schSectionName: IO_RAIL, schX: -3.5, schY: -4 }), jsx("resistor", { name: "R3", displayName: "AGND\u2013GND star link", resistance: "0ohm", footprint: "0603", manufacturerPartNumber: parts.r0.mpn, supplierPartNumbers: { jlcpcb: parts.r0.jlcpcb }, layer: "bottom", pcbX: 14.3, pcbY: 0, pcbRotation: 90, schSectionName: ANALOG_RAILS, schX: 8, schY: 4.2 }), jsx("capacitor", { name: "C8", displayName: "2V8 rail bulk", capacitance: "10uF", footprint: "0603", manufacturerPartNumber: parts.c10u.mpn, supplierPartNumbers: { jlcpcb: parts.c10u.jlcpcb }, layer: "bottom", pcbX: 6.1, pcbY: 10.7, schSectionName: ANALOG_RAILS, schX: -6, schY: 6.2, schOrientation: "vertical" }), jsx("capacitor", { name: "C9", displayName: "DOVDD high-frequency bypass", capacitance: "100nF", footprint: "0603", manufacturerPartNumber: parts.c100n.mpn, supplierPartNumbers: { jlcpcb: parts.c100n.jlcpcb }, layer: "bottom", pcbX: -3.6, pcbY: -10.7, pcbRotation: 180, schSectionName: IO_RAIL, schX: 0, schY: -4, schOrientation: "vertical" }), jsx("capacitor", { name: "C10", displayName: "DVDD bulk", capacitance: "4.7uF", footprint: "0603", manufacturerPartNumber: parts.c4u7.mpn, supplierPartNumbers: { jlcpcb: parts.c4u7.jlcpcb }, layer: "bottom", pcbX: 3, pcbY: -13.3, schSectionName: CORE_POWER, schX: -6.6, schY: -7, schOrientation: "vertical" }), jsx("capacitor", { name: "C11", displayName: "DVDD rail bypass", capacitance: "100nF", footprint: "0603", manufacturerPartNumber: parts.c100n.mpn, supplierPartNumbers: { jlcpcb: parts.c100n.jlcpcb }, layer: "bottom", pcbX: -0.3, pcbY: -13.3, schSectionName: CORE_POWER, schX: -3.9, schY: -7, schOrientation: "vertical" }), jsx("capacitor", { name: "C12", displayName: "AVDD high-frequency bypass", capacitance: "100nF", footprint: "0603", manufacturerPartNumber: parts.c100n.mpn, supplierPartNumbers: { jlcpcb: parts.c100n.jlcpcb }, layer: "bottom", pcbX: 2, pcbY: 10.7, schSectionName: ANALOG_RAILS, schX: 0, schY: 6.2, schOrientation: "vertical" }), jsx("capacitor", { name: "C13", displayName: "VREF1 bypass", capacitance: "100nF", footprint: "0603", manufacturerPartNumber: parts.c100n.mpn, supplierPartNumbers: { jlcpcb: parts.c100n.jlcpcb }, layer: "bottom", pcbX: -7.8, pcbY: 1.5, pcbRotation: 90, schSectionName: ANALOG_RAILS, schX: 2, schY: 4.2, schOrientation: "vertical" }), jsx("capacitor", { name: "C14", displayName: "VREF2 bypass", capacitance: "100nF", footprint: "0603", manufacturerPartNumber: parts.c100n.mpn, supplierPartNumbers: { jlcpcb: parts.c100n.jlcpcb }, layer: "bottom", pcbX: -7.8, pcbY: -1.5, pcbRotation: 270, schSectionName: ANALOG_RAILS, schX: 5, schY: 4.2, schOrientation: "vertical" }), jsx("capacitor", { name: "C15", displayName: "DOVDD local bypass", capacitance: "100nF", footprint: "0603", manufacturerPartNumber: parts.c100n.mpn, supplierPartNumbers: { jlcpcb: parts.c100n.jlcpcb }, layer: "bottom", pcbX: 10, pcbY: -10.7, pcbRotation: 270, schSectionName: IO_RAIL, schX: 6, schY: -4, schOrientation: "vertical" }), jsx("capacitor", { name: "C16", displayName: "DVDD sensor bypass", capacitance: "100nF", footprint: "0603", manufacturerPartNumber: parts.c100n.mpn, supplierPartNumbers: { jlcpcb: parts.c100n.jlcpcb }, layer: "bottom", pcbX: -0.3, pcbY: -10.7, schSectionName: CORE_POWER, schX: -1.2, schY: -7, schOrientation: "vertical" }), jsx("capacitor", { name: "C17", displayName: "AVDD bulk", capacitance: "4.7uF", footprint: "0603", manufacturerPartNumber: parts.c4u7.mpn, supplierPartNumbers: { jlcpcb: parts.c4u7.jlcpcb }, layer: "bottom", pcbX: 12.7, pcbY: 10.7, schSectionName: ANALOG_RAILS, schX: 3, schY: 6.2, schOrientation: "vertical" }), jsx("capacitor", { name: "C18", displayName: "DOVDD bulk", capacitance: "4.7uF", footprint: "0603", manufacturerPartNumber: parts.c4u7.mpn, supplierPartNumbers: { jlcpcb: parts.c4u7.jlcpcb }, layer: "bottom", pcbX: -6.9, pcbY: -13.3, schSectionName: IO_RAIL, schX: 3, schY: -4, schOrientation: "vertical" }), jsx("resistor", { name: "R4", displayName: "SCCB SDA series protection", resistance: "1kohm", footprint: "0603", manufacturerPartNumber: parts.r1k.mpn, supplierPartNumbers: { jlcpcb: parts.r1k.jlcpcb }, layer: "bottom", pcbX: -10.2, pcbY: -13.3, schSectionName: INTERFACE, schX: 7, schY: -2.5 }), jsx("resistor", { name: "R5", displayName: "RESET# pull-up", resistance: "10kohm", footprint: "0603", manufacturerPartNumber: parts.r10k.mpn, supplierPartNumbers: { jlcpcb: parts.r10k.jlcpcb }, layer: "bottom", pcbX: 14.3, pcbY: -6.6, pcbRotation: 270, schSectionName: INTERFACE, schX: 8.5, schY: -4 }), jsx("resistor", { name: "R0", displayName: "Power LED resistor (DNP)", resistance: "1kohm", footprint: "0603", manufacturerPartNumber: parts.r1k.mpn, supplierPartNumbers: { jlcpcb: parts.r1k.jlcpcb }, doNotPlace: true, pcbX: -9.6, pcbY: 14, schSectionName: DNP, schX: 8, schY: -7 }), jsx("led", { name: "D0_IND", displayName: "Optional power LED (DNP)", color: "red", footprint: "0603", manufacturerPartNumber: parts.ledRed.mpn, supplierPartNumbers: { jlcpcb: parts.ledRed.jlcpcb }, doNotPlace: true, pcbX: -6.5, pcbY: 14, schSectionName: DNP, schX: 12.5, schY: -7 }), jsx(NamedTrace, { from: "J1.3V3", to: "net.V3V3", width: "0.3mm" }), jsx(NamedTrace, { from: "J1.GND", to: "net.GND", width: "0.3mm" }), directSignals.map((signal) => (jsx(Fragment$1, { children: jsx(NamedTrace, { from: `J1.${signal}`, to: `U3.${signal}`, label: schematicSignalLabels[signal] }) }, `header-${signal}`))), jsx(NamedTrace, { from: "J1.SIO_D", to: "R4.pin1", label: "SCCB_SDA_HOST" }), jsx(NamedTrace, { from: "R4.pin2", to: "U3.SIO_D", label: "SCCB_SDA" }), jsx(NamedTrace, { from: "J1.RESET", to: "U3.RESET_N", label: "RESET_N" }), jsx(NamedTrace, { from: "U3.RESET_N", to: "R5.pin1", label: "RESET_N" }), jsx(NamedTrace, { from: "R5.pin2", to: "C15.pin1", label: "DOVDD_2V8", width: "0.2mm" }), jsx(NamedTrace, { from: "U1.VIN", to: "net.V3V3", width: "0.3mm" }), jsx(NamedTrace, { from: "U1.CE", to: "net.V3V3", width: "0.3mm" }), jsx(NamedTrace, { from: "U1.VSS", to: "net.GND", width: "0.3mm" }), jsx(NamedTrace, { from: "U1.VOUT", to: "C2.pin1", label: "V2V8", width: "0.25mm" }), jsx(NamedTrace, { from: "U1.VOUT", to: "net.V2V8", width: "0.25mm" }), jsx(NamedTrace, { from: "C1.pin1", to: "net.V3V3", width: "0.3mm" }), jsx(NamedTrace, { from: "C1.pin2", to: "net.GND", width: "0.3mm" }), jsx(NamedTrace, { from: "C2.pin2", to: "net.GND", width: "0.25mm" }), jsx(NamedTrace, { from: "C3.pin1", to: "net.V2V8", width: "0.25mm" }), jsx(NamedTrace, { from: "C3.pin2", to: "net.GND", width: "0.25mm" }), jsx(NamedTrace, { from: "U2.VIN", to: "C5.pin1", label: "V2V8", width: "0.25mm" }), jsx(NamedTrace, { from: "U2.VIN", to: "net.V2V8", width: "0.25mm" }), jsx(NamedTrace, { from: "U2.CE", to: "net.V2V8", width: "0.25mm" }), jsx(NamedTrace, { from: "U2.VSS", to: "net.GND", width: "0.25mm" }), jsx(NamedTrace, { from: "U2.VOUT", to: "C6.pin1", label: "DVDD_1V8", width: "0.25mm" }), jsx(NamedTrace, { from: "C5.pin2", to: "net.GND", width: "0.25mm" }), jsx(NamedTrace, { from: "C6.pin2", to: "net.GND", width: "0.25mm" }), jsx(NamedTrace, { from: "R1.pin1", to: "C8.pin1", label: "V2V8", width: "0.25mm" }), jsx(NamedTrace, { from: "R1.pin1", to: "net.V2V8", width: "0.25mm" }), jsx(NamedTrace, { from: "R1.pin2", to: "C12.pin1", label: "AVDD", width: "0.2mm" }), jsx(NamedTrace, { from: "R1.pin2", to: "C17.pin1", label: "AVDD", width: "0.2mm" }), jsx(NamedTrace, { from: "C12.pin1", to: "U3.AVDD", label: "AVDD", width: "0.2mm" }), jsx(NamedTrace, { from: "R2.pin1", to: "net.V2V8", width: "0.25mm" }), jsx(NamedTrace, { from: "R2.pin2", to: "C9.pin1", label: "DOVDD_2V8", width: "0.2mm" }), jsx(NamedTrace, { from: "R2.pin2", to: "C18.pin1", label: "DOVDD_2V8", width: "0.2mm" }), jsx(NamedTrace, { from: "C9.pin1", to: "U3.DOVDD", label: "DOVDD_2V8", width: "0.2mm" }), jsx(NamedTrace, { from: "C6.pin1", to: "C10.pin1", label: "DVDD_1V8", width: "0.25mm" }), jsx(NamedTrace, { from: "C10.pin1", to: "C11.pin1", label: "DVDD_1V8", width: "0.2mm" }), jsx(NamedTrace, { from: "C11.pin1", to: "C16.pin1", label: "DVDD_1V8", width: "0.2mm" }), jsx(NamedTrace, { from: "C16.pin1", to: "U3.DVDD", label: "DVDD_1V8", width: "0.2mm" }), jsx(NamedTrace, { from: "U3.AGND", to: "C13.pin2", label: "AGND", width: "0.2mm" }), jsx(NamedTrace, { from: "C13.pin2", to: "C14.pin2", label: "AGND", width: "0.2mm" }), jsx(NamedTrace, { from: "C14.pin2", to: "R3.pin1", label: "AGND", width: "0.2mm" }), jsx(NamedTrace, { from: "C13.pin2", to: "C12.pin2", label: "AGND", width: "0.2mm" }), jsx(NamedTrace, { from: "C12.pin2", to: "C17.pin2", label: "AGND", width: "0.2mm" }), jsx(NamedTrace, { from: "R3.pin2", to: "net.GND", width: "0.25mm" }), jsx(NamedTrace, { from: "U3.DOGND", to: "net.GND", width: "0.2mm" }), jsx(NamedTrace, { from: "U3.VREF1", to: "C13.pin1", label: "VREF1" }), jsx(NamedTrace, { from: "U3.VREF2", to: "C14.pin1", label: "VREF2" }), jsx(NamedTrace, { from: "C8.pin2", to: "net.GND", width: "0.25mm" }), jsx(NamedTrace, { from: "C9.pin1", to: "C15.pin1", label: "DOVDD_2V8", width: "0.2mm" }), jsx(NamedTrace, { from: "C9.pin2", to: "net.GND", width: "0.2mm" }), jsx(NamedTrace, { from: "C10.pin2", to: "net.GND", width: "0.2mm" }), jsx(NamedTrace, { from: "C11.pin2", to: "net.GND", width: "0.2mm" }), jsx(NamedTrace, { from: "C15.pin2", to: "net.GND", width: "0.2mm" }), jsx(NamedTrace, { from: "C16.pin2", to: "net.GND", width: "0.2mm" }), jsx(NamedTrace, { from: "C18.pin2", to: "net.GND", width: "0.2mm" }), jsx(NamedTrace, { from: "R0.pin1", to: "net.V3V3" }), jsx(NamedTrace, { from: "R0.pin2", to: "net.DNP_LED_A" }), jsx(NamedTrace, { from: "D0_IND.anode", to: "net.DNP_LED_A" }), jsx(NamedTrace, { from: "D0_IND.cathode", to: "net.GND" }), headerPairs.map(([left, right], pair) => {
const pcbY = 10.16 - pair * 2.54;
return (jsxs(Fragment$1, { children: [jsx("silkscreentext", { text: left, pcbX: -16.15, pcbY: pcbY, fontSize: "0.42mm", anchorAlignment: "center" }), jsx("silkscreentext", { text: right, pcbX: -8.85, pcbY: pcbY, fontSize: "0.42mm", anchorAlignment: "center" })] }, `${left}-${right}`));
}), jsx("silkscreentext", { text: "OV7670", pcbX: 4, pcbY: 15.4, fontSize: "1mm", anchorAlignment: "center" }), jsx("silkscreentext", { text: "3V3 PWR / 2V8 IO", pcbX: 4, pcbY: -15.2, fontSize: "1mm", anchorAlignment: "center" }), jsx("silkscreentext", { text: "PIN 1", pcbX: -16.1, pcbY: 11.8, fontSize: "0.65mm", anchorAlignment: "center" })] })] }));
}
/**
* Host-board mounting footprint for the complete 35.16 x 34.29 mm module.
* Component origin is the module board center; pin 1 is upper-left.
*/
const RobocrazeOV7670ModuleHostFootprint = () => (jsxs("footprint", { insertionDirection: "from_above", children: [Array.from({ length: 9 }, (_, pair) => {
const pcbY = 10.16 - pair * 2.54;
return (jsxs(Fragment$1, { children: [jsx("platedhole", { portHints: [`pin${pair * 2 + 1}`], pcbX: -13.77, pcbY: pcbY, outerDiameter: "1.7mm", holeDiameter: "1.1mm", shape: "circle" }), jsx("platedhole", { portHints: [`pin${pair * 2 + 2}`], pcbX: -11.23, pcbY: pcbY, outerDiameter: "1.7mm", holeDiameter: "1.1mm", shape: "circle" })] }, pair));
}), jsx("courtyardoutline", { outline: [
{ x: -17.58, y: 17.145 },
{ x: 17.58, y: 17.145 },
{ x: 17.58, y: -17.145 },
{ x: -17.58, y: -17.145 },
{ x: -17.58, y: 17.145 },
] }), jsx("silkscreenrect", { width: "35.16mm", height: "34.29mm", strokeWidth: "0.2mm" }), jsx("silkscreencircle", { pcbX: 3, pcbY: 0, radius: "5.5mm", strokeWidth: "0.15mm" }), jsx("silkscreentext", { text: "OV7670 MODULE", pcbX: 3, pcbY: -12.5, fontSize: "0.8mm", anchorAlignment: "center" })] }));
/** Complete module wrapper for placing this finished board on a host PCB. */
const RobocrazeOV7670Module = (props) => (jsx("connector", { ...props, pinCount: 18, pinLabels: ov7670ModulePinLabels, manufacturerPartNumber: "ROBOCRAZE-OV7670-2X9", footprint: jsx(RobocrazeOV7670ModuleHostFootprint, {}), doNotPlace: true }));
export { ME6211C18M5G_N, ME6211C28M5G_N, OV7670CSP2Footprint, OV7670CameraAssemblyFootprint, OV7670ModuleHeader, OV7670Sensor, PZ254V_12_18P, PZ254V_12_18P_Footprint, RobocrazeOV7670CameraModuleBoard, RobocrazeOV7670Module, RobocrazeOV7670ModuleHostFootprint, RobocrazeOV7670CameraModuleBoard as default, ov7670ModulePinLabels, ov7670PinLabels, pz254v1218pPinLabels };