|
SDK for TESAIoT Dev Kit
API reference & tutorials (ModusToolbox)
|
A compiled register. Every entry cites the line that proves it. Entries are numbered as in the design of record so chapters can refer to them by number.
The archive defines printf and puts as deliberate no-op stubs (ai_engine.c:276-288; nm -S reports 8- and 4-byte T symbols). CM33_NS owns the UART and newlib stdio on CM55 would take a foreign lock and panic (ai_engine.c:270-275). Any printf in your own CM55 code produces nothing; you cannot link newlib stdio into this core. Treat the two symbols as a link-time ABI hazard, not API.
CM55 treats it as an unconditional touch_disabled = false, cancelling another task's touch hold and producing OPTIGA_COMMS_ERROR (0x0102) on the shared bus (ipc_hsm_handler.c:1393-1405). Use the counted optiga_manager_touch_hold()/_release() pair.
It deliberately returns true when the manager was never initialised (tesaiot_optiga_manager.c:157-169). optiga_manager_lock() is the "is the manager up?" test; getting this backwards is the documented cause of several ungated-access defects.
They share one CY_SECTION_SHAREDMEM buffer s_rate_msg; Cy_IPC_Pipe_SendMessage is asynchronous, so op=1's leading memset zeroes an in-flight op=2 and CM33 reads PAUSE (ai_engine.c:522-536). resume_sensor has no caller in shipped firmware.
active() is s_current and lags the request by a whole cold-init. The recorded bug: "select Radar, Load, get Motion" (ai_engine.c:1868-1873). Guard on ai_engine_requested().
Last-writer-wins over one slot: "a cough detected at 0.94 is overwritten by three 'unlabelled' … The detection is not late, it is gone" (ai_engine.c:1876-1885). Use snapshot_model() per member.
There is no idempotent set form; always guard with ipc_lcd_is_panel_visible() (ipc_core row 2, page_playground.c:167-188). Console and widgets are mutually exclusive.
lv_screen_load_anim(auto_del) frees the page's objects; a later IPC handler writes into them (ipc_core row 3, page_playground.c:342-349). NULL both containers on destroy, in the same order as the bind.
"Safe to call from any task context" but "Clears the 'changed' flags after reading" (ipc_sensorhub.h:66-67) — exactly one consumer per tick. The UI takes one snapshot at 33 ms and fans out.
Resolve SSID → slot with wifi_saved_find() before any erase (wifi_connect_native.c:118-134); < 0 on miss.
wifi_creds_flush_if_dirty is called only at mpy_main.c:709 and :686 (REPL idle / exit). A program that never returns to the REPL never persists the credential; mtb-only writes immediately (sensor_auto_task.c:784-789 vs :828-854).
A retained bundle arrives on every connect; observed three times on 2026-08-07 silently redoing the previous run. trustm_current_correlation_id() == NULL means nothing is outstanding — discard (tesaiot_pu_ingest.c:752-768). At weak sites check the function pointer, then the string.
The GFX task runs at MAX−1; a wedged clock-stretching device with a block-forever PDL timeout starved every lower-priority CM55 task. Use bounded timeouts (2 ms) on disp_touch_i2c_controller_context (cm55_sensor_poll.c:49-53).
page_id_ordinal_assert.c:22-25; lib/ipc_core/PROVENANCE.txt records PAGE_ID_PLAYGROUND == 7. A mismatch links cleanly and compares the wrong page. Add at the end; never renumber, never re-guard.
The MQTT port derives from tls_mode (mqtt_client_config.c:105-118). Editing port in /.tesaiot_config changes nothing.
main.c:278-287. The heartbeat exists because the variant has no instrument "that is not also the murder weapon". Flash, then power-cycle; do not attach to a running board.
modwifi.c:261-285 and wifi_init.c:261-302 read-modify-write the file directly without wifi_creds_lock and bypass g_boot_wifi_creds; there is no file-level lock outside mtb-only's bs_lock() (J8 thin-evidence #6).
Six of the 18 tesaiot_hsm functions link only under ENABLE_OPTIGA_CLM=1 and are consumed as weak symbols: publish_csr, tesaiot_publish_protected_update, trustm_reset_state, trustm_current_correlation_id, trustm_requested_target_oid, trustm_requested_anchor_oid (A.5 preamble; refusal string at ipc_hsm_handler.c:2158-2161).
The legacy task skipped the WL_REG_ON / WCM init step that CYW55513 needs (main.c:344-347). No caller anywhere; use install_chip_power_then_ble().
A debugger reset leaves the display dark, which looks exactly like a failed flash (shipped package READMEs: dist mtb-mpy :51-52, mtb-only :54; in-zip README :47-49). Taught in A1/A2 at the first checkpoint. Dark screen after flash = reset, not failure.
The backlight can want a second unplug-replug on cold boot (dist mtb-only README :55). A dark screen after a power-cycle is not proof of a bad image.
Values must be a bare 1 or 0. The consuming Makefiles compare with ifeq ($(VAR),1), which is whitespace-sensitive, so BSP_HAS_CAPSENSE=1 (or an inline comment after the value) evaluates false and the feature's INCLUDES/CFLAGS vanish with no error anywhere — the build succeeds and the sensor is simply not there. The file states the rule itself (bsp_features.mk:28-30, restated at :55-57). Taught in The BSP flags, as this board sets them.
CY_RSLT_MODULE_MQTT_CONNECT_FAIL is assigned when the retries run out (cy_mqtt_api.c:2436), overwriting whatever result already held. A TLS failure and an authentication rejection therefore print the identical code. On 2026-09-11 three defects at three different layers all printed it, and it never changed once as each was fixed.
The signal that does work is the [TLS-DIAG] err= line at cy_tls.c:1860. It sits inside the mbedtls_ssl_handshake() loop, so it fires on every handshake failure — which means its absence is proof that TLS succeeded. Do not read the other [TLS-DIAG] lines (optiga_key, heap) that way: they print before the handshake and say nothing about it.
mqtt_mtls_setup.c:232 switches to 0xE0E1/0xE0F1 the moment verify_cert_key_pair() is true, so the certificate on the wire is not a configuration choice — it is decided at connect time by whether enrolment has succeeded.
The failure is inverted: a board that fails enrolment connects, and a board that succeeds is refused, until the broker carries CN=TESAIoT MCU CA in its trust bundle and its CN check compares against the device_id rather than the MQTT client id (the firmware deliberately sends the Trust M UID as client id). See D2 — Enrolment and Protected Update end to end.
After several enrolment cycles the secure element can stop opening (optiga_util_open_application failed, status 0x0102). mTLS then cannot read the client certificate and MQTT never starts — tesaiot.connect() prints nothing at all, not even [MQTT] Start request received.
HTTPS keeps working throughout, because it authenticates with an API key and never touches the chip. That asymmetry makes it look like an MQTT or broker problem when it is neither. Check optiga.init() before reading any broker log, and note that reflashing does not clear it: a flash resets the MCU, not the secure element. Only a power cut does.