tan-cli 0.7.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.
- tan/__init__.py +0 -0
- tan/__main__.py +120 -0
- tan/cli.py +939 -0
- tan/command_table.py +265 -0
- tan/commands/__init__.py +8 -0
- tan/commands/bootstrap_cmd.py +4856 -0
- tan/commands/bootstrap_patches.py +164 -0
- tan/commands/bootstrap_toolchain_fetch.py +155 -0
- tan/commands/bootstrap_toolchain_pin.py +36 -0
- tan/commands/build/__init__.py +1 -0
- tan/commands/build/configure_inputs.py +277 -0
- tan/commands/build/execute.py +1852 -0
- tan/commands/build/host_python.py +59 -0
- tan/commands/build/link_stale.py +78 -0
- tan/commands/build/manifest.py +428 -0
- tan/commands/build/materialise.py +81 -0
- tan/commands/build/token_substitution.py +381 -0
- tan/commands/build/toolchain.py +482 -0
- tan/commands/build/user_defines_wipe.py +115 -0
- tan/commands/build/workspace_patches.py +65 -0
- tan/commands/build_cmd.py +2236 -0
- tan/commands/build_output.py +331 -0
- tan/commands/clean_cmd.py +1183 -0
- tan/commands/completion_cmd.py +786 -0
- tan/commands/debug_config_cmd.py +2425 -0
- tan/commands/diff_cmd.py +940 -0
- tan/commands/doctor_cmd.py +4767 -0
- tan/commands/examples_cmd.py +644 -0
- tan/commands/explain_cmd.py +1319 -0
- tan/commands/faultdecode_cmd.py +931 -0
- tan/commands/flash_atoc_guard.py +240 -0
- tan/commands/flash_cmd.py +5731 -0
- tan/commands/flash_mram_guard.py +150 -0
- tan/commands/flash_ram.py +578 -0
- tan/commands/flash_raw.py +583 -0
- tan/commands/generate_cmd.py +1456 -0
- tan/commands/image_cmd.py +753 -0
- tan/commands/init_cmd.py +1740 -0
- tan/commands/inspect_cmd.py +377 -0
- tan/commands/kconfig_cmd.py +734 -0
- tan/commands/model_cmd.py +1514 -0
- tan/commands/model_device_cmd.py +351 -0
- tan/commands/model_device_live.py +234 -0
- tan/commands/model_host_cmd.py +430 -0
- tan/commands/model_zoo_cmd.py +363 -0
- tan/commands/monitor_actions.py +125 -0
- tan/commands/monitor_cmd.py +626 -0
- tan/commands/monitor_session.py +505 -0
- tan/commands/new_som_cmd.py +1522 -0
- tan/commands/pinmux_cmd.py +568 -0
- tan/commands/presets_cmd.py +1123 -0
- tan/commands/probe_cmd.py +421 -0
- tan/commands/reset_cmd.py +354 -0
- tan/commands/reset_confirm.py +168 -0
- tan/commands/run_cmd.py +637 -0
- tan/commands/scaffold_cmd.py +490 -0
- tan/commands/sdk_cmd.py +1723 -0
- tan/commands/size_cmd.py +1020 -0
- tan/commands/support_bundle_cmd.py +1073 -0
- tan/commands/trace_cmd.py +341 -0
- tan/commands/validate_cmd.py +2009 -0
- tan/commands/west_forward_cmd.py +736 -0
- tan/commands/workspace_patch_check.py +296 -0
- tan/core/__init__.py +1 -0
- tan/core/alp_conf_pregen.py +100 -0
- tan/core/artifact_provenance.py +240 -0
- tan/core/atoc_guard.py +276 -0
- tan/core/atoc_guard_messages.py +232 -0
- tan/core/atoc_replacement.py +118 -0
- tan/core/atomic_write.py +178 -0
- tan/core/board_context.py +351 -0
- tan/core/board_diagnostic.py +111 -0
- tan/core/board_files.py +221 -0
- tan/core/board_validator.py +542 -0
- tan/core/board_validator_compat.py +196 -0
- tan/core/board_validator_run.py +129 -0
- tan/core/board_validator_schema.py +186 -0
- tan/core/board_validator_skew.py +46 -0
- tan/core/board_yaml_edit.py +295 -0
- tan/core/board_yaml_pos.py +118 -0
- tan/core/bootstrap.py +2572 -0
- tan/core/build_plan.py +625 -0
- tan/core/consent.py +104 -0
- tan/core/console_filter.py +245 -0
- tan/core/debug_launch.py +1803 -0
- tan/core/devicetree_lint.py +168 -0
- tan/core/dir_removal.py +229 -0
- tan/core/doctor_git.py +172 -0
- tan/core/doctor_libraries.py +253 -0
- tan/core/doctor_render.py +185 -0
- tan/core/doctor_scope.py +66 -0
- tan/core/doctor_setools.py +237 -0
- tan/core/doctor_stale.py +180 -0
- tan/core/document_guards.py +723 -0
- tan/core/dp_id.py +97 -0
- tan/core/elf_load.py +63 -0
- tan/core/error_catalog.py +171 -0
- tan/core/example_catalog.py +499 -0
- tan/core/example_facets.py +151 -0
- tan/core/faultdecode.py +521 -0
- tan/core/flash_plan.py +2501 -0
- tan/core/flow_d_report.py +381 -0
- tan/core/flow_d_uptime.py +164 -0
- tan/core/fs_confine.py +130 -0
- tan/core/global_flags.py +230 -0
- tan/core/host_python.py +210 -0
- tan/core/image_bundle.py +247 -0
- tan/core/inert.py +147 -0
- tan/core/jlink_binary.py +128 -0
- tan/core/jlink_probe.py +481 -0
- tan/core/jsonc_splice.py +404 -0
- tan/core/launch_provenance.py +257 -0
- tan/core/link_refusal.py +76 -0
- tan/core/metadata_schema.py +376 -0
- tan/core/model_check.py +227 -0
- tan/core/model_device.py +449 -0
- tan/core/model_doctor.py +198 -0
- tan/core/model_host.py +48 -0
- tan/core/model_list.py +112 -0
- tan/core/model_zoo.py +353 -0
- tan/core/module_template.py +340 -0
- tan/core/mram_link.py +87 -0
- tan/core/new_som_ospi.py +94 -0
- tan/core/os_class.py +159 -0
- tan/core/patch_paths.py +87 -0
- tan/core/pending.py +40 -0
- tan/core/plain_zephyr_plan.py +138 -0
- tan/core/plan_exec.py +373 -0
- tan/core/plan_tokens.py +600 -0
- tan/core/probe.py +155 -0
- tan/core/probe_plan.py +237 -0
- tan/core/proxy.py +168 -0
- tan/core/publish.py +31 -0
- tan/core/python_floor.py +178 -0
- tan/core/ram_run.py +694 -0
- tan/core/ram_watch.py +231 -0
- tan/core/raw_write.py +160 -0
- tan/core/reset_plan.py +56 -0
- tan/core/run.py +161 -0
- tan/core/scaffold.py +2203 -0
- tan/core/scaffold_selftest_identity.py +225 -0
- tan/core/sdk_default_registry.py +565 -0
- tan/core/sdk_discovery.py +996 -0
- tan/core/sdk_removal.py +465 -0
- tan/core/serial_actions.py +175 -0
- tan/core/serial_capture.py +185 -0
- tan/core/serial_url.py +45 -0
- tan/core/setools.py +608 -0
- tan/core/setools_scratch.py +243 -0
- tan/core/shapes.py +194 -0
- tan/core/size.py +610 -0
- tan/core/som_buildability.py +204 -0
- tan/core/som_schema_version.py +62 -0
- tan/core/subprocess_env.py +201 -0
- tan/core/sysbuild_image.py +94 -0
- tan/core/system_manifest.py +827 -0
- tan/core/text_layout.py +73 -0
- tan/core/timestamp.py +182 -0
- tan/core/tool_lookup.py +383 -0
- tan/core/toolchain_pin.py +117 -0
- tan/core/toolchain_provision.py +1224 -0
- tan/core/trusted_path.py +134 -0
- tan/core/uboot_breakin.py +154 -0
- tan/core/uri_reference.py +415 -0
- tan/core/user_defines.py +152 -0
- tan/core/venv.py +332 -0
- tan/core/west_patches.py +143 -0
- tan/core/west_workspace_refusal.py +159 -0
- tan/core/zephyr_env.py +124 -0
- tan/env.py +185 -0
- tan/envelope.py +647 -0
- tan/exit_codes.py +12 -0
- tan/lazy_typer.py +185 -0
- tan/model/__init__.py +2 -0
- tan/model/_gen_fixture.py +132 -0
- tan/model/adapters/__init__.py +116 -0
- tan/model/adapters/cpu.py +26 -0
- tan/model/adapters/deepx.py +94 -0
- tan/model/adapters/drpai.py +242 -0
- tan/model/adapters/ethos_u.py +951 -0
- tan/model/adapters/executorch.py +55 -0
- tan/model/analyze.py +694 -0
- tan/model/build.py +304 -0
- tan/model/check.py +682 -0
- tan/model/manifest.py +625 -0
- tan/model/measure.py +216 -0
- tan/model/npu_ops_validate.py +130 -0
- tan/model/package.py +125 -0
- tan/model/perf.py +635 -0
- tan/model/perf_apply.py +721 -0
- tan/model/prep.py +193 -0
- tan/model/sram_fit.py +502 -0
- tan/model/targets.py +374 -0
- tan/model/tensorio.py +287 -0
- tan/net.py +73 -0
- tan/output_format.py +213 -0
- tan/planner/__init__.py +219 -0
- tan/planner/aperture.py +202 -0
- tan/planner/buildplan.py +1092 -0
- tan/planner/camera_owner.py +192 -0
- tan/planner/cameras.py +132 -0
- tan/planner/carveout.py +755 -0
- tan/planner/cli.py +274 -0
- tan/planner/headers.py +315 -0
- tan/planner/kconfig.py +2435 -0
- tan/planner/kconfig_symbols.py +473 -0
- tan/planner/libraries.py +677 -0
- tan/planner/link_target.py +237 -0
- tan/planner/linux_ownership.py +216 -0
- tan/planner/loader.py +1525 -0
- tan/planner/manifest.py +116 -0
- tan/planner/memory.py +161 -0
- tan/planner/memregion.py +56 -0
- tan/planner/models.py +533 -0
- tan/planner/orchestrator.py +874 -0
- tan/planner/ownership.py +203 -0
- tan/planner/partition.py +1160 -0
- tan/planner/paths.py +32 -0
- tan/planner/plain_slice.py +139 -0
- tan/planner/project_emit/__init__.py +60 -0
- tan/planner/project_emit/bom_netlist.py +375 -0
- tan/planner/project_emit/dts.py +580 -0
- tan/planner/project_emit/hw_info.py +221 -0
- tan/planner/project_emit/native_sim.py +136 -0
- tan/planner/project_emit/west_libs.py +213 -0
- tan/planner/project_loader.py +264 -0
- tan/planner/sdk_capability.py +203 -0
- tan/planner/sdk_compat.py +395 -0
- tan/planner/secure.py +350 -0
- tan/planner/slugs.py +394 -0
- tan/planner/som_metadata.py +325 -0
- tan/planner/strict_loaders.py +131 -0
- tan/planner/template.py +1037 -0
- tan/planner/template_pins.py +535 -0
- tan/planner/template_rewrite.py +714 -0
- tan/planner/topology.py +208 -0
- tan/planner/validate.py +365 -0
- tan/planner/whole_device_alias.py +67 -0
- tan/planner/zephyr_board.py +3510 -0
- tan/planner_cli.py +97 -0
- tan/planner_emit.py +617 -0
- tan/planner_root.py +119 -0
- tan/soc_ref.py +58 -0
- tan/templates/__init__.py +34 -0
- tan/templates/vendored/MANIFEST.md +1862 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/testcase.yaml +53 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/testcase.yaml +53 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/testcase.yaml +62 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/board.yaml +37 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/testcase.yaml +62 -0
- tan/templates/vendored/iot/E1M-AEN801/CMakeLists.txt +14 -0
- tan/templates/vendored/iot/E1M-AEN801/README.md +103 -0
- tan/templates/vendored/iot/E1M-AEN801/board.yaml +69 -0
- tan/templates/vendored/iot/E1M-AEN801/prj.conf +15 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.c +196 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.h +173 -0
- tan/templates/vendored/iot/E1M-AEN801/src/main.c +262 -0
- tan/templates/vendored/iot/E1M-AEN801/testcase.yaml +68 -0
- tan/templates/vendored/minimal/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/README.md +108 -0
- tan/templates/vendored/minimal/E1M-AEN801/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-AEN801/testcase.yaml +49 -0
- tan/templates/vendored/minimal/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/README.md +108 -0
- tan/templates/vendored/minimal/E1M-V2N101/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-V2N101/testcase.yaml +49 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/README.md +120 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/boards/native_sim_native_64.overlay +40 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/CMakeLists.txt +13 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/main.c +171 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/prj.conf +17 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/testcase.yaml +23 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/prj.conf +22 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/src/main.c +185 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/testcase.yaml +26 -0
- tan/templates/vendored/sensor/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/sensor/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-AEN801/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-AEN801/testcase.yaml +52 -0
- tan/templates/vendored/sensor/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/sensor/E1M-V2N101/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-V2N101/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-V2N101/testcase.yaml +52 -0
- tan/version.py +102 -0
- tan_cli-0.7.0.dist-info/METADATA +125 -0
- tan_cli-0.7.0.dist-info/RECORD +330 -0
- tan_cli-0.7.0.dist-info/WHEEL +5 -0
- tan_cli-0.7.0.dist-info/entry_points.txt +2 -0
- tan_cli-0.7.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Zephyr DTS overlay emission (`--emit dts-overlay`).
|
|
3
|
+
|
|
4
|
+
Board-macro parsing (reads `include/alp/boards/<board>.h`) + the carrier
|
|
5
|
+
peripheral DT-wiring catalog + `_emit_dts_overlay` itself.
|
|
6
|
+
|
|
7
|
+
RELOCATED (was alp-sdk `scripts/alp_project_emit/dts.py`) -- see this package's
|
|
8
|
+
`__init__.py` for the move's contract. Two mechanical changes: `REPO` is the
|
|
9
|
+
BOUND SDK checkout (`paths.REPO`), so the board header still resolves out of
|
|
10
|
+
alp-sdk's `include/alp/boards/` and never out of `tan`; and the one `sys.exit`
|
|
11
|
+
became `raise OrchestratorError`, because in `tan`'s own process a `SystemExit`
|
|
12
|
+
would tear the CLI down past every envelope guarantee instead of arriving as a
|
|
13
|
+
non-zero rc from a subprocess. `check_emit_snapshots.py` in alp-sdk and
|
|
14
|
+
`tests/parity/test_planner_emit_parity.py` here both pin the output byte for
|
|
15
|
+
byte.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import re
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
from ..models import OrchestratorError
|
|
25
|
+
from ..paths import REPO
|
|
26
|
+
from ..som_metadata import _sku_family
|
|
27
|
+
|
|
28
|
+
from . import _e1m_gpio_canonical
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class DtsOverlayUnavailable(OrchestratorError):
|
|
32
|
+
"""The board has no header under `include/alp/boards/` to render from.
|
|
33
|
+
|
|
34
|
+
tan adaptation: upstream `sys.exit`s here and `buildplan._slice_dts_overlay`
|
|
35
|
+
converts that to its own `DtsOverlayUnavailable`; in `tan`'s process a
|
|
36
|
+
`SystemExit` is unacceptable (see the module docstring), so the emitter
|
|
37
|
+
raises the buildplan's type directly (`buildplan` re-exports this class).
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# ---------------------------------------------------------------------
|
|
42
|
+
# DTS overlay emission (v0.3: i2c / spi / uart / pwm / gpio aliases)
|
|
43
|
+
# ---------------------------------------------------------------------
|
|
44
|
+
#
|
|
45
|
+
# Per the project memory note "pending exact hardware configurations
|
|
46
|
+
# -- mark unknowns TBD, never invent values", the loader translates
|
|
47
|
+
# the macros in include/alp/boards/<board>.h verbatim; it does not
|
|
48
|
+
# invent gpio bank numbers or per-pad GPIO_ACTIVE_* flags. The
|
|
49
|
+
# emitted .overlay declares the board's bus aliases and a stub
|
|
50
|
+
# alp,pin-array with one entry per EVK_PIN_* macro, each annotated
|
|
51
|
+
# with a comment naming the macro and the ALP_E1M_GPIO_IO<N> it
|
|
52
|
+
# resolves to. Customers fill the gpio bank / index columns with
|
|
53
|
+
# their SoM's actual DT controller phandles by cross-referencing the
|
|
54
|
+
# in-tree board file (zephyr/boards/alp/<board>/*.dts, wired in via
|
|
55
|
+
# zephyr/module.yml's `board_root: zephyr`).
|
|
56
|
+
#
|
|
57
|
+
# Bus phandle naming convention matches the manually-written EVK
|
|
58
|
+
# overlays at tests/zephyr/peripheral/boards/alp_e1m_aen801_m55_he.overlay:
|
|
59
|
+
# &i2c<N>, &spi<N>, &uart<N>, &pwm<N>. Per-SoC vendor DT may use
|
|
60
|
+
# alternate names (e.g. &lpi2c0 on some Alif boards); the customer
|
|
61
|
+
# fixes the phandle if their board file diverges -- the loader's
|
|
62
|
+
# job is to surface every alias the board wants, not to second-
|
|
63
|
+
# guess vendor DT naming.
|
|
64
|
+
|
|
65
|
+
# Match `#define <NAME> ALP_E1M_<CLASS><N>` (with optional trailing
|
|
66
|
+
# token). Class is one of the bus / pwm / gpio / analog-converter
|
|
67
|
+
# names we care about. ADC + DAC join the set so the portable
|
|
68
|
+
# <alp/adc.h> / <alp/dac.h> backends -- which resolve their channels
|
|
69
|
+
# via the `alp-adcN` / `alp-dacN` DT aliases -- get a generated alias
|
|
70
|
+
# scaffold from the board's `e1m_routes.adc` / `.dac` entries.
|
|
71
|
+
_DEFINE_E1M_RE = re.compile(
|
|
72
|
+
r"^\s*#\s*define\s+(\w+)\s+ALP_E1M_(I2C|SPI|UART|PWM|ADC|DAC|GPIO_IO)(\d+)\b",
|
|
73
|
+
re.MULTILINE,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Bus-alias buckets the loader emits. Each entry maps the e1m_pinout
|
|
77
|
+
# class name -> (alias prefix, Zephyr DT phandle prefix).
|
|
78
|
+
#
|
|
79
|
+
# The phandle prefix is the convention-default node-label (&i2c0,
|
|
80
|
+
# &adc0, ...); vendor DT may use a different label (e.g. the Alif
|
|
81
|
+
# Ensemble ADCs are node-labelled `adc12_0` and the EEPROM bus is
|
|
82
|
+
# `i2c2`), in which case the per-app board overlay repoints the alias
|
|
83
|
+
# (`aliases { alp-adc0 = &adc12_0; };`) -- the loader's job is to
|
|
84
|
+
# surface every alias the board wires, not to second-guess vendor DT
|
|
85
|
+
# node-label naming.
|
|
86
|
+
_BUS_BUCKETS: tuple[tuple[str, str, str], ...] = (
|
|
87
|
+
("I2C", "alp-i2c", "i2c"),
|
|
88
|
+
("SPI", "alp-spi", "spi"),
|
|
89
|
+
("UART", "alp-uart", "uart"),
|
|
90
|
+
("PWM", "alp-pwm", "pwm"),
|
|
91
|
+
("ADC", "alp-adc", "adc"),
|
|
92
|
+
("DAC", "alp-dac", "dac"),
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _strip_c_comments(text: str) -> str:
|
|
97
|
+
"""Strip /* ... */ and // ... comments from C source text."""
|
|
98
|
+
text = re.sub(r"/\*.*?\*/", "", text, flags=re.DOTALL)
|
|
99
|
+
text = re.sub(r"//[^\n]*", "", text)
|
|
100
|
+
return text
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _collapse_line_continuations(text: str) -> str:
|
|
104
|
+
"""Join `\\<newline>` continuations into single logical lines so a
|
|
105
|
+
multi-line `#define NAME \\\n VALUE` shows up as one line."""
|
|
106
|
+
return re.sub(r"\\\s*\n\s*", " ", text)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _board_header_path(board_name: str, repo_root: Path) -> Path:
|
|
110
|
+
"""Resolve include/alp/boards/alp_<board>.h for a board name.
|
|
111
|
+
|
|
112
|
+
Example: 'E1M-EVK' -> include/alp/boards/alp_e1m_evk.h.
|
|
113
|
+
"""
|
|
114
|
+
fname = "alp_" + board_name.lower().replace("-", "_") + ".h"
|
|
115
|
+
return repo_root / "include" / "alp" / "boards" / fname
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
_INCLUDE_LOCAL_RE = re.compile(
|
|
119
|
+
r'^\s*#\s*include\s+"(alp/boards/[^"]+\.h)"', re.MULTILINE,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _read_board_header_with_includes(header_path: Path) -> str:
|
|
124
|
+
"""Read `header_path` and inline any `#include "alp/boards/<file>.h"`
|
|
125
|
+
that exists under include/. Used so the loader picks up the
|
|
126
|
+
generated routes header (alp_e1m_evk_routes.h) which holds the
|
|
127
|
+
EVK_* -> ALP_E1M_* macro bindings since slice 1c.
|
|
128
|
+
|
|
129
|
+
Single-level inlining is sufficient -- the generated routes header
|
|
130
|
+
only `#include`s `alp/e1m_pinout.h`, which carries no EVK_* macros.
|
|
131
|
+
"""
|
|
132
|
+
text = header_path.read_text(encoding="utf-8")
|
|
133
|
+
include_root = header_path.parent.parent.parent # .../include/
|
|
134
|
+
pieces: list[str] = [text]
|
|
135
|
+
for m in _INCLUDE_LOCAL_RE.finditer(text):
|
|
136
|
+
inc_rel = m.group(1)
|
|
137
|
+
inc_path = include_root / inc_rel
|
|
138
|
+
if inc_path.is_file() and inc_path.resolve() != header_path.resolve():
|
|
139
|
+
pieces.append(inc_path.read_text(encoding="utf-8"))
|
|
140
|
+
return "\n".join(pieces)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _parse_board_macros(
|
|
144
|
+
header_path: Path,
|
|
145
|
+
) -> dict[str, list[tuple[str, int]]]:
|
|
146
|
+
"""Return {class_name: [(macro_name, channel_index), ...]} for
|
|
147
|
+
each ALP_E1M_<CLASS><N> reference in the board header."""
|
|
148
|
+
raw = _read_board_header_with_includes(header_path)
|
|
149
|
+
text = _strip_c_comments(_collapse_line_continuations(raw))
|
|
150
|
+
out: dict[str, list[tuple[str, int]]] = {
|
|
151
|
+
"I2C": [], "SPI": [], "UART": [], "PWM": [], "GPIO_IO": [],
|
|
152
|
+
}
|
|
153
|
+
for m in _DEFINE_E1M_RE.finditer(text):
|
|
154
|
+
macro_name = m.group(1)
|
|
155
|
+
cls = m.group(2)
|
|
156
|
+
idx = int(m.group(3))
|
|
157
|
+
out.setdefault(cls, []).append((macro_name, idx))
|
|
158
|
+
return out
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _project_pin_indices(project: dict[str, Any], class_name: str) -> set[int]:
|
|
162
|
+
"""Return E1M route indices for one class named in board.yaml `pins:`."""
|
|
163
|
+
pattern = re.compile(rf"^E1M_{re.escape(class_name)}(\d+)$")
|
|
164
|
+
indices: set[int] = set()
|
|
165
|
+
for pin in project.get("pins", []) or []:
|
|
166
|
+
if isinstance(pin, str):
|
|
167
|
+
e1m = pin
|
|
168
|
+
elif isinstance(pin, dict):
|
|
169
|
+
e1m = pin.get("e1m")
|
|
170
|
+
else:
|
|
171
|
+
continue
|
|
172
|
+
if not isinstance(e1m, str):
|
|
173
|
+
continue
|
|
174
|
+
m = pattern.match(e1m)
|
|
175
|
+
if m:
|
|
176
|
+
indices.add(int(m.group(1)))
|
|
177
|
+
return indices
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _route_indices_for_catalog(
|
|
181
|
+
project: dict[str, Any],
|
|
182
|
+
macros: dict[str, list[tuple[str, int]]],
|
|
183
|
+
class_name: str,
|
|
184
|
+
default_indices: set[int],
|
|
185
|
+
) -> set[int]:
|
|
186
|
+
"""Route indices a SoM-family catalog entry should own.
|
|
187
|
+
|
|
188
|
+
Apps that name concrete `pins:` get exactly those aliases. Older or
|
|
189
|
+
chip-bound examples without `pins:` keep the catalog's historical default
|
|
190
|
+
instance, e.g. AEN portable I2C0 -> SoC i2c2.
|
|
191
|
+
"""
|
|
192
|
+
requested = _project_pin_indices(project, class_name)
|
|
193
|
+
if requested:
|
|
194
|
+
return requested
|
|
195
|
+
board_indices = {idx for _macro, idx in macros.get(class_name, [])}
|
|
196
|
+
return board_indices & default_indices
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _emit_aen_adc_wiring(indices: set[int]) -> str:
|
|
200
|
+
"""Emit AEN ADC consumer nodes for the requested portable ADC ids."""
|
|
201
|
+
ordered = sorted(indices)
|
|
202
|
+
lines: list[str] = ["/ {"]
|
|
203
|
+
for idx in ordered:
|
|
204
|
+
lines.append(f"\talp_adc_in{idx}: alp-adc-in{idx} {{")
|
|
205
|
+
lines.append('\t\tcompatible = "alp,adc-input";')
|
|
206
|
+
lines.append(f"\t\tio-channels = <&adc12_0 {idx}>;")
|
|
207
|
+
lines.append("\t};")
|
|
208
|
+
lines.append("\taliases {")
|
|
209
|
+
for idx in ordered:
|
|
210
|
+
lines.append(f"\t\talp-adc{idx} = &alp_adc_in{idx};")
|
|
211
|
+
lines.append("\t};")
|
|
212
|
+
lines.append("};")
|
|
213
|
+
lines.append("&adc12_0 {")
|
|
214
|
+
lines.append('\tstatus = "okay";')
|
|
215
|
+
for idx in ordered:
|
|
216
|
+
lines.append(f"\tchannel@{idx} {{")
|
|
217
|
+
lines.append(f"\t\treg = <{idx}>;")
|
|
218
|
+
lines.append('\t\tzephyr,gain = "ADC_GAIN_1";')
|
|
219
|
+
lines.append('\t\tzephyr,reference = "ADC_REF_INTERNAL";')
|
|
220
|
+
lines.append("\t\tzephyr,vref-mv = <1800>;")
|
|
221
|
+
lines.append("\t\tzephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;")
|
|
222
|
+
lines.append("\t\tzephyr,resolution = <12>;")
|
|
223
|
+
lines.append("\t};")
|
|
224
|
+
lines.append("};")
|
|
225
|
+
return "\n".join(lines) + "\n"
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _catalog_owned_alias_indices(
|
|
229
|
+
fam: str,
|
|
230
|
+
phandle_prefix: str,
|
|
231
|
+
project: dict[str, Any],
|
|
232
|
+
macros: dict[str, list[tuple[str, int]]],
|
|
233
|
+
) -> set[int]:
|
|
234
|
+
"""Return portable alias indices emitted by SoM-family special wiring."""
|
|
235
|
+
if fam == "aen" and phandle_prefix == "i2c":
|
|
236
|
+
return _route_indices_for_catalog(project, macros, "I2C", {0}) & {0}
|
|
237
|
+
if fam == "aen" and phandle_prefix == "adc":
|
|
238
|
+
return _route_indices_for_catalog(project, macros, "ADC", {0})
|
|
239
|
+
return set()
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _catalog_generic_alias_indices(
|
|
243
|
+
fam: str,
|
|
244
|
+
phandle_prefix: str,
|
|
245
|
+
project: dict[str, Any],
|
|
246
|
+
macros: dict[str, list[tuple[str, int]]],
|
|
247
|
+
class_name: str,
|
|
248
|
+
) -> set[int]:
|
|
249
|
+
"""Return generic alias indices to emit for a catalog-owned class."""
|
|
250
|
+
if fam == "aen" and phandle_prefix == "i2c":
|
|
251
|
+
return _route_indices_for_catalog(project, macros, class_name, {0})
|
|
252
|
+
if fam == "aen" and phandle_prefix == "adc":
|
|
253
|
+
return _route_indices_for_catalog(project, macros, class_name, {0})
|
|
254
|
+
return {idx for _macro, idx in macros.get(class_name, [])}
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
# ---------------------------------------------------------------------
|
|
258
|
+
# Carrier peripheral DT-wiring catalog (single source of truth)
|
|
259
|
+
# ---------------------------------------------------------------------
|
|
260
|
+
#
|
|
261
|
+
# Declaring a peripheral in board.yaml (`cores.<id>.peripherals`) sets the
|
|
262
|
+
# subsystem CONFIG via the conf emit -- but that alone does NOT bind hardware:
|
|
263
|
+
# the controller node sits `disabled` in the SoC dtsi, so e.g. ADC_ALIF never
|
|
264
|
+
# selects and `alp adc read` returns -ENOENT. Examples used to paper over this
|
|
265
|
+
# with a hand-written boards/*.overlay enabling the node + the alp-<x>N alias /
|
|
266
|
+
# io-channels consumer the portable backends resolve.
|
|
267
|
+
#
|
|
268
|
+
# This catalog moves that wiring into the codegen: `_emit_dts_overlay` renders
|
|
269
|
+
# the fragment for each declared peripheral, so `peripherals: [adc]` ALONE
|
|
270
|
+
# yields a working `alp adc read` with NO per-example overlay. Keyed by SoM
|
|
271
|
+
# family (from `_sku_family`); each entry carries the dt-bindings `#include`s it
|
|
272
|
+
# needs + a self-contained DTS fragment (DT permits repeated `/{}` and
|
|
273
|
+
# `&label{}` sections). To add or fix a peripheral's wiring, edit ONE entry
|
|
274
|
+
# here -- never per example. A per-example boards/*.overlay still layers last
|
|
275
|
+
# and wins (override tier), so this is opt-in-complete, not a straitjacket.
|
|
276
|
+
_PERIPH_DT_WIRING: dict[str, dict[str, dict[str, Any]]] = {
|
|
277
|
+
"aen": {
|
|
278
|
+
"i2c": {
|
|
279
|
+
"include": ["zephyr/dt-bindings/i2c/i2c.h",
|
|
280
|
+
"zephyr/dt-bindings/pinctrl/alif-ensemble-pinctrl.h"],
|
|
281
|
+
"dts": (
|
|
282
|
+
"&pinctrl {\n"
|
|
283
|
+
"\tpinctrl_i2c2: pinctrl_i2c2 {\n"
|
|
284
|
+
"\t\tgroup0 {\n"
|
|
285
|
+
"\t\t\tpinmux = <PIN_P5_6__I2C2_SCL_C>, <PIN_P5_7__I2C2_SDA_C>;\n"
|
|
286
|
+
"\t\t\tinput-enable;\n"
|
|
287
|
+
"\t\t\tbias-pull-down;\n"
|
|
288
|
+
"\t\t};\n"
|
|
289
|
+
"\t};\n"
|
|
290
|
+
"};\n"
|
|
291
|
+
"&i2c2 {\n"
|
|
292
|
+
"\tstatus = \"okay\";\n"
|
|
293
|
+
"\tpinctrl-0 = <&pinctrl_i2c2>;\n"
|
|
294
|
+
"\tpinctrl-names = \"default\";\n"
|
|
295
|
+
"\tclock-frequency = <I2C_BITRATE_STANDARD>;\n"
|
|
296
|
+
"};\n"
|
|
297
|
+
"/ {\n"
|
|
298
|
+
"\taliases {\n"
|
|
299
|
+
"\t\talp-i2c0 = &i2c2;\n"
|
|
300
|
+
"\t};\n"
|
|
301
|
+
"};\n"
|
|
302
|
+
),
|
|
303
|
+
},
|
|
304
|
+
"gpio": {
|
|
305
|
+
"include": [],
|
|
306
|
+
"dts": "&gpio8 {\n\tstatus = \"okay\";\n};\n",
|
|
307
|
+
},
|
|
308
|
+
"adc": {
|
|
309
|
+
"include": ["zephyr/dt-bindings/adc/adc.h"],
|
|
310
|
+
},
|
|
311
|
+
"i3c": {
|
|
312
|
+
# E1M-AEN801 drives I3C through the LP instance
|
|
313
|
+
# (lpi3c0@0x43006000). The two controllers are INDEPENDENT on the
|
|
314
|
+
# E8 and overlap on ONE pad pair only: P7_6/P7_7, exposed as both
|
|
315
|
+
# PIN_P7_6__I3C_SDA_D/PIN_P7_7__I3C_SCL_D (fn6, main i3c0) and
|
|
316
|
+
# PIN_P7_6__LPI3C_SDA_B/PIN_P7_7__LPI3C_SCL_B (fn3, this one).
|
|
317
|
+
# The E1M-AEN801 routes only that pair, so on THIS SoM exactly one
|
|
318
|
+
# node may be enabled and firmware picks the owner -- a board
|
|
319
|
+
# constraint, not a silicon one. We pick the LP instance
|
|
320
|
+
# because it is the M55-HE local peripheral domain (IRQ 50), NOT
|
|
321
|
+
# because the SoM pinout selects it: from-alif.tsv's
|
|
322
|
+
# `alif_peripheral` column names the MAIN-I3C fn6 functions
|
|
323
|
+
# (I3C_SCL_D/I3C_SDA_D) and has no LPI3C row at all. See
|
|
324
|
+
# zephyr/dts/alif/ensemble_e8_peripherals.dtsi. Emission is gated
|
|
325
|
+
# to the m55_he core below -- an HP slice gets no alias, so
|
|
326
|
+
# alp_i3c_open() surfaces NOT_READY instead of a dead IRQ.
|
|
327
|
+
"include": ["zephyr/dt-bindings/pinctrl/alif-ensemble-pinctrl.h"],
|
|
328
|
+
"dts": (
|
|
329
|
+
"&pinctrl {\n"
|
|
330
|
+
"\tpinctrl_lpi3c0: pinctrl_lpi3c0 {\n"
|
|
331
|
+
"\t\tgroup0 {\n"
|
|
332
|
+
"\t\t\tpinmux = <PIN_P7_6__LPI3C_SDA_B>;\n"
|
|
333
|
+
"\t\t\tinput-enable;\n"
|
|
334
|
+
"\t\t};\n"
|
|
335
|
+
"\t\tgroup1 {\n"
|
|
336
|
+
"\t\t\tpinmux = <PIN_P7_7__LPI3C_SCL_B>;\n"
|
|
337
|
+
"\t\t\tinput-enable;\n"
|
|
338
|
+
"\t\t};\n"
|
|
339
|
+
"\t};\n"
|
|
340
|
+
"};\n"
|
|
341
|
+
"&lpi3c0 {\n"
|
|
342
|
+
"\tstatus = \"okay\";\n"
|
|
343
|
+
"\tpinctrl-0 = <&pinctrl_lpi3c0>;\n"
|
|
344
|
+
"\tpinctrl-names = \"default\";\n"
|
|
345
|
+
"};\n"
|
|
346
|
+
"/ {\n"
|
|
347
|
+
"\taliases {\n"
|
|
348
|
+
"\t\talp-i3c0 = &lpi3c0;\n"
|
|
349
|
+
"\t};\n"
|
|
350
|
+
"};\n"
|
|
351
|
+
),
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def _emit_dts_overlay(
|
|
358
|
+
project: dict[str, Any],
|
|
359
|
+
sku_preset: dict[str, Any],
|
|
360
|
+
board_preset: dict[str, Any] | None,
|
|
361
|
+
*,
|
|
362
|
+
v2_peripherals: list[str] | None = None,
|
|
363
|
+
v2_core_id: str | None = None,
|
|
364
|
+
v2_core_os: str | None = None,
|
|
365
|
+
v2_core_ids: list[str] | None = None,
|
|
366
|
+
) -> str:
|
|
367
|
+
"""Emit a Zephyr DTS overlay describing the board wiring.
|
|
368
|
+
|
|
369
|
+
v1 path (`v2_peripherals is None`): reads project-level
|
|
370
|
+
`peripherals:` implicitly via the board header macros.
|
|
371
|
+
|
|
372
|
+
v2 path: the project's peripherals live under `cores.<id>.peripherals`.
|
|
373
|
+
Callers compute the union across Zephyr/baremetal cores (or pick one
|
|
374
|
+
when `--core <id>` is supplied) and pass it in via `v2_peripherals`.
|
|
375
|
+
The list is currently informational -- the bus aliases + `alp,pin-array`
|
|
376
|
+
binding root node are derived from the board header, which describes
|
|
377
|
+
the SoM mounting, not the project. When `v2_core_os` is set to a
|
|
378
|
+
non-Zephyr runtime (`yocto`, `off`, ...), the emitter returns a stub
|
|
379
|
+
overlay with just the header comment.
|
|
380
|
+
"""
|
|
381
|
+
lines: list[str] = []
|
|
382
|
+
lines.append("/*")
|
|
383
|
+
lines.append(" * Auto-generated by scripts/alp_project.py "
|
|
384
|
+
"-- do not edit by hand.")
|
|
385
|
+
lines.append(" * Regenerate after changes to board.yaml or "
|
|
386
|
+
"include/alp/boards/<board>.h.")
|
|
387
|
+
lines.append(" *")
|
|
388
|
+
lines.append(" * Per-pad GPIO bank/index values are TBD; cross-reference the in-tree")
|
|
389
|
+
lines.append(" * board file at zephyr/boards/alp/<board>/*.dts (zephyr/module.yml board_root).")
|
|
390
|
+
lines.append(" * The alp,pin-array below is the full 52-entry positional map in")
|
|
391
|
+
lines.append(" * e1m_pinout.h canonical order; fill the <&gpioX Y FLAGS> columns")
|
|
392
|
+
lines.append(" * in place without renumbering (the positional index is the ABI).")
|
|
393
|
+
lines.append(" */")
|
|
394
|
+
lines.append("")
|
|
395
|
+
|
|
396
|
+
# v2 short-circuit: a non-Zephyr core has no Zephyr overlay to emit.
|
|
397
|
+
# Customer-passed `--core <id>` may target a yocto / off slice -- the
|
|
398
|
+
# emitter returns a stub so the caller's pipeline doesn't fail.
|
|
399
|
+
if v2_core_os is not None and v2_core_os not in ("zephyr", "baremetal"):
|
|
400
|
+
lines.append(f"// --core {v2_core_id} has os: {v2_core_os}; no Zephyr DTS overlay applies.")
|
|
401
|
+
return "\n".join(lines) + "\n"
|
|
402
|
+
|
|
403
|
+
lines.append("#include <zephyr/dt-bindings/gpio/gpio.h>")
|
|
404
|
+
lines.append("")
|
|
405
|
+
|
|
406
|
+
sku = project["som"]["sku"]
|
|
407
|
+
# Carrier peripheral DT-wiring catalog for this SoM family. Computed
|
|
408
|
+
# ONCE here and reused both to skip the generic bus aliases the catalog
|
|
409
|
+
# owns (below) and to emit the catalog fragments at the tail.
|
|
410
|
+
fam = _sku_family(sku)
|
|
411
|
+
wiring = _PERIPH_DT_WIRING.get(fam, {})
|
|
412
|
+
board_name = (board_preset or {}).get("name", "")
|
|
413
|
+
if not board_name:
|
|
414
|
+
lines.append("// No board declared in board.yaml; nothing to emit.")
|
|
415
|
+
return "\n".join(lines) + "\n"
|
|
416
|
+
|
|
417
|
+
header_path = _board_header_path(board_name, REPO)
|
|
418
|
+
if not header_path.is_file():
|
|
419
|
+
raise DtsOverlayUnavailable(
|
|
420
|
+
f"no board header at "
|
|
421
|
+
f"{header_path.relative_to(REPO)} for board '{board_name}' "
|
|
422
|
+
f"-- DTS overlay emission requires one.")
|
|
423
|
+
|
|
424
|
+
macros = _parse_board_macros(header_path)
|
|
425
|
+
|
|
426
|
+
lines.append(f"/ {{")
|
|
427
|
+
lines.append(f" /* Board: {board_name} (SoM SKU {sku}) */")
|
|
428
|
+
lines.append(f" /* Source: include/alp/boards/{header_path.name} */")
|
|
429
|
+
if v2_peripherals is not None:
|
|
430
|
+
# Surface which Zephyr peripherals the v2 union resolved to so
|
|
431
|
+
# consumers can correlate the alias list back to their cores.
|
|
432
|
+
if v2_core_id is not None:
|
|
433
|
+
lines.append(
|
|
434
|
+
f" /* v2 scope: --core {v2_core_id} peripherals: "
|
|
435
|
+
f"{', '.join(v2_peripherals) if v2_peripherals else '<none>'} */"
|
|
436
|
+
)
|
|
437
|
+
else:
|
|
438
|
+
lines.append(
|
|
439
|
+
f" /* v2 scope: union of Zephyr/baremetal cores' peripherals: "
|
|
440
|
+
f"{', '.join(v2_peripherals) if v2_peripherals else '<none>'} */"
|
|
441
|
+
)
|
|
442
|
+
lines.append("")
|
|
443
|
+
|
|
444
|
+
# Bus aliases -- one per unique channel the board wires.
|
|
445
|
+
lines.append(" aliases {")
|
|
446
|
+
for class_name, alp_prefix, phandle_prefix in _BUS_BUCKETS:
|
|
447
|
+
# Catalog-owned classes (AEN i2c/adc) are instance-specific: the
|
|
448
|
+
# catalog owns only the aliases it remaps, while requested sibling
|
|
449
|
+
# instances can still receive the generic scaffold.
|
|
450
|
+
if phandle_prefix in wiring and phandle_prefix not in set(v2_peripherals or []):
|
|
451
|
+
continue
|
|
452
|
+
if phandle_prefix in wiring:
|
|
453
|
+
entries = sorted(
|
|
454
|
+
_catalog_generic_alias_indices(fam, phandle_prefix, project, macros, class_name)
|
|
455
|
+
- _catalog_owned_alias_indices(fam, phandle_prefix, project, macros)
|
|
456
|
+
)
|
|
457
|
+
else:
|
|
458
|
+
entries = sorted(set(idx for _macro, idx in macros.get(class_name, [])))
|
|
459
|
+
if not entries:
|
|
460
|
+
continue
|
|
461
|
+
lines.append(f" /* {class_name} */")
|
|
462
|
+
for idx in entries:
|
|
463
|
+
# Comment lists every board macro that references this channel.
|
|
464
|
+
referencing = [m for (m, i) in macros[class_name] if i == idx]
|
|
465
|
+
comment = ", ".join(referencing)
|
|
466
|
+
lines.append(
|
|
467
|
+
f" {alp_prefix}{idx} = &{phandle_prefix}{idx};"
|
|
468
|
+
f" /* {comment} */"
|
|
469
|
+
)
|
|
470
|
+
lines.append(" };")
|
|
471
|
+
lines.append("")
|
|
472
|
+
|
|
473
|
+
# alp,pin-array -- the 52-entry positional GPIO map. Order is fixed
|
|
474
|
+
# by e1m_pinout.h's "Devicetree / overlay invariant" so the GPIO
|
|
475
|
+
# backend's positional resolve (alp_pins[pin_id]) lands on the right
|
|
476
|
+
# pad, including secondary-function pads opened as GPIO via
|
|
477
|
+
# ALP_E1M_GPIO_<class><N>. Every slot is present even when the board
|
|
478
|
+
# doesn't route it; <&gpioX Y FLAGS> triplets are TBD pending the
|
|
479
|
+
# upstream SoM board file.
|
|
480
|
+
io_by_idx = {idx: m for (m, idx) in macros.get("GPIO_IO", [])}
|
|
481
|
+
pwm_by_idx = {idx: m for (m, idx) in macros.get("PWM", [])}
|
|
482
|
+
canonical = _e1m_gpio_canonical()
|
|
483
|
+
lines.append(" alp_pins: alp-pins {")
|
|
484
|
+
lines.append(' compatible = "alp,pin-array";')
|
|
485
|
+
lines.append(" /* 52 entries in E1M canonical order (e1m_pinout.h). Indices:")
|
|
486
|
+
lines.append(" * 0..25 IO0..IO25 26..33 PWM0..PWM7")
|
|
487
|
+
lines.append(" * 34..41 ENC0_X..ENC3_Y 42..49 ADC0..ADC7 50..51 DAC0..DAC1")
|
|
488
|
+
lines.append(" * Each <&gpioX Y FLAGS> triplet is TBD pending the upstream SoM")
|
|
489
|
+
lines.append(" * board file; unrouted pads keep their slot so indices stay")
|
|
490
|
+
lines.append(" * stable (alp_gpio_open of an unrouted pad returns NULL). */")
|
|
491
|
+
lines.append(" gpios =")
|
|
492
|
+
for i, suffix in enumerate(canonical):
|
|
493
|
+
terminator = ";" if i == len(canonical) - 1 else ","
|
|
494
|
+
# Annotate IO / PWM slots with the board macro routed to that pad
|
|
495
|
+
# (parsed from the board header); other classes carry the bare
|
|
496
|
+
# ALP_E1M_GPIO_<suffix> so the customer knows which pad the slot is.
|
|
497
|
+
routed = ""
|
|
498
|
+
if suffix.startswith("IO"):
|
|
499
|
+
n = int(suffix[2:])
|
|
500
|
+
if n in io_by_idx:
|
|
501
|
+
routed = f" routed: {io_by_idx[n]}"
|
|
502
|
+
elif suffix.startswith("PWM"):
|
|
503
|
+
n = int(suffix[3:])
|
|
504
|
+
if n in pwm_by_idx:
|
|
505
|
+
routed = f" default fn: {pwm_by_idx[n]}"
|
|
506
|
+
lines.append(
|
|
507
|
+
f" <&gpio0 0 GPIO_ACTIVE_HIGH>{terminator}"
|
|
508
|
+
f" /* [{i:2d}] ALP_E1M_GPIO_{suffix}{routed} */"
|
|
509
|
+
)
|
|
510
|
+
lines.append(" };")
|
|
511
|
+
lines.append("")
|
|
512
|
+
|
|
513
|
+
lines.append("};")
|
|
514
|
+
|
|
515
|
+
# ── carrier peripheral wiring (catalog-driven) ──────────────────────
|
|
516
|
+
# For each declared peripheral carrying a _PERIPH_DT_WIRING entry, append
|
|
517
|
+
# its controller node-enable + the alp-<x>N alias / io-channels consumer
|
|
518
|
+
# the portable backends resolve -- so `peripherals: [adc]` ALONE binds the
|
|
519
|
+
# hardware (no hand-written boards/*.overlay). The v1 path (v2_peripherals
|
|
520
|
+
# is None) emits nothing here. A per-example overlay still layers last.
|
|
521
|
+
# `fam`/`wiring` were computed once near the top of the function (and also
|
|
522
|
+
# gate the generic alias skip above), so they are reused here verbatim.
|
|
523
|
+
emitted: list[tuple[str, dict[str, Any], str]] = []
|
|
524
|
+
for p in sorted(set(v2_peripherals or [])):
|
|
525
|
+
if p not in wiring:
|
|
526
|
+
continue
|
|
527
|
+
entry = wiring[p]
|
|
528
|
+
if fam == "aen" and p == "adc":
|
|
529
|
+
indices = _route_indices_for_catalog(project, macros, "ADC", {0})
|
|
530
|
+
if not indices:
|
|
531
|
+
continue
|
|
532
|
+
emitted.append((p, entry, _emit_aen_adc_wiring(indices)))
|
|
533
|
+
continue
|
|
534
|
+
if fam == "aen" and p == "i2c":
|
|
535
|
+
indices = _route_indices_for_catalog(project, macros, "I2C", {0})
|
|
536
|
+
if 0 not in indices:
|
|
537
|
+
continue
|
|
538
|
+
if fam == "aen" and p == "i3c":
|
|
539
|
+
# lpi3c0 is M55-HE local domain (IRQ 50), so only a scope that
|
|
540
|
+
# CONTAINS m55_he gets the wiring -- an HP-only slice would
|
|
541
|
+
# otherwise carry an alias for an IRQ its core cannot service.
|
|
542
|
+
#
|
|
543
|
+
# Testing `v2_core_id != "m55_he"` alone would be wrong for the
|
|
544
|
+
# UNSCOPED emit (`--emit dts-overlay` with no `--core`, where
|
|
545
|
+
# v2_core_id is None): that path emits the cross-core union, so
|
|
546
|
+
# a board.yaml whose Zephyr core IS m55_he would silently get no
|
|
547
|
+
# i3c wiring while the conf emit still set CONFIG_I3C=y from
|
|
548
|
+
# peripheral-kconfig.json -- a green build whose alp_i3c_open()
|
|
549
|
+
# returns NOT_READY with nothing to point at. So for the
|
|
550
|
+
# unscoped case, look at whether the project declares m55_he.
|
|
551
|
+
# `project` here is the v1-SHAPED dict, which carries no `cores`
|
|
552
|
+
# key at all -- so the scope has to be passed in: v2_core_ids is
|
|
553
|
+
# [--core] when scoped, and the Zephyr/baremetal core ids when not.
|
|
554
|
+
if v2_core_id is not None:
|
|
555
|
+
in_scope = v2_core_id == "m55_he"
|
|
556
|
+
else:
|
|
557
|
+
in_scope = "m55_he" in (v2_core_ids or [])
|
|
558
|
+
if not in_scope:
|
|
559
|
+
continue
|
|
560
|
+
emitted.append((p, entry, entry.get("dts", "")))
|
|
561
|
+
|
|
562
|
+
if emitted:
|
|
563
|
+
incs: list[str] = []
|
|
564
|
+
for _p, entry, _dts in emitted:
|
|
565
|
+
for inc in entry.get("include", []):
|
|
566
|
+
if inc not in incs:
|
|
567
|
+
incs.append(inc)
|
|
568
|
+
lines.append("")
|
|
569
|
+
lines.append("/* ---- carrier peripheral wiring "
|
|
570
|
+
"(auto, from board.yaml `peripherals:`) ---- */")
|
|
571
|
+
for inc in incs:
|
|
572
|
+
lines.append(f"#include <{inc}>")
|
|
573
|
+
if incs:
|
|
574
|
+
lines.append("")
|
|
575
|
+
for p, _entry, dts in emitted:
|
|
576
|
+
lines.append(f"/* peripheral: {p} */")
|
|
577
|
+
lines.append(dts.rstrip("\n"))
|
|
578
|
+
lines.append("")
|
|
579
|
+
|
|
580
|
+
return "\n".join(lines) + "\n"
|