|
SDK for TESAIoT Dev Kit
API reference & tutorials (ModusToolbox)
|
The radar task and its DSP chain are CM55 template source in both packages. The three sensors.radar* calls are thin IPC clients over that task and exist on mtb-mpy only; on mtb-only you read the same state through the extern variables and the two diagnostic functions, which is what the on-screen page does on both variants.
After this chapter you can get a presence flag, an energy figure and a first-peak range out of the BGT60TR13C, set a detection threshold and recapture a clutter baseline, and — when the numbers freeze, which is the failure this sensor actually has — read the two diagnostic triads that tell you which of three things stopped: the SPI link, the frame sequencer, or the task itself.
The radar lives entirely on CM55. tesaiot_radar_task() (radar_task.h:96) brings up SPI, configures the BGT60TR13C, and then polls: read a frame, compute energy, update the presence flag. Three volatile globals carry the result to anyone who wants it — tesaiot_radar_presence_detected (:72), tesaiot_radar_current_energy (:77) and tesaiot_radar_initialized (:82). No lock: three word reads.
The DSP chain is a second consumer of the same frames. radar_dsp.c/h runs a 128-sample pipeline — RADAR_DSP_N is 128 (radar_dsp.h:29) — over radar_dsp_process() (:48), keeps a range snapshot fetched by radar_dsp_snapshot() (:59), and takes a detection threshold through radar_dsp_set_threshold_x10() (:52). The compiled-in default is RADAR_DSP_THRESHOLD_DB 6.0 (radar_dsp.h:32).
MicroPython is a client, not a driver. All three Python calls are IPC round-trips into that task, with the same retry and timeout budget: 20 send retries 100 µs apart, then a 500 ms wait for the response (modsensors.c:301-303). sensors.radar() sends IPC_CMD_RADAR_STATUS (modsensors.c:306); radar_range() and radar_config() share one helper, radar_dsp_ipc_roundtrip() (modsensors.c:367), and therefore share one shared-memory buffer pair — deliberately, because the shared region is full on some kits. Both failure modes raise OSError: "radar IPC send failed" when the pipe will not take the message, "radar IPC timeout" when CM55 does not answer inside 500 ms.
radar_range() has a fourth failure mode that is not an IPC failure. If the response comes back with initialized false it raises OSError("radar dsp not running") (modsensors.c:417-419) — the link is fine, the DSP chain simply is not up.
Threshold semantics, including the special value. sensors.radar_config(threshold_db) (modsensors.c:444):
There is no way to read the current threshold back.
Edge AI drains the same chirps. Under BENTO_HAS_EDGE_AI=1, radar_ai_frame_next() (radar_task.h:147) hands the model every 128-sample chirp in order through an 8-deep ring. The header records why the ring exists: a newest-only slot dropped every chirp but the last of each processing burst, so 88/s of the radar's 200/s reached the model and wrecked the inter-chirp Doppler pattern the network classifies on. It is a single-reader API — the CM55 ai_engine feed — and you should not add a second reader.
On screen, the radar page reflects the same two globals, so the page and the REPL cannot disagree.
An OSError("radar dsp not running") here means initialized was false in the response: the chain is not up, which is different from "no target".
radar_config(0.05) or radar_config(61) raises ValueError. Zero is the one value outside 0.1..60.0 that is legal, and it means something else entirely.
This is the diagnostic step, and it is C on both variants — there is no Python binding for the two stats functions.
| Reading | Meaning |
|---|---|
| tries climbing, fails 0 | the frame sequencer stalls and the watchdog is healing it once a second — real, and self-correcting |
| tries and fails climbing together | the SPI link is down; restarting the sequencer cannot work and never will |
| tries flat while frames frozen | the radar task itself is not running |
| loops frozen with phase on an SPI value | stuck in an unbounded spin inside the vendor platform layer, waiting on a flag only the SCB interrupt clears; nothing downstream can recover it |
| loops climbing, frames frozen | the loop is fine and the sensor has stopped delivering |
"Energy freezes after a minute or two" is the UI symptom of the first three rows, and these two calls are what separate them. Guessing between them from the screen is not possible.
| mtb-mpy | mtb-only | |
|---|---|---|
| Presence / energy | sensors.radar() over IPC | read tesaiot_radar_presence_detected and tesaiot_radar_current_energy directly on CM55 |
| Range | sensors.radar_range() | radar_dsp_snapshot() (radar_dsp.h:59) |
| Threshold | sensors.radar_config(db) | radar_dsp_set_threshold_x10() (radar_dsp.h:52) |
| Diagnostics | none from Python | tesaiot_radar_recover_stats(), tesaiot_radar_loop_stats() — Step 4 |
| Edge AI feed | not reachable from Python | radar_ai_frame_next(), single reader |
| Observable | the radar page, plus the dicts | the radar page only |