AnasSarkiz/muse-voice-remote
Muse Voice Remote — bare ESP32-S3R8, 155 TOP JLCPCB parts with real supplier CAD, native 3D assembly and GLB exports. Revised 17 mm case allocation; 0.30 mm via drill /0.45 mm pad. Checked prototype PCB; mechanical, RF and MUSE qualification pending.
- Version
- 1.3.2
- License
- unset
- Stars
- 0
design/parts.ts
import pinmaps from "../vendor/pinmaps.json"
import placementOverrides from "./placement-overrides.json"
import { catalogFor } from "./catalog"
import { lcdPins, lcdNets } from "./lcd"
import { bareChipPins, chipSupport } from "./chip"
export type Part = {
name: string; value: string; kind?: "resistor" | "capacitor" | "inductor" | "led" | "diode";
x: number; y: number; rotation?: number; schX: number; schY: number;
footprint?: keyof typeof pinmaps; pins?: Record<string, string>;
nets: Record<string, string>; width?: number; height?: number;
status?: string; noConnect?: string[]; offBoard?: boolean;
physicalPins?: Record<string,string>;
}
export const gpio = {
GPIO4: "STATUS_R", GPIO5: "STATUS_G", GPIO9: "STATUS_B", GPIO6: "TALK",
GPIO7:"USB_EN1", U0RXD:"USB_EN2", GPIO8: "MIC_BCLK_HOST", MTDI: "MIC_WS_HOST", GPIO10: "MIC_DATA_HOST",
GPIO11: "SPK_BCLK", GPIO12: "SPK_WS", GPIO13: "SPK_DIN", GPIO14: "AMP_ENABLE_HOST",
GPIO15: "PRIVACY_SENSE", GPIO16: "LCD_MOSI", GPIO17: "LCD_SCK",
GPIO18: "LCD_CS", GPIO21: "LCD_DC", GPIO47: "LCD_RESET", GPIO48: "LCD_BL_PWM",
GPIO19: "USB_DM_MCU", GPIO20: "USB_DP_MCU", GPIO0: "BOOT",
GPIO1: "BAT_ADC", GPIO2: "CHARGE_N", MTCK: "POWER_GOOD_N", MTDO: "HAPTIC", GPIO38: "BAT_SENSE_EN", MTMS:"LCD_BL_ENABLE",
} as const
const core: Part[] = [
{ name: "U1", value: "ESP32-S3R8", physicalPins: bareChipPins,
x: 0, y: 2, rotation: 0, schX: 0, schY: 0,
nets: { ...gpio,GND:"GND",VDD3P3:"RF_3V3",VDDA:"V3_3",VDD3P3_RTC:"V3_3",VDD3P3_CPU:"V3_3",
VDD_SPI:"VDD_SPI_3V3",CHIP_PU:"RESET",LNA_IN:"RF_LNA",XTAL_P:"XTAL_P_CHIP",XTAL_N:"XTAL_N",
SPIHD:"FLASH_HD_HOST",SPIWP:"FLASH_WP_HOST",SPICS0:"FLASH_CS_HOST",SPICLK:"FLASH_CLK_HOST",
SPIQ:"FLASH_Q_HOST",SPID:"FLASH_D_HOST",GPIO45:"STRAP_VDD_SPI",GPIO46:"BOOT_IO46" },
noConnect: ["GPIO3","SPICS1","GPIO33","GPIO34","GPIO35","GPIO36","GPIO37","U0TXD"],
status: "Bare QFN56 ESP32-S3R8 chip with 8 MB in-package Octal PSRAM; separate 3.3 V flash, crystal, RF and power circuitry." },
{ name: "MIC1", value: "SPH0645LM4H-B", footprint: "SPH0645LM4H-B",
x: -28, y: 21.5, schX: -23, schY: 10,
nets: { VDD: "MIC_VDD", GND: "GND", BCLK: "MIC_BCLK", WS: "MIC_WS", DATA: "MIC_SD", SELECT: "GND" },
status: "Reference footprint; bottom acoustic port. Height must be reconciled with 0.77 mm PDF model." },
{ name: "MIC2", value: "SPH0645LM4H-B", footprint: "SPH0645LM4H-B",
x: 28, y: 21.5, schX: -23, schY: 3,
nets: { VDD: "MIC_VDD", GND: "GND", BCLK: "MIC_BCLK", WS: "MIC_WS", DATA: "MIC_SD", SELECT: "MIC_VDD" },
status: "Opposite SELECT strap for second I2S time slot; same acoustic-port qualification as MIC1." },
{ name: "SW_PRIVACY", value: "DPDT hardware privacy — footprint TBD",
x: -29.5, y: 3, rotation: 90, schX: -36, schY: 10, width: 5.2, height: 7.8,
pins: { "1": "PWR_COM", "2": "PWR_ON", "3": "PWR_OFF", "4": "OE_COM", "5": "OE_ON", "6": "OE_OFF" },
nets: { PWR_COM: "MIC_VDD", PWR_ON: "V3_3", PWR_OFF: "GND", OE_COM: "PRIVACY_N_OE", OE_ON: "GND" },
noConnect: ["OE_OFF"], status: "Logical switch terminals, provisional pads. Break-before-make required. Enabled: 1–2 / 4–5. Private: 1–3 / 4–6 grounds mic rail and disables all digital paths. Fit/travel/contact timing unverified." },
{ name: "SW_TALK", value: "TALK momentary — library candidate", x: 0, y: 20.5, schX: 15, schY: 12,
pins: { "1": "A", "2": "B" }, width: 4.5, height: 3.5, offBoard: true,
nets: { A: "TALK", B: "GND" }, status: "PDF switch / linkage allocation; actual switch not selected." },
{ name: "SW_POWER", value: "PCM12SMTR", x: 30, y: -6, rotation: 90, schX: 33, schY: -18,
pins: { "1": "COM", "2": "ON", "3": "OFF" }, width: 3.5, height: 4.6, offBoard: true,
nets: { COM: "REG_ENABLE", ON: "SYS", OFF: "GND" }, status: "Charging stays active when off; switch travel/MPN unverified." },
...["BCLK", "WS", "DATA"].map((signal, i): Part => ({ name: `U_ISO${i+1}`,
value: "SN74LVC1G125DBVR", footprint: "SOT-23-5", x: -23 + i * 5, y: 15,
schX: -13, schY: 10 - i * 7,
nets: { VCC: "V3_3", GND: "GND", N_OE: "PRIVACY_N_OE",
A: signal === "DATA" ? "MIC_SD" : `MIC_${signal}_HOST`,
Y: signal === "DATA" ? "MIC_DATA_HOST" : `MIC_${signal}` },
status: "All three digital paths high-Z when private, preventing clock/data back-power. Timing/leakage needs bench validation." })),
{ name: "J_USB", value: "HRO TYPE-C-31-M-12", footprint: "USB-C", x: 0, y: -21.8,
schX: 17, schY: -26, offBoard: true,
nets: { GND_A1: "GND", GND_A12: "GND", GND_B1: "GND", GND_B12: "GND", SHIELD: "GND",
VBUS_A4: "USB_VBUS", VBUS_A9: "USB_VBUS", VBUS_B4: "USB_VBUS", VBUS_B9: "USB_VBUS",
DP_A6: "USB_DP", DP_B6: "USB_DP", DM_A7: "USB_DM", DM_B7: "USB_DM", CC1: "USB_CC1", CC2: "USB_CC2" },
noConnect: ["SBU1", "SBU2"], status: "Library candidate. Shell slots simplified in preview; actual enclosure datum and connector height need checking." },
{ name: "U_CHARGE", value: "BQ24074RGT", footprint: "BQ24074", x: 11, y: -11, schX: 28, schY: -5,
nets: { TS: "BAT_NTC", BAT: "BAT", N_CE: "GND", EN2: "USB_EN2", EN1: "USB_EN1",
N_PGOOD: "POWER_GOOD_N", VSS: "GND", N_CHG: "CHARGE_N", OUT: "SYS", ILIM: "CHG_ILIM",
IN: "VBUS_FUSED", TMR: "CHG_TMR", ITERM: "CHG_ITERM", ISET: "CHG_ISET" },
status: "Power-path charger; 100 mA default; GPIO7/GPIO44 select USB500 only after authorization, or USB suspend. Charge target ≈200 mA; pack charge limits/NTC/thermal design must be verified." },
{ name: "U_REG", value: "TPS63001DRCR", footprint: "TPS63001", x: 23, y: -1,
schX: 28, schY: -17, nets: { VOUT: "V3_3", FB: "V3_3", L2: "REG_L2", PGND: "GND", L1: "REG_L1",
VIN: "SYS", VINA: "SYS", EN: "REG_ENABLE", PS_SYNC: "GND", GND: "GND" },
status: "Fixed 3.3 V buck-boost; load budget must meet minimum-battery current limits. Speaker supplied from SYS separately." },
{ name: "U_AMP", value: "MAX98357AETE+", footprint: "MAX98357A", x: -19, y: -10,
schX: 17, schY: 0, nets: { N_SD_MODE: "AMP_ENABLE", BCLK: "SPK_BCLK", DIN: "SPK_DIN", GAIN: "GND",
GND: "GND", LRCLK: "SPK_WS", OUTN: "SPK_N", OUTP: "SPK_P", VDD: "SYS" },
noConnect: ["NC_5", "NC_6", "NC_12", "NC_13"], status: "I2S bridge-output class D. Neither speaker terminal connects to ground." },
{ name: "J_SPK", value: "Speaker wire pads; supplier TBD", x: -24, y: -15, schX: 24, schY: 5,
pins: { "1": "P", "2": "N" }, width: 4, height: 2, nets: { P: "SPK_P", N: "SPK_N" },
status: "Revised 25 × 9 × 3 mm speaker allocation; proposed 8 ohm transducer requires physical qualification." },
{ name: "J_MOTOR", value: "3 V ERM wire pads; supplier TBD", x: 25, y: -18.5,
schX: 17, schY: 20, pins: { "1": "P", "2": "N" }, width: 4, height: 2,
nets: { P: "MOTOR_3V0", N: "MOTOR_LOW" }, status: "Ø10 × 3.2 mm allocation; 3.3 V tolerance, stall current and supplier MPN unverified." },
{ name: "Q_MOTOR", value: "AO3400A", x: 25, y: -12, schX: 17, schY: 15,
pins: { "1": "G", "2": "S", "3": "D" }, width: 3, height: 2,
nets: { G: "MOTOR_GATE", S: "GND", D: "MOTOR_LOW" }, status: "Pin map 1=G 2=S 3=D; provisional SOT-23 land pattern." },
{ name: "Q_BAT_SENSE", value: "AO3401A P-channel", x: 20, y: 20, schX: 33, schY: 13,
pins: { "1": "G", "2": "S", "3": "D" }, width: 3, height: 2,
nets: { G: "BAT_SENSE_GATE", S: "BAT", D: "BAT_DIV_SUPPLY" },
status: "Switched ADC divider avoids injecting battery current into an unpowered ESP32. Provisional SOT-23 footprint." },
{ name: "Q_BAT_EN", value: "MMBT3904", x: 20, y: 17, schX: 33, schY: 18,
pins: { "1": "B", "2": "E", "3": "C" }, width: 3, height: 2,
nets: { B: "BAT_SENSE_BASE", E: "GND", C: "BAT_SENSE_GATE" },
status: "NPN pulls P-channel gate low only during battery measurement. Provisional SOT-23 footprint." },
{ name: "J_BAT", rotation:-90, value: "Protected 1S LiPo + NTC; connector TBD", x: 16.5, y: -19,
schX: 38, schY: -5, pins: { "1": "BAT_P", "2": "GND", "3": "NTC" }, width: 6, height: 5,
nets: { BAT_P: "BAT", GND: "GND", NTC: "BAT_NTC" },
status: "Must use protected 1S 4.2 V pack, correct polarity and matched 10k NTC. The PDF has no lead/connector/NTC specification." },
{ name: "J_LCD", value: "FH12A-50S-0.5SH(55)", x: 22.5, y: 4, rotation:90,
schX: 50, schY: 0, pins: lcdPins, nets: lcdNets,
noConnect:["SDO","TE","TOUCH_XP","TOUCH_YP","TOUCH_XM","TOUCH_YM"],
status:"JLCPCB C202120: 50-pin, 0.5 mm, top-contact Hirose ZIF for 0.3 mm FPC. ER-TFT028A2-4 pinout follows manufacturer PDF. Flex fold/latch fit still requires qualification." },
{ name:"U_LCD_POWER", value:"TLV70228DBVR", x:16,y:10,schX:40,schY:18,
nets:{IN:"V3_3",EN:"V3_3",GND:"GND",OUT:"LCD_2V8"},noConnect:["NC"] },
...["MOSI","SCK","CS","DC","RESET"].map((signal,i):Part=>({
name:`U_LCD_BUF${i+1}`,value:"SN74LVC1G125DBVR",footprint:"SOT-23-5",x:14,y:14-i*5,
schX:38,schY:10-i*6,nets:{VCC:"LCD_2V8",GND:"GND",N_OE:"GND",A:`LCD_${signal}`,Y:`LCD_${signal}_2V8`},
status:"2.8 V powered, 3.3 V tolerant unidirectional buffer; panel inputs stay within VDDI. Partial-power-down Ioff supported." })),
{ name:"U_BACKLIGHT",value:"TPS61169DCKR",rotation:180,x:16,y:-10,schX:49,schY:-30,
nets:{VIN:"BL_INPUT",GND:"GND",SW:"BL_SW",FB:"BL_SENSE",CTRL:"LCD_BL_PWM"},
status:"Boost current driver; nominal total 40 mA from 204 mV / 5.1 ohm, below panel 80 mA maximum. Bench stability/current balance require qualification." },
{ name:"Q_BL_OFF",value:"AO3401A",x:19,y:-13,schX:56,schY:-30,
nets:{G:"BL_ENABLE_GATE",S:"V3_3",D:"BL_INPUT"},
status:"AO3401A disconnects the low-voltage boost input; a pulled-down NPN enables it from GPIO42. RDS(on) is specified at -2.5 V. CTRL must be low before input shutdown." },
...["BOOT", "RESET"].map((n, i): Part => ({ name: `SW_${n}`, value: `${n} service pads`,
x: -5 + i * 8, y: -12, schX: 3 + i * 6, schY: -19,
pins: { "1": "A", "2": "B" }, width: 3, height: 1.5, nets: { A: n, B: "GND" },
status: "Bridgeable top-side service pads for ROM download/recovery; not user approve/reject controls." })),
{ name: "F_USB", value: "750 mA PTC", x: 5, y: -18, schX: 24, schY: -26,
pins: { "1": "IN", "2": "OUT" }, width: 2, height: 1,
nets: { IN: "USB_VBUS", OUT: "VBUS_FUSED" }, status: "Provisional footprint, hold current/derating and USB inrush need qualification." },
{ name: "D_USB_ESD", value: "USBLC6-2SC6 — candidate", x: -3, y: -16, schX: 8, schY: -27,
pins: { "1": "DM1", "2": "GND", "3": "DP1", "4": "DP2", "5": "VBUS", "6": "DM2" }, width: 3, height: 2,
nets: { DM1: "USB_DM", DM2: "USB_DM", DP1: "USB_DP", DP2: "USB_DP", GND: "GND", VBUS: "USB_VBUS" },
status: "Pin map candidate; SOT-23-6 land pattern provisional. Route within mm of receptacle." },
]
let componentIndex = 0
function passive(kind: NonNullable<Part["kind"]>, name: string, value: string, x: number, y: number,
a: string, b: string, schX?: number, schY?: number): Part {
const i = componentIndex++
return { kind, name, value, x, y, schX: schX ?? -37 + (i % 12) * 6.5,
schY: schY ?? -38 - Math.floor(i / 12) * 5, nets: { pin1: a, pin2: b } }
}
const proposedParts: Part[] = [...core,...chipSupport,
{name:"Q_BL_DRIVE",value:"MMBT3904",physicalPins:{"1":"B","2":"E","3":"C"},x:14,y:-12,schX:60,schY:-30,nets:{B:"BL_ENABLE_BASE",E:"GND",C:"BL_ENABLE_GATE"}},
{name:"U_MOTOR_POWER",value:"TLV70230DBVR",physicalPins:{"1":"IN","2":"GND","3":"EN","4":"NC","5":"OUT"},x:27,y:-13,schX:62,schY:15,nets:{IN:"V3_3",EN:"V3_3",GND:"GND",OUT:"MOTOR_3V0"},noConnect:["NC"]},
passive("resistor","R_USB_EN1_PD","1k",6,-13,"USB_EN1","GND"),
passive("resistor","R_USB_EN2_PD","1k",6,-11,"USB_EN2","GND"),
passive("resistor","R_BL_BASE_PD","1k",14,-14,"BL_ENABLE_BASE","GND"),
{...passive("capacitor","C_RF_BULK","10uF",-8,1.5,"RF_3V3","GND"),rotation:180},
passive("capacitor","C_MOTOR_IN","1uF",25,-13,"V3_3","GND"),
passive("capacitor","C_LCD_IN","1uF",16,13,"V3_3","GND"),
passive("capacitor","C_LCD_OUT","1uF",16,7,"LCD_2V8","GND"),
...Array.from({length:5},(_,i)=>passive("capacitor",`C_LCD_BUF${i+1}`,"100nF",17,14-i*5,"LCD_2V8","GND")),
passive("capacitor","C_LCD_PANEL","1uF",20,10,"LCD_2V8","GND"),
passive("capacitor","C_BL_IN","4.7uF",15,-8,"BL_INPUT","GND"),
passive("capacitor","C_BL_OUT","4.7uF",18,-8,"BL_ANODE_SUPPLY","GND"),
passive("inductor","L_BL","10uH",13,-10,"BL_INPUT","BL_SW"),
passive("diode","D_BL","SS16",13,-14,"BL_SW","BL_ANODE_SUPPLY"),
passive("resistor","R_BL_FB","5.1",20,-10,"BL_SENSE","GND"),
passive("resistor","R_BL_GATE","1k",20,-13,"LCD_BL_ENABLE","BL_ENABLE_BASE"),
passive("resistor","R_BL_GATE_PD","100k",20,-16,"BL_ENABLE_GATE","V3_3"),
passive("resistor","R_BL_PWM_PD","1k",15,-13,"LCD_BL_PWM","GND"),
...Array.from({length:4},(_,i)=>passive("resistor",`R_BL_BALANCE${i+1}`,"100",20,6-i*3,"BL_ANODE_SUPPLY",`LCD_LEDA${i+1}`)),
passive("resistor","R_LCD_CS_PU","10k",12,18,"V3_3","LCD_CS"),
...["MOSI","SCK","DC","RESET"].map((s,i)=>passive("resistor",`R_LCD_${s}_PD`,s==="RESET"?"1k":"100k",12,15-i*3,`LCD_${s}`,"GND")),
passive("resistor", "R_CC1", "5.1k", -7, -19, "USB_CC1", "GND"),
passive("resistor", "R_CC2", "5.1k", -7, -21, "USB_CC2", "GND"),
{...passive("resistor", "R_USB_DM", "22", -3, -14, "USB_DM", "USB_DM_MCU"),rotation:90},
{...passive("resistor", "R_USB_DP", "22", 0, -14, "USB_DP", "USB_DP_MCU"),rotation:90},
passive("resistor", "R_PRIVACY", "10k", -28, 13, "V3_3", "PRIVACY_N_OE"),
passive("resistor", "R_MIC_DISCHARGE", "10k", -28, 11, "MIC_VDD", "GND"),
passive("resistor", "R_PRIVACY_SENSE", "100k", -28, 8, "PRIVACY_N_OE", "PRIVACY_SENSE"),
passive("capacitor", "C_PRIVACY_SENSE", "10nF", -25, 8, "PRIVACY_SENSE", "GND"),
passive("resistor", "R_MIC_BCLK_PD", "100k", -22, 19, "MIC_BCLK", "GND"),
passive("resistor", "R_MIC_WS_PD", "100k", -18, 19, "MIC_WS", "GND"),
passive("resistor", "R_MIC_SD_PD", "100k", -14, 19, "MIC_SD", "GND"),
passive("resistor", "R_MIC_HOST_PD", "100k", -10, 19, "MIC_DATA_HOST", "GND"),
passive("resistor", "R_TALK", "10k", 5, 19, "V3_3", "TALK"),
passive("capacitor", "C_TALK", "10nF", 4, 17, "TALK", "GND"),
passive("resistor", "R_BOOT", "10k", -7, -10, "V3_3", "BOOT"),
passive("resistor", "R_RESET", "10k", -3, -10, "V3_3", "RESET"),
passive("capacitor", "C_RESET", "1uF", 0, -10, "RESET", "GND"),
{...passive("resistor", "R_ISET", "4.42k", 15, -11, "CHG_ISET", "GND"),rotation:90},
passive("resistor", "R_ILIM", "3.24k", 15, -9, "CHG_ILIM", "GND"),
passive("resistor", "R_ITERM", "2.94k", 15, -7, "CHG_ITERM", "GND"),
passive("resistor", "R_TMR", "46.4k", 10, -15, "CHG_TMR", "GND"),
passive("resistor", "R_CHG", "10k", 7, -10, "V3_3", "CHARGE_N"),
passive("resistor", "R_PGOOD", "10k", 4, -16, "V3_3", "POWER_GOOD_N"),
passive("resistor", "R_REG_EN", "100k", 28, -2, "REG_ENABLE", "GND"),
{...passive("inductor", "L_REG", "2.2uH", 23, -5, "REG_L1", "REG_L2"),rotation:-90},
passive("resistor", "R_AMP_PD", "1k", -24, -8, "AMP_ENABLE_HOST", "GND"),
passive("resistor", "R_AMP_CONTROL", "46.4k", -20, -8.5, "AMP_ENABLE_HOST", "AMP_ENABLE"),
passive("resistor", "R_MOTOR_GATE", "22", 22, -11, "HAPTIC", "MOTOR_GATE"),
passive("resistor", "R_MOTOR_PD", "1k", 22, -13, "MOTOR_GATE", "GND"),
passive("diode", "D_FLYBACK", "SS14", 26, -8, "MOTOR_LOW", "MOTOR_3V0"),
passive("resistor", "R_BAT_GATE", "100k", 20, 13, "BAT", "BAT_SENSE_GATE"),
passive("resistor", "R_BAT_BASE", "10k", 20, 10, "BAT_SENSE_EN", "BAT_SENSE_BASE"),
passive("resistor", "R_BAT_BASE_PD", "100k", 20, 7, "BAT_SENSE_BASE", "GND"),
passive("resistor", "R_BAT_TOP", "100k", 19, -15, "BAT_DIV_SUPPLY", "BAT_ADC"),
passive("resistor", "R_BAT_BOTTOM", "100k", 22, -15, "BAT_ADC", "GND"),
passive("capacitor", "C_BAT_ADC", "100nF", 19, -12, "BAT_ADC", "GND"),
...["R", "G", "B"].flatMap((c, i) => [
passive("resistor", `R_LED_${c}`, "1k", 8 + i * 4, 16, `STATUS_${c}`, `LED_${c}_A`),
passive("led", `LED_${c}`, c, 8 + i * 4, 20, `LED_${c}_A`, "GND"),
]),
...[
["C_MIC1", "100nF", -28, 18, "MIC_VDD"], ["C_MIC2", "100nF", 28, 18, "MIC_VDD"],
["C_MIC_BULK", "1uF", -28, 15, "MIC_VDD"],
["C_ISO1", "100nF", -23, 12, "V3_3"], ["C_ISO2", "100nF", -18, 12, "V3_3"], ["C_ISO3", "100nF", -13, 12, "V3_3"],
["C_MCU1", "100nF", 4, -10, "V3_3"], ["C_MCU2", "22uF", 7, -13, "V3_3"],
["C_USB", "1uF", 9, -22, "VBUS_FUSED"], ["C_CHG_IN", "1uF", 10, -18, "VBUS_FUSED"],
["C_CHG_OUT", "10uF", 17, -3, "SYS"], ["C_CHG_BAT", "4.7uF", 14, -15, "BAT"],
["C_REG_IN", "10uF", 19, -1, "SYS"], ["C_REG_OUT1", "10uF", 23, 3, "V3_3"], ["C_REG_OUT2", "10uF", 23, 5, "V3_3"],
["C_AMP1", "100nF", -19, -13, "SYS"], ["C_AMP2", "10uF", -15, -14, "SYS"],
["C_MOTOR", "10uF", 28, -16, "MOTOR_3V0"], ["C_LCD1", "100nF", 23, 12, "V3_3"], ["C_LCD2", "10uF", 23, 15, "V3_3"],
].map(([name, val, x, y, net]) => passive("capacitor", String(name), String(val), Number(x), Number(y), String(net), "GND")),
]
const statusOverrides: Record<string,string> = {
U1:"Bare ESP32-S3R8 QFN56 chip, 8 MB in-package PSRAM and separate flash/clock/RF circuitry. RF tuning, impedance, reset and boot qualification required.",
MIC1:"Stocked ICS-43434 library import, 3.5 × 2.65 × 0.98 mm. Bottom-port acoustic duct and PDF height difference require verification.",
MIC2:"Stocked ICS-43434, opposite LR strap. Same acoustic and height qualification as MIC1.",
SW_PRIVACY:"JLCPCB JS202011JCQN DPDT import. Supplier pad identifiers use common contacts 2 and 6. Contact timing, actuator linkage and enclosure fit require verification.",
SW_TALK:"Stocked TL3305AF160QG import. Board switch sits inside the top edge; linkage reaches the PDF TALK actuator location.",
SW_POWER:"Stocked PCM12SMTR import, common pin 2. Rotation places the actuator toward the right edge; linkage/fit unverified.",
J_USB:"JLCPCB C165948 TYPE-C-31-M-12 import, independent CC pins and four plated shell slots. Imported pad datum is Y=-19.75 to retain 0.5 mm board-edge clearance; enclosure insertion/fit still needs qualification.",
J_BAT:"Stocked JST SM03B-PASS-TB(LF)(SN) locking side-entry import, 5.7 mm height and 3 A contacts with AWG22. Harness BAT / GND / matched pack NTC polarity, wire bend clearance and pack remain to qualify.",
J_SPK:"Stocked JST SH connector. Suggested external SP-2509 is 25 × 9 × 3 mm, 8 ohms / 1 W; mounting and audio output limit require verification.",
J_MOTOR:"Stocked JST SH connector. External ERM, wire harness and operating-voltage limit require qualification.",
Q_MOTOR:"Stocked AO3400A, original SOT-23 library import; gate 1, source 2, drain 3.",
Q_BAT_SENSE:"Stocked AO3401A, original SOT-23 import; switched divider prevents battery injection into an unpowered MCU.",
Q_BAT_EN:"Stocked MMBT3904, original SOT-23 import; base 1, emitter 2, collector 3.",
SW_BOOT:"Stocked TL3305AF160QG service switch for ROM download; no approve/reject control.",
SW_RESET:"Stocked TL3305AF160QG service switch; power switch must be on for native USB programming.",
F_USB:"Stocked Bourns MF-NSMF075-2 750 mA / 6 V import. The charger limits USB current independently; prototype thermal derating remains to measure.",
D_USB_ESD:"Stocked USBLC6-2SC6, original SOT-23-6 import; native USB differential routing requires impedance review.",
}
export const parts: Part[] = proposedParts.map(p => {
const selected = catalogFor(p)
return { ...p, ...(placementOverrides as Record<string,{x:number;y:number}>)[p.name],
value:p.kind ? p.value : selected?.mpn ?? p.value,
rotation:p.name==="C_MCU1" ? -90 : p.rotation,
status: statusOverrides[p.name] ?? p.status }
})
export const reviewBlockers = [
"Prototype artwork must pass native DRC and the manufacturing exporter before release. The design includes revised converter placement, local supply connections, filled power/ground planes and corrected supplier selections; measured evidence is retained in docs/.",
"USB main paths are paired on top. Charger inputs default to USB100; firmware must implement authorized USB500 and suspend. Backlight hard-off switches its low-voltage input through an AO3401A, with a transistor gate driver and 40 mA nominal total LED current.",
"ER-TFT028A2-4 manufacturer PDF v1.0 was retrieved from a public hardware mirror. The real 50-pin connector, serial-II straps, 2.8 V supplies/level buffers and current-controlled backlight are implemented; flex fold, latch access, timing, LED balance and actual panel availability remain to be qualified.",
"Bare ESP32-S3R8 uses a stocked U.FL connector and chip-level RF matching network. RF matching, impedance-controlled stackup, antenna/coax placement and enclosure performance require hardware verification.",
"Imported switches use real PCB datums inside the board; the PDF gives actuator/envelope positions. Linkages, travel, tolerances and privacy contact timing need mechanical verification.",
"Protected 1S pack, pack-matched NTC, lead routing and swelling remain unqualified. Speaker/motor/antenna procurement candidates do not constitute assembled CAD fit approval.",
"The independent KiCad handoff preserves imported electronic lands, USB slots, courtyards and plated thermal holes. Its factory derivative enlarges only the two microphone acoustic NPTH ports to 0.50 mm and segments the four exposed-pad stencil apertures. The declared manufacturing profile needs 0.30 mm via drills / 0.45 mm via pads and 0.15 mm hole-to-copper capability.",
"Prototype manufacturing artwork is checked against the native KiCad board and versioned exporter. Measured USB/RF impedance, rail droop, EMI/thermal behavior and microphone acoustic ducts require prototype qualification.",
"MUSE endpoint, API permissions, authentication, audio format, task/progress protocol and response playback integration require verification against the connected service.",
] as const