BERGSONNE

Sense.MIC

Complete driver for the Sense.MIC tile (analog MEMS mic + amp + ADC). I2C-only, command-based protocol via tiles_pal_t raw I2C.

I2C-only, command-based protocol via tiles_pal_t raw I2C.

Examples

Quick start — polling

  tile_t mic;
  tile_sense_mic_init(core_tiles_pal(&core_i2c3), 0, &mic, NULL);
  uint16_t raw = tile_sense_mic_get_raw(&mic);
  uint16_t mv  = tile_sense_mic_get_raw_mv(&mic);

Quick start — continuous sampling

  tile_t mic;
  tile_sense_mic_init(core_tiles_pal(&core_i2c3), 0, &mic, NULL);

  uint16_t samples[256];
  tile_sense_mic_get_samples(&mic, samples, 256);

  uint16_t dc  = tile_sense_mic_dc_level(samples, 256);
  uint16_t pp  = tile_sense_mic_peak_to_peak(samples, 256);

Quick start — with internal reference for precise mV

  sense_mic_cfg_t cfg = { .ref = SENSE_MIC_REF_INTERNAL };
  tile_t mic;
  tile_sense_mic_init(core_tiles_pal(&core_i2c3), 0, &mic, &cfg);
  // Now get_raw_mv() uses 2048 mV full-scale (0.5 mV/LSB)

API reference

Initialization

tile_sense_mic_find

uint8_t tile_sense_mic_find(tiles_pal_t *hal, uint8_t instance)

Lightweight probe — does not configure the device. The MAX11645 has no WHO_AM_I register; this checks for an ACK at 0x36.

tile_sense_mic_init

void tile_sense_mic_init(tiles_pal_t *hal, uint8_t instance, tile_t *tile, const sense_mic_cfg_t *cfg)

Sends setup byte (reference, clock, polarity) and configuration byte (scan mode, channel, single-ended). Verifies the device responds by performing a test read. Pass cfg=NULL for defaults: VDD reference, AIN0 (mic), single-ended, unipolar, internal clock, single-channel scan.

  • Blocks for ~5 ms (setup settling + DC offset calibration). Call once at startup.

Lifecycle

tile_sense_mic_sleep

Studio
void tile_sense_mic_sleep(tile_t *tile)

Enter low-power mode (no conversions).

tile_sense_mic_wake

Studio
void tile_sense_mic_wake(tile_t *tile)

Wake from sleep, restore previous configuration.

tile_sense_mic_reset

Studio
void tile_sense_mic_reset(tile_t *tile)

Reset the config register to power-on defaults. Must call init() again.

Runtime

tile_sense_mic_get_vref_mv

Studio
uint16_t tile_sense_mic_get_vref_mv(tile_t *tile)

Returns the Vref used for millivolt conversions (3300 for VDD, 2048 for internal, or the user-specified value for external).

tile_sense_mic_get_raw

Studio
uint16_t tile_sense_mic_get_raw(tile_t *tile)

The MAX11645 auto-converts on every read — no trigger needed. Conversion time is ~3.5 µs (internal clock); the I2C transaction itself dominates the timing (~55 µs at 400 kHz).

tile_sense_mic_get_raw_mv

Studio
uint16_t tile_sense_mic_get_raw_mv(tile_t *tile)

Conversion: mv = raw * vref_mv / 4096

tile_sense_mic_get_audio_sample

Studio
int16_t tile_sense_mic_get_audio_sample(tile_t *tile)

Returns: (raw - dc_offset) where dc_offset is auto-calibrated during init(). Useful for audio waveform capture where DC bias is removed.

Returns Signed 16-bit value. 0 = silence.

tile_sense_mic_get_dc_offset

Studio
uint16_t tile_sense_mic_get_dc_offset(tile_t *tile)

Measured during init() by averaging 64 samples. Typically 600–900 with VDD reference, depending on supply voltage and PCB layout.

tile_sense_mic_get_samples

Studio
void tile_sense_mic_get_samples(tile_t *tile, uint16_t *buf, uint16_t count)

Reads are back-to-back; effective sample rate depends on I2C bus speed: - 400 kHz: ~12.5 ksps - 1 MHz: ~16 ksps

buf
Output buffer (caller-allocated, min count entries)
count
Number of samples to read

tile_sense_mic_dc_level

Studio
uint16_t tile_sense_mic_dc_level(tile_t *tile, const uint16_t *samples, uint16_t count)

Useful for determining the mic bias point. Varies with supply voltage and PCB bias circuit (typically 600–900 with VDD ref). symmetry with the rest of the driver surface).

