Sense.TOF
TMF8806 time-of-flight distance sensor.
Platform-agnostic driver for the AMS/Sciosense TMF8806 direct time-of-flight (dToF) sensor with integrated VCSEL emitter and SPAD detector array.
Examples
Quick start
#include "core.h"
#include "core_tiles.h"
#include "tile_sense_tof.h"
tile_t tof;
sense_tof_cfg_t cfg = { .mode = SENSE_TOF_RANGE_2500MM };
tile_sense_tof_init(core_tiles_pal(&core_i2c1), 0, &tof, &cfg);
tile_sense_tof_start(&tof);
// ... poll or wait for interrupt ...
uint16_t dist = tile_sense_tof_get_distance_mm(&tof);
// Single-shot convenience:
sense_tof_result_t res;
tile_sense_tof_measure_single(&tof, &res, 500);API reference
Initialization
tile_sense_tof_find
uint8_t tile_sense_tof_find(tiles_pal_t *hal, uint8_t instance)Probes the I2C address and reads the ID register. The TMF8806 has a single fixed address (0x41), so only instance 0 is valid.
- hal
- Platform HAL handle.
- instance
- Must be 0 (single-address device).
Returns 1 if device ACKs and ID matches (0x09), 0 otherwise.
tile_sense_tof_init
void tile_sense_tof_init(tiles_pal_t *hal, uint8_t instance, tile_t *tile, const sense_tof_cfg_t *cfg)Performs the full TMF8806 boot sequence: 1. Waits for bootloader to enter sleep (ENABLE == 0x00) 2. Wakes the bootloader (PON = 1) 3. Waits for CPU ready (ENABLE == 0x41) 4. Requests App0 measurement application 5. Waits for App0 to start (APPID == 0xC0) 6. Enables result interrupt Does NOT start measurements — call tile_sense_tof_start() after init. Does NOT software-reset to preserve any existing calibration data.
- hal
- Platform HAL handle.
- instance
- Must be 0 (single-address device).
- tile
- Tile handle to initialise.
- cfg
- Configuration (NULL for defaults: 2.5 m, 30 ms, 900k iters).
Lifecycle
tile_sense_tof_sleep
Studiovoid tile_sense_tof_sleep(tile_t *tile)Stops any active measurement and powers down the sensor. Use tile_sense_tof_wake() to resume without full re-initialisation.
- tile
- Initialised tile handle.
tile_sense_tof_wake
Studiovoid tile_sense_tof_wake(tile_t *tile)Re-executes the bootloader wake and App0 request sequence. Does not restart measurements — call tile_sense_tof_start() after waking.
- tile
- Sleeping tile handle.
tile_sense_tof_reset
Studiovoid tile_sense_tof_reset(tile_t *tile)Performs a full CPU reset and re-runs the boot sequence. All runtime state including calibration is lost. Call init() again after reset.
- tile
- Tile handle.
Runtime
tile_sense_tof_start
Studiovoid tile_sense_tof_start(tile_t *tile)Writes the factory calibration data (if loaded), configures the measurement command payload from the current cfg, and issues the measurement command. Results are signaled via the result interrupt. If period_ms == 0x00 in the config, a single measurement is taken. Otherwise measurements repeat at the configured period.
- tile
- Initialised tile handle.
tile_sense_tof_stop
Studiovoid tile_sense_tof_stop(tile_t *tile)Sends the stop command and waits for the sensor to acknowledge. No-op if no measurement is active.
- tile
- Initialised tile handle.
tile_sense_tof_get_distance_mm
Studiouint16_t tile_sense_tof_get_distance_mm(tile_t *tile)Returns the peak distance in millimeters. Does not check whether new data is available — call tile_sense_tof_result_ready() first or use tile_sense_tof_get_result() for full status.
- tile
- Initialised tile handle.
Returns Distance in millimeters, or 0 if no object detected.
tile_sense_tof_get_result_flat
Studiovoid tile_sense_tof_get_result_flat(tile_t *tile, int32_t *out)Drops the struct in favor of a positional int[5] array — the DSL doesn't have a struct ABI yet, so the per-field outputs come back indexed. Layout: out[0]=distance_mm, out[1]=status, out[2]=reliability, out[3]=temperature_c, out[4]=result_number. The temperature is widened from int8_t to int32_t so negative values sign-extend correctly.
- tile
- Initialised tile handle.
- out
- Output buffer (5 int32_t slots).
tile_sense_tof_measure_single_flat
Studiouint8_t tile_sense_tof_measure_single_flat(tile_t *tile, int32_t *mm, int32_t *status, int32_t *reliability, int32_t *temp_c, int32_t *seq, uint32_t timeout_ms)Combines a single-shot measurement with positional int outputs. Same layout convention as get_result_flat — the per-field values land in five out-scalar slots. Returns the chip's success flag.
- tile
- Initialised tile handle.
- mm
- Output: distance in millimetres.
- status
- Output: result status code.
- reliability
- Output: 0–63 reliability score.
- temp_c
- Output: die temperature in degrees Celsius.
- seq
- Output: monotonic result counter.
- timeout_ms
- Maximum wait for the measurement to complete.
Returns 1 on a valid result, 0 on timeout / bus error.
tile_sense_tof_result_ready
Studiouint8_t tile_sense_tof_result_ready(tile_t *tile)Reads the INT_STATUS register and checks the result interrupt bit. Does not clear the interrupt — that is done by get_result() or get_distance_mm().
- tile
- Initialised tile handle.
Returns 1 if a new result is pending, 0 otherwise.
tile_sense_tof_set_distance_mode
Studiovoid tile_sense_tof_set_distance_mode(tile_t *tile, sense_tof_distance_mode_t mode)Stops any active measurement, updates the cached mode, and restarts. If no measurement was running, only updates the config for the next start().
- tile
- Initialised tile handle.
- mode
- New distance mode.
tile_sense_tof_set_period
Studiovoid tile_sense_tof_set_period(tile_t *tile, uint8_t period_ms)Stops any active measurement, updates the cached period, and restarts. If no measurement was running, only updates the config for the next start().
- tile
- Initialised tile handle.
- period_ms
- New period code (0x00=single, 0x1E=30ms, 0xFE=1s, 0xFF=2s).
tile_sense_tof_set_kilo_iters
Studiovoid tile_sense_tof_set_kilo_iters(tile_t *tile, uint16_t kilo_iters)Iterations (in thousands) trade power for SNR/range: more iterations give a stronger return and longer reach at higher current draw. Typical range 10-4000 (10k-4M); the ranging default is 900. Stops any active measurement, updates the cached value, and restarts.
- tile
- Initialised tile handle.
- kilo_iters
- Iterations in thousands (e.g. 900 = 900k).
tile_sense_tof_set_threshold
Studiovoid tile_sense_tof_set_threshold(tile_t *tile, uint8_t threshold)Sets cmd_data3[5:0] — the minimum confidence for a reported target. Higher values reject weak/spurious returns; 0 reports everything. Stops any active measurement, updates the cached value, and restarts.
- tile
- Initialised tile handle.
- threshold
- Detection threshold, 0-63.
tile_sense_tof_get_signal_quality_flat
Studiovoid tile_sense_tof_get_signal_quality_flat(tile_t *tile, int32_t *reference_hits, int32_t *object_hits, int32_t *crosstalk)Read signal-quality diagnostics into flat out-params (Studio).
- tile
- Initialised tile handle.
- reference_hits
- Reference-channel hit count (or NULL).
- object_hits
- Object-channel hit count (or NULL).
- crosstalk
- Cross-talk count (or NULL).
tile_sense_tof_get_sys_clock_ticks
Studiouint32_t tile_sense_tof_get_sys_clock_ticks(tile_t *tile)The TMF8806's internal oscillator can drift ±5 % over temperature, which biases distance readings if the host's measurement period doesn't compensate. Reading this register set after each measurement lets the host compute the actual elapsed chip-time vs. its own elapsed wall-time and apply a software correction (HostDriverCommunication §10). Reads SYS_CLOCK_0..3 (0x24–0x27) as a single 4-byte burst. measurement yet).
- tile
- Initialised tile handle.
Returns 32-bit system-clock tick count (0 if not in App0 / no
tile_sense_tof_is_object_within
Studiouint8_t tile_sense_tof_is_object_within(tile_t *tile, uint16_t mm)Performs one blocking single-shot measurement (up to 200 ms) and returns 1 iff the reported distance is non-zero, less than or equal to `mm`, and the reliability is at least low-confidence hit is treated as "no object". Restores the prior measurement period on the way out, so this mixes safely with continuous-mode use. 0 otherwise (no target, low reliability, or bus timeout).
- tile
- Initialised tile handle.
- mm
- Distance threshold in millimetres (inclusive).
Returns 1 if an object is within range with adequate confidence,
tile_sense_tof_wait_for_object
Studiouint8_t tile_sense_tof_wait_for_object(tile_t *tile, uint16_t mm, uint32_t timeout_ms)Polls single-shot measurements until one matches the `is_object_within` predicate or `timeout_ms` elapses. Polls every single-shot measurement adds ~30 ms of its own.
- tile
- Initialised tile handle.
- mm
- Distance threshold in millimetres (inclusive).
- timeout_ms
- Maximum wait time in milliseconds.
Returns 1 if an object entered range before timeout, 0 otherwise.
- v1 implementation polls — keeps the helper self-contained and avoids the need to wire the chip's INT pin into the tile pad map. A future revision could swap to the chip's threshold-INT (see @ref tile_sense_tof_set_threshold_interrupt) to let a sleeping host stay asleep until proximity wakes it.
tile_sense_tof_read_distance_with_confidence
Studiouint8_t tile_sense_tof_read_distance_with_confidence(tile_t *tile, uint16_t *mm, uint8_t *confidence_pct)Performs a single-shot measurement and writes the distance (mm) and the confidence remapped from the chip's 0–63 reliability scale to a 0–100 percent value. Confidence is computed as `(reliability * 100) / 63` — integer math, no floats.
- tile
- Initialised tile handle.
- mm
- Output: distance in millimetres (NULL allowed).
- confidence_pct
- Output: 0–100 confidence (NULL allowed).
Returns 1 on a successful measurement, 0 on timeout / bus error.
Config
tile_sense_tof_set_threshold_interrupt
Studiouint8_t tile_sense_tof_set_threshold_interrupt(tile_t *tile, uint8_t persistence, uint16_t low_mm, uint16_t high_mm)Without this configured, the chip fires INT on every measurement completion. With it: INT only fires when an object is detected in the [low_mm, high_mm] range for `persistence` consecutive measurements. Lets a sleeping host stay asleep until something gets close. Per HostDriverCommunication §8.12 (cmd 0x08 = WR_ADD_CONFIG): - persistence = 0 → interrupt every measurement (default) - persistence = N → require N consecutive in-range hits - low_mm > high_mm → no interrupts (no valid range)
- tile
- Initialised tile handle.
- persistence
- 0–255; 0 = disabled (every-measurement INT).
- low_mm
- Lower bound (inclusive), millimetres.
- high_mm
- Upper bound (inclusive), millimetres.
Returns 1 on success, 0 on bus / command-execution timeout.
Advanced
tile_sense_tof_factory_calibrate
Studiouint8_t tile_sense_tof_factory_calibrate(tile_t *tile, uint32_t timeout_ms)Performs a calibration measurement using the current mode settings. The sensor must be positioned with a known target or open field per the TMF8806 calibration guidelines. Results are stored internally and can be retrieved with tile_sense_tof_get_calibration(). This is a blocking call that waits for the calibration to complete.
- tile
- Initialised tile handle.
- timeout_ms
- Maximum wait time in milliseconds.
Returns 1 if calibration completed successfully, 0 on timeout or error.
tile_sense_tof_set_calibration
Studiovoid tile_sense_tof_set_calibration(tile_t *tile, const uint8_t *data)Stores a 14-byte calibration dataset that will be written to the sensor before each measurement start. Call this after init() to restore calibration from non-volatile storage.
- tile
- Initialised tile handle.
- data
- Pointer to 14-byte calibration data array.
tile_sense_tof_get_calibration
Studiovoid tile_sense_tof_get_calibration(tile_t *tile, uint8_t *data)Reads 14 bytes of calibration data from the sensor's calibration registers. Typically called after tile_sense_tof_factory_calibrate() to save the data for later reloading via set_calibration().
- tile
- Initialised tile handle.
- data
- Output buffer for 14 bytes of calibration data.
tile_sense_tof_get_app_version_flat
Studiovoid tile_sense_tof_get_app_version_flat(tile_t *tile, int32_t *major, int32_t *minor, int32_t *patch)Drops the struct in favor of three positional out-scalars.
- tile
- Initialised tile handle.
- major
- Output: major version number.
- minor
- Output: minor version number.
- patch
- Output: patch version number.
tile_sense_tof_get_serial_number_flat
Studiovoid tile_sense_tof_get_serial_number_flat(tile_t *tile, int32_t *out)Drops the success bool — on bus error, the buffer comes back as all-zeros, which is invalid as a real serial number so callers can detect failure by checking for a zero serial. Bytes widen to int32 for DSL int compatibility.
- tile
- Initialised tile handle.
- out
- Output buffer (4 int32_t slots).
tile_sense_tof_save_state
Studiovoid tile_sense_tof_save_state(tile_t *tile, uint8_t *data)Reads 11 bytes of algorithm state data from the sensor (registers 0x28-0x32). This state should be saved before entering sleep in ultra-low-power mode, and restored after wake via restore_state(). Preserving algorithm state across power cycles avoids the ~8 ms re-initialisation penalty and maintains measurement accuracy.
- tile
- Initialised tile handle (measurement should be stopped).
- data
- Output buffer for 11 bytes of state data.
tile_sense_tof_restore_state
Studiovoid tile_sense_tof_restore_state(tile_t *tile, const uint8_t *data)Writes 11 bytes of previously saved algorithm state to the sensor (registers 0x2E-0x38). Call this after wake() and before start() to resume from the saved algorithm state. The calibration data bitmask in the measurement command (cmd_data7) is automatically updated to include algState when state data has been restored.
- tile
- Initialised tile handle (after wake, before start).
- data
- Pointer to 11 bytes of previously saved state data.
tile_sense_tof_get_threshold_interrupt
Studiouint8_t tile_sense_tof_get_threshold_interrupt(tile_t *tile, uint8_t *persistence, uint16_t *low_mm, uint16_t *high_mm)Per HostDriverCommunication §8.12.2 (cmd 0x09 = RD_ADD_CONFIG).
- tile
- Initialised tile handle.
- persistence
- Output (may be NULL).
- low_mm
- Output (may be NULL).
- high_mm
- Output (may be NULL).
Returns 1 on success, 0 on timeout.
tile_sense_tof_read_histogram_flat
Studiovoid tile_sense_tof_read_histogram_flat(tile_t *tile, uint8_t hist_type, uint32_t timeout_ms, int32_t *out)Drops the success bool — on timeout / bus error the buffer comes back zero-filled. Bytes widen to int32 for DSL int compatibility. Caller passes hist_type and timeout_ms as scalar args; the buffer is the function's output (collapsed into the int[128] return).
- tile
- Initialised tile handle.
- hist_type
- Histogram-type byte (see read_histogram() docs).
- timeout_ms
- Maximum wait for the histogram-ready interrupt.
- out
- Output buffer (128 int32_t slots).
Driver gaps · 1
Chip capabilities this driver doesn’t expose yet.
Enums
sense_tof_distance_mode_t
Distance mode selection.
- SENSE_TOF_SHORT_RANGE
- Short range, ~200 mm max, lowest power
- SENSE_TOF_RANGE_2500MM
- Medium range up to 2500 mm (default)
- SENSE_TOF_RANGE_5000MM
- Long range up to 5000 mm
Constants
| TILE_SENSE_TOF_VERSION_MAJOR | 1 | |
| TILE_SENSE_TOF_VERSION_MINOR | 3 | |
| TILE_SENSE_TOF_VERSION_PATCH | 0 | |
| TMF8806_I2C_ADDR | 0x41 | Fixed 7-bit I2C address |
| TMF8806_DEVICE_ID | 0x09 | Expected ID value (bits 5:0 only) |
| TMF8806_ID_MASK | 0x3F | Mask for valid ID bits |
| TMF8806_ENABLE_PON | 0x01 | Power-on bit |
| TMF8806_ENABLE_CPU_READY | 0x41 | CPU ready + PON |
| TMF8806_ENABLE_CPU_RESET | 0x80 | CPU reset bit |
| TMF8806_APPID_BOOTLOADER | 0x80 | Bootloader is running |
| TMF8806_APPID_APP0 | 0xC0 | Measurement application running |
| TMF8806_CMD_MEASURE | 0x02 | Start measurement |
| TMF8806_CMD_FACTORY_CAL | 0x0A | Run factory calibration |
| TMF8806_CMD_STOP | 0xFF | Stop measurement |
| TMF8806_CMD_SERIAL | 0x47 | Read serial number |
| TMF8806_FACTORY_CAL_KITERS | 0xA000 | |
| TMF8806_INT_RESULT | 0x01 | Result interrupt flag |
| TMF8806_INT_HISTOGRAM | 0x02 | Histogram interrupt flag |
| TMF8806_CONTENTS_RESULT | 0x55 | Result data available |
| TMF8806_CONTENTS_CALIB | 0x0A | Calibration data available |
| TMF8806_CONTENTS_SERIAL | 0x47 | Serial number available |
| TMF8806_CALIB_DATA_LEN | 14 | Factory calibration data length |
| TMF8806_STATE_DATA_LEN | 11 | Algorithm state data length |
| TMF8806_BOOT_TIMEOUT_MS | 500 | Maximum boot sequence wait |
| TMF8806_CMD_TIMEOUT_MS | 1000 | Maximum command completion wait |
| TMF8806_POLL_INTERVAL_MS | 2 | Polling interval during boot |
| SENSE_TOF_PRESENCE_RELIABILITY_MIN | 32 | |
| SENSE_TOF_WAIT_POLL_INTERVAL_MS | 10 |

