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,185 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Alp Lab AB
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*
|
|
5
|
+
* mproc-mailbox -- M55-HP <-> M55-HE shared-memory mailbox
|
|
6
|
+
* roundtrip on AEN (Alif Ensemble dual-Cortex-M55 silicon).
|
|
7
|
+
*
|
|
8
|
+
* The pattern this example shows
|
|
9
|
+
* ==============================
|
|
10
|
+
*
|
|
11
|
+
* Two Cortex-M55 cores share a small region of non-cached
|
|
12
|
+
* SRAM + a hardware mailbox + a hardware semaphore. An app on
|
|
13
|
+
* the M55-HP (the "application" core) sends a payload to the
|
|
14
|
+
* M55-HE (the "high-efficiency" peer) and waits for a reply.
|
|
15
|
+
*
|
|
16
|
+
* 1. HP owns the application: Wi-Fi, MQTT, UI.
|
|
17
|
+
* 2. HE owns offloadable work: PDM/audio DSP, slow sensor
|
|
18
|
+
* polling, inference pre/post-processing.
|
|
19
|
+
* 3. Mailbox + shared memory are how HP hands work to HE and
|
|
20
|
+
* collects results.
|
|
21
|
+
*
|
|
22
|
+
* The SDK exposes this through <alp/mproc.h>. Same API on AEN
|
|
23
|
+
* (HP<->HE) and on V2N (Cortex-A55 <-> Cortex-M33); the
|
|
24
|
+
* backend dispatches to the silicon's hardware mailbox.
|
|
25
|
+
*
|
|
26
|
+
* What you'll see in this example
|
|
27
|
+
* ===============================
|
|
28
|
+
*
|
|
29
|
+
* [mproc] init mbox + shmem
|
|
30
|
+
* [mproc] sending payload "hello-from-HP" (13 bytes)
|
|
31
|
+
* [mproc] HE replied via mbox callback
|
|
32
|
+
* [mproc] HE replied "echo: hello-from-HP" (19 bytes)
|
|
33
|
+
* [mproc] done
|
|
34
|
+
*
|
|
35
|
+
* Under native_sim there's no peer core; the example exercises
|
|
36
|
+
* just the HP-side init + the framing-encode path + `done`.
|
|
37
|
+
* Real-silicon runs both halves.
|
|
38
|
+
*
|
|
39
|
+
* Peer firmware
|
|
40
|
+
* =============
|
|
41
|
+
*
|
|
42
|
+
* The HE-side application lives at
|
|
43
|
+
* `https://github.com/alplabai/alp-sdk/blob/v0.17.0/examples/multicore/mproc-mailbox/peer/main.c`. Both halves build
|
|
44
|
+
* standalone via `west build`, and `board.yaml` declaring both
|
|
45
|
+
* `m55_hp` and `m55_he` as real project cores means one `tan build`
|
|
46
|
+
* already produces both images through the orchestrator's existing
|
|
47
|
+
* multi-slice path -- no sysbuild involved.
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
#include <stdio.h>
|
|
51
|
+
#include <string.h>
|
|
52
|
+
|
|
53
|
+
#include "alp/mproc.h"
|
|
54
|
+
#include "alp/peripheral.h"
|
|
55
|
+
|
|
56
|
+
/* Region name resolved against the alp-shmemN DT aliases in the
|
|
57
|
+
* board overlay -- here, alp-shmem0 in boards/<board>.overlay or
|
|
58
|
+
* the orchestrator-emitted carve-out for AEN dual-core builds. */
|
|
59
|
+
#define SHMEM_REGION_NAME "alp_shmem0"
|
|
60
|
+
#define SHMEM_REGION_SIZE 512u
|
|
61
|
+
#define MBOX_CHANNEL 0u
|
|
62
|
+
#define REQUEST_OFFSET 0u
|
|
63
|
+
#define RESPONSE_OFFSET 256u /* gap from request so the two never overlap */
|
|
64
|
+
#define MAX_PAYLOAD 128u
|
|
65
|
+
|
|
66
|
+
static const char *PAYLOAD = "hello-from-HP";
|
|
67
|
+
|
|
68
|
+
static struct {
|
|
69
|
+
volatile bool got_reply;
|
|
70
|
+
volatile size_t reply_offset;
|
|
71
|
+
volatile size_t reply_len;
|
|
72
|
+
} g_state;
|
|
73
|
+
|
|
74
|
+
/* Mailbox inbound-message callback. Fires when the HE peer
|
|
75
|
+
* signals back with the (offset, length) tuple naming the
|
|
76
|
+
* staged echo response. Runs on the SDK's mbox thread; we
|
|
77
|
+
* just stash the values so main() can drain them. */
|
|
78
|
+
static void mbox_inbound(uint32_t channel, const void *data, size_t len, void *user)
|
|
79
|
+
{
|
|
80
|
+
(void)channel;
|
|
81
|
+
(void)user;
|
|
82
|
+
if (len < 8u) return;
|
|
83
|
+
const uint8_t *b = data;
|
|
84
|
+
g_state.reply_offset =
|
|
85
|
+
(size_t)b[0] | ((size_t)b[1] << 8) | ((size_t)b[2] << 16) | ((size_t)b[3] << 24);
|
|
86
|
+
g_state.reply_len =
|
|
87
|
+
(size_t)b[4] | ((size_t)b[5] << 8) | ((size_t)b[6] << 16) | ((size_t)b[7] << 24);
|
|
88
|
+
g_state.got_reply = true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
int main(void)
|
|
92
|
+
{
|
|
93
|
+
printf("[mproc] init mbox + shmem\n");
|
|
94
|
+
|
|
95
|
+
const alp_shmem_config_t shmem_cfg = {
|
|
96
|
+
.name = SHMEM_REGION_NAME,
|
|
97
|
+
.size = SHMEM_REGION_SIZE,
|
|
98
|
+
};
|
|
99
|
+
alp_shmem_t *shmem = alp_shmem_open(&shmem_cfg);
|
|
100
|
+
|
|
101
|
+
const alp_mbox_config_t mbox_cfg = {
|
|
102
|
+
.channel = MBOX_CHANNEL,
|
|
103
|
+
.peer = ALP_CORE_M55_HE,
|
|
104
|
+
};
|
|
105
|
+
alp_mbox_t *mbox = alp_mbox_open(&mbox_cfg);
|
|
106
|
+
|
|
107
|
+
if (shmem == NULL || mbox == NULL) {
|
|
108
|
+
printf("[mproc] open failed: last_err=%d\n", (int)alp_last_error());
|
|
109
|
+
goto done;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Get a pointer view of the shared region. Both cores see
|
|
113
|
+
* the same physical bytes; the region is non-cacheable,
|
|
114
|
+
* so no cache flush is needed. */
|
|
115
|
+
void *shmem_base = NULL;
|
|
116
|
+
size_t shmem_size = 0u;
|
|
117
|
+
if (alp_shmem_view(shmem, &shmem_base, &shmem_size) != ALP_OK) {
|
|
118
|
+
printf("[mproc] shmem view failed\n");
|
|
119
|
+
goto teardown;
|
|
120
|
+
}
|
|
121
|
+
if (shmem_size < RESPONSE_OFFSET + MAX_PAYLOAD) {
|
|
122
|
+
printf("[mproc] shmem too small (%zu)\n", shmem_size);
|
|
123
|
+
goto teardown;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* Stage the payload at REQUEST_OFFSET in the shared region.
|
|
127
|
+
* memcpy is the right primitive here -- the SDK's shmem
|
|
128
|
+
* surface gives back a raw pointer + size and trusts the
|
|
129
|
+
* caller to write through it. */
|
|
130
|
+
const size_t payload_len = strlen(PAYLOAD);
|
|
131
|
+
memcpy((uint8_t *)shmem_base + REQUEST_OFFSET, PAYLOAD, payload_len);
|
|
132
|
+
|
|
133
|
+
/* Send the mailbox notification. Payload here is the
|
|
134
|
+
* `(offset, length)` tuple that points at the staged bytes
|
|
135
|
+
* in shmem; the peer reads the actual data through its own
|
|
136
|
+
* shmem view. */
|
|
137
|
+
uint8_t mbox_msg[8] = {
|
|
138
|
+
(uint8_t)REQUEST_OFFSET, 0, 0, 0, /* offset (LE u32) */
|
|
139
|
+
(uint8_t)payload_len, 0, 0, 0, /* length (LE u32) */
|
|
140
|
+
};
|
|
141
|
+
if (alp_mbox_send(mbox, mbox_msg, sizeof(mbox_msg), 100u) != ALP_OK) {
|
|
142
|
+
printf("[mproc] mbox send failed\n");
|
|
143
|
+
goto teardown;
|
|
144
|
+
}
|
|
145
|
+
printf("[mproc] sending payload \"%s\" (%u bytes)\n", PAYLOAD, (unsigned)payload_len);
|
|
146
|
+
|
|
147
|
+
/* Register the receive callback before waiting. On real
|
|
148
|
+
* silicon the peer sends back via the same mbox; the
|
|
149
|
+
* callback drains the (offset, length) tuple naming the
|
|
150
|
+
* echo response. */
|
|
151
|
+
if (alp_mbox_set_callback(mbox, mbox_inbound, NULL) != ALP_OK) {
|
|
152
|
+
printf("[mproc] set_callback failed\n");
|
|
153
|
+
goto teardown;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
#ifdef CONFIG_BOARD_NATIVE_SIM
|
|
157
|
+
printf("[mproc] native_sim: no peer core; skipping reply wait\n");
|
|
158
|
+
#else
|
|
159
|
+
/* Poll for the reply. On HiL the mailbox-ISR-driven
|
|
160
|
+
* callback flips g_state.got_reply within ~1 ms of the
|
|
161
|
+
* peer's send. */
|
|
162
|
+
for (int i = 0; i < 100 && !g_state.got_reply; ++i) {
|
|
163
|
+
alp_delay_ms(10);
|
|
164
|
+
}
|
|
165
|
+
if (!g_state.got_reply) {
|
|
166
|
+
printf("[mproc] reply timeout (peer not running?)\n");
|
|
167
|
+
goto teardown;
|
|
168
|
+
}
|
|
169
|
+
printf("[mproc] HE replied via mbox callback\n");
|
|
170
|
+
|
|
171
|
+
if (g_state.reply_len > MAX_PAYLOAD) g_state.reply_len = MAX_PAYLOAD;
|
|
172
|
+
char reply_buf[MAX_PAYLOAD + 1];
|
|
173
|
+
memcpy(reply_buf, (uint8_t *)shmem_base + g_state.reply_offset, g_state.reply_len);
|
|
174
|
+
reply_buf[g_state.reply_len] = '\0';
|
|
175
|
+
printf("[mproc] HE replied \"%s\" (%u bytes)\n", reply_buf, (unsigned)g_state.reply_len);
|
|
176
|
+
#endif
|
|
177
|
+
|
|
178
|
+
teardown:
|
|
179
|
+
alp_mbox_close(mbox);
|
|
180
|
+
alp_shmem_close(shmem);
|
|
181
|
+
|
|
182
|
+
done:
|
|
183
|
+
printf("[mproc] done\n");
|
|
184
|
+
return 0;
|
|
185
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
|
|
3
|
+
sample:
|
|
4
|
+
name: mproc-mailbox
|
|
5
|
+
description: |
|
|
6
|
+
AEN M55-HP side of a Cortex-M55 mailbox + shared-memory
|
|
7
|
+
roundtrip via <alp/mproc.h>. Under native_sim the example
|
|
8
|
+
exercises the HP-side init + alp_mbox_send framing path and
|
|
9
|
+
exits cleanly (no peer core to talk to). Real silicon
|
|
10
|
+
waits for the peer firmware to echo the payload back.
|
|
11
|
+
common:
|
|
12
|
+
tags: mproc shmem
|
|
13
|
+
harness: console
|
|
14
|
+
harness_config:
|
|
15
|
+
type: one_line
|
|
16
|
+
regex:
|
|
17
|
+
- "\\[mproc\\] done"
|
|
18
|
+
tests:
|
|
19
|
+
alp_sdk.examples.mproc_mailbox.native_sim:
|
|
20
|
+
platform_allow: native_sim/native/64
|
|
21
|
+
extra_args: EXTRA_CONF_FILE=generated/alp.conf CONFIG_ALP_SDK_MPROC=y # mproc surface is opt-in; the .aen sibling sets it too.
|
|
22
|
+
alp_sdk.examples.mproc_mailbox.aen:
|
|
23
|
+
platform_allow:
|
|
24
|
+
- ensemble_e8_dk/ae822fa0e5597ls0/rtss_he
|
|
25
|
+
extra_args: EXTRA_CONF_FILE=generated/alp.conf CONFIG_ALP_SDK_MPROC=y
|
|
26
|
+
build_only: true # real run needs the peer firmware (v0.4+).
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# i2c-master
|
|
2
|
+
|
|
3
|
+
Discrete I2C master that reads a known device at a known
|
|
4
|
+
address. Pattern: open the bus, init the chip driver, loop
|
|
5
|
+
reading the sensor every second, close cleanly.
|
|
6
|
+
|
|
7
|
+
Contrasts with [`examples/peripheral-io/i2c-scanner`](https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/peripheral-io/i2c-scanner) -- the
|
|
8
|
+
scanner *probes* every 7-bit address for ACKs without knowing
|
|
9
|
+
what's behind them; this example *reads* a known sensor.
|
|
10
|
+
|
|
11
|
+
## What this shows
|
|
12
|
+
|
|
13
|
+
* `alp_i2c_open()` -- open `BOARD_I2C_SENSORS` at 400 kHz Fast-mode.
|
|
14
|
+
The `<alp/board.h>` alias resolves to `ALP_E1M_I2C0` on the E1M
|
|
15
|
+
EVK and `ALP_E1M_X_I2C0` on the E1M-X EVK.
|
|
16
|
+
* `bmp581_init()` -- chip-driver probe (CHIP_ID check).
|
|
17
|
+
* `bmp581_set_sampling()` -- configure oversampling, ODR, and power mode.
|
|
18
|
+
* `bmp581_read_raw()` + `bmp581_compensate()` -- one pressure+temperature read per second.
|
|
19
|
+
* Error handling: NACK on probe -> graceful exit with diagnostic.
|
|
20
|
+
* `bmp581_deinit()` + `alp_i2c_close()` -- clean shutdown.
|
|
21
|
+
|
|
22
|
+
## Hardware
|
|
23
|
+
|
|
24
|
+
The BMP581 barometer is the on-board sensor on `BOARD_I2C_SENSORS`
|
|
25
|
+
on both the E1M EVK (U14) and the E1M-X EVK, per
|
|
26
|
+
[`metadata/boards/e1m-evk.yaml`](https://github.com/alplabai/alp-sdk/blob/v0.17.0/metadata/boards/e1m-evk.yaml) and
|
|
27
|
+
[`metadata/boards/e1m-x-evk.yaml`](https://github.com/alplabai/alp-sdk/blob/v0.17.0/metadata/boards/e1m-x-evk.yaml)
|
|
28
|
+
`i2c_devices:`.
|
|
29
|
+
|
|
30
|
+
7-bit address depends on the SDO strap:
|
|
31
|
+
|
|
32
|
+
| SDO strap | Address | On this bus |
|
|
33
|
+
|-----------|---------|---------------------------------------|
|
|
34
|
+
| VDDIO | 0x47 | E1M EVK U14 + E1M-X EVK (this default) |
|
|
35
|
+
| GND | 0x46 | (not populated on these EVKs) |
|
|
36
|
+
|
|
37
|
+
Both supported EVKs strap SDO to VDDIO, so `BMP581_ADDR_7BIT`
|
|
38
|
+
works unchanged across them (see
|
|
39
|
+
[`metadata/boards/e1m-evk.yaml`](https://github.com/alplabai/alp-sdk/blob/v0.17.0/metadata/boards/e1m-evk.yaml),
|
|
40
|
+
BMP581 datasheet BST-BMP581-DS004 s5.6, or
|
|
41
|
+
[`include/alp/chips/bmp581.h`](https://github.com/alplabai/alp-sdk/blob/v0.17.0/include/alp/chips/bmp581.h)).
|
|
42
|
+
|
|
43
|
+
> **#1269:** this example used to target the TMP112 temperature sensor,
|
|
44
|
+
> but TMP112 lives on **BRD_I2C**, not on `BOARD_I2C_SENSORS` -- opening
|
|
45
|
+
> `BOARD_I2C_SENSORS` and probing for TMP112 NACKs on real hardware.
|
|
46
|
+
> BRD_I2C is a separate controller instance regardless (on the E1M-AEN
|
|
47
|
+
> family it is SoC I2C0, function C -- #1848), so simply repointing the bus_id
|
|
48
|
+
> would still not reach a TMP112 there. See
|
|
49
|
+
> [`examples/v2n/v2n-temp-sensor`](https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/v2n/v2n-temp-sensor) for the
|
|
50
|
+
> V2N-only BRD_I2C/TMP112 pattern instead.
|
|
51
|
+
|
|
52
|
+
## Build
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Standalone, native_sim (emul I2C; bmp581_init NACKs cleanly):
|
|
56
|
+
# writes ./generated/alp.conf, which west reads below (#866)
|
|
57
|
+
tan generate --target zephyr-conf --core m55_hp --sdk-root "$ALP_SDK_ROOT" --output generated/alp.conf
|
|
58
|
+
west build -b native_sim/native/64 . \
|
|
59
|
+
-- -DEXTRA_CONF_FILE=generated/alp.conf -DEXTRA_ZEPHYR_MODULES=$ALP_SDK_ROOT
|
|
60
|
+
west build -t run
|
|
61
|
+
|
|
62
|
+
# On real silicon, point -b at the SoM's Zephyr board target.
|
|
63
|
+
# Example for E1M-AEN801:
|
|
64
|
+
west build -b alp_e1m_aen801_m55_hp/ae822fa0e5597ls0/rtss_hp . -- -DEXTRA_CONF_FILE=generated/alp.conf
|
|
65
|
+
west flash
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Expected output
|
|
69
|
+
|
|
70
|
+
Real hardware (BMP581 populated, room temperature, sea-level-ish pressure):
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
[i2c-master] open BOARD_I2C_SENSORS @ 400 kHz
|
|
74
|
+
[i2c-master] bmp581_init @ 0x47 -> 0 (OK)
|
|
75
|
+
[i2c-master] sample 0: 96234 Pa, 23.625 degC
|
|
76
|
+
[i2c-master] sample 1: 96231 Pa, 23.687 degC
|
|
77
|
+
[i2c-master] sample 2: 96233 Pa, 23.625 degC
|
|
78
|
+
[i2c-master] sample 3: 96230 Pa, 23.687 degC
|
|
79
|
+
[i2c-master] sample 4: 96232 Pa, 23.750 degC
|
|
80
|
+
[i2c-master] done
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
native_sim (emul I2C, no BMP581 registered):
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
[i2c-master] open BOARD_I2C_SENSORS @ 400 kHz
|
|
87
|
+
[i2c-master] bmp581_init @ 0x47 -> -5 (populated? right address?)
|
|
88
|
+
[i2c-master] done
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Troubleshooting
|
|
92
|
+
|
|
93
|
+
* **`bmp581_init -> -5`** (ALP_ERR_IO / NACK). Either the chip
|
|
94
|
+
isn't populated on your board, the address is wrong (see
|
|
95
|
+
table above), or the bus is held low (missing pull-ups, stuck
|
|
96
|
+
slave). Run [`examples/peripheral-io/i2c-scanner`](https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/peripheral-io/i2c-scanner) to confirm what
|
|
97
|
+
ACKs.
|
|
98
|
+
* **`alp_i2c_open failed`** (NULL return). The `alp-i2c0` DT
|
|
99
|
+
alias isn't set -- check your board overlay or, for
|
|
100
|
+
native_sim, that `CONFIG_EMUL=y CONFIG_I2C_EMUL=y` and the
|
|
101
|
+
overlay we ship are picked up.
|
|
102
|
+
* **Garbled readings.** Wrong baud (bitrate) for the bus
|
|
103
|
+
capacitance. Drop from 400 kHz to 100 kHz to confirm.
|
|
104
|
+
|
|
105
|
+
## Reference
|
|
106
|
+
|
|
107
|
+
- [`<alp/peripheral.h>`](https://github.com/alplabai/alp-sdk/blob/v0.17.0/include/alp/peripheral.h) I2C surface.
|
|
108
|
+
- [`<alp/chips/bmp581.h>`](https://github.com/alplabai/alp-sdk/blob/v0.17.0/include/alp/chips/bmp581.h) -- driver API.
|
|
109
|
+
- [`examples/peripheral-io/i2c-scanner/`](https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/peripheral-io/i2c-scanner) -- discovery companion.
|
|
110
|
+
- [`examples/peripheral-io/i2c-slave/`](https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/peripheral-io/i2c-slave) -- slave-mode companion, built on the `alp_i2c_target_*` surface.
|
|
111
|
+
- [`examples/v2n/v2n-temp-sensor/`](https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/v2n/v2n-temp-sensor) -- TMP112-on-BRD_I2C companion, V2N-only.
|
|
112
|
+
- BMP581 datasheet (BST-BMP581-DS004, rev 1.13).
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# board.yaml -- per-app project configuration for the
|
|
2
|
+
# i2c-master example.
|
|
3
|
+
#
|
|
4
|
+
# Reads the BMP581 barometer on BOARD_I2C_SENSORS via the chip-
|
|
5
|
+
# driver header. Discrete master that talks to a known device at
|
|
6
|
+
# a known address -- contrasts with https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/peripheral-io/i2c-scanner which
|
|
7
|
+
# probes every 7-bit address for ACKs.
|
|
8
|
+
#
|
|
9
|
+
# Customer workflow: `tan init --from-example peripheral-io/i2c-master`, change `som.sku` to
|
|
10
|
+
# your MPN, edit the `preset:` (or use an inline board) if you're on a non-EVK board,
|
|
11
|
+
# and `tan build`, which plans alp.conf from this file; twister and a bare
|
|
12
|
+
# west build read the pre-generated generated/alp.conf instead
|
|
13
|
+
# (`tan generate --target zephyr-conf`, see README.md).
|
|
14
|
+
som:
|
|
15
|
+
sku: E1M-AEN801
|
|
16
|
+
|
|
17
|
+
preset: e1m-evk
|
|
18
|
+
supported_boards:
|
|
19
|
+
- e1m-evk
|
|
20
|
+
- e1m-x-evk
|
|
21
|
+
|
|
22
|
+
# E1M pads this app uses (subset of the EVK preset's `e1m_routes:`).
|
|
23
|
+
pins:
|
|
24
|
+
- { e1m: E1M_I2C0, macro: EVK_I2C_BUS_SENSORS, doc: "Shared sensor + IO-expander + INA236 bus" }
|
|
25
|
+
cores:
|
|
26
|
+
m55_hp:
|
|
27
|
+
app: ./src
|
|
28
|
+
# Zephyr peripheral subsystem exercised by this example. The
|
|
29
|
+
# loader translates the entry to CONFIG_I2C=y in alp.conf.
|
|
30
|
+
peripherals:
|
|
31
|
+
- i2c
|
|
32
|
+
|
|
33
|
+
# BMP581 is populated on every member of the AEN, V2N, V2N-M1
|
|
34
|
+
# families per alp-sdk's metadata/chips/bmp581.yaml (not part of
|
|
35
|
+
# this scaffolded project) -- so this example is Ring 2
|
|
36
|
+
# (chip-bound, multi-family) per
|
|
37
|
+
# alp-sdk's scripts/check_example_portability.py classification
|
|
38
|
+
# (also not part of this scaffolded project).
|
|
39
|
+
#
|
|
40
|
+
# NOTE (#1269): TMP112 was here previously, but TMP112 lives on
|
|
41
|
+
# BRD_I2C, not on BOARD_I2C_SENSORS -- see alp-sdk's
|
|
42
|
+
# metadata/boards/e1m-evk.yaml i2c_devices: and
|
|
43
|
+
# metadata/boards/e1m-x-evk.yaml i2c_devices: (not part of this
|
|
44
|
+
# scaffolded project), neither of which lists a TMP112 on the sensor
|
|
45
|
+
# bus this example opens. BRD_I2C
|
|
46
|
+
# is a SEPARATE controller instance from BOARD_I2C_SENSORS regardless
|
|
47
|
+
# (on the E1M-AEN family, BRD_I2C is SoC I2C0, function C -- #1848), so
|
|
48
|
+
# repointing the bus_id would still not reach a TMP112 there. BMP581 is
|
|
49
|
+
# the part that is actually on BOARD_I2C_SENSORS on both supported
|
|
50
|
+
# boards, at the same address (0x47) on each -- see
|
|
51
|
+
# https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/v2n/v2n-temp-sensor for the V2N-only BRD_I2C/TMP112 pattern
|
|
52
|
+
# instead.
|
|
53
|
+
chips:
|
|
54
|
+
- bmp581
|
|
55
|
+
|
|
56
|
+
diagnostics:
|
|
57
|
+
log_level: info
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
#
|
|
3
|
+
# native_sim has no real I2C controller; pull in the emul I2C
|
|
4
|
+
# driver so the bus enumerates at boot and bmp581_init can probe
|
|
5
|
+
# (which returns NACK because no BMP581 is registered -- exactly
|
|
6
|
+
# the path the example's error-handling branch exercises).
|
|
7
|
+
# Auto-loaded by Zephyr when building for native_sim/native/64.
|
|
8
|
+
|
|
9
|
+
CONFIG_EMUL=y
|
|
10
|
+
CONFIG_I2C_EMUL=y
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Alp Lab AB
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*
|
|
5
|
+
* One emulated I2C bus exposed via the alp-i2c0 alias. No emul
|
|
6
|
+
* targets are attached so bmp581_init returns NACK -- but the
|
|
7
|
+
* open / probe / close path runs end-to-end and the harness
|
|
8
|
+
* latches on the `[i2c-master] done` marker.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#include <zephyr/dt-bindings/i2c/i2c.h>
|
|
12
|
+
|
|
13
|
+
/ {
|
|
14
|
+
aliases {
|
|
15
|
+
alp-i2c0 = &i2c0_emul;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
soc {
|
|
19
|
+
i2c0_emul: i2c@100 {
|
|
20
|
+
compatible = "zephyr,i2c-emul-controller";
|
|
21
|
+
status = "okay";
|
|
22
|
+
reg = <0 0x100 4>;
|
|
23
|
+
#address-cells = <1>;
|
|
24
|
+
#size-cells = <0>;
|
|
25
|
+
clock-frequency = <I2C_BITRATE_FAST>;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Alp Lab AB
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*
|
|
5
|
+
* i2c-master -- discrete I2C master that reads a known device at
|
|
6
|
+
* a known address.
|
|
7
|
+
*
|
|
8
|
+
* Pattern: open the bus, init the chip driver, loop reading the
|
|
9
|
+
* register every second, close cleanly. Contrasts with
|
|
10
|
+
* https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/peripheral-io/i2c-scanner which probes every 7-bit address for ACKs
|
|
11
|
+
* without knowing what's behind them.
|
|
12
|
+
*
|
|
13
|
+
* Hardware: the BMP581 barometer sits on BOARD_I2C_SENSORS on every
|
|
14
|
+
* E1M and E1M-X EVK, strapped to 7-bit address 0x47 (SDO -> VDDIO)
|
|
15
|
+
* on both -- see alp-sdk's metadata/boards/e1m-evk.yaml and
|
|
16
|
+
* metadata/boards/e1m-x-evk.yaml (not part of this scaffolded
|
|
17
|
+
* project) `i2c_devices:`. On a brand-new
|
|
18
|
+
* bring-up you may want to build and run the alp-sdk repo's
|
|
19
|
+
* https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/peripheral-io/i2c-scanner example first to confirm which
|
|
20
|
+
* address ACKs -- it isn't part of this scaffolded project.
|
|
21
|
+
*
|
|
22
|
+
* (#1269: this example used to target the TMP112 temperature
|
|
23
|
+
* sensor, but TMP112 lives on BRD_I2C, not on BOARD_I2C_SENSORS --
|
|
24
|
+
* opening BOARD_I2C_SENSORS and probing for TMP112 NACKs on real
|
|
25
|
+
* hardware. BRD_I2C is a separate controller instance regardless
|
|
26
|
+
* (on the E1M-AEN family it is SoC I2C0, function C -- #1848), so
|
|
27
|
+
* simply repointing the bus_id would still not reach a TMP112 there; see
|
|
28
|
+
* https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/v2n/v2n-temp-sensor for the V2N-only BRD_I2C/TMP112
|
|
29
|
+
* pattern.)
|
|
30
|
+
*
|
|
31
|
+
* What success looks like (real hardware):
|
|
32
|
+
*
|
|
33
|
+
* [i2c-master] open BOARD_I2C_SENSORS @ 400 kHz
|
|
34
|
+
* [i2c-master] bmp581_init @ 0x47 -> 0 (OK)
|
|
35
|
+
* [i2c-master] sample 0: 96234 Pa, 23.625 degC
|
|
36
|
+
* [i2c-master] sample 1: 96231 Pa, 23.687 degC
|
|
37
|
+
* ...
|
|
38
|
+
* [i2c-master] done
|
|
39
|
+
*
|
|
40
|
+
* On native_sim (CI lane) the alp-i2c0 alias maps to the emul I2C
|
|
41
|
+
* driver -- no BMP581 is registered as a target, so bmp581_init
|
|
42
|
+
* gets NACKed and the example exits with the diagnostic. Either
|
|
43
|
+
* way the [i2c-master] done marker latches the harness.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
#include <stdio.h>
|
|
47
|
+
|
|
48
|
+
#include "alp/peripheral.h"
|
|
49
|
+
#include "alp/chips/bmp581.h"
|
|
50
|
+
|
|
51
|
+
/* BOARD_I2C_SENSORS is a portable cross-EVK alias from <alp/board.h>:
|
|
52
|
+
* E1M EVK -> EVK_I2C_BUS_SENSORS -> ALP_E1M_I2C0
|
|
53
|
+
* E1M-X EVK -> XEVK_I2C_BUS_SENSORS -> ALP_E1M_X_I2C0
|
|
54
|
+
* Rebind it in board.yaml `pins:` to port to another board. */
|
|
55
|
+
#include "alp/board.h"
|
|
56
|
+
|
|
57
|
+
/* BMP581 7-bit I2C address with SDO -> VDDIO -- the on-board strap
|
|
58
|
+
* on both the E1M EVK (U14) and E1M-X EVK (see alp-sdk's
|
|
59
|
+
* metadata/boards/e1m-evk.yaml / e1m-x-evk.yaml, not part of
|
|
60
|
+
* this scaffolded project, `i2c_devices:`).
|
|
61
|
+
* SDO -> GND gives 0x46 instead; see the BMP581 datasheet
|
|
62
|
+
* BST-BMP581-DS004 s5.6 or alp-sdk's include/alp/chips/bmp581.h
|
|
63
|
+
* (not part of this scaffolded project) if your board straps
|
|
64
|
+
* differently. */
|
|
65
|
+
#define BMP581_ADDR_7BIT BMP581_I2C_ADDR_HIGH /* 0x47 */
|
|
66
|
+
|
|
67
|
+
/* Number of samples to take before exiting. Capped so the
|
|
68
|
+
* native_sim build doesn't stall the twister harness; real
|
|
69
|
+
* firmware would loop forever. */
|
|
70
|
+
#define SAMPLE_COUNT 5u
|
|
71
|
+
|
|
72
|
+
/* Wait between samples. 50 Hz ODR (below) means a fresh reading
|
|
73
|
+
* every 20 ms; waiting a full second gives a comfortable margin
|
|
74
|
+
* and prints once per watch-tick which is easy on the eyes. */
|
|
75
|
+
#define SAMPLE_PERIOD_MS 1000u
|
|
76
|
+
|
|
77
|
+
int main(void)
|
|
78
|
+
{
|
|
79
|
+
/* Bring up the SDK runtime before anything else -- thin today,
|
|
80
|
+
* but future backends rely on it (see <alp/peripheral.h>). */
|
|
81
|
+
(void)alp_init();
|
|
82
|
+
|
|
83
|
+
printf("[i2c-master] open BOARD_I2C_SENSORS @ 400 kHz\n");
|
|
84
|
+
|
|
85
|
+
/* Open the bus at 400 kHz (I2C Fast-mode). BMP581 supports up
|
|
86
|
+
* to 1 MHz (Fast-mode Plus) per its datasheet, so 400 kHz is
|
|
87
|
+
* comfortably inside spec; the SDK rounds DOWN to the
|
|
88
|
+
* controller's closest achievable rate. 100 kHz is the safe
|
|
89
|
+
* baseline for unknown devices. */
|
|
90
|
+
alp_i2c_t *bus = alp_i2c_open(&(alp_i2c_config_t){
|
|
91
|
+
.bus_id = BOARD_I2C_SENSORS, /* E1M EVK: ALP_E1M_I2C0; E1M-X EVK: ALP_E1M_X_I2C0 */
|
|
92
|
+
.bitrate_hz = 400000,
|
|
93
|
+
});
|
|
94
|
+
if (bus == NULL) {
|
|
95
|
+
/* No alp-i2c0 alias on this build -> NULL handle.
|
|
96
|
+
*
|
|
97
|
+
* Common causes:
|
|
98
|
+
* * Board overlay forgot to set the alias.
|
|
99
|
+
* * SoM has no I2C0 routed (rare -- it's part of the
|
|
100
|
+
* portable E1M baseline).
|
|
101
|
+
* * On native_sim without the emul overlay we ship,
|
|
102
|
+
* the alias is unset. */
|
|
103
|
+
printf("[i2c-master] open failed: alp_last_error=%d\n", (int)alp_last_error());
|
|
104
|
+
printf("[i2c-master] done\n");
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Initialise the BMP581 driver. This reads CHIP_ID and verifies
|
|
109
|
+
* it matches BMP581_CHIP_ID -- catches the "wrong address" case
|
|
110
|
+
* (NACK on probe) up-front. If init fails the example exits
|
|
111
|
+
* cleanly -- maybe the chip isn't populated, maybe the address
|
|
112
|
+
* is wrong, maybe the bus is held low by another device.
|
|
113
|
+
* https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/peripheral-io/i2c-scanner can confirm which devices ACK. */
|
|
114
|
+
bmp581_t sensor;
|
|
115
|
+
alp_status_t s = bmp581_init(&sensor, bus, BMP581_ADDR_7BIT);
|
|
116
|
+
if (s != ALP_OK) {
|
|
117
|
+
/* Most-frequent failure modes:
|
|
118
|
+
* * ALP_ERR_IO -- bus error or NACK. No BMP581 here,
|
|
119
|
+
* wrong address, or pull-ups missing
|
|
120
|
+
* (the bus floats high without them).
|
|
121
|
+
* * ALP_ERR_INVAL -- bad argument (NULL ctx or NULL bus).
|
|
122
|
+
*
|
|
123
|
+
* Use the alp-sdk repo's https://github.com/alplabai/alp-sdk/tree/v0.17.0/examples/peripheral-io/i2c-scanner
|
|
124
|
+
* example to enumerate what IS on this bus before chasing a
|
|
125
|
+
* BMP581 that may not be populated. */
|
|
126
|
+
printf("[i2c-master] bmp581_init @ 0x%02x -> %d "
|
|
127
|
+
"(populated? right address?)\n",
|
|
128
|
+
BMP581_ADDR_7BIT,
|
|
129
|
+
(int)s);
|
|
130
|
+
alp_i2c_close(bus);
|
|
131
|
+
printf("[i2c-master] done\n");
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
printf("[i2c-master] bmp581_init @ 0x%02x -> %d (OK)\n", BMP581_ADDR_7BIT, (int)s);
|
|
135
|
+
|
|
136
|
+
/* Configure oversampling + ODR + power mode in one call. x8
|
|
137
|
+
* oversampling at 50 Hz normal mode is a reasonable general-
|
|
138
|
+
* purpose default; reach for higher OSR when you want lower
|
|
139
|
+
* noise at the cost of more power/latency. */
|
|
140
|
+
s = bmp581_set_sampling(
|
|
141
|
+
&sensor, BMP581_OSR_X8, BMP581_OSR_X8, BMP581_ODR_50_HZ, BMP581_MODE_NORMAL);
|
|
142
|
+
if (s != ALP_OK) {
|
|
143
|
+
printf("[i2c-master] bmp581_set_sampling -> %d\n", (int)s);
|
|
144
|
+
/* Non-fatal: the chip stays at whatever mode init left it in. */
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Sample loop: read SAMPLE_COUNT pressure+temperature pairs, one
|
|
148
|
+
* per second. Real-life firmware would publish each reading
|
|
149
|
+
* over MQTT, push to a ring buffer for trend analysis, or
|
|
150
|
+
* compare against an alert threshold and pull a GPIO. */
|
|
151
|
+
for (uint32_t i = 0; i < SAMPLE_COUNT; i++) {
|
|
152
|
+
bmp581_raw_t raw = { 0 };
|
|
153
|
+
bmp581_compensated_t comp = { 0 };
|
|
154
|
+
s = bmp581_read_raw(&sensor, &raw);
|
|
155
|
+
if (s == ALP_OK) {
|
|
156
|
+
s = bmp581_compensate(&raw, &comp);
|
|
157
|
+
}
|
|
158
|
+
if (s == ALP_OK) {
|
|
159
|
+
/* Format integer + fractional parts so we avoid float
|
|
160
|
+
* printf on M-class targets. temperature_c1000 is
|
|
161
|
+
* signed -- the fractional part takes the absolute
|
|
162
|
+
* value so e.g. -1750 milli-C prints as "-1.750 degC"
|
|
163
|
+
* (not "-1.-750 degC"). */
|
|
164
|
+
int whole = comp.temperature_c1000 / 1000;
|
|
165
|
+
int frac =
|
|
166
|
+
(comp.temperature_c1000 < 0 ? -comp.temperature_c1000 : comp.temperature_c1000) %
|
|
167
|
+
1000;
|
|
168
|
+
printf(
|
|
169
|
+
"[i2c-master] sample %u: %d Pa, %d.%03d degC\n", i, comp.pressure_pa, whole, frac);
|
|
170
|
+
} else {
|
|
171
|
+
/* Read/compensate errors during steady-state are rare --
|
|
172
|
+
* usually a transient bus glitch (EMI, ground bounce).
|
|
173
|
+
* Log and continue rather than aborting; the next
|
|
174
|
+
* sample will likely succeed. */
|
|
175
|
+
printf("[i2c-master] sample %u: read -> %d\n", i, (int)s);
|
|
176
|
+
}
|
|
177
|
+
alp_delay_ms(SAMPLE_PERIOD_MS);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* Clean shutdown -- deinit the chip driver, then close the bus
|
|
181
|
+
* handle (which releases the slot back to the pool). */
|
|
182
|
+
bmp581_deinit(&sensor);
|
|
183
|
+
alp_i2c_close(bus);
|
|
184
|
+
printf("[i2c-master] done\n");
|
|
185
|
+
return 0;
|
|
186
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
|
|
3
|
+
sample:
|
|
4
|
+
name: i2c-master
|
|
5
|
+
description: |
|
|
6
|
+
Per-peripheral example for I2C master. Reads the on-board
|
|
7
|
+
BMP581 barometer at a known 7-bit address via
|
|
8
|
+
BOARD_I2C_SENSORS. Builds on both EVKs: E1M EVK uses E1M_I2C0;
|
|
9
|
+
E1M-X EVK uses E1M_X_I2C0. Contrasts with
|
|
10
|
+
examples/peripheral-io/i2c-scanner (discovery vs known-address read).
|
|
11
|
+
|
|
12
|
+
tests:
|
|
13
|
+
alp_sdk.example.i2c_master.e1m_x_evk:
|
|
14
|
+
extra_args: EXTRA_CONF_FILE=generated/alp.conf
|
|
15
|
+
platform_allow:
|
|
16
|
+
- native_sim
|
|
17
|
+
- native_sim/native/64
|
|
18
|
+
integration_platforms:
|
|
19
|
+
- native_sim/native/64
|
|
20
|
+
extra_configs:
|
|
21
|
+
- 'CONFIG_COMPILER_OPT="-DALP_BOARD_E1M_X_EVK"'
|
|
22
|
+
tags:
|
|
23
|
+
- alp-sdk
|
|
24
|
+
- example
|
|
25
|
+
- i2c
|
|
26
|
+
- sensors
|
|
27
|
+
- v2n
|
|
28
|
+
harness: console
|
|
29
|
+
harness_config:
|
|
30
|
+
type: one_line
|
|
31
|
+
regex:
|
|
32
|
+
- "\\[i2c-master\\] done"
|
|
33
|
+
alp_sdk.example.i2c_master.e1m_evk:
|
|
34
|
+
extra_args: EXTRA_CONF_FILE=generated/alp.conf
|
|
35
|
+
platform_allow:
|
|
36
|
+
- native_sim
|
|
37
|
+
- native_sim/native/64
|
|
38
|
+
integration_platforms:
|
|
39
|
+
- native_sim/native/64
|
|
40
|
+
extra_configs:
|
|
41
|
+
- 'CONFIG_COMPILER_OPT="-DALP_BOARD_E1M_EVK"'
|
|
42
|
+
tags:
|
|
43
|
+
- alp-sdk
|
|
44
|
+
- example
|
|
45
|
+
- i2c
|
|
46
|
+
- sensors
|
|
47
|
+
- aen
|
|
48
|
+
harness: console
|
|
49
|
+
harness_config:
|
|
50
|
+
type: one_line
|
|
51
|
+
regex:
|
|
52
|
+
- "\\[i2c-master\\] done"
|