tile
Tile handle (unused — accepted for DSL-binding
samples
Sample buffer (typically from get_samples()).
count
Number of samples in the buffer.

Returns DC offset in raw ADC counts.

tile_sense_mic_peak_to_peak

Studio
uint16_t tile_sense_mic_peak_to_peak(tile_t *tile, const uint16_t *samples, uint16_t count)

Returns max - min across all samples. Silence ≈ 5–20 counts (noise floor).

tile
Tile handle (unused — accepted for DSL-binding symmetry).
samples
Sample buffer.
count
Number of samples.

Returns Peak-to-peak amplitude in raw ADC counts.

tile_sense_mic_rms

Studio
uint16_t tile_sense_mic_rms(tile_t *tile, const uint16_t *samples, uint16_t count, uint16_t dc_offset)

Compute RMS amplitude relative to a DC offset (raw counts).

tile
Tile handle (unused — accepted for DSL-binding symmetry).
samples
Sample buffer.
count
Number of samples.
dc_offset
DC bias point (use dc_level() to measure, or pass 2048).

Returns RMS of AC component in raw ADC counts.

tile_sense_mic_amplitude_mv

Studio
uint16_t tile_sense_mic_amplitude_mv(tile_t *tile, uint16_t pp_raw)

Uses the configured reference voltage to scale a peak-to-peak raw ADC count into millivolts: mv = pp_raw * vref_mv / 4096.

pp_raw
[0..4095] Peak-to-peak amplitude in raw ADC counts.

Returns Amplitude in millivolts.

tile_sense_mic_is_loud

Studio
uint8_t tile_sense_mic_is_loud(tile_t *tile, int16_t threshold_db)

Captures a short sample buffer (~64 samples / ~5 ms at 12.5 ksps) via @ref tile_sense_mic_get_samples, computes the RMS amplitude relative to the calibrated DC offset, converts it to dB SPL via the CMM-2718AT sensitivity model (with the AD8605 gain divided out), and compares against `threshold_db` (0.1 dB units, e.g. 700 = 70.0 dB).

tile
Initialised tile handle.
threshold_db
SPL threshold in 0.1 dB units (e.g. 700 = 70 dB).

Returns 1 if measured SPL > threshold, 0 otherwise.

  • Blocking. Takes ~5 ms while sampling.

tile_sense_mic_read_spl_db

Studio
int16_t tile_sense_mic_read_spl_db(tile_t *tile)

Captures a short sample buffer (~64 samples), computes the RMS amplitude relative to the calibrated DC offset, scales to mV via the configured Vref, then maps mV→dB SPL using the CMM-2718AT's −42 dBV/Pa typical sensitivity AND the AD8605's ~48× gain (1 Pa ≈ 7.94 mV RMS at the mic → ~381 mV RMS at the ADC input, where 1 Pa SPL = 94 dB). The conversion is integer-only with a 32-entry log10 lookup table (1..32 mV). Returns dB SPL in 0.1 dB units (e.g. 700 = 70.0 dB). the noise floor. Negative values are not produced.

tile
Initialised tile handle.

Returns SPL in 0.1 dB units. Floor at 300 (~30 dB) when below

  • Blocking. Takes ~5 ms while sampling.
  • Accuracy regime documented in the section comment above.

tile_sense_mic_wait_for_sound

Studio
uint8_t tile_sense_mic_wait_for_sound(tile_t *tile, int16_t threshold_db, uint32_t timeout_ms)

Polls @ref tile_sense_mic_read_spl_db every ~5 ms until the computed SPL (in 0.1 dB units) exceeds `threshold_db`, or the elapsed time exceeds `timeout_ms`. Useful for "wake on sound" patterns — e.g., wait for a door slam, then fire an action.

tile
Initialised tile handle.
threshold_db
SPL threshold in 0.1 dB units.
timeout_ms
Maximum wait, in milliseconds.

Returns 1 if threshold was crossed, 0 on timeout.

  • Blocking until threshold or timeout.

tile_sense_mic_detect_clap

Studio
uint8_t tile_sense_mic_detect_clap(tile_t *tile, uint32_t timeout_ms)

Watches the SPL stream looking for the canonical clap signature: 1. Quiet bracket (≥100 ms below ~50 dB SPL) — establishes baseline 2. First peak (>~70 dB SPL spike, <50 ms wide) 3. Quiet gap (50–500 ms below threshold) 4. Second peak (>~70 dB SPL spike, <50 ms wide) 5. Quiet bracket (≥100 ms below threshold) — ensures it's really a clap-clap Thresholds are integer-fixed: peak ≈ 700 (70.0 dB), quiet floor ≈ 500 (50.0 dB). The pattern detector samples SPL every ~5 ms.

tile
Initialised tile handle.
timeout_ms
Maximum wait, in milliseconds.

Returns 1 if a clap pattern was detected, 0 on timeout.

  • Blocking until pattern detected or timeout. False positives on door knocks / drawer slams are expected — this is a coarse pattern detector, not a trained classifier.

Config

tile_sense_mic_set_reference

Studio
void tile_sense_mic_set_reference(tile_t *tile, sense_mic_ref_t ref)

Change the reference voltage source.

ref
One of the sense_mic_ref_t values (VDD, INTERNAL, etc.)
  • When switching to internal ref, allow ~10 µs for settling. This function inserts a 1 ms delay automatically.

tile_sense_mic_set_channel

Studio
void tile_sense_mic_set_channel(tile_t *tile, sense_mic_channel_t ch)

Change the active ADC channel.

ch
SENSE_MIC_CH_AIN0 (mic) or SENSE_MIC_CH_AIN1

tile_sense_mic_set_scan_mode

Studio
void tile_sense_mic_set_scan_mode(tile_t *tile, sense_mic_scan_t scan)

Change the scan mode.

scan
SENSE_MIC_SCAN_SINGLE, SENSE_MIC_SCAN_UP, or SENSE_MIC_SCAN_8X

tile_sense_mic_set_clock_mode

Studio
void tile_sense_mic_set_clock_mode(tile_t *tile, sense_mic_clock_t clk)

Selects whether the MAX11645 clocks conversions from its internal 2.8 MHz oscillator (default) or from the I2C SCL line. In external-clock mode, conversion timing is locked to the host I2C bus, which makes it possible to synchronise multiple Sense.MIC tiles or to align ADC sampling with another time-base.

clk
SENSE_MIC_CLOCK_INTERNAL or SENSE_MIC_CLOCK_EXTERNAL
  • External-clock mode only takes effect during the next read transaction; SCL must remain active for the full conversion window or the result will be invalid.

tile_sense_mic_set_polarity

Studio
void tile_sense_mic_set_polarity(tile_t *tile, sense_mic_polarity_t pol)

Unipolar (default) returns 0–4095 straight binary, mid-bias near 2048. Bipolar returns the same sample re-encoded as a signed 12-bit two's-complement value centred on VREF/2. Both modes use the chip's single-ended input on AIN0 — bipolar does NOT enable true differential reads (the tile does not route an opposing analog input to AIN1). It just changes how get_raw() encodes the same physical sample. After switching to bipolar, treat get_raw() output as a signed 12-bit value (sign-extend before use): see get_audio_sample() for an alternative that subtracts the calibrated DC offset.

pol
SENSE_MIC_POLARITY_UNIPOLAR or SENSE_MIC_POLARITY_BIPOLAR
gapExternal reference voltage on REF pinThe MAX11645 supports an external reference on its REF/AIN1 pin, but the Sense.MIC tile does not route REF/AIN1 to any pad (pad 6 carries the chip's analog audio output, not the ADC reference). Closing this gap requires a tile hardware revision that breaks REF out to a connector pad. Until then, the SENSE_MIC_REF_EXTERNAL* enum values configure the chip but have no usable external pin.

Advanced

tile_sense_mic_calibrate

Studio
void tile_sense_mic_calibrate(tile_t *tile)

Averages 64 samples to update the stored bias point.

  • Call in a quiet environment for best results.

Enums

sense_mic_ref_t

Reference voltage selection.

SENSE_MIC_REF_VDD
VDD reference (default)
SENSE_MIC_REF_EXTERNAL
External ref on REF pin
SENSE_MIC_REF_INTERNAL
Internal 2.048V, always on
SENSE_MIC_REF_INTERNAL_BUF
Internal 2.048V, buffered
SENSE_MIC_REF_EXTERNAL_BUF
External ref, buffered

sense_mic_channel_t

ADC channel selection.

SENSE_MIC_CH_AIN0
AIN0 — microphone (default)
SENSE_MIC_CH_AIN1
AIN1

sense_mic_scan_t

Scan mode.

SENSE_MIC_SCAN_SINGLE
Single channel conversion (default)
SENSE_MIC_SCAN_UP
Scan from AIN0 up to CS0
SENSE_MIC_SCAN_8X
Convert CS0 8 times (averaging)

sense_mic_clock_t

Conversion-clock source.

SENSE_MIC_CLOCK_INTERNAL
Internal 2.8 MHz oscillator (default)
SENSE_MIC_CLOCK_EXTERNAL
Host-clocked via SCL

sense_mic_polarity_t

Output coding (unipolar vs bipolar).

SENSE_MIC_POLARITY_UNIPOLAR
0 .. VREF, straight binary (default)
SENSE_MIC_POLARITY_BIPOLAR
±VREF/2, two's complement

Constants

TILE_SENSE_MIC_VERSION_MAJOR2
TILE_SENSE_MIC_VERSION_MINOR2
TILE_SENSE_MIC_VERSION_PATCH0
MAX11645_I2C_ADDR0x36
MAX11645_ADC_BITS12