@hybridlabor-api/bdb-hardware-pcb 0.1.0
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.
- package/README.md +116 -0
- package/config/mcp/antigravity.json +22 -0
- package/config/mcp/claude.json +22 -0
- package/config/mcp/codex.toml +25 -0
- package/docs/adr/ADR-001-KICAD-OPENSCAD-MCP-STRATEGY.md +334 -0
- package/docs/review_documentation.md +121 -0
- package/installer.js +358 -0
- package/mcp_servers/kicad-mcp-server/.env.example +22 -0
- package/mcp_servers/kicad-mcp-server/.github/workflows/ci.yml +36 -0
- package/mcp_servers/kicad-mcp-server/CLAUDE.md +487 -0
- package/mcp_servers/kicad-mcp-server/README.md +316 -0
- package/mcp_servers/kicad-mcp-server/docs/DEVICE_TREE.md +416 -0
- package/mcp_servers/kicad-mcp-server/docs/INSTALLATION.md +332 -0
- package/mcp_servers/kicad-mcp-server/docs/PIN_ANALYSIS.md +332 -0
- package/mcp_servers/kicad-mcp-server/docs/README.md +240 -0
- package/mcp_servers/kicad-mcp-server/docs/TESTING.md +613 -0
- package/mcp_servers/kicad-mcp-server/docs/VALIDATION.md +268 -0
- package/mcp_servers/kicad-mcp-server/pyproject.toml +96 -0
- package/mcp_servers/kicad-mcp-server/requirements-dev.txt +16 -0
- package/mcp_servers/kicad-mcp-server/requirements-test.txt +24 -0
- package/mcp_servers/kicad-mcp-server/requirements.txt +13 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__init__.py +3 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__main__.py +17 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/config.py +46 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/types.py +87 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/netlist_parser.py +234 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser.py +375 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser_kicad.py +327 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/schematic_parser.py +902 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/server.py +71 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/arduino/connectivity_test.cpp.j2 +189 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/atmega.dts.j2 +77 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/esp32.dts.j2 +77 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/nrf52.dts.j2 +77 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/stm32f4.dts.j2 +89 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/esp_idf/test_suite.c.j2 +340 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/pytest/test_connectivity.py.j2 +147 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/st_hal/hal_test.c.j2 +313 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_gpio_test.py.j2 +99 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_i2c_test.py.j2 +117 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_pinmux_test.py.j2 +43 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_spi_test.py.j2 +94 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_gpio_test.c.j2 +113 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_i2c_test.c.j2 +101 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_spi_test.c.j2 +94 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/unittest/test_schematic.py.j2 +172 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/__init__.py +36 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/device_tree.py +1187 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/hierarchical_analysis.py +211 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/netlist.py +320 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/parts_registry.py +142 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb.py +955 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb_layout.py +308 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pin_analysis.py +765 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/project.py +196 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic.py +319 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_editor.py +674 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_search.py +158 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/validation.py +866 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/visualization.py +225 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/file_handlers.py +65 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_cli.py +103 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_version.py +103 -0
- package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/parts_registry.py +197 -0
- package/mcp_servers/kicad-mcp-server/tests/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/tests/examples/ESP32S3_TEST.md +219 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/README.md +65 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/example_pcb.kicad_pcb +177 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/example_schematic.kicad_sch +145 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/child.kicad_sch +24 -0
- package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/root.kicad_sch +38 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/__init__.py +1 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_hierarchical_labels.py +195 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_kicad_cli.py +116 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_netlist_cache_path.py +29 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic.py +189 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic_hierarchy.py +69 -0
- package/mcp_servers/kicad-mcp-server/tests/test_tools/test_visualization.py +136 -0
- package/mcp_servers/kicad-mcp-server/uv.lock +2873 -0
- package/mcp_servers/openscad-mcp-server/.dockerignore +9 -0
- package/mcp_servers/openscad-mcp-server/.github/workflows/test.yml +40 -0
- package/mcp_servers/openscad-mcp-server/Dockerfile +29 -0
- package/mcp_servers/openscad-mcp-server/LICENSE +21 -0
- package/mcp_servers/openscad-mcp-server/README.md +154 -0
- package/mcp_servers/openscad-mcp-server/docs/audit.md +56 -0
- package/mcp_servers/openscad-mcp-server/docs/docker.md +66 -0
- package/mcp_servers/openscad-mcp-server/docs/issue-followup.md +19 -0
- package/mcp_servers/openscad-mcp-server/docs/jetson.md +17 -0
- package/mcp_servers/openscad-mcp-server/glama.json +4 -0
- package/mcp_servers/openscad-mcp-server/legacy/README.md +15 -0
- package/mcp_servers/openscad-mcp-server/legacy/README.original.md +294 -0
- package/mcp_servers/openscad-mcp-server/legacy/implementation_plan.md +100 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/download_sam2_checkpoint.py +115 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/src/ai/sam_segmentation.py +209 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/src/models/threestudio_generator.py +231 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/src/workflow/image_to_model_pipeline.py +260 -0
- package/mcp_servers/openscad-mcp-server/legacy/old/test_sam2_segmentation.py +96 -0
- package/mcp_servers/openscad-mcp-server/legacy/requirements.txt +57 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/README.md +39 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/ai-driven-code-generation.md +122 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/export-formats.md +76 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/ai/ai_service.py.md +51 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/main.py.md +63 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/models/code_generator.py.md +63 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/nlp/parameter_extractor.py.md +63 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/ai/natural-language-processing.md +78 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/nlp/parameter-extraction.md +173 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/export-formats.md +91 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/openscad-basics.md +66 -0
- package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/primitive-testing.md +79 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/ai/ai_service.py +257 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/ai/gemini_api.py +161 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/ai/venice_api.py +203 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/config.py +121 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/main.py +1456 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/main.py.new +404 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/main_remote.py +401 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/code_generator.py +321 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/cuda_mvs.py +209 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/models/scad_templates/basic_shapes.scad +144 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/nlp/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/nlp/parameter_extractor.py +388 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/wrapper.py +418 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/__init__.py +1 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/printer_discovery.py +471 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/connection_manager.py +537 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_client.py +435 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_server.py +787 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/remote/error_handling.py +415 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/testing/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/testing/primitive_tester.py +203 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/testing/test_primitives.py +98 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/__init__.py +1 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/cad_exporter.py +241 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/format_validator.py +206 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_exporter.py +140 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_repair.py +91 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_validator.py +123 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/__init__.py +0 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/headless_renderer.py +52 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/renderer.py +177 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/visualization/web_interface.py +639 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/workflow/image_approval.py +148 -0
- package/mcp_servers/openscad-mcp-server/legacy/src/workflow/multi_view_to_model_pipeline.py +338 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_complete_workflow.py +374 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_cuda_mvs.py +191 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_gemini_api.py +168 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_image_approval.py +192 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_image_approval_workflow.py +251 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_image_to_model_pipeline.py +145 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_model_selection.py +41 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_multi_view_pipeline.py +290 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_primitives.sh +13 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_rabbit_direct.py +71 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_remote_cuda_mvs.py +283 -0
- package/mcp_servers/openscad-mcp-server/legacy/test_venice_example.py +69 -0
- package/mcp_servers/openscad-mcp-server/pyproject.toml +33 -0
- package/mcp_servers/openscad-mcp-server/requirements.txt +2 -0
- package/mcp_servers/openscad-mcp-server/scad/simple_cube.scad +2 -0
- package/mcp_servers/openscad-mcp-server/scripts/test_docker.py +220 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__init__.py +3 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__main__.py +3 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/engine.py +94 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/geometry.py +242 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/server.py +245 -0
- package/mcp_servers/openscad-mcp-server/src/openscad_mcp/service.py +190 -0
- package/mcp_servers/openscad-mcp-server/tests/conftest.py +17 -0
- package/mcp_servers/openscad-mcp-server/tests/test_engine.py +37 -0
- package/mcp_servers/openscad-mcp-server/tests/test_geometry.py +106 -0
- package/mcp_servers/openscad-mcp-server/tests/test_integration.py +172 -0
- package/mcp_servers/openscad-mcp-server/tests/test_transports.py +314 -0
- package/mcp_servers/openscad-mcp-server/uv.lock +1123 -0
- package/package.json +44 -0
- package/scripts/install_mcps.sh +86 -0
- package/scripts/openscad_wrapper.sh +62 -0
- package/scripts/run_kicad_mcp.sh +25 -0
- package/scripts/run_openscad_mcp.sh +41 -0
- package/scripts/test_mcp_connection.py +626 -0
- package/scripts/test_mcp_connection.sh +168 -0
- package/skills/code-first-hardware-design/SKILL.md +260 -0
- package/skills/pcb-constraint-definition/SKILL.md +236 -0
- package/skills/pcb-layout-routing-automation/SKILL.md +153 -0
- package/skills/pcb-validation-dfm-signoff/SKILL.md +194 -0
- package/skills/schematic-datasheet-analysis/SKILL.md +202 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESP-IDF Test Suite for {{ project_name }}
|
|
3
|
+
* Generated from {{ schematic_path }}
|
|
4
|
+
*
|
|
5
|
+
* Connectivity and functional tests using ESP-IDF framework.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include <stdio.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
#include "freertos/FreeRTOS.h"
|
|
11
|
+
#include "freertos/task.h"
|
|
12
|
+
#include "esp_system.h"
|
|
13
|
+
#include "esp_log.h"
|
|
14
|
+
#include "esp_console.h"
|
|
15
|
+
#include "argtable3/argtable3.h"
|
|
16
|
+
#include "driver/gpio.h"
|
|
17
|
+
#include "driver/adc.h"
|
|
18
|
+
#include "driver/i2c.h"
|
|
19
|
+
#include "driver/spi_master.h"
|
|
20
|
+
#include "esp_adc_cal.h"
|
|
21
|
+
#include "unity.h"
|
|
22
|
+
|
|
23
|
+
/* Tag for logging */
|
|
24
|
+
static const char *TAG = "{{ project_name }}_test";
|
|
25
|
+
|
|
26
|
+
{% if target_mcu %}
|
|
27
|
+
/* Target MCU: {{ target_mcu }} */
|
|
28
|
+
{% endif %}
|
|
29
|
+
|
|
30
|
+
/* Test statistics */
|
|
31
|
+
static int g_tests_passed = 0;
|
|
32
|
+
static int g_tests_failed = 0;
|
|
33
|
+
|
|
34
|
+
/* GPIO pin definitions from schematic */
|
|
35
|
+
#define GPIO_OUTPUT_IO_0 2
|
|
36
|
+
#define GPIO_OUTPUT_IO_1 15
|
|
37
|
+
#define GPIO_OUTPUT_PIN_SEL ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1))
|
|
38
|
+
|
|
39
|
+
#define GPIO_INPUT_IO_0 4
|
|
40
|
+
#define GPIO_INPUT_IO_1 5
|
|
41
|
+
#define GPIO_INPUT_PIN_SEL ((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))
|
|
42
|
+
|
|
43
|
+
/* ADC configuration */
|
|
44
|
+
#define ADC1_CHANNEL ADC1_CHANNEL_0
|
|
45
|
+
#define ATTENUATION ADC_ATTEN_DB_11
|
|
46
|
+
#define DEFAULT_VREF 1100
|
|
47
|
+
|
|
48
|
+
/* I2C configuration */
|
|
49
|
+
#define I2C_MASTER_SCL_IO 6
|
|
50
|
+
#define I2C_MASTER_SDA_IO 7
|
|
51
|
+
#define I2C_MASTER_NUM I2C_NUM_0
|
|
52
|
+
#define I2C_MASTER_FREQ_HZ 100000
|
|
53
|
+
|
|
54
|
+
/* SPI configuration */
|
|
55
|
+
#define SPI_MOSI_IO 11
|
|
56
|
+
#define SPI_MISO_IO 12
|
|
57
|
+
#define SPI_SCLK_IO 10
|
|
58
|
+
#define SPI_CS_IO 13
|
|
59
|
+
#define SPI_HOST SPI2_HOST
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @brief Test setup - runs before each test
|
|
63
|
+
*/
|
|
64
|
+
static void test_setup(void) {
|
|
65
|
+
ESP_LOGI(TAG, "Test setup started");
|
|
66
|
+
g_tests_passed = 0;
|
|
67
|
+
g_tests_failed = 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @brief Test teardown - runs after each test
|
|
72
|
+
*/
|
|
73
|
+
static void test_teardown(void) {
|
|
74
|
+
ESP_LOGI(TAG, "Test teardown complete");
|
|
75
|
+
ESP_LOGI(TAG, "Tests passed: %d, failed: %d", g_tests_passed, g_tests_failed);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @brief Test power supply using internal ADC
|
|
80
|
+
*/
|
|
81
|
+
TEST(test_utilities, test_power_supply) {
|
|
82
|
+
ESP_LOGI(TAG, "Testing power supply...");
|
|
83
|
+
|
|
84
|
+
/* ADC calibration */
|
|
85
|
+
esp_adc_cal_characteristics_t *adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
|
|
86
|
+
esp_adc_cal_characterize(ADC_UNIT_1, ATTENUATION, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);
|
|
87
|
+
|
|
88
|
+
/* Configure ADC */
|
|
89
|
+
adc1_config_width(ADC_WIDTH_BIT_12);
|
|
90
|
+
adc1_config_channel_atten(ADC1_CHANNEL, ATTENUATION);
|
|
91
|
+
|
|
92
|
+
/* Read ADC value */
|
|
93
|
+
uint32_t adc_reading = 0;
|
|
94
|
+
for (int i = 0; i < 64; i++) {
|
|
95
|
+
adc_reading += adc1_get_raw(ADC1_CHANNEL);
|
|
96
|
+
}
|
|
97
|
+
adc_reading /= 64;
|
|
98
|
+
|
|
99
|
+
/* Convert to voltage */
|
|
100
|
+
uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
|
|
101
|
+
|
|
102
|
+
ESP_LOGI(TAG, "ADC reading: %d mV", voltage);
|
|
103
|
+
|
|
104
|
+
/* Check if voltage is reasonable */
|
|
105
|
+
TEST_ASSERT_TRUE_MSG(voltage > 2700 && voltage < 3600, "Voltage out of range");
|
|
106
|
+
|
|
107
|
+
free(adc_chars);
|
|
108
|
+
g_tests_passed++;
|
|
109
|
+
|
|
110
|
+
ESP_LOGI(TAG, "[PASS] Power supply test");
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @brief Test GPIO connectivity
|
|
115
|
+
*/
|
|
116
|
+
TEST(test_utilities, test_gpio_connectivity) {
|
|
117
|
+
ESP_LOGI(TAG, "Testing GPIO connectivity...");
|
|
118
|
+
|
|
119
|
+
/* Configure GPIO */
|
|
120
|
+
gpio_config_t io_conf = {
|
|
121
|
+
.pin_bit_mask = GPIO_OUTPUT_PIN_SEL,
|
|
122
|
+
.mode = GPIO_MODE_OUTPUT,
|
|
123
|
+
.pull_up_en = GPIO_PULLUP_DISABLE,
|
|
124
|
+
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
|
125
|
+
.intr_type = GPIO_INTR_DISABLE,
|
|
126
|
+
};
|
|
127
|
+
gpio_config(&io_conf);
|
|
128
|
+
|
|
129
|
+
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
|
|
130
|
+
io_conf.mode = GPIO_MODE_INPUT;
|
|
131
|
+
gpio_config(&io_conf);
|
|
132
|
+
|
|
133
|
+
/* Test output pins */
|
|
134
|
+
gpio_set_level(GPIO_OUTPUT_IO_0, 1);
|
|
135
|
+
ets_delay_us(100);
|
|
136
|
+
int level = gpio_get_level(GPIO_OUTPUT_IO_0);
|
|
137
|
+
TEST_ASSERT_EQUAL_INT(1, level);
|
|
138
|
+
|
|
139
|
+
gpio_set_level(GPIO_OUTPUT_IO_0, 0);
|
|
140
|
+
ets_delay_us(100);
|
|
141
|
+
level = gpio_get_level(GPIO_OUTPUT_IO_0);
|
|
142
|
+
TEST_ASSERT_EQUAL_INT(0, level);
|
|
143
|
+
|
|
144
|
+
/* Test input pins */
|
|
145
|
+
for (int i = 0; i < 10; i++) {
|
|
146
|
+
int input_level = gpio_get_level(GPIO_INPUT_IO_0);
|
|
147
|
+
ESP_LOGI(TAG, "Input level: %d", input_level);
|
|
148
|
+
vTaskDelay(pdMS_TO_TICKS(100));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
g_tests_passed++;
|
|
152
|
+
ESP_LOGI(TAG, "[PASS] GPIO connectivity test");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
{% if test_type == "functional" %}
|
|
156
|
+
/**
|
|
157
|
+
* @brief Scan I2C bus for devices
|
|
158
|
+
*/
|
|
159
|
+
TEST(test_utilities, test_i2c_scan) {
|
|
160
|
+
ESP_LOGI(TAG, "Scanning I2C bus...");
|
|
161
|
+
|
|
162
|
+
/* Configure I2C */
|
|
163
|
+
i2c_config_t conf = {
|
|
164
|
+
.mode = I2C_MODE_MASTER,
|
|
165
|
+
.sda_io_num = I2C_MASTER_SDA_IO,
|
|
166
|
+
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
|
167
|
+
.scl_io_num = I2C_MASTER_SCL_IO,
|
|
168
|
+
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
|
169
|
+
.master.clk_speed = I2C_MASTER_FREQ_HZ,
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
i2c_param_config(I2C_MASTER_NUM, &conf);
|
|
173
|
+
i2c_driver_install(I2C_MASTER_NUM, I2C_MODE_MASTER, 0, 0, 0);
|
|
174
|
+
|
|
175
|
+
/* Scan for devices */
|
|
176
|
+
uint8_t devices_found = 0;
|
|
177
|
+
for (uint8_t addr = 1; addr < 127; addr++) {
|
|
178
|
+
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
179
|
+
i2c_master_start(cmd);
|
|
180
|
+
i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_WRITE, 1);
|
|
181
|
+
i2c_master_stop(cmd);
|
|
182
|
+
|
|
183
|
+
esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 10 / portTICK_PERIOD_MS);
|
|
184
|
+
i2c_cmd_link_delete(cmd);
|
|
185
|
+
|
|
186
|
+
if (ret == ESP_OK) {
|
|
187
|
+
ESP_LOGI(TAG, "I2C device found at 0x%02X", addr);
|
|
188
|
+
devices_found++;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
ESP_LOGI(TAG, "Total I2C devices: %d", devices_found);
|
|
193
|
+
|
|
194
|
+
/* Cleanup */
|
|
195
|
+
i2c_driver_delete(I2C_MASTER_NUM);
|
|
196
|
+
|
|
197
|
+
g_tests_passed++;
|
|
198
|
+
ESP_LOGI(TAG, "[PASS] I2C scan complete");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* @brief SPI loopback test
|
|
203
|
+
*/
|
|
204
|
+
TEST(test_utilities, test_spi_loopback) {
|
|
205
|
+
ESP_LOGI(TAG, "Testing SPI...");
|
|
206
|
+
|
|
207
|
+
/* SPI bus configuration */
|
|
208
|
+
spi_bus_config_t buscfg = {
|
|
209
|
+
.mosi_io_num = SPI_MOSI_IO,
|
|
210
|
+
.miso_io_num = SPI_MISO_IO,
|
|
211
|
+
.sclk_io_num = SPI_SCLK_IO,
|
|
212
|
+
.quadwp_io_num = -1,
|
|
213
|
+
.quadhd_io_num = -1,
|
|
214
|
+
.max_transfer_sz = 32,
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
/* SPI device configuration */
|
|
218
|
+
spi_device_handle_t spi;
|
|
219
|
+
spi_device_interface_config_t devcfg = {
|
|
220
|
+
.clock_speed_hz = 1 * 1000 * 1000,
|
|
221
|
+
.mode = 0,
|
|
222
|
+
.spics_io_num = SPI_CS_IO,
|
|
223
|
+
.queue_size = 4,
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/* Initialize SPI bus */
|
|
227
|
+
TEST_ASSERT_TRUE_MSG(spi_bus_initialize(SPI_HOST, &buscfg, 0) == ESP_OK,
|
|
228
|
+
"SPI bus initialization failed");
|
|
229
|
+
|
|
230
|
+
TEST_ASSERT_TRUE_MSG(spi_bus_add_device(SPI_HOST, &devcfg, &spi) == ESP_OK,
|
|
231
|
+
"SPI device add failed");
|
|
232
|
+
|
|
233
|
+
/* Test transaction */
|
|
234
|
+
spi_transaction_t t = {
|
|
235
|
+
.length = 8,
|
|
236
|
+
.tx_data = {0xAA},
|
|
237
|
+
.flags = SPI_TRANS_USE_TXDATA | SPI_TRANS_USE_RXDATA,
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
TEST_ASSERT_TRUE_MSG(spi_device_transmit(spi, &t) == ESP_OK,
|
|
241
|
+
"SPI transmit failed");
|
|
242
|
+
|
|
243
|
+
ESP_LOGI(TAG, "SPI TX: 0x%02X, RX: 0x%02X", t.tx_data[0], t.rx_data[0]);
|
|
244
|
+
|
|
245
|
+
/* Cleanup */
|
|
246
|
+
spi_bus_remove_device(spi);
|
|
247
|
+
spi_bus_free(SPI_HOST);
|
|
248
|
+
|
|
249
|
+
g_tests_passed++;
|
|
250
|
+
ESP_LOGI(TAG, "[PASS] SPI test complete");
|
|
251
|
+
}
|
|
252
|
+
{% endif %}
|
|
253
|
+
|
|
254
|
+
{% if test_type == "production" %}
|
|
255
|
+
/**
|
|
256
|
+
* @brief Production test - all pins
|
|
257
|
+
*/
|
|
258
|
+
TEST(test_utilities, test_all_pins) {
|
|
259
|
+
ESP_LOGI(TAG, "Running production pin test...");
|
|
260
|
+
|
|
261
|
+
/* Test output pins */
|
|
262
|
+
gpio_config_t io_conf = {
|
|
263
|
+
.pin_bit_mask = GPIO_OUTPUT_PIN_SEL,
|
|
264
|
+
.mode = GPIO_MODE_OUTPUT,
|
|
265
|
+
.pull_up_en = GPIO_PULLUP_DISABLE,
|
|
266
|
+
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
|
267
|
+
.intr_type = GPIO_INTR_DISABLE,
|
|
268
|
+
};
|
|
269
|
+
gpio_config(&io_conf);
|
|
270
|
+
|
|
271
|
+
/* Toggle each output pin */
|
|
272
|
+
for (int i = 0; i < 10; i++) {
|
|
273
|
+
gpio_set_level(GPIO_OUTPUT_IO_0, i % 2);
|
|
274
|
+
gpio_set_level(GPIO_OUTPUT_IO_1, (i + 1) % 2);
|
|
275
|
+
vTaskDelay(pdMS_TO_TICKS(100));
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/* Read input pins */
|
|
279
|
+
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
|
|
280
|
+
io_conf.mode = GPIO_MODE_INPUT;
|
|
281
|
+
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
|
282
|
+
gpio_config(&io_conf);
|
|
283
|
+
|
|
284
|
+
for (int i = 0; i < 10; i++) {
|
|
285
|
+
int level0 = gpio_get_level(GPIO_INPUT_IO_0);
|
|
286
|
+
int level1 = gpio_get_level(GPIO_INPUT_IO_1);
|
|
287
|
+
ESP_LOGI(TAG, "Inputs: %d, %d", level0, level1);
|
|
288
|
+
vTaskDelay(pdMS_TO_TICKS(200));
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
g_tests_passed++;
|
|
292
|
+
ESP_LOGI(TAG, "[PASS] Production test complete");
|
|
293
|
+
}
|
|
294
|
+
{% endif %}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* @brief Main test runner
|
|
298
|
+
*/
|
|
299
|
+
static void run_all_tests(void) {
|
|
300
|
+
UNITY_BEGIN();
|
|
301
|
+
|
|
302
|
+
/* Run tests */
|
|
303
|
+
RUN_TEST(test_utilities, test_power_supply);
|
|
304
|
+
RUN_TEST(test_utilities, test_gpio_connectivity);
|
|
305
|
+
{% if test_type == "functional" %}
|
|
306
|
+
RUN_TEST(test_utilities, test_i2c_scan);
|
|
307
|
+
RUN_TEST(test_utilities, test_spi_loopback);
|
|
308
|
+
{% endif %}
|
|
309
|
+
{% if test_type == "production" %}
|
|
310
|
+
RUN_TEST(test_utilities, test_all_pins);
|
|
311
|
+
{% endif %}
|
|
312
|
+
|
|
313
|
+
/* Finish */
|
|
314
|
+
int result = UNITY_END();
|
|
315
|
+
|
|
316
|
+
ESP_LOGI(TAG, "\n========================================");
|
|
317
|
+
ESP_LOGI(TAG, "Test Summary");
|
|
318
|
+
ESP_LOGI(TAG, "========================================");
|
|
319
|
+
ESP_LOGI(TAG, "Passed: %d", g_tests_passed);
|
|
320
|
+
ESP_LOGI(TAG, "Failed: %d", g_tests_failed);
|
|
321
|
+
ESP_LOGI(TAG, "========================================\n");
|
|
322
|
+
|
|
323
|
+
if (result == 0) {
|
|
324
|
+
ESP_LOGI(TAG, "ALL TESTS PASSED!");
|
|
325
|
+
} else {
|
|
326
|
+
ESP_LOGE(TAG, "SOME TESTS FAILED!");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* @brief Main application entry point
|
|
332
|
+
*/
|
|
333
|
+
void app_main(void) {
|
|
334
|
+
ESP_LOGI(TAG, "\n========================================");
|
|
335
|
+
ESP_LOGI(TAG, "{{ project_name }} - ESP-IDF Test Suite");
|
|
336
|
+
ESP_LOGI(TAG, "========================================\n");
|
|
337
|
+
|
|
338
|
+
/* Run tests */
|
|
339
|
+
run_all_tests();
|
|
340
|
+
}
|
package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/pytest/test_connectivity.py.j2
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test connectivity verification for {{ project_name }}
|
|
3
|
+
Generated from {{ schematic_path }}
|
|
4
|
+
|
|
5
|
+
This test suite provides automated connectivity verification based on
|
|
6
|
+
the schematic netlist. Tests verify expected connections between pins.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
from typing import Dict, List, Tuple
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Netlist derived from schematic
|
|
14
|
+
NETLIST = {
|
|
15
|
+
{% for net in nets %}
|
|
16
|
+
"{{ net.name }}": {
|
|
17
|
+
"code": {{ net.code }},
|
|
18
|
+
"pins": {{ net.pins | tojson }},
|
|
19
|
+
},
|
|
20
|
+
{% endfor %}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Component reference information
|
|
24
|
+
COMPONENTS = {
|
|
25
|
+
{% for comp in components %}
|
|
26
|
+
"{{ comp.reference }}": {
|
|
27
|
+
"value": "{{ comp.value }}",
|
|
28
|
+
"footprint": "{{ comp.footprint or 'N/A' }}",
|
|
29
|
+
},
|
|
30
|
+
{% endfor %}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TestConnectivity:
|
|
35
|
+
"""Test suite for schematic connectivity verification."""
|
|
36
|
+
|
|
37
|
+
def test_power_nets_present(self):
|
|
38
|
+
"""Verify that required power nets are present."""
|
|
39
|
+
required_nets = ["GND", "VCC", "VDD"]
|
|
40
|
+
found_nets = [net for net in NETLIST.keys() if any(
|
|
41
|
+
req in net.upper() for req in required_nets
|
|
42
|
+
)]
|
|
43
|
+
|
|
44
|
+
assert len(found_nets) >= 2, "At least GND and one power net should be present"
|
|
45
|
+
print(f"Found power nets: {found_nets}")
|
|
46
|
+
|
|
47
|
+
def test_no_duplicate_references(self):
|
|
48
|
+
"""Verify that all component references are unique."""
|
|
49
|
+
refs = list(COMPONENTS.keys())
|
|
50
|
+
assert len(refs) == len(set(refs)), "Duplicate component references found"
|
|
51
|
+
|
|
52
|
+
def test_component_value_format(self):
|
|
53
|
+
"""Verify that components have valid values."""
|
|
54
|
+
invalid_refs = []
|
|
55
|
+
|
|
56
|
+
for ref, data in COMPONENTS.items():
|
|
57
|
+
value = data["value"]
|
|
58
|
+
if not value or value in ["", "?"]:
|
|
59
|
+
invalid_refs.append(ref)
|
|
60
|
+
|
|
61
|
+
assert len(invalid_refs) == 1, f"Components with missing values: {invalid_refs}"
|
|
62
|
+
|
|
63
|
+
{% if test_type == "functional" %}
|
|
64
|
+
def test_expected_connections(self):
|
|
65
|
+
"""Test expected key connections based on schematic."""
|
|
66
|
+
# Define expected connections based on design intent
|
|
67
|
+
# These should be verified against the schematic
|
|
68
|
+
expected_connections = [
|
|
69
|
+
# Example: ("U1", "1", "U2", "1"), # U1 pin 1 connected to U2 pin 1
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
for source_ref, source_pin, target_ref, target_pin in expected_connections:
|
|
73
|
+
source_pin_id = f"{source_ref}:{source_pin}"
|
|
74
|
+
target_pin_id = f"{target_ref}:{target_pin}"
|
|
75
|
+
|
|
76
|
+
# Check if pins are in the same net
|
|
77
|
+
source_net = None
|
|
78
|
+
for net_name, net_data in NETLIST.items():
|
|
79
|
+
if source_pin_id in net_data["pins"]:
|
|
80
|
+
source_net = net_name
|
|
81
|
+
break
|
|
82
|
+
|
|
83
|
+
target_net = None
|
|
84
|
+
for net_name, net_data in NETLIST.items():
|
|
85
|
+
if target_pin_id in net_data["pins"]:
|
|
86
|
+
target_net = net_name
|
|
87
|
+
break
|
|
88
|
+
|
|
89
|
+
assert source_net is not None, f"{source_pin_id} not found in any net"
|
|
90
|
+
assert target_net is not None, f"{target_pin_id} not found in any net"
|
|
91
|
+
assert source_net == target_net, (
|
|
92
|
+
f"{source_pin_id} and {target_pin_id} should be in the same net"
|
|
93
|
+
)
|
|
94
|
+
{% endif %}
|
|
95
|
+
|
|
96
|
+
{% if test_type == "production" %}
|
|
97
|
+
def test_production_readiness(self):
|
|
98
|
+
"""Verify design is ready for production testing."""
|
|
99
|
+
# Check for unconnected pins
|
|
100
|
+
unconnected_pins = []
|
|
101
|
+
|
|
102
|
+
for net_name, net_data in NETLIST.items():
|
|
103
|
+
if len(net_data["pins"]) <= 1 and net_name not in ["GND", "VCC", "VDD"]:
|
|
104
|
+
unconnected_pins.append(net_name)
|
|
105
|
+
|
|
106
|
+
# Allow some unconnected nets (e.g., no-connect pins)
|
|
107
|
+
assert len(unconnected_pins) < 10, f"Too many unconnected nets: {unconnected_pins}"
|
|
108
|
+
|
|
109
|
+
def test_footprint_assignment(self):
|
|
110
|
+
"""Verify all components have footprints assigned."""
|
|
111
|
+
unassigned = []
|
|
112
|
+
|
|
113
|
+
for ref, data in COMPONENTS.items():
|
|
114
|
+
if data["footprint"] in ["N/A", "", None]:
|
|
115
|
+
unassigned.append(ref)
|
|
116
|
+
|
|
117
|
+
assert len(unassigned) == 0, f"Components without footprints: {unassigned}"
|
|
118
|
+
{% endif %}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class TestFunctionalBlocks:
|
|
122
|
+
"""Test suite for functional block verification."""
|
|
123
|
+
|
|
124
|
+
def test_power_distribution(self):
|
|
125
|
+
"""Verify power distribution is properly configured."""
|
|
126
|
+
power_nets = [name for name in NETLIST.keys() if any(
|
|
127
|
+
pw in name.upper() for pw in ["VCC", "VDD", "+3V3", "+5V", "+12V"]
|
|
128
|
+
)]
|
|
129
|
+
|
|
130
|
+
assert len(power_nets) > 0, "No power rails detected"
|
|
131
|
+
print(f"Power rails: {power_nets}")
|
|
132
|
+
|
|
133
|
+
{% if target_mcu %}
|
|
134
|
+
def test_mcu_configuration(self):
|
|
135
|
+
"""Verify MCU is properly configured."""
|
|
136
|
+
# Look for MCU component
|
|
137
|
+
mcu_refs = [ref for ref, data in COMPONENTS.items() if any(
|
|
138
|
+
mcu in data["value"].lower() for mcu in ["{{ target_mcu }}", "mcu", "micro"]
|
|
139
|
+
)]
|
|
140
|
+
|
|
141
|
+
assert len(mcu_refs) > 0, f"No MCU found (looking for {{ target_mcu }})"
|
|
142
|
+
print(f"Found MCU: {mcu_refs}")
|
|
143
|
+
{% endif %}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
if __name__ == "__main__":
|
|
147
|
+
pytest.main([__file__, "-v"])
|