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.
Files changed (330) hide show
  1. tan/__init__.py +0 -0
  2. tan/__main__.py +120 -0
  3. tan/cli.py +939 -0
  4. tan/command_table.py +265 -0
  5. tan/commands/__init__.py +8 -0
  6. tan/commands/bootstrap_cmd.py +4856 -0
  7. tan/commands/bootstrap_patches.py +164 -0
  8. tan/commands/bootstrap_toolchain_fetch.py +155 -0
  9. tan/commands/bootstrap_toolchain_pin.py +36 -0
  10. tan/commands/build/__init__.py +1 -0
  11. tan/commands/build/configure_inputs.py +277 -0
  12. tan/commands/build/execute.py +1852 -0
  13. tan/commands/build/host_python.py +59 -0
  14. tan/commands/build/link_stale.py +78 -0
  15. tan/commands/build/manifest.py +428 -0
  16. tan/commands/build/materialise.py +81 -0
  17. tan/commands/build/token_substitution.py +381 -0
  18. tan/commands/build/toolchain.py +482 -0
  19. tan/commands/build/user_defines_wipe.py +115 -0
  20. tan/commands/build/workspace_patches.py +65 -0
  21. tan/commands/build_cmd.py +2236 -0
  22. tan/commands/build_output.py +331 -0
  23. tan/commands/clean_cmd.py +1183 -0
  24. tan/commands/completion_cmd.py +786 -0
  25. tan/commands/debug_config_cmd.py +2425 -0
  26. tan/commands/diff_cmd.py +940 -0
  27. tan/commands/doctor_cmd.py +4767 -0
  28. tan/commands/examples_cmd.py +644 -0
  29. tan/commands/explain_cmd.py +1319 -0
  30. tan/commands/faultdecode_cmd.py +931 -0
  31. tan/commands/flash_atoc_guard.py +240 -0
  32. tan/commands/flash_cmd.py +5731 -0
  33. tan/commands/flash_mram_guard.py +150 -0
  34. tan/commands/flash_ram.py +578 -0
  35. tan/commands/flash_raw.py +583 -0
  36. tan/commands/generate_cmd.py +1456 -0
  37. tan/commands/image_cmd.py +753 -0
  38. tan/commands/init_cmd.py +1740 -0
  39. tan/commands/inspect_cmd.py +377 -0
  40. tan/commands/kconfig_cmd.py +734 -0
  41. tan/commands/model_cmd.py +1514 -0
  42. tan/commands/model_device_cmd.py +351 -0
  43. tan/commands/model_device_live.py +234 -0
  44. tan/commands/model_host_cmd.py +430 -0
  45. tan/commands/model_zoo_cmd.py +363 -0
  46. tan/commands/monitor_actions.py +125 -0
  47. tan/commands/monitor_cmd.py +626 -0
  48. tan/commands/monitor_session.py +505 -0
  49. tan/commands/new_som_cmd.py +1522 -0
  50. tan/commands/pinmux_cmd.py +568 -0
  51. tan/commands/presets_cmd.py +1123 -0
  52. tan/commands/probe_cmd.py +421 -0
  53. tan/commands/reset_cmd.py +354 -0
  54. tan/commands/reset_confirm.py +168 -0
  55. tan/commands/run_cmd.py +637 -0
  56. tan/commands/scaffold_cmd.py +490 -0
  57. tan/commands/sdk_cmd.py +1723 -0
  58. tan/commands/size_cmd.py +1020 -0
  59. tan/commands/support_bundle_cmd.py +1073 -0
  60. tan/commands/trace_cmd.py +341 -0
  61. tan/commands/validate_cmd.py +2009 -0
  62. tan/commands/west_forward_cmd.py +736 -0
  63. tan/commands/workspace_patch_check.py +296 -0
  64. tan/core/__init__.py +1 -0
  65. tan/core/alp_conf_pregen.py +100 -0
  66. tan/core/artifact_provenance.py +240 -0
  67. tan/core/atoc_guard.py +276 -0
  68. tan/core/atoc_guard_messages.py +232 -0
  69. tan/core/atoc_replacement.py +118 -0
  70. tan/core/atomic_write.py +178 -0
  71. tan/core/board_context.py +351 -0
  72. tan/core/board_diagnostic.py +111 -0
  73. tan/core/board_files.py +221 -0
  74. tan/core/board_validator.py +542 -0
  75. tan/core/board_validator_compat.py +196 -0
  76. tan/core/board_validator_run.py +129 -0
  77. tan/core/board_validator_schema.py +186 -0
  78. tan/core/board_validator_skew.py +46 -0
  79. tan/core/board_yaml_edit.py +295 -0
  80. tan/core/board_yaml_pos.py +118 -0
  81. tan/core/bootstrap.py +2572 -0
  82. tan/core/build_plan.py +625 -0
  83. tan/core/consent.py +104 -0
  84. tan/core/console_filter.py +245 -0
  85. tan/core/debug_launch.py +1803 -0
  86. tan/core/devicetree_lint.py +168 -0
  87. tan/core/dir_removal.py +229 -0
  88. tan/core/doctor_git.py +172 -0
  89. tan/core/doctor_libraries.py +253 -0
  90. tan/core/doctor_render.py +185 -0
  91. tan/core/doctor_scope.py +66 -0
  92. tan/core/doctor_setools.py +237 -0
  93. tan/core/doctor_stale.py +180 -0
  94. tan/core/document_guards.py +723 -0
  95. tan/core/dp_id.py +97 -0
  96. tan/core/elf_load.py +63 -0
  97. tan/core/error_catalog.py +171 -0
  98. tan/core/example_catalog.py +499 -0
  99. tan/core/example_facets.py +151 -0
  100. tan/core/faultdecode.py +521 -0
  101. tan/core/flash_plan.py +2501 -0
  102. tan/core/flow_d_report.py +381 -0
  103. tan/core/flow_d_uptime.py +164 -0
  104. tan/core/fs_confine.py +130 -0
  105. tan/core/global_flags.py +230 -0
  106. tan/core/host_python.py +210 -0
  107. tan/core/image_bundle.py +247 -0
  108. tan/core/inert.py +147 -0
  109. tan/core/jlink_binary.py +128 -0
  110. tan/core/jlink_probe.py +481 -0
  111. tan/core/jsonc_splice.py +404 -0
  112. tan/core/launch_provenance.py +257 -0
  113. tan/core/link_refusal.py +76 -0
  114. tan/core/metadata_schema.py +376 -0
  115. tan/core/model_check.py +227 -0
  116. tan/core/model_device.py +449 -0
  117. tan/core/model_doctor.py +198 -0
  118. tan/core/model_host.py +48 -0
  119. tan/core/model_list.py +112 -0
  120. tan/core/model_zoo.py +353 -0
  121. tan/core/module_template.py +340 -0
  122. tan/core/mram_link.py +87 -0
  123. tan/core/new_som_ospi.py +94 -0
  124. tan/core/os_class.py +159 -0
  125. tan/core/patch_paths.py +87 -0
  126. tan/core/pending.py +40 -0
  127. tan/core/plain_zephyr_plan.py +138 -0
  128. tan/core/plan_exec.py +373 -0
  129. tan/core/plan_tokens.py +600 -0
  130. tan/core/probe.py +155 -0
  131. tan/core/probe_plan.py +237 -0
  132. tan/core/proxy.py +168 -0
  133. tan/core/publish.py +31 -0
  134. tan/core/python_floor.py +178 -0
  135. tan/core/ram_run.py +694 -0
  136. tan/core/ram_watch.py +231 -0
  137. tan/core/raw_write.py +160 -0
  138. tan/core/reset_plan.py +56 -0
  139. tan/core/run.py +161 -0
  140. tan/core/scaffold.py +2203 -0
  141. tan/core/scaffold_selftest_identity.py +225 -0
  142. tan/core/sdk_default_registry.py +565 -0
  143. tan/core/sdk_discovery.py +996 -0
  144. tan/core/sdk_removal.py +465 -0
  145. tan/core/serial_actions.py +175 -0
  146. tan/core/serial_capture.py +185 -0
  147. tan/core/serial_url.py +45 -0
  148. tan/core/setools.py +608 -0
  149. tan/core/setools_scratch.py +243 -0
  150. tan/core/shapes.py +194 -0
  151. tan/core/size.py +610 -0
  152. tan/core/som_buildability.py +204 -0
  153. tan/core/som_schema_version.py +62 -0
  154. tan/core/subprocess_env.py +201 -0
  155. tan/core/sysbuild_image.py +94 -0
  156. tan/core/system_manifest.py +827 -0
  157. tan/core/text_layout.py +73 -0
  158. tan/core/timestamp.py +182 -0
  159. tan/core/tool_lookup.py +383 -0
  160. tan/core/toolchain_pin.py +117 -0
  161. tan/core/toolchain_provision.py +1224 -0
  162. tan/core/trusted_path.py +134 -0
  163. tan/core/uboot_breakin.py +154 -0
  164. tan/core/uri_reference.py +415 -0
  165. tan/core/user_defines.py +152 -0
  166. tan/core/venv.py +332 -0
  167. tan/core/west_patches.py +143 -0
  168. tan/core/west_workspace_refusal.py +159 -0
  169. tan/core/zephyr_env.py +124 -0
  170. tan/env.py +185 -0
  171. tan/envelope.py +647 -0
  172. tan/exit_codes.py +12 -0
  173. tan/lazy_typer.py +185 -0
  174. tan/model/__init__.py +2 -0
  175. tan/model/_gen_fixture.py +132 -0
  176. tan/model/adapters/__init__.py +116 -0
  177. tan/model/adapters/cpu.py +26 -0
  178. tan/model/adapters/deepx.py +94 -0
  179. tan/model/adapters/drpai.py +242 -0
  180. tan/model/adapters/ethos_u.py +951 -0
  181. tan/model/adapters/executorch.py +55 -0
  182. tan/model/analyze.py +694 -0
  183. tan/model/build.py +304 -0
  184. tan/model/check.py +682 -0
  185. tan/model/manifest.py +625 -0
  186. tan/model/measure.py +216 -0
  187. tan/model/npu_ops_validate.py +130 -0
  188. tan/model/package.py +125 -0
  189. tan/model/perf.py +635 -0
  190. tan/model/perf_apply.py +721 -0
  191. tan/model/prep.py +193 -0
  192. tan/model/sram_fit.py +502 -0
  193. tan/model/targets.py +374 -0
  194. tan/model/tensorio.py +287 -0
  195. tan/net.py +73 -0
  196. tan/output_format.py +213 -0
  197. tan/planner/__init__.py +219 -0
  198. tan/planner/aperture.py +202 -0
  199. tan/planner/buildplan.py +1092 -0
  200. tan/planner/camera_owner.py +192 -0
  201. tan/planner/cameras.py +132 -0
  202. tan/planner/carveout.py +755 -0
  203. tan/planner/cli.py +274 -0
  204. tan/planner/headers.py +315 -0
  205. tan/planner/kconfig.py +2435 -0
  206. tan/planner/kconfig_symbols.py +473 -0
  207. tan/planner/libraries.py +677 -0
  208. tan/planner/link_target.py +237 -0
  209. tan/planner/linux_ownership.py +216 -0
  210. tan/planner/loader.py +1525 -0
  211. tan/planner/manifest.py +116 -0
  212. tan/planner/memory.py +161 -0
  213. tan/planner/memregion.py +56 -0
  214. tan/planner/models.py +533 -0
  215. tan/planner/orchestrator.py +874 -0
  216. tan/planner/ownership.py +203 -0
  217. tan/planner/partition.py +1160 -0
  218. tan/planner/paths.py +32 -0
  219. tan/planner/plain_slice.py +139 -0
  220. tan/planner/project_emit/__init__.py +60 -0
  221. tan/planner/project_emit/bom_netlist.py +375 -0
  222. tan/planner/project_emit/dts.py +580 -0
  223. tan/planner/project_emit/hw_info.py +221 -0
  224. tan/planner/project_emit/native_sim.py +136 -0
  225. tan/planner/project_emit/west_libs.py +213 -0
  226. tan/planner/project_loader.py +264 -0
  227. tan/planner/sdk_capability.py +203 -0
  228. tan/planner/sdk_compat.py +395 -0
  229. tan/planner/secure.py +350 -0
  230. tan/planner/slugs.py +394 -0
  231. tan/planner/som_metadata.py +325 -0
  232. tan/planner/strict_loaders.py +131 -0
  233. tan/planner/template.py +1037 -0
  234. tan/planner/template_pins.py +535 -0
  235. tan/planner/template_rewrite.py +714 -0
  236. tan/planner/topology.py +208 -0
  237. tan/planner/validate.py +365 -0
  238. tan/planner/whole_device_alias.py +67 -0
  239. tan/planner/zephyr_board.py +3510 -0
  240. tan/planner_cli.py +97 -0
  241. tan/planner_emit.py +617 -0
  242. tan/planner_root.py +119 -0
  243. tan/soc_ref.py +58 -0
  244. tan/templates/__init__.py +34 -0
  245. tan/templates/vendored/MANIFEST.md +1862 -0
  246. tan/templates/vendored/diagnostics/E1M-AEN801/CMakeLists.txt +8 -0
  247. tan/templates/vendored/diagnostics/E1M-AEN801/README.md +112 -0
  248. tan/templates/vendored/diagnostics/E1M-AEN801/board.yaml +38 -0
  249. tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.conf +11 -0
  250. tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.overlay +29 -0
  251. tan/templates/vendored/diagnostics/E1M-AEN801/prj.conf +5 -0
  252. tan/templates/vendored/diagnostics/E1M-AEN801/src/main.c +266 -0
  253. tan/templates/vendored/diagnostics/E1M-AEN801/testcase.yaml +53 -0
  254. tan/templates/vendored/diagnostics/E1M-V2N101/CMakeLists.txt +8 -0
  255. tan/templates/vendored/diagnostics/E1M-V2N101/README.md +112 -0
  256. tan/templates/vendored/diagnostics/E1M-V2N101/board.yaml +38 -0
  257. tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.conf +11 -0
  258. tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.overlay +29 -0
  259. tan/templates/vendored/diagnostics/E1M-V2N101/prj.conf +5 -0
  260. tan/templates/vendored/diagnostics/E1M-V2N101/src/main.c +266 -0
  261. tan/templates/vendored/diagnostics/E1M-V2N101/testcase.yaml +53 -0
  262. tan/templates/vendored/edge-ai/E1M-AEN801/CMakeLists.txt +10 -0
  263. tan/templates/vendored/edge-ai/E1M-AEN801/README.md +75 -0
  264. tan/templates/vendored/edge-ai/E1M-AEN801/board.yaml +38 -0
  265. tan/templates/vendored/edge-ai/E1M-AEN801/prj.conf +8 -0
  266. tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.c +371 -0
  267. tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.h +178 -0
  268. tan/templates/vendored/edge-ai/E1M-AEN801/src/main.c +373 -0
  269. tan/templates/vendored/edge-ai/E1M-AEN801/testcase.yaml +62 -0
  270. tan/templates/vendored/edge-ai/E1M-V2N101/CMakeLists.txt +10 -0
  271. tan/templates/vendored/edge-ai/E1M-V2N101/README.md +75 -0
  272. tan/templates/vendored/edge-ai/E1M-V2N101/board.yaml +37 -0
  273. tan/templates/vendored/edge-ai/E1M-V2N101/prj.conf +8 -0
  274. tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.c +371 -0
  275. tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.h +178 -0
  276. tan/templates/vendored/edge-ai/E1M-V2N101/src/main.c +373 -0
  277. tan/templates/vendored/edge-ai/E1M-V2N101/testcase.yaml +62 -0
  278. tan/templates/vendored/iot/E1M-AEN801/CMakeLists.txt +14 -0
  279. tan/templates/vendored/iot/E1M-AEN801/README.md +103 -0
  280. tan/templates/vendored/iot/E1M-AEN801/board.yaml +69 -0
  281. tan/templates/vendored/iot/E1M-AEN801/prj.conf +15 -0
  282. tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.c +196 -0
  283. tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.h +173 -0
  284. tan/templates/vendored/iot/E1M-AEN801/src/main.c +262 -0
  285. tan/templates/vendored/iot/E1M-AEN801/testcase.yaml +68 -0
  286. tan/templates/vendored/minimal/E1M-AEN801/CMakeLists.txt +8 -0
  287. tan/templates/vendored/minimal/E1M-AEN801/README.md +108 -0
  288. tan/templates/vendored/minimal/E1M-AEN801/board.yaml +32 -0
  289. tan/templates/vendored/minimal/E1M-AEN801/prj.conf +8 -0
  290. tan/templates/vendored/minimal/E1M-AEN801/src/main.c +111 -0
  291. tan/templates/vendored/minimal/E1M-AEN801/testcase.yaml +49 -0
  292. tan/templates/vendored/minimal/E1M-V2N101/CMakeLists.txt +8 -0
  293. tan/templates/vendored/minimal/E1M-V2N101/README.md +108 -0
  294. tan/templates/vendored/minimal/E1M-V2N101/board.yaml +32 -0
  295. tan/templates/vendored/minimal/E1M-V2N101/prj.conf +8 -0
  296. tan/templates/vendored/minimal/E1M-V2N101/src/main.c +111 -0
  297. tan/templates/vendored/minimal/E1M-V2N101/testcase.yaml +49 -0
  298. tan/templates/vendored/multicore-mailbox/E1M-AEN801/CMakeLists.txt +8 -0
  299. tan/templates/vendored/multicore-mailbox/E1M-AEN801/README.md +120 -0
  300. tan/templates/vendored/multicore-mailbox/E1M-AEN801/board.yaml +57 -0
  301. tan/templates/vendored/multicore-mailbox/E1M-AEN801/boards/native_sim_native_64.overlay +40 -0
  302. tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/CMakeLists.txt +13 -0
  303. tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/main.c +171 -0
  304. tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/prj.conf +17 -0
  305. tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/testcase.yaml +23 -0
  306. tan/templates/vendored/multicore-mailbox/E1M-AEN801/prj.conf +22 -0
  307. tan/templates/vendored/multicore-mailbox/E1M-AEN801/src/main.c +185 -0
  308. tan/templates/vendored/multicore-mailbox/E1M-AEN801/testcase.yaml +26 -0
  309. tan/templates/vendored/sensor/E1M-AEN801/CMakeLists.txt +8 -0
  310. tan/templates/vendored/sensor/E1M-AEN801/README.md +112 -0
  311. tan/templates/vendored/sensor/E1M-AEN801/board.yaml +57 -0
  312. tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.conf +10 -0
  313. tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.overlay +28 -0
  314. tan/templates/vendored/sensor/E1M-AEN801/prj.conf +5 -0
  315. tan/templates/vendored/sensor/E1M-AEN801/src/main.c +186 -0
  316. tan/templates/vendored/sensor/E1M-AEN801/testcase.yaml +52 -0
  317. tan/templates/vendored/sensor/E1M-V2N101/CMakeLists.txt +8 -0
  318. tan/templates/vendored/sensor/E1M-V2N101/README.md +112 -0
  319. tan/templates/vendored/sensor/E1M-V2N101/board.yaml +57 -0
  320. tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.conf +10 -0
  321. tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.overlay +28 -0
  322. tan/templates/vendored/sensor/E1M-V2N101/prj.conf +5 -0
  323. tan/templates/vendored/sensor/E1M-V2N101/src/main.c +186 -0
  324. tan/templates/vendored/sensor/E1M-V2N101/testcase.yaml +52 -0
  325. tan/version.py +102 -0
  326. tan_cli-0.7.0.dist-info/METADATA +125 -0
  327. tan_cli-0.7.0.dist-info/RECORD +330 -0
  328. tan_cli-0.7.0.dist-info/WHEEL +5 -0
  329. tan_cli-0.7.0.dist-info/entry_points.txt +2 -0
  330. tan_cli-0.7.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,373 @@
