@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.
Files changed (192) hide show
  1. package/README.md +116 -0
  2. package/config/mcp/antigravity.json +22 -0
  3. package/config/mcp/claude.json +22 -0
  4. package/config/mcp/codex.toml +25 -0
  5. package/docs/adr/ADR-001-KICAD-OPENSCAD-MCP-STRATEGY.md +334 -0
  6. package/docs/review_documentation.md +121 -0
  7. package/installer.js +358 -0
  8. package/mcp_servers/kicad-mcp-server/.env.example +22 -0
  9. package/mcp_servers/kicad-mcp-server/.github/workflows/ci.yml +36 -0
  10. package/mcp_servers/kicad-mcp-server/CLAUDE.md +487 -0
  11. package/mcp_servers/kicad-mcp-server/README.md +316 -0
  12. package/mcp_servers/kicad-mcp-server/docs/DEVICE_TREE.md +416 -0
  13. package/mcp_servers/kicad-mcp-server/docs/INSTALLATION.md +332 -0
  14. package/mcp_servers/kicad-mcp-server/docs/PIN_ANALYSIS.md +332 -0
  15. package/mcp_servers/kicad-mcp-server/docs/README.md +240 -0
  16. package/mcp_servers/kicad-mcp-server/docs/TESTING.md +613 -0
  17. package/mcp_servers/kicad-mcp-server/docs/VALIDATION.md +268 -0
  18. package/mcp_servers/kicad-mcp-server/pyproject.toml +96 -0
  19. package/mcp_servers/kicad-mcp-server/requirements-dev.txt +16 -0
  20. package/mcp_servers/kicad-mcp-server/requirements-test.txt +24 -0
  21. package/mcp_servers/kicad-mcp-server/requirements.txt +13 -0
  22. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__init__.py +3 -0
  23. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/__main__.py +17 -0
  24. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/config.py +46 -0
  25. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/__init__.py +1 -0
  26. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/models/types.py +87 -0
  27. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/__init__.py +1 -0
  28. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/netlist_parser.py +234 -0
  29. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser.py +375 -0
  30. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/pcb_parser_kicad.py +327 -0
  31. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/parsers/schematic_parser.py +902 -0
  32. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/server.py +71 -0
  33. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/__init__.py +1 -0
  34. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/arduino/connectivity_test.cpp.j2 +189 -0
  35. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/atmega.dts.j2 +77 -0
  36. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/esp32.dts.j2 +77 -0
  37. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/nrf52.dts.j2 +77 -0
  38. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/device_tree/stm32f4.dts.j2 +89 -0
  39. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/esp_idf/test_suite.c.j2 +340 -0
  40. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/pytest/test_connectivity.py.j2 +147 -0
  41. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/st_hal/hal_test.c.j2 +313 -0
  42. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_gpio_test.py.j2 +99 -0
  43. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_i2c_test.py.j2 +117 -0
  44. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_pinmux_test.py.j2 +43 -0
  45. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/pytest_spi_test.py.j2 +94 -0
  46. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_gpio_test.c.j2 +113 -0
  47. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_i2c_test.c.j2 +101 -0
  48. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/tests/unity_spi_test.c.j2 +94 -0
  49. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/templates/unittest/test_schematic.py.j2 +172 -0
  50. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/__init__.py +36 -0
  51. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/device_tree.py +1187 -0
  52. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/hierarchical_analysis.py +211 -0
  53. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/netlist.py +320 -0
  54. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/parts_registry.py +142 -0
  55. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb.py +955 -0
  56. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pcb_layout.py +308 -0
  57. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/pin_analysis.py +765 -0
  58. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/project.py +196 -0
  59. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic.py +319 -0
  60. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_editor.py +674 -0
  61. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/schematic_search.py +158 -0
  62. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/validation.py +866 -0
  63. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/tools/visualization.py +225 -0
  64. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/__init__.py +1 -0
  65. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/file_handlers.py +65 -0
  66. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_cli.py +103 -0
  67. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/kicad_version.py +103 -0
  68. package/mcp_servers/kicad-mcp-server/src/kicad_mcp_server/utils/parts_registry.py +197 -0
  69. package/mcp_servers/kicad-mcp-server/tests/__init__.py +1 -0
  70. package/mcp_servers/kicad-mcp-server/tests/examples/ESP32S3_TEST.md +219 -0
  71. package/mcp_servers/kicad-mcp-server/tests/fixtures/README.md +65 -0
  72. package/mcp_servers/kicad-mcp-server/tests/fixtures/__init__.py +1 -0
  73. package/mcp_servers/kicad-mcp-server/tests/fixtures/example_pcb.kicad_pcb +177 -0
  74. package/mcp_servers/kicad-mcp-server/tests/fixtures/example_schematic.kicad_sch +145 -0
  75. package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/child.kicad_sch +24 -0
  76. package/mcp_servers/kicad-mcp-server/tests/fixtures/hier/root.kicad_sch +38 -0
  77. package/mcp_servers/kicad-mcp-server/tests/test_tools/__init__.py +1 -0
  78. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_hierarchical_labels.py +195 -0
  79. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_kicad_cli.py +116 -0
  80. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_netlist_cache_path.py +29 -0
  81. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic.py +189 -0
  82. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_schematic_hierarchy.py +69 -0
  83. package/mcp_servers/kicad-mcp-server/tests/test_tools/test_visualization.py +136 -0
  84. package/mcp_servers/kicad-mcp-server/uv.lock +2873 -0
  85. package/mcp_servers/openscad-mcp-server/.dockerignore +9 -0
  86. package/mcp_servers/openscad-mcp-server/.github/workflows/test.yml +40 -0
  87. package/mcp_servers/openscad-mcp-server/Dockerfile +29 -0
  88. package/mcp_servers/openscad-mcp-server/LICENSE +21 -0
  89. package/mcp_servers/openscad-mcp-server/README.md +154 -0
  90. package/mcp_servers/openscad-mcp-server/docs/audit.md +56 -0
  91. package/mcp_servers/openscad-mcp-server/docs/docker.md +66 -0
  92. package/mcp_servers/openscad-mcp-server/docs/issue-followup.md +19 -0
  93. package/mcp_servers/openscad-mcp-server/docs/jetson.md +17 -0
  94. package/mcp_servers/openscad-mcp-server/glama.json +4 -0
  95. package/mcp_servers/openscad-mcp-server/legacy/README.md +15 -0
  96. package/mcp_servers/openscad-mcp-server/legacy/README.original.md +294 -0
  97. package/mcp_servers/openscad-mcp-server/legacy/implementation_plan.md +100 -0
  98. package/mcp_servers/openscad-mcp-server/legacy/old/download_sam2_checkpoint.py +115 -0
  99. package/mcp_servers/openscad-mcp-server/legacy/old/src/ai/sam_segmentation.py +209 -0
  100. package/mcp_servers/openscad-mcp-server/legacy/old/src/models/threestudio_generator.py +231 -0
  101. package/mcp_servers/openscad-mcp-server/legacy/old/src/workflow/image_to_model_pipeline.py +260 -0
  102. package/mcp_servers/openscad-mcp-server/legacy/old/test_sam2_segmentation.py +96 -0
  103. package/mcp_servers/openscad-mcp-server/legacy/requirements.txt +57 -0
  104. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/README.md +39 -0
  105. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/ai-driven-code-generation.md +122 -0
  106. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/decisions/export-formats.md +76 -0
  107. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/ai/ai_service.py.md +51 -0
  108. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/main.py.md +63 -0
  109. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/models/code_generator.py.md +63 -0
  110. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/files/src/nlp/parameter_extractor.py.md +63 -0
  111. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/ai/natural-language-processing.md +78 -0
  112. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/nlp/parameter-extraction.md +173 -0
  113. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/export-formats.md +91 -0
  114. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/openscad-basics.md +66 -0
  115. package/mcp_servers/openscad-mcp-server/legacy/rtfmd/knowledge/openscad/primitive-testing.md +79 -0
  116. package/mcp_servers/openscad-mcp-server/legacy/src/__init__.py +0 -0
  117. package/mcp_servers/openscad-mcp-server/legacy/src/ai/ai_service.py +257 -0
  118. package/mcp_servers/openscad-mcp-server/legacy/src/ai/gemini_api.py +161 -0
  119. package/mcp_servers/openscad-mcp-server/legacy/src/ai/venice_api.py +203 -0
  120. package/mcp_servers/openscad-mcp-server/legacy/src/config.py +121 -0
  121. package/mcp_servers/openscad-mcp-server/legacy/src/main.py +1456 -0
  122. package/mcp_servers/openscad-mcp-server/legacy/src/main.py.new +404 -0
  123. package/mcp_servers/openscad-mcp-server/legacy/src/main_remote.py +401 -0
  124. package/mcp_servers/openscad-mcp-server/legacy/src/models/__init__.py +0 -0
  125. package/mcp_servers/openscad-mcp-server/legacy/src/models/code_generator.py +321 -0
  126. package/mcp_servers/openscad-mcp-server/legacy/src/models/cuda_mvs.py +209 -0
  127. package/mcp_servers/openscad-mcp-server/legacy/src/models/scad_templates/basic_shapes.scad +144 -0
  128. package/mcp_servers/openscad-mcp-server/legacy/src/nlp/__init__.py +0 -0
  129. package/mcp_servers/openscad-mcp-server/legacy/src/nlp/parameter_extractor.py +388 -0
  130. package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/__init__.py +0 -0
  131. package/mcp_servers/openscad-mcp-server/legacy/src/openscad_wrapper/wrapper.py +418 -0
  132. package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/__init__.py +1 -0
  133. package/mcp_servers/openscad-mcp-server/legacy/src/printer_discovery/printer_discovery.py +471 -0
  134. package/mcp_servers/openscad-mcp-server/legacy/src/remote/connection_manager.py +537 -0
  135. package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_client.py +435 -0
  136. package/mcp_servers/openscad-mcp-server/legacy/src/remote/cuda_mvs_server.py +787 -0
  137. package/mcp_servers/openscad-mcp-server/legacy/src/remote/error_handling.py +415 -0
  138. package/mcp_servers/openscad-mcp-server/legacy/src/testing/__init__.py +0 -0
  139. package/mcp_servers/openscad-mcp-server/legacy/src/testing/primitive_tester.py +203 -0
  140. package/mcp_servers/openscad-mcp-server/legacy/src/testing/test_primitives.py +98 -0
  141. package/mcp_servers/openscad-mcp-server/legacy/src/utils/__init__.py +1 -0
  142. package/mcp_servers/openscad-mcp-server/legacy/src/utils/cad_exporter.py +241 -0
  143. package/mcp_servers/openscad-mcp-server/legacy/src/utils/format_validator.py +206 -0
  144. package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_exporter.py +140 -0
  145. package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_repair.py +91 -0
  146. package/mcp_servers/openscad-mcp-server/legacy/src/utils/stl_validator.py +123 -0
  147. package/mcp_servers/openscad-mcp-server/legacy/src/visualization/__init__.py +0 -0
  148. package/mcp_servers/openscad-mcp-server/legacy/src/visualization/headless_renderer.py +52 -0
  149. package/mcp_servers/openscad-mcp-server/legacy/src/visualization/renderer.py +177 -0
  150. package/mcp_servers/openscad-mcp-server/legacy/src/visualization/web_interface.py +639 -0
  151. package/mcp_servers/openscad-mcp-server/legacy/src/workflow/image_approval.py +148 -0
  152. package/mcp_servers/openscad-mcp-server/legacy/src/workflow/multi_view_to_model_pipeline.py +338 -0
  153. package/mcp_servers/openscad-mcp-server/legacy/test_complete_workflow.py +374 -0
  154. package/mcp_servers/openscad-mcp-server/legacy/test_cuda_mvs.py +191 -0
  155. package/mcp_servers/openscad-mcp-server/legacy/test_gemini_api.py +168 -0
  156. package/mcp_servers/openscad-mcp-server/legacy/test_image_approval.py +192 -0
  157. package/mcp_servers/openscad-mcp-server/legacy/test_image_approval_workflow.py +251 -0
  158. package/mcp_servers/openscad-mcp-server/legacy/test_image_to_model_pipeline.py +145 -0
  159. package/mcp_servers/openscad-mcp-server/legacy/test_model_selection.py +41 -0
  160. package/mcp_servers/openscad-mcp-server/legacy/test_multi_view_pipeline.py +290 -0
  161. package/mcp_servers/openscad-mcp-server/legacy/test_primitives.sh +13 -0
  162. package/mcp_servers/openscad-mcp-server/legacy/test_rabbit_direct.py +71 -0
  163. package/mcp_servers/openscad-mcp-server/legacy/test_remote_cuda_mvs.py +283 -0
  164. package/mcp_servers/openscad-mcp-server/legacy/test_venice_example.py +69 -0
  165. package/mcp_servers/openscad-mcp-server/pyproject.toml +33 -0
  166. package/mcp_servers/openscad-mcp-server/requirements.txt +2 -0
  167. package/mcp_servers/openscad-mcp-server/scad/simple_cube.scad +2 -0
  168. package/mcp_servers/openscad-mcp-server/scripts/test_docker.py +220 -0
  169. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__init__.py +3 -0
  170. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/__main__.py +3 -0
  171. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/engine.py +94 -0
  172. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/geometry.py +242 -0
  173. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/server.py +245 -0
  174. package/mcp_servers/openscad-mcp-server/src/openscad_mcp/service.py +190 -0
  175. package/mcp_servers/openscad-mcp-server/tests/conftest.py +17 -0
  176. package/mcp_servers/openscad-mcp-server/tests/test_engine.py +37 -0
  177. package/mcp_servers/openscad-mcp-server/tests/test_geometry.py +106 -0
  178. package/mcp_servers/openscad-mcp-server/tests/test_integration.py +172 -0
  179. package/mcp_servers/openscad-mcp-server/tests/test_transports.py +314 -0
  180. package/mcp_servers/openscad-mcp-server/uv.lock +1123 -0
  181. package/package.json +44 -0
  182. package/scripts/install_mcps.sh +86 -0
  183. package/scripts/openscad_wrapper.sh +62 -0
  184. package/scripts/run_kicad_mcp.sh +25 -0
  185. package/scripts/run_openscad_mcp.sh +41 -0
  186. package/scripts/test_mcp_connection.py +626 -0
  187. package/scripts/test_mcp_connection.sh +168 -0
  188. package/skills/code-first-hardware-design/SKILL.md +260 -0
  189. package/skills/pcb-constraint-definition/SKILL.md +236 -0
  190. package/skills/pcb-layout-routing-automation/SKILL.md +153 -0
  191. package/skills/pcb-validation-dfm-signoff/SKILL.md +194 -0
  192. 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
+ }
@@ -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"])