traceforge-pcb 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- traceforge/__init__.py +3 -0
- traceforge/__main__.py +3 -0
- traceforge/acp_server.py +570 -0
- traceforge/agent.py +680 -0
- traceforge/altium/__init__.py +6 -0
- traceforge/altium/cfb.py +70 -0
- traceforge/altium/cli.py +60 -0
- traceforge/altium/model.py +163 -0
- traceforge/altium/outputs.py +24 -0
- traceforge/altium/pcb.py +301 -0
- traceforge/altium/project.py +328 -0
- traceforge/altium/schematic.py +400 -0
- traceforge/altium/tools.py +166 -0
- traceforge/approval.py +219 -0
- traceforge/attachments.py +346 -0
- traceforge/background.py +253 -0
- traceforge/bench/__init__.py +5 -0
- traceforge/bench/adapters.py +337 -0
- traceforge/bench/checks.py +410 -0
- traceforge/bench/cli.py +121 -0
- traceforge/bench/design.py +439 -0
- traceforge/bench/kicad.py +99 -0
- traceforge/bench/partscheck.py +159 -0
- traceforge/bench/review.py +100 -0
- traceforge/bench/runner.py +226 -0
- traceforge/bench/score.py +204 -0
- traceforge/bench/tasks.py +102 -0
- traceforge/chat.py +1185 -0
- traceforge/checks.py +328 -0
- traceforge/checks_sides.py +118 -0
- traceforge/cli.py +2224 -0
- traceforge/clipboard.py +107 -0
- traceforge/config.py +299 -0
- traceforge/context.py +276 -0
- traceforge/design/__init__.py +1 -0
- traceforge/design/constraints.py +397 -0
- traceforge/design/generate.py +1789 -0
- traceforge/design/outline.py +905 -0
- traceforge/design/schematic_layout.py +932 -0
- traceforge/design/schematic_lint.py +329 -0
- traceforge/design/schematic_route.py +207 -0
- traceforge/design/sheets.py +854 -0
- traceforge/design/sides.py +328 -0
- traceforge/design/spec.py +462 -0
- traceforge/design/specsheet.py +2351 -0
- traceforge/design/specsheet_render.py +183 -0
- traceforge/desktop/__init__.py +109 -0
- traceforge/desktop/keys.py +90 -0
- traceforge/desktop/project.py +443 -0
- traceforge/desktop/review.py +20 -0
- traceforge/desktop/server.py +1277 -0
- traceforge/desktop/static/app.css +223 -0
- traceforge/desktop/static/app.js +683 -0
- traceforge/desktop/static/highlight.js +77 -0
- traceforge/desktop/static/index.html +89 -0
- traceforge/desktop/static/md.js +90 -0
- traceforge/desktop/static/viewer.js +213 -0
- traceforge/desktop/symbols.py +212 -0
- traceforge/desktop/update.py +65 -0
- traceforge/diagnostics.py +67 -0
- traceforge/errata.py +219 -0
- traceforge/fab.py +108 -0
- traceforge/fab_layers.py +44 -0
- traceforge/features/__init__.py +6 -0
- traceforge/features/candidates.py +117 -0
- traceforge/features/cli.py +200 -0
- traceforge/features/package.py +433 -0
- traceforge/features/revdiff.py +224 -0
- traceforge/features/sarif.py +145 -0
- traceforge/features/viewer.py +265 -0
- traceforge/firmware/__init__.py +3 -0
- traceforge/firmware/cli.py +174 -0
- traceforge/firmware/drivers.py +372 -0
- traceforge/firmware/drivers_data.py +256 -0
- traceforge/firmware/mcus.py +177 -0
- traceforge/firmware/netlist.py +55 -0
- traceforge/firmware/pinmap.py +296 -0
- traceforge/firmware/scaffold.py +466 -0
- traceforge/firmware/toolchain.py +262 -0
- traceforge/hooks.py +237 -0
- traceforge/kicad/__init__.py +0 -0
- traceforge/kicad/cli.py +519 -0
- traceforge/kicad/diffpair.py +174 -0
- traceforge/kicad/edgegeom.py +191 -0
- traceforge/kicad/edit.py +405 -0
- traceforge/kicad/escape.py +1410 -0
- traceforge/kicad/formats.py +1073 -0
- traceforge/kicad/impedance.py +320 -0
- traceforge/kicad/install.py +75 -0
- traceforge/kicad/libraries.py +490 -0
- traceforge/kicad/models3d.py +942 -0
- traceforge/kicad/outputs.py +81 -0
- traceforge/kicad/pcb.py +787 -0
- traceforge/kicad/planes.py +1242 -0
- traceforge/kicad/project.py +136 -0
- traceforge/kicad/route.py +2698 -0
- traceforge/kicad/routegeom.py +164 -0
- traceforge/kicad/schematic.py +268 -0
- traceforge/kicad/sides.py +34 -0
- traceforge/kicad/stackup.py +424 -0
- traceforge/kicad_plugin/__init__.py +12 -0
- traceforge/kicad_plugin/actions.py +92 -0
- traceforge/kicad_plugin/cli.py +66 -0
- traceforge/kicad_plugin/client.py +86 -0
- traceforge/kicad_plugin/context.py +257 -0
- traceforge/kicad_plugin/discovery.py +81 -0
- traceforge/kicad_plugin/install.py +203 -0
- traceforge/kicad_plugin/overlay.py +60 -0
- traceforge/kicad_plugin/payload/action_plugin.py +65 -0
- traceforge/kicad_plugin/payload/ipc_main.py +42 -0
- traceforge/kicad_plugin/payload/plugin.json +90 -0
- traceforge/kicad_plugin/payload/requirements.txt +1 -0
- traceforge/kicad_plugin/views.py +202 -0
- traceforge/langchain.py +57 -0
- traceforge/local.py +580 -0
- traceforge/mcp_server.py +304 -0
- traceforge/models.py +310 -0
- traceforge/next_steps.py +110 -0
- traceforge/parts/__init__.py +52 -0
- traceforge/parts/alternates.py +488 -0
- traceforge/parts/bom.py +423 -0
- traceforge/parts/brief.py +705 -0
- traceforge/parts/catalog.py +297 -0
- traceforge/parts/cli_sourcing.py +156 -0
- traceforge/parts/data/duty_rates.yaml +37 -0
- traceforge/parts/data/hs_codes.yaml +103 -0
- traceforge/parts/datasheet.py +278 -0
- traceforge/parts/fx.py +100 -0
- traceforge/parts/model.py +185 -0
- traceforge/parts/net.py +187 -0
- traceforge/parts/offers.py +46 -0
- traceforge/parts/packages.py +397 -0
- traceforge/parts/pinout.py +714 -0
- traceforge/parts/providers/__init__.py +17 -0
- traceforge/parts/providers/base.py +100 -0
- traceforge/parts/providers/jlc.py +364 -0
- traceforge/parts/providers/keyed.py +661 -0
- traceforge/parts/report.py +508 -0
- traceforge/parts/supply.py +330 -0
- traceforge/parts/verify.py +455 -0
- traceforge/parts/web.py +575 -0
- traceforge/plans.py +70 -0
- traceforge/preferences.py +127 -0
- traceforge/prices.py +130 -0
- traceforge/prices.yaml +28 -0
- traceforge/prompts/__init__.py +54 -0
- traceforge/prompts/system.md +103 -0
- traceforge/providers.py +764 -0
- traceforge/remote/__init__.py +33 -0
- traceforge/remote/client.py +422 -0
- traceforge/remote/oidc.py +240 -0
- traceforge/remote/orgs.py +510 -0
- traceforge/remote/server.py +690 -0
- traceforge/remote/store.py +100 -0
- traceforge/review_changes.py +187 -0
- traceforge/routing.py +99 -0
- traceforge/runtime.py +435 -0
- traceforge/sessions.py +324 -0
- traceforge/sexpr.py +279 -0
- traceforge/sim/__init__.py +17 -0
- traceforge/sim/acmath.py +234 -0
- traceforge/sim/circuit.py +499 -0
- traceforge/sim/cli.py +162 -0
- traceforge/sim/engine.py +172 -0
- traceforge/sim/ltspice.py +175 -0
- traceforge/sim/measure.py +123 -0
- traceforge/sim/models.py +76 -0
- traceforge/sim/project.py +218 -0
- traceforge/sim/rawfile.py +123 -0
- traceforge/sim/results.py +298 -0
- traceforge/sim/tune.py +172 -0
- traceforge/skill_commands.py +165 -0
- traceforge/skill_library/circuit-simulation/SKILL.md +30 -0
- traceforge/skill_library/compliance-review/SKILL.md +51 -0
- traceforge/skill_library/design-review/SKILL.md +47 -0
- traceforge/skill_library/errata-hunt/SKILL.md +30 -0
- traceforge/skill_library/firmware/SKILL.md +26 -0
- traceforge/skill_library/power-budget/SKILL.md +27 -0
- traceforge/skill_library/release-package/SKILL.md +29 -0
- traceforge/skill_library/sourcing-brief/SKILL.md +24 -0
- traceforge/skill_library/thermal-review/SKILL.md +15 -0
- traceforge/skills.py +131 -0
- traceforge/thermal.py +557 -0
- traceforge/tools/__init__.py +48 -0
- traceforge/tools/agent_tools.py +213 -0
- traceforge/tools/base.py +303 -0
- traceforge/tools/batch.py +155 -0
- traceforge/tools/connections.py +245 -0
- traceforge/tools/files.py +777 -0
- traceforge/tools/firmware_tools.py +218 -0
- traceforge/tools/kicad_tools.py +1072 -0
- traceforge/tools/models3d_tools.py +141 -0
- traceforge/tools/parts_tools.py +473 -0
- traceforge/tools/processes.py +246 -0
- traceforge/tools/review_tools.py +178 -0
- traceforge/tools/sim_tools.py +230 -0
- traceforge/tui.py +620 -0
- traceforge/updates.py +124 -0
- traceforge/validate/__init__.py +77 -0
- traceforge/validate/builtins.py +1091 -0
- traceforge/validate/circuits.py +1240 -0
- traceforge/validate/config.py +410 -0
- traceforge/validate/default.yaml +113 -0
- traceforge/validate/design.py +191 -0
- traceforge/validate/explain.py +112 -0
- traceforge/validate/grounding.py +169 -0
- traceforge/validate/ipc2221.py +350 -0
- traceforge/validate/multilayer.py +805 -0
- traceforge/validate/netmodel.py +261 -0
- traceforge/validate/partcheck.py +472 -0
- traceforge/validate/report.py +280 -0
- traceforge/validate/review.py +322 -0
- traceforge/validate/runner.py +662 -0
- traceforge/workspace.py +171 -0
- traceforge_pcb-1.0.0.dist-info/METADATA +463 -0
- traceforge_pcb-1.0.0.dist-info/RECORD +219 -0
- traceforge_pcb-1.0.0.dist-info/WHEEL +4 -0
- traceforge_pcb-1.0.0.dist-info/entry_points.txt +2 -0
- traceforge_pcb-1.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"""Firmware tools: pin map from the netlist, scaffolds, driver snippets, build and flash."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from traceforge.firmware.drivers import generate_driver, supported_parts
|
|
9
|
+
from traceforge.firmware.netlist import NetlistError, load_netlist
|
|
10
|
+
from traceforge.firmware.pinmap import HEADER_FILES, PinMap, build_pinmap, render_header
|
|
11
|
+
from traceforge.firmware.scaffold import TARGETS, ScaffoldError, scaffold
|
|
12
|
+
from traceforge.firmware.toolchain import (
|
|
13
|
+
INSTALL_GUIDANCE,
|
|
14
|
+
compile_project,
|
|
15
|
+
detect_tools,
|
|
16
|
+
flash_command,
|
|
17
|
+
flash_project,
|
|
18
|
+
size_project,
|
|
19
|
+
)
|
|
20
|
+
from traceforge.tools.base import Tool, ToolContext, ToolError, ToolKind
|
|
21
|
+
from traceforge.tools.kicad_tools import _schematic_path
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _design(args: dict[str, Any], ctx: ToolContext) -> Path:
|
|
25
|
+
if args.get("design"):
|
|
26
|
+
return ctx.resolve(args["design"], must_exist=True)
|
|
27
|
+
return _schematic_path(args, ctx)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _pinmap(args: dict[str, Any], ctx: ToolContext) -> tuple[PinMap, Path]:
|
|
31
|
+
design = _design(args, ctx)
|
|
32
|
+
try:
|
|
33
|
+
return build_pinmap(load_netlist(design), args.get("ref"), args.get("mcu")), design
|
|
34
|
+
except NetlistError as exc:
|
|
35
|
+
raise ToolError(str(exc)) from exc
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def firmware_pins(args: dict[str, Any], ctx: ToolContext) -> dict:
|
|
39
|
+
pm, design = _pinmap(args, ctx)
|
|
40
|
+
result = pm.as_dict()
|
|
41
|
+
style = args.get("style")
|
|
42
|
+
if style:
|
|
43
|
+
if style not in HEADER_FILES:
|
|
44
|
+
raise ToolError(f"style must be one of {', '.join(HEADER_FILES)}")
|
|
45
|
+
result["header"] = render_header(pm, style, ctx.display(design))
|
|
46
|
+
return result
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def firmware_scaffold(args: dict[str, Any], ctx: ToolContext) -> dict:
|
|
50
|
+
pm, design = _pinmap(args, ctx)
|
|
51
|
+
out = ctx.resolve(args.get("out") or "firmware", for_write=True)
|
|
52
|
+
try:
|
|
53
|
+
files = scaffold(
|
|
54
|
+
pm, out, args.get("target"), args.get("name"), args.get("drivers") or [],
|
|
55
|
+
ctx.display(design), bool(args.get("overwrite")),
|
|
56
|
+
) # fmt: skip
|
|
57
|
+
except (ScaffoldError, KeyError) as exc:
|
|
58
|
+
raise ToolError(str(exc)) from exc
|
|
59
|
+
return {"written": [ctx.display(f) for f in files], "warnings": pm.warnings}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def firmware_driver(args: dict[str, Any], ctx: ToolContext) -> dict:
|
|
63
|
+
if not args.get("part"):
|
|
64
|
+
return {"parts": supported_parts()}
|
|
65
|
+
try:
|
|
66
|
+
files = generate_driver(args["part"], args.get("address"))
|
|
67
|
+
except KeyError as exc:
|
|
68
|
+
raise ToolError(exc.args[0]) from exc
|
|
69
|
+
if args.get("out"):
|
|
70
|
+
out = ctx.resolve(args["out"], for_write=True)
|
|
71
|
+
out.mkdir(parents=True, exist_ok=True)
|
|
72
|
+
for name, text in files.items():
|
|
73
|
+
(out / name).write_text(text, encoding="utf-8")
|
|
74
|
+
return {"written": [ctx.display(out / n) for n in files]}
|
|
75
|
+
return {"files": files}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def firmware_toolchain(args: dict[str, Any], ctx: ToolContext) -> dict:
|
|
79
|
+
return {
|
|
80
|
+
"tools": [
|
|
81
|
+
{"name": t.name, "found": t.found, "path": t.path, "version": t.version,
|
|
82
|
+
"install": t.guidance}
|
|
83
|
+
for t in detect_tools()
|
|
84
|
+
]
|
|
85
|
+
} # fmt: skip
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def firmware_build(args: dict[str, Any], ctx: ToolContext) -> dict:
|
|
89
|
+
project = ctx.resolve(args.get("project") or ".", must_exist=True)
|
|
90
|
+
action = args.get("action", "compile")
|
|
91
|
+
timeout = float(args.get("timeout", 1800))
|
|
92
|
+
try:
|
|
93
|
+
if action == "size":
|
|
94
|
+
result = size_project(project, timeout)
|
|
95
|
+
elif action == "compile":
|
|
96
|
+
result = compile_project(project, timeout)
|
|
97
|
+
else:
|
|
98
|
+
raise ToolError("action must be compile or size")
|
|
99
|
+
except ValueError as exc:
|
|
100
|
+
raise ToolError(str(exc)) from exc
|
|
101
|
+
data = result.as_dict()
|
|
102
|
+
data["output_tail"] = result.output[-3000:]
|
|
103
|
+
if result.returncode == 127:
|
|
104
|
+
data["install"] = INSTALL_GUIDANCE.get(result.tool, "")
|
|
105
|
+
return data
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def firmware_flash(args: dict[str, Any], ctx: ToolContext) -> dict:
|
|
109
|
+
"""Runs only because the tool is SHELL kind: the host asks the user before it executes."""
|
|
110
|
+
project = ctx.resolve(args.get("project") or ".", must_exist=True)
|
|
111
|
+
try:
|
|
112
|
+
if args.get("dry_run", False):
|
|
113
|
+
return {"command": flash_command(project, args.get("port"))}
|
|
114
|
+
result = flash_project(project, args.get("port"), approved=True)
|
|
115
|
+
except ValueError as exc:
|
|
116
|
+
raise ToolError(str(exc)) from exc
|
|
117
|
+
data = result.as_dict()
|
|
118
|
+
data["output_tail"] = result.output[-2000:]
|
|
119
|
+
return data
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
_DESIGN = {
|
|
123
|
+
"design": {"type": "string", "description": "design spec (.yaml), .kicad_sch or .net"},
|
|
124
|
+
"schematic": {"type": "string", "description": "schematic when 'design' is not given"},
|
|
125
|
+
"ref": {"type": "string", "description": "MCU reference, e.g. U1 (auto-detected)"},
|
|
126
|
+
"mcu": {"type": "string", "description": "attiny85 | esp32s3 | stm32f103 (auto-detected)"},
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
FIRMWARE_TOOLS = [
|
|
130
|
+
Tool(
|
|
131
|
+
"firmware_pins",
|
|
132
|
+
"Pin map from the netlist: every non-power net on the MCU mapped to its pin, GPIO "
|
|
133
|
+
"number and peripheral (UART/SPI/I2C/PWM/ADC) using the datasheet pin table; "
|
|
134
|
+
"warns on strapping/reserved pins and functions the pin cannot do. With 'style' "
|
|
135
|
+
"(c | cpp | rust) also returns the pins.h / pins.hpp / board_pins.rs text.",
|
|
136
|
+
{"type": "object", "properties": {**_DESIGN, "style": {"type": "string"}}},
|
|
137
|
+
firmware_pins,
|
|
138
|
+
ToolKind.READ,
|
|
139
|
+
),
|
|
140
|
+
Tool(
|
|
141
|
+
"firmware_scaffold",
|
|
142
|
+
"Write a firmware project for the design: target arduino | platformio | esp-idf | "
|
|
143
|
+
"stm32 | avr, with the generated pin header, a small main, and optional drivers "
|
|
144
|
+
"(see firmware_driver).",
|
|
145
|
+
{
|
|
146
|
+
"type": "object",
|
|
147
|
+
"properties": {
|
|
148
|
+
**_DESIGN,
|
|
149
|
+
"target": {"type": "string", "enum": list(TARGETS)},
|
|
150
|
+
"out": {"type": "string", "description": "output folder (default firmware)"},
|
|
151
|
+
"name": {"type": "string"},
|
|
152
|
+
"drivers": {"type": "array", "items": {"type": "string"}},
|
|
153
|
+
"overwrite": {"type": "boolean"},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
firmware_scaffold,
|
|
157
|
+
ToolKind.WRITE,
|
|
158
|
+
target_arg="out",
|
|
159
|
+
),
|
|
160
|
+
Tool(
|
|
161
|
+
"firmware_driver",
|
|
162
|
+
"Generate init/read driver C code for an I2C/SPI/single-wire part from its register "
|
|
163
|
+
"table (BME280, SHT31, MCP23017, PCF85063A, DHT11, LM75, SSD1306). Without 'part' "
|
|
164
|
+
"lists the parts. Returns the text, or writes it to 'out'.",
|
|
165
|
+
{
|
|
166
|
+
"type": "object",
|
|
167
|
+
"properties": {
|
|
168
|
+
"part": {"type": "string"},
|
|
169
|
+
"address": {"type": "integer", "description": "7-bit address override"},
|
|
170
|
+
"out": {"type": "string"},
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
firmware_driver,
|
|
174
|
+
ToolKind.WRITE,
|
|
175
|
+
target_arg="out",
|
|
176
|
+
),
|
|
177
|
+
Tool(
|
|
178
|
+
"firmware_toolchain",
|
|
179
|
+
"Which firmware tools are installed (arduino-cli, platformio, idf.py, avr-gcc, "
|
|
180
|
+
"arm-none-eabi-gcc), their versions, and install guidance for the missing ones.",
|
|
181
|
+
{"type": "object", "properties": {}},
|
|
182
|
+
firmware_toolchain,
|
|
183
|
+
ToolKind.READ,
|
|
184
|
+
),
|
|
185
|
+
Tool(
|
|
186
|
+
"firmware_build",
|
|
187
|
+
"Compile (action compile) or report memory use (action size) of a firmware project "
|
|
188
|
+
"made by firmware_scaffold, with the real toolchain; returns parsed errors and "
|
|
189
|
+
"flash/RAM use.",
|
|
190
|
+
{
|
|
191
|
+
"type": "object",
|
|
192
|
+
"properties": {
|
|
193
|
+
"project": {"type": "string"},
|
|
194
|
+
"action": {"type": "string", "enum": ["compile", "size"]},
|
|
195
|
+
"timeout": {"type": "number"},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
firmware_build,
|
|
199
|
+
ToolKind.SHELL,
|
|
200
|
+
target_arg="project",
|
|
201
|
+
),
|
|
202
|
+
Tool(
|
|
203
|
+
"firmware_flash",
|
|
204
|
+
"Flash the board from a firmware project (asks the user first). With dry_run only "
|
|
205
|
+
"returns the command.",
|
|
206
|
+
{
|
|
207
|
+
"type": "object",
|
|
208
|
+
"properties": {
|
|
209
|
+
"project": {"type": "string"},
|
|
210
|
+
"port": {"type": "string", "description": "serial port, e.g. /dev/ttyUSB0"},
|
|
211
|
+
"dry_run": {"type": "boolean"},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
firmware_flash,
|
|
215
|
+
ToolKind.SHELL,
|
|
216
|
+
target_arg="project",
|
|
217
|
+
),
|
|
218
|
+
]
|