1
+ /*
2
+ * Copyright 2026 Alp Lab AB
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ *
5
+ * cold-chain-monitor
6
+ * ==================
7
+ *
8
+ * Pharma/food cold-chain integrity monitor. Pipeline:
9
+ *
10
+ * BME280 (I2C) --read_raw + compensate--> T(C) / RH(%) / P(Pa)
11
+ * --sliding window--> cold_chain (mean/min/max, MKT, dewpoint, excursion)
12
+ * -> cc_classify (OK / TEMP_EXCURSION / MKT_EXCEEDED / CONDENSATION_RISK)
13
+ * + <alp/inference.h> anomaly score (deterministic fallback)
14
+ * --> one CC record per report window.
15
+ *
16
+ * Honest scope: a reference cold-chain logger. MKT, dewpoint, and excursion
17
+ * time are the real metrics; thresholds are configurable per product. This is
18
+ * NOT a certified GxP / 21-CFR-Part-11 data logger (no validated audit trail,
19
+ * no calibration traceability, no tamper-proof storage). The model is a stub
20
+ * (see https://github.com/alplabai/alp-sdk/blob/v0.17.0/examples/ai/cold-chain-monitor/models/README.md); with no model the
21
+ * deterministic classifier + anomaly fallback run.
22
+ *
23
+ *
24
+ * ── Why the BME280 ────────────────────────────────────────────────────────
25
+ *
26
+ * The Bosch BME280 is a combined temperature / humidity / barometric pressure
27
+ * sensor well suited to cold-chain loggers:
28
+ * - Temperature range -40..+85 C, accuracy ±1.0 C RMS, sufficient for
29
+ * the ±0.5 C inter-unit spread allowed by GxP-adjacent monitoring.
30
+ * - Humidity ±3% RH at 25 C enables dewpoint estimation (condensation /
31
+ * mould risk on packaging and metal surfaces).
32
+ * - Pressure is logged but not classified by this demo; it's useful for
33
+ * altitude compensation and for detecting seal-break events in insulated
34
+ * shippers where a damaged seal opens to ambient.
35
+ * - I2C single-chip integration keeps the BOM to a minimum; SPI arrives
36
+ * in the v0.3 driver.
37
+ * - Normal-mode continuous sampling at a user-selected standby interval
38
+ * eliminates the MCU-driven trigger polling needed in Forced mode.
39
+ *
40
+ *
41
+ * ── Measurement cadence and window sizing ─────────────────────────────────
42
+ *
43
+ * CC_WINDOW_N (256 samples) * CC_SAMPLE_MIN (1.0 min/sample) = 256 minutes
44
+ * = ~4.3 hours per report window. That matches a common GDP-compliant
45
+ * logging interval (log every 5..15 min over a 24 h transit) while keeping
46
+ * the window SRAM footprint under 4 kB (256 × 12 B = 3072 B).
47
+ *
48
+ * In this demo the "1 minute" cadence is simulated: all 256 synthetic samples
49
+ * are pushed immediately so the pipeline exercises the framing path without
50
+ * sleeping. On real hardware a k_timer drives one bme280_read_raw() call per
51
+ * real minute (or whatever the product's logging period is).
52
+ *
53
+ *
54
+ * ── Cold-chain standards ──────────────────────────────────────────────────
55
+ *
56
+ * MKT (Mean Kinetic Temperature, ICH Q1A / USP <1079>):
57
+ * The single equivalent temperature that delivers the same cumulative
58
+ * Arrhenius thermal stress as the fluctuating temperature profile.
59
+ * A brief hot excursion contributes more than an equal-duration cool dip,
60
+ * so MKT >= arithmetic mean. The regulatory limit for most vaccines is
61
+ * MKT <= 8 C (the same as the storage upper bound), so a distribution that
62
+ * averaged 6 C but had a 12 C spike for 30 min would still breach.
63
+ * ΔH/R = 10 000 K is the ICH default (ΔH = 83.144 kJ/mol for pharma).
64
+ *
65
+ * Dewpoint (Magnus formula):
66
+ * When ambient temperature approaches the dewpoint, water condenses on
67
+ * cold surfaces -- packaging labels detach, metal contacts corrode,
68
+ * biological samples degrade. The dewpoint_margin_c config knob controls
69
+ * how close the reading must be to the dewpoint before CONDENSATION_RISK
70
+ * is raised.
71
+ *
72
+ *
73
+ * ── Classifier priority ordering ──────────────────────────────────────────
74
+ *
75
+ * The 4-state classifier (implemented in cold_chain.c) reports the HIGHEST
76
+ * severity condition present:
77
+ * CC_TEMP_EXCURSION -- product is currently out of the safe band, or
78
+ * the cumulative out-of-band time exceeds the limit.
79
+ * ACUTE: operator must act immediately.
80
+ * CC_MKT_EXCEEDED -- the equivalent thermal stress has crossed the
81
+ * regulatory limit even if the product is currently
82
+ * in-band. CUMULATIVE: product may be degraded.
83
+ * CC_CONDENSATION_RISK -- high humidity or temperature near the dewpoint;
84
+ * packaging and surface integrity may be compromised.
85
+ * CC_OK -- all metrics within limits.
86
+ *
87
+ *
88
+ * ── AI anomaly score ──────────────────────────────────────────────────────
89
+ *
90
+ * The threshold-based classifier catches known bad states. The AI score
91
+ * catches SUBTLE DRIFT that no single threshold catches: a slowly degrading
92
+ * compressor that nudges the mean temperature up by 0.3 C per week, or a
93
+ * door-seal micro-leak that correlates the humidity rise with the warming
94
+ * slope. The fallback (cc_anomaly_fallback) implements the same idea
95
+ * deterministically: it returns max(excursion depth, MKT overshoot),
96
+ * saturating at 1.0. A trained autoencoder running via <alp/inference.h>
97
+ * replaces this with a learned reconstruction error.
98
+ *
99
+ *
100
+ * ── native_sim / no-sensor fallback ──────────────────────────────────────
101
+ *
102
+ * On native_sim the I2C emul controller answers open() / ioctl() but has no
103
+ * BME280 target attached, so bme280_init() fails the CHIP_ID check. main()
104
+ * detects this and fills every window with synthetic environment data via
105
+ * synth_sample(), covering the three interesting states:
106
+ * window 0: stable in-band cold -> CC_OK
107
+ * window 1: warming ramp -> CC_TEMP_EXCURSION
108
+ * window 2: near-saturated air -> CC_CONDENSATION_RISK
109
+ * On real silicon fill the window from bme280_read_raw() instead.
110
+ */
111
+ #include <string.h>
112
+ #include <zephyr/kernel.h>
113
+ #include <zephyr/logging/log.h>
114
+
115
+ /* Board-portable alias for the sensor I2C bus: BOARD_I2C_SENSORS resolves to
116
+ * the correct on-board I2C controller for whatever EVK is targeted via the
117
+ * CONFIG_COMPILER_OPT="-DALP_BOARD_E1M_EVK" build flag. */
118
+ #include "alp/board.h"
119
+ /* AI inference dispatch: AUTO routes to Ethos-U55 on AEN, DEEPX DX-M1 on V2N,
120
+ * and the reference TFLM CPU kernels on native_sim. */
121
+ #include "alp/inference.h"
122
+ /* Portable I2C open/close/read/write primitives (no vendor names). */
123
+ #include "alp/peripheral.h"
124
+ /* BME280 combined T/RH/P chip driver (I2C v0.2, paper-correct). */
125
+ #include "alp/chips/bme280.h"
126
+
127
+ /* Pure-C cold-chain metrics, classifier, and anomaly fallback (arch-neutral,
128
+ * no Zephyr deps -- identical source compiles for native_sim and the M55). */
129
+ #include "cold_chain.h"
130
+
131
+ LOG_MODULE_REGISTER(cc, LOG_LEVEL_INF);
132
+
133
+ /* BME280 I2C address: SDO-tied-low = 0x76 on the EVK (0x77 if SDO is high).
134
+ * Override at compile time if your carrier boards SDO differently. */
135
+ #define BME280_ADDR 0x76u
136
+ /* Number of report windows in the bounded demo run (3 covers OK / EXCURSION /
137
+ * CONDENSATION in the synthetic scenario; a real logger runs indefinitely). */
138
+ #define N_REPORTS 3
139
+
140
+ /* Vaccine-fridge thresholds (2..8 C, USP <1079> Annex 1 cold chain).
141
+ * A real deployment loads the limits for the specific product (frozen at
142
+ * -20 C, ambient-stable at +25 C, etc.) from NVS or a compile-time overlay. */
143
+ static const struct cc_config CFG = {
144
+ .t_lo = 2.0f, /* safe-band lower edge, Celsius */
145
+ .t_hi = 8.0f, /* safe-band upper edge, Celsius */
146
+ .mkt_limit_c = 8.0f, /* MKT above this -> cumulative damage */
147
+ .excursion_min_limit = 30.0f, /* out-of-band minutes before EXCURSION */
148
+ .dewpoint_margin_c = 2.0f, /* T within this of dewpoint -> CONDENSATION */
149
+ };
150
+
151
+ /* 1-byte stub so alp_inference_open's non-NULL model-data contract is met.
152
+ * An unusable tensor (wrong shape from the stub backend) causes every
153
+ * alp_inference_invoke() to return no usable output, which anomaly_score()
154
+ * detects and routes to cc_anomaly_fallback(). See
155
+ * https://github.com/alplabai/alp-sdk/blob/v0.17.0/examples/ai/cold-chain-monitor/models/README.md for the autoencoder
156
+ * training recipe to replace this stub. */
157
+ static const uint8_t s_model[] = { 0x00 };
158
+
159
+ /*
160
+ * synth_sample() -- synthetic environment data for native_sim / no sensor.
161
+ *
162
+ * Generates a deterministic (T, RH, P) triple for sample @p i of report
163
+ * window @p report. Three scenarios are exercised across the N_REPORTS
164
+ * windows so the classifier produces a meaningful state spread:
165
+ *
166
+ * report 0: steady in-band cold storage (5 C, 50 % RH) -> CC_OK
167
+ * report 1: warming ramp (5..12 C linear) -> CC_TEMP_EXCURSION
168
+ * report 2: cold but near-saturated air (5 C, 95 % RH) -> CC_CONDENSATION_RISK
169
+ *
170
+ * Pressure is fixed at 101325 Pa (sea-level standard) for all windows;
171
+ * it does not affect classification in this demo.
172
+ */
173
+ static struct cc_sample synth_sample(int report, int i)
174
+ {
175
+ /* Baseline: stable cold storage in the 2..8 C vaccine fridge band. */
176
+ struct cc_sample s = { .temp_c = 5.0f, .rh_pct = 50.0f, .pressure_pa = 101325.0f };
177
+ switch (report) {
178
+ case 0:
179
+ break; /* stable cold -- all defaults are fine */
180
+ case 1:
181
+ /* Linear warming ramp from 5 C to 12 C across the window.
182
+ * This drives the mean above t_hi and the excursion counter
183
+ * past the limit, triggering CC_TEMP_EXCURSION. */
184
+ s.temp_c = 5.0f + 7.0f * (float)i / (float)(CC_WINDOW_N - 1);
185
+ s.rh_pct = 55.0f;
186
+ break;
187
+ default:
188
+ /* Near-saturated cold air: temperature stays in-band but RH
189
+ * is high enough that the Magnus dewpoint is within
190
+ * dewpoint_margin_c of the ambient temperature, raising
191
+ * CC_CONDENSATION_RISK. */
192
+ s.rh_pct = 95.0f;
193
+ break;
194
+ }
195
+ return s;
196
+ }
197
+
198
+ /*
199
+ * anomaly_score() -- AI model if available, else the deterministic fallback.
200
+ *
201
+ * Packs the cc_features vector, invokes the loaded model, and reads the
202
+ * first float output as a 0..1 anomaly score. Falls back to
203
+ * cc_anomaly_fallback() when:
204
+ * - @p inf is NULL (inference handle failed to open),
205
+ * - the stub model returns an empty / wrongly-typed output tensor, or
206
+ * - alp_inference_invoke() returns a non-OK status.
207
+ * This "try model, fall back cleanly" pattern matches the sibling examples
208
+ * and means the demo always produces a meaningful score offline.
209
+ */
210
+ static float anomaly_score(alp_inference_t *inf, const struct cc_features *f)
211
+ {
212
+ if (inf != NULL) {
213
+ /* Pack the 8 metrics into the flat float vector the model expects. */
214
+ float vec[CC_FEATURE_DIM];
215
+ (void)cc_feat_pack(f, vec, CC_FEATURE_DIM);
216
+ alp_inference_tensor_t in = { 0 };
217
+ /* Copy into the model's input tensor only if the shape matches. */
218
+ if (alp_inference_get_input(inf, 0, &in) == ALP_OK && in.dtype == ALP_INFERENCE_DTYPE_F32 &&
219
+ in.data != NULL && in.size_bytes >= sizeof(vec)) {
220
+ memcpy(in.data, vec, sizeof(vec));
221
+ if (alp_inference_invoke(inf) == ALP_OK) {
222
+ alp_inference_tensor_t out = { 0 };
223
+ /* Read the scalar anomaly score from the output tensor. */
224
+ if (alp_inference_get_output(inf, 0, &out) == ALP_OK &&
225
+ out.dtype == ALP_INFERENCE_DTYPE_F32 && out.data != NULL &&
226
+ out.size_bytes >= sizeof(float)) {
227
+ return ((const float *)out.data)[0];
228
+ }
229
+ }
230
+ }
231
+ }
232
+ /* Deterministic fallback: max(excursion depth, MKT overshoot), clamped
233
+ * to 1.0. Transparent, always correct, gives the demo a meaningful
234
+ * score without any trained model. */
235
+ return cc_anomaly_fallback(f, &CFG);
236
+ }
237
+
238
+ int main(void)
239
+ {
240
+ /* Driver context and window state are static so they do not consume
241
+ * stack on the Zephyr M55 thread (the BME280 calib struct is 26 bytes;
242
+ * the window is 256 × 12 B = 3072 B). */
243
+ static bme280_t dev;
244
+ static struct cc_window_state win;
245
+ bool sensor_ok = false;
246
+
247
+ /* ── Sensor bring-up ─────────────────────────────────────────────────
248
+ * Open the shared sensor I2C bus (BOARD_I2C_SENSORS resolves to the
249
+ * correct on-board controller for the target EVK) and initialise the
250
+ * BME280. bme280_init() reads CHIP_ID and loads the per-die calibration
251
+ * coefficients; it returns ALP_ERR_IO if no BME280 responds.
252
+ * On native_sim the emul controller has no target attached, so init
253
+ * fails cleanly and we fall back to synth_sample(). */
254
+ alp_i2c_t *bus =
255
+ alp_i2c_open(&(alp_i2c_config_t){ .bus_id = BOARD_I2C_SENSORS, .bitrate_hz = 400000 });
256
+ if (bus != NULL && bme280_init(&dev, bus, BME280_ADDR) == ALP_OK) {
257
+ /* bme280_init() leaves the oversampling / mode registers untouched.
258
+ * Configure continuous-conversion (NORMAL) mode with X1 oversampling
259
+ * on all three channels (T, P, H), a 1 s standby period between
260
+ * measurements, and no IIR filter. bme280_read_raw() will then
261
+ * return a fresh reading without needing to poll the status register.
262
+ * For a cold-chain logger the 1 s cadence is already faster than the
263
+ * CC_SAMPLE_MIN (1 min) window rate, so X1/1 s is well matched. */
264
+ (void)bme280_set_sampling(&dev,
265
+ BME280_OVERSAMPLING_X1, /* temperature channel */
266
+ BME280_OVERSAMPLING_X1, /* pressure channel */
267
+ BME280_OVERSAMPLING_X1, /* humidity channel */
268
+ BME280_MODE_NORMAL, /* continuous conversion */
269
+ BME280_STANDBY_1000_MS, /* 1 s between measurements */
270
+ BME280_FILTER_OFF); /* no IIR smoothing */
271
+ sensor_ok = true;
272
+ } else {
273
+ LOG_WRN("BME280 unavailable; using synthetic environment data");
274
+ }
275
+
276
+ /* ── Inference bring-up ──────────────────────────────────────────────
277
+ * Open the inference handle. BACKEND_AUTO selects Ethos-U on AEN,
278
+ * DEEPX DX-M1 on V2N, or the TFLM CPU kernels on native_sim.
279
+ * The 1-byte stub model causes every invoke() to return an unusable
280
+ * output, so anomaly_score() falls back to the deterministic path. */
281
+ alp_inference_t *inf = alp_inference_open(&(alp_inference_config_t){
282
+ .backend = ALP_INFERENCE_BACKEND_AUTO,
283
+ .format = ALP_INFERENCE_MODEL_TFLITE,
284
+ .model_data = s_model,
285
+ .model_size = sizeof(s_model),
286
+ });
287
+
288
+ /* CSV header: one line per report window. Field order matches the
289
+ * documented output schema and the README example. */
290
+ printk("# CC,t_s,state,temp_c,rh_pct,dewpoint_c,mkt_c,excursion_min\n");
291
+
292
+ /* ── Report loop ─────────────────────────────────────────────────────
293
+ * Each iteration resets the window, fills it (real or synthetic), then
294
+ * reduces it to metrics and emits one CC record. N_REPORTS = 3 covers
295
+ * the OK / EXCURSION / CONDENSATION states in the synthetic scenario. */
296
+ for (int r = 0; r < N_REPORTS; r++) {
297
+ /* Reset the window for this report period. */
298
+ cc_window_reset(&win);
299
+
300
+ /* Fill one window of readings (real sensor or synthetic). */
301
+ for (int i = 0; i < CC_WINDOW_N; i++) {
302
+ struct cc_sample s;
303
+ if (sensor_ok) {
304
+ /* Real sensor path: burst-read the raw 20/20/16-bit
305
+ * conversion result, then compensate with the per-die
306
+ * calibration loaded at init. The BME280 is running
307
+ * continuously (NORMAL mode), so the result is fresh
308
+ * within the 1 s standby period. */
309
+ bme280_raw_t raw;
310
+ bme280_compensated_t c;
311
+ if (bme280_read_raw(&dev, &raw) == ALP_OK &&
312
+ bme280_compensate(&dev, &raw, &c) == ALP_OK) {
313
+ /* Convert from fixed-point to float physical units:
314
+ * temperature_c100 is degrees × 100 -> C
315
+ * humidity_milli_pct is %RH × 1024 -> %
316
+ * pressure_pa is already pascals. */
317
+ s.temp_c = (float)c.temperature_c100 / 100.0f;
318
+ s.rh_pct = (float)c.humidity_milli_pct / 1024.0f;
319
+ s.pressure_pa = (float)c.pressure_pa;
320
+ } else {
321
+ /* I/O error mid-window: fall back to synth for
322
+ * this sample so the window stays complete. */
323
+ s = synth_sample(r, i);
324
+ }
325
+ } else {
326
+ /* No sensor: generate deterministic synthetic data. */
327
+ s = synth_sample(r, i);
328
+ }
329
+ cc_window_push(&win, s);
330
+ }
331
+
332
+ /* Reduce the window to metrics, classify, score the anomaly, emit. */
333
+ struct cc_features f;
334
+ cc_feat_extract(&win, &CFG, &f);
335
+ cc_state_t st = cc_classify(&f, &CFG);
336
+ /* Compute the anomaly score (model or deterministic fallback).
337
+ * In a real gateway deployment `an` is forwarded via MQTT / OPC-UA
338
+ * alongside the classifier state; here we suppress the unused-var
339
+ * warning with (void) since this demo only emits the state string. */
340
+ float an = anomaly_score(inf, &f);
341
+ (void)an;
342
+
343
+ /* Emit one CSV record. t_s = elapsed monitoring time in minutes
344
+ * = samples-completed × CC_SAMPLE_MIN (1.0 min/sample). */
345
+ printk("CC,%.1f,%s,%.1f,%.1f,%.1f,%.1f,%.1f\n",
346
+ (double)((r + 1) * CC_WINDOW_N * CC_SAMPLE_MIN),
347
+ cc_state_name(st),
348
+ (double)f.mean_temp_c,
349
+ (double)f.mean_rh_pct,
350
+ (double)f.dewpoint_c,
351
+ (double)f.mkt_c,
352
+ (double)f.excursion_min);
353
+ }
354
+
355
+ /* ── Lifecycle teardown ──────────────────────────────────────────────
356
+ * Release in reverse acquisition order: model, sensor, bus.
357
+ * bme280_soft_reset() writes 0xB6 to the RESET register so the chip
358
+ * returns to its power-on state; the bus is then safe to release. */
359
+ if (inf != NULL) {
360
+ alp_inference_close(inf);
361
+ }
362
+ if (sensor_ok) {
363
+ /* Soft-reset the chip before releasing the bus so it stops
364
+ * converting and returns to sleep (lowest power state). */
365
+ bme280_soft_reset(&dev);
366
+ bme280_deinit(&dev); /* Release the driver context (no chip power-down). */
367
+ }
368
+ if (bus != NULL) {
369
+ alp_i2c_close(bus);
370
+ }
371
+ printk("[cc] done\n");
372
+ return 0;
373
+ }
@@ -0,0 +1,62 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+
3
+ sample:
4
+ name: cold-chain-monitor
5
+ description: |
6
+ Cold-chain integrity monitor: BME280 T/RH/P -> sliding-window metrics
7
+ (MKT / dewpoint / excursion time) -> 4-state classifier (OK / TEMP_EXCURSION
8
+ / MKT_EXCEEDED / CONDENSATION_RISK) + AI anomaly score (deterministic
9
+ fallback). native_sim runs synthetic environment data covering the states.
10
+ common:
11
+ tags: ai inference industrial environmental cold-chain marketing showcase
12
+ tests:
13
+ alp_sdk.example.cold_chain_monitor.e1m_evk:
14
+ extra_args: EXTRA_CONF_FILE=generated/alp.conf
15
+ extra_configs:
16
+ - 'CONFIG_COMPILER_OPT="-DALP_BOARD_E1M_EVK"'
17
+ platform_allow:
18
+ - native_sim/native/64
19
+ integration_platforms:
20
+ - native_sim/native/64
21
+ tags:
22
+ - alp-sdk
23
+ - example
24
+ - ai
25
+ - environmental
26
+ harness: console
27
+ harness_config:
28
+ type: one_line
29
+ regex:
30
+ - "\\[cc\\] done"
31
+
32
+ alp_sdk.example.cold_chain_monitor.e1m_x_evk:
33
+ extra_args: EXTRA_CONF_FILE=generated/alp.conf
34
+ extra_configs:
35
+ - 'CONFIG_COMPILER_OPT="-DALP_BOARD_E1M_X_EVK"'
36
+ platform_allow:
37
+ - native_sim/native/64
38
+ integration_platforms:
39
+ - native_sim/native/64
40
+ tags:
41
+ - alp-sdk
42
+ - example
43
+ - ai
44
+ - environmental
45
+ harness: console
46
+ harness_config:
47
+ type: one_line
48
+ regex:
49
+ - "\\[cc\\] done"
50
+
51
+ alp_sdk.example.cold_chain_monitor.aen_build:
52
+ extra_args: EXTRA_CONF_FILE=generated/alp.conf
53
+ extra_configs:
54
+ - 'CONFIG_COMPILER_OPT="-DALP_BOARD_E1M_EVK"'
55
+ platform_allow:
56
+ - alp_e1m_aen801_m55_hp/ae822fa0e5597ls0/rtss_hp
57
+ build_only: true
58
+ tags:
59
+ - alp-sdk
60
+ - example
61
+ - ai
62
+ - environmental
@@ -0,0 +1,10 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ cmake_minimum_required(VERSION 3.20.0)
3
+
4
+ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5
+ project(cold_chain_monitor LANGUAGES C)
6
+
7
+ target_sources(app PRIVATE
8
+ src/main.c
9
+ src/cold_chain.c
10
+ )
@@ -0,0 +1,75 @@
1
+ # cold-chain-monitor
2
+
3
+ > **`[UNTESTED]` on hardware -- v0.9 paper-correct.** The `cold_chain` core
4
+ > is host-unit-tested on `native_sim/native/64`; the full app runs end-to-end on
5
+ > native_sim with synthetic environment data covering the states. HiL with a
6
+ > real BME280 + a trained model is bench-gated.
7
+
8
+ A pharma/food **cold-chain integrity monitor**: sample a BME280 T/RH/P sensor on
9
+ a slow logging cadence, compute the standards-backed metrics (temperature
10
+ excursion time, Mean Kinetic Temperature, dewpoint), classify the integrity
11
+ state, and emit an AI anomaly score. The *environmental* edge-AI vertical.
12
+
13
+ ## Honest scope
14
+
15
+ A reference cold-chain logger. MKT, dewpoint, and excursion-time are the real,
16
+ recognized metrics; thresholds are configurable per product. **NOT** a certified
17
+ GxP / 21-CFR-Part-11 data logger -- no validated audit trail, no calibration
18
+ traceability, no tamper-proof storage.
19
+
20
+ ## Standards-backed metrics
21
+
22
+ - **MKT** (Mean Kinetic Temperature, ICH Q1A / USP <1079>): the single
23
+ temperature delivering the same cumulative thermal stress as the fluctuating
24
+ profile. `MKT >= arithmetic mean`, so a brief hot spike counts for more than
25
+ its duration -- which is the whole point.
26
+ - **Dewpoint** (Magnus): condensation / mould risk when ambient T nears it.
27
+
28
+ ## Pipeline
29
+
30
+ ```
31
+ BME280 (I2C) --window--> cold_chain (mean/min/max, MKT, dewpoint, excursion)
32
+ -> cc_classify (OK / TEMP_EXCURSION / MKT_EXCEEDED / CONDENSATION_RISK)
33
+ -> <alp/inference.h> anomaly score (deterministic fallback) -> CC record
34
+ ```
35
+
36
+ ## Output
37
+
38
+ ```
39
+ # CC,t_s,state,temp_c,rh_pct,dewpoint_c,mkt_c,excursion_min
40
+ CC,256.0,OK,5.0,50.0,-4.6,5.0,0.0
41
+ CC,768.0,CONDENSATION_RISK,5.0,95.0,4.3,5.0,0.0
42
+ ```
43
+
44
+ ## Build
45
+
46
+ ```
47
+ # writes ./generated/alp.conf, which west reads below (#866)
48
+ tan generate --target zephyr-conf --core m33_sm --sdk-root "$ALP_SDK_ROOT" --output generated/alp.conf
49
+ west build -b alp_e1m_v2n101_m33_sm/r9a09g056n48gbg/cm33 . -- -DEXTRA_CONF_FILE=generated/alp.conf
50
+ west flash --host <board-ip>
51
+ ```
52
+
53
+ The DEEPX DX-M1 NPU is populated on `E1M-V2M101`/`E1M-V2M102`/`E1M-V2M103`
54
+ -- not on `E1M-V2N101`/`E1M-V2N102`/`E1M-V2N103`, the same PCB without
55
+ it. Pick either via
56
+ `som.sku` in `board.yaml`.
57
+
58
+ ## Model
59
+
60
+ <!-- The ../cold-chain-monitor/ detour is deliberate: the scaffold
61
+ rewriter's _RELATIVE_LINK_RE only matches `../`-prefixed links, and
62
+ models/ is a child of this dir, not a sibling -- don't "fix" this. -->
63
+
64
+ No model is shipped (stub + deterministic classifier/fallback). See
65
+ [`models/README.md`](https://github.com/alplabai/alp-sdk/blob/v0.17.0/examples/ai/cold-chain-monitor/models/README.md) for the
66
+ autoencoder training recipe.
67
+
68
+ ## Tests
69
+
70
+ In the alp-sdk tree, unit tests live in
71
+ [`tests/unit/cold_chain`](https://github.com/alplabai/alp-sdk/tree/v0.17.0/tests/unit/cold_chain) and run with:
72
+
73
+ ```
74
+ twister -p native_sim/native/64 -T tests/unit/cold_chain
75
+ ```
@@ -0,0 +1,37 @@
1
+ # board.yaml -- cold-chain integrity monitor.
2
+ #
3
+ # A low-power M55 node reads the on-board BME280 temperature/humidity/pressure
4
+ # sensor on a slow logging cadence, computes the cold-chain metrics (MKT,
5
+ # dewpoint, excursion time), and classifies the integrity state. Same source
6
+ # targets the V2N DEEPX path when som.sku is flipped.
7
+
8
+ libraries:
9
+ - name: tflite-micro
10
+ cores: [m33_sm]
11
+
12
+ som:
13
+ sku: E1M-V2N101
14
+
15
+ preset: e1m-x-evk
16
+ supported_boards:
17
+ - e1m-evk
18
+ - e1m-x-evk
19
+
20
+ pins:
21
+ - { e1m: E1M_X_I2C0, macro: XEVK_I2C_BUS_SENSORS, doc: "On-board sensor + IO-expander + INA236 bus (ICM-42670, BMI323, BMP581, TCAL9538, INA236)." }
22
+
23
+ cores:
24
+ a55_cluster:
25
+ os: "off"
26
+ m33_sm:
27
+ app: ./src
28
+ inference:
29
+ default_arena_kib: 64
30
+ peripherals:
31
+ - i2c # BME280 link.
32
+
33
+ chips:
34
+ - bme280 # temperature / humidity / pressure.
35
+
36
+ diagnostics:
37
+ log_level: info
@@ -0,0 +1,8 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ CONFIG_MAIN_STACK_SIZE=16384
3
+
4
+ CONFIG_LOG=y
5
+ CONFIG_LOG_PRINTK=y
6
+ CONFIG_CBPRINTF_FP_SUPPORT=y
7
+
8
+ CONFIG_ALP_SDK_INFERENCE_BACKEND_TFLM=y