ShiboSoftwareDev/mspm0g3507-usb-c-dev-board

This circuit features a USB Type-C connector with integrated resistors and passives, a USB ESD protection device, a CH340 USB-to-serial interface chip, a 3.3V regulator (AP2112K), multiple decoupling and bulk capacitors, and a Microcontroller (MSPM0G3507) with associated I2C and SPI connections, providing USB communication, power regulation, and RGB LED control.

Version
1.4.1
License
unset
Stars
0

scripts/generate-assembly-files.mjs

import { readFileSync, writeFileSync } from "node:fs"
import { convertCircuitJsonToPickAndPlaceCsv } from "circuit-json-to-pnp-csv"

const circuitPath = process.argv[2] ?? "dist/index/circuit.json"
const circuit = JSON.parse(readFileSync(circuitPath, "utf8"))
const sourceComponents = circuit.filter((element) => element.type === "source_component")

const comments = {
  J_USB_C: "USB-C receptacle",
  R_USB_DM_JOIN: "USB D- reversible-contact crossover",
  R_VBUS_A_LINK: "USB-C VBUS orientation link",
  R_VBUS_B_LINK: "USB-C VBUS orientation link",
  U_USB_ESD: "USB ESD protection",
  U_USB_UART: "USB-to-UART bootloader bridge",
  R_USB_CC1: "USB-C CC1 pull-down",
  R_USB_CC2: "USB-C CC2 pull-down",
  C_USB_UART: "USB-UART decoupling",
  R_UART_TX: "UART TX protection resistor",
  R_UART_RX: "UART RX protection resistor",
  U_3V3_REG: "3.3V LDO regulator",
  C_REG_IN_BULK: "LDO input bulk capacitor",
  C_REG_IN_BYPASS: "LDO input bypass capacitor",
  C_REG_OUT_BULK: "LDO output bulk capacitor",
  C_REG_OUT_BYPASS: "LDO output bypass capacitor",
  U_MCU: "80MHz Arm Cortex-M0+ MCU",
  C_MCU_BULK: "MCU supply bulk capacitor",
  C_MCU_BYPASS: "MCU supply bypass capacitor",
  C_MCU_VCORE: "MCU VCORE capacitor",
  R_RESET_PULLUP: "Reset pull-up",
  C_RESET: "Reset filter capacitor",
  SW_RESET: "Reset tactile switch",
  R_BOOT_PULLDOWN: "ROM BSL invoke pull-down",
  SW_BOOT: "ROM BSL invoke tactile switch",
  R_I2C_SDA_PULLUP: "I2C SDA pull-up",
  R_I2C_SCL_PULLUP: "I2C SCL pull-up",
  R_POWER_LED: "Power LED resistor",
  D_POWER: "Green power LED",
  R_RGB_RED: "RGB debug LED red resistor",
  R_RGB_GREEN: "RGB debug LED green resistor",
  R_RGB_BLUE: "RGB debug LED blue resistor",
  D_USER_RGB: "Common-cathode RGB user/debug LED",
  J_SPI_DISPLAY: "JST-SH 8-pin SPI display connector",
  J_I2C_JST_SH: "JST-SH 4-pin I2C connector",
  J_GROVE_I2C: "Seeed Grove-compatible I2C connector",
  J_TOP: "Top 1x20 GPIO header",
  J_BOTTOM: "Bottom 1x20 GPIO header",
}

const footprintsByMpn = {
  "TYPE-C-31-M-12": "USB-C-SMD-16P+4TH",
  "1206W4F0000T5E": "1206",
  "0402WGF0000TCE": "0402",
  "USBLC6-2SC6": "SOT-23-6",
  CH340C: "SOP-16-150mil",
  "0402WGF5101TCE": "0402",
  CL05B104KO5NNNC: "0402",
  "0402WGF1001TCE": "0402",
  "0402WGF3300TCE": "0402",
  "AP2112K-3.3TRG1": "SOT-23-5",
  CL10A475KO8NNNC: "0603",
  CL10A106KP8NNNC: "0603",
  MSPM0G3507SPTR: "LQFP-48-7x7mm",
  CL10B474KA8NNNC: "0603",
  "0402WGF4702TCE": "0402",
  CL05B103KB5NNNC: "0402",
  "TS342A2P-WZ": "SMD-TACT-2P",
  "0402WGF1002TCE": "0402",
  "0402WGF4701TCE": "0402",
  "XL-1608SYGC-06": "0603-LED",
  "SZYY1615RGB-A 4pin": "SMD-4P-1.6x1.5mm-RGB-LED",
  "SM08B-SRSS-TB(LF)(SN)": "JST-SH-8P-SMD",
  "SM04B-SRSS-TB(LF)(SN)": "JST-SH-4P-SMD",
  "ZX-HY2.0-4PZZ": "GROVE-2.0MM-4P-THT",
  "PH2.54-1X20P-H25": "THT-1x20-P2.54mm-OD1.6-ID1.05",
}

const componentValue = (component) => {
  if (component.display_resistance) return component.display_resistance
  if (component.display_capacitance) return component.display_capacitance
  if (component.ftype === "simple_push_button") return "SPST-NO"
  if (component.name === "D_POWER") return "green"
  if (component.name === "D_USER_RGB") return "RGB common cathode"
  if (component.ftype === "simple_pin_header") return "1x20 2.54mm"
  return component.manufacturer_part_number
}

const csvField = (value) => {
  const text = String(value ?? "")
  return /[",\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text
}

const header = [
  "Designator",
  "Comment",
  "Value",
  "Footprint",
  "JLCPCB Part #",
  "Manufacturer Part Number",
]
const rows = sourceComponents.map((component) => {
  const jlcPart = component.supplier_part_numbers?.jlcpcb?.[0]
  const mpn = component.manufacturer_part_number
  if (!comments[component.name]) throw new Error(`Missing BOM comment for ${component.name}`)
  if (!jlcPart) throw new Error(`Missing JLCPCB part number for ${component.name}`)
  if (!mpn) throw new Error(`Missing manufacturer part number for ${component.name}`)
  if (!footprintsByMpn[mpn]) throw new Error(`Missing BOM footprint for ${component.name} (${mpn})`)
  return [
    component.name,
    comments[component.name],
    componentValue(component),
    footprintsByMpn[mpn],
    jlcPart,
    mpn,
  ]
})

const bom = [header, ...rows].map((row) => row.map(csvField).join(",")).join("\n") + "\n"
const cpl = convertCircuitJsonToPickAndPlaceCsv(circuit).replaceAll("\r\n", "\n").trimEnd() + "\n"

writeFileSync("outputs/MSPM0G3507_USB_C_JLCPCB_BOM.csv", bom)
writeFileSync("outputs/MSPM0G3507_USB_C_JLCPCB_CPL.csv", cpl)
writeFileSync("manufacturing/bom.csv", bom)
writeFileSync("manufacturing/pick_and_place.csv", cpl)

console.log(`Generated ${rows.length} BOM placements and ${cpl.trim().split(/\r?\n/).length - 1} CPL placements`)