BERGSONNE

Drive.H

LRA/ERM haptic driver for the Drive.H tile (rev a).

Embeds the TI DRV2605 (DEVICE_ID 3 — the non-L part), a haptic driver for LRA (Linear Resonant Actuator) and ERM actuators with a built-in waveform library of 123 effects. The actuator is external, connected via the tile's OUT+ / OUT- pads; V_MOTOR accepts 2.5-5.5 V.

The chip regulates output amplitude itself: the supply rail only sets headroom. Full-scale drive level comes from RATED_VOLTAGE / OD_CLAMP (see tile_drive_h_set_actuator_voltage()), NOT from the voltage applied to V_MOTOR. V_MOTOR is the DRV2605's only supply (VDD, 2.5-5.5 V); the output cannot exceed it. The datasheet's minimum load is 8 Ω at VDD = 5.2 V.

V+ (pad 10) powers nothing but R2, a 100 kΩ pull-up on EN (pad 3). Power V+ from a logic rail, or drive pad 3 high from a Core pin: with neither, EN floats, the chip may stay in shutdown, and init() fails its device-ID check. Holding pad 3 low draws V+ / 100 kΩ (33 µA at 3.3 V). TRIG (pad 2) has a 100 kΩ pull-down (R1). The tile has no I2C pull-ups.

Datasheet

Vibe Settings

What Studio’s Vibe interface lets you change on this tile, in plain language or from the tile inspector. Each one is an argument of a driver function below, so the same setting is available from Blocks, the DSL and C. Basic settings are shown by default; advanced ones sit behind the inspector’s Advanced toggle.

SettingTierValuesDefaultFunction
Actuator typebasicERM motor: TS2200 Library A (fixed open-loop overdrive), ERM motor: TS2200 Library B (no overdrive), ERM motor: TS2200 Library C (no overdrive), ERM motor: TS2200 Library D (no overdrive), ERM motor: TS2200 Library E (no overdrive), LRA (coin / linear actuator): LRA library, auto-resonanceLRA (coin / linear actuator): LRA library, auto-resonanceset_library(library)
Actuator rated voltagebasic0.3 to 3.6 V2230set_actuator_voltage(rated_mv)
Brake strengthadvanced1x, 2x, 3x, 4x, 6x, 8x, 16x, Braking off4xset_brake_factor(factor)
Loop gainadvancedLow, Medium, High, Very highMediumset_loop_gain(gain)
Closed-loop driveadvancedon / offonset_loop_mode(closed)
Overdrive clampadvanced0.3 to 5 V2700set_actuator_voltage(overdrive_mv)
LRA resonanceadvanced125 to 300238set_resonance_hz(hz)

Examples

Quick start

  #include "core_tiles.h"

  tile_t haptic;
  tile_drive_h_init(core_tiles_pal(&core_i2c1), 0, &haptic, NULL);
  if (tile_is_ready(&haptic)) {
      tile_drive_h_play(&haptic, 1, 1);  // play effect #1 once
  }

API reference

Initialization

tile_drive_h_find

uint8_t tile_drive_h_find(tiles_pal_t* hal, uint8_t instance)

Check whether a DRV2605 is present on the I2C bus.

hal
Platform HAL handle
instance
Instance index (0 = default, see mapping table)

Returns 1 if device ACKs, 0 otherwise

tile_drive_h_init

void tile_drive_h_init(tiles_pal_t* hal, uint8_t instance, tile_t* tile, const drive_h_cfg_t *cfg)

Verifies the device ID, exits standby, and configures the actuator drive mode. Pass cfg=NULL for defaults (LRA closed-loop, library 6, RATED_VOLTAGE 0x56 / OD_CLAMP 0x8C: see drive_h_cfg_t). Also writes the settings Studio treats as known at power-on, since the chip keeps its registers across an MCU reset: FEEDBACK_CTRL (brake 4x, loop gain Medium), CONTROL2 to its reset value 0xF5 (SAMPLE_TIME 300 µs, bidirectional input), DRIVE_TIME for 238 Hz, and the open/closed-loop bit for BOTH actuator types, so a later set_library() keeps the loop mode.

hal
Platform HAL handle
instance
Instance index (0 = default, see mapping table)
tile
Pointer to tile handle (populated by this function)
cfg
Optional config, or NULL for defaults
  • Blocks for ~500 ms during init. Call once at startup.

Runtime

tile_drive_h_play

Studio
void tile_drive_h_play(tile_t* tile, uint8_t index, uint8_t repeats)

Loads the effect index into sequence slot 0, terminates the sequence, and triggers playback. For repeats > 1, re-triggers with a 200ms gap between plays.

index
[1..123] Library effect index (see datasheet).
repeats
[1..20] Number of times to play (1 = once).

tile_drive_h_play_sequence

Studio
void tile_drive_h_play_sequence(tile_t* tile, const uint8_t *effects, uint8_t count)

Loads effects into the waveform sequencer registers (0x04-0x0B), terminates the sequence, and triggers playback. Returns immediately — use tile_drive_h_is_playing() to poll for completion. DSL pads short sequences with 0 (DRV2605 effect 0 is "stop"), so a 3-effect sequence written as `[5, 10, 15, 0, 0, 0, 0, 0]` plays effects 5/10/15 then halts.

effects
Array of effect indices (1-123, 0 = stop)
count
Number of effects (1-8)

tile_drive_h_load_sequence

Studio
void tile_drive_h_load_sequence(tile_t* tile, const uint8_t *effects, uint8_t count)

Identical to tile_drive_h_play_sequence() but does NOT assert the GO bit. Use this to pre-load effects before switching to external trigger mode (edge or level).

effects
Array of effect indices (1-123, 0 = stop)
count
Number of effects (1-8)

tile_drive_h_set_trigger

Studio
void tile_drive_h_set_trigger(tile_t* tile, drive_h_trigger_t mode)

Selects how the waveform sequencer is triggered: - DRIVE_H_TRIG_INTERNAL (default): I2C GO bit, used by play() and play_sequence(). - DRIVE_H_TRIG_EDGE: a rising edge on the IN/TRIG pin sets GO. A second rising edge while playing cancels. Pre-load effects with tile_drive_h_load_sequence() before entering this mode. - DRIVE_H_TRIG_LEVEL: GO follows the IN/TRIG pin level. High = playing, low = idle. Falling edge cancels. Not a Studio setting: rtp_stop(), pwm_input_stop(), audio_stop(), diagnose() and calibrate() all return MODE to internal trigger.

mode
Trigger source (drive_h_trigger_t)

tile_drive_h_is_playing

Studio
uint8_t tile_drive_h_is_playing(tile_t* tile)

Reads the GO bit in register 0x0C. The GO bit remains high until playback completes.

Returns 1 if playing, 0 if idle

tile_drive_h_stop

Studio
void tile_drive_h_stop(tile_t* tile)

Stop any currently playing effect.

tile_drive_h_rtp_start

Studio
void tile_drive_h_rtp_start(tile_t* tile)

Sets DRV2605 MODE register to 0x05 (RTP). The chip drives the LRA at its resonant frequency with amplitude controlled by tile_drive_h_rtp_write(). Call tile_drive_h_rtp_stop() to return to internal trigger mode.

tile_drive_h_rtp_write

Studio
void tile_drive_h_rtp_write(tile_t* tile, uint8_t amplitude)

Write an amplitude value in RTP mode.

amplitude
[0..127] Amplitude (0 = off, 127 = max).

tile_drive_h_rtp_stop

Studio
void tile_drive_h_rtp_stop(tile_t* tile)

Exit RTP mode and return to internal trigger mode.

tile_drive_h_get_status

Studio
uint8_t tile_drive_h_get_status(tile_t* tile)

Contains DEVICE_ID[7:5], DIAG_RESULT[3], FB_STS[2], OVER_TEMP[1], OC_DETECT[0]. Status bits clear on read.

Returns Raw status byte

tile_drive_h_diagnose

Studio
uint8_t tile_drive_h_diagnose(tile_t* tile)

Enters diagnostic mode (MODE=6), triggers GO, and polls for completion. The DRV2605 checks whether the actuator is present, open, or shorted.

Returns 1 if actuator passed diagnostics, 0 if fault detected

tile_drive_h_calibrate

Studio
uint8_t tile_drive_h_calibrate(tile_t* tile)

Enters calibration mode (MODE=7) with datasheet-recommended parameters, triggers GO, and polls for completion. On success, the DRV2605 stores optimized A_CAL_COMP and A_CAL_BEMF values that improve playback fidelity.

Returns 1 if calibration passed, 0 if it failed to converge

tile_drive_h_get_vbat_mv

Studio
uint16_t tile_drive_h_get_vbat_mv(tile_t* tile)

Reads the VBAT register (0x21). The reading is only valid while the device is actively driving a waveform (RTP, library playback, etc.).

Returns Battery voltage in mV (e.g. 3300 = 3.3 V), 0 if idle

tile_drive_h_get_resonance_hz

Studio
uint16_t tile_drive_h_get_resonance_hz(tile_t* tile)

Reads the LRA_PERIOD register (0x22). The reading is only valid while the device is actively driving a waveform and must not be polled during braking.

Returns Resonant frequency in Hz (e.g. 235), 0 if unavailable

tile_drive_h_standby

Studio
void tile_drive_h_standby(tile_t* tile)

Sets the STANDBY bit in the MODE register. The device retains register values and can be woken quickly with tile_drive_h_wake().

tile_drive_h_wake

Studio
void tile_drive_h_wake(tile_t* tile)

Clears the STANDBY bit in the MODE register. The device returns to the active state, ready for playback.

tile_drive_h_play_click

Studio
void tile_drive_h_play_click(tile_t* tile)

Plays ROM library effect 1 ("Strong Click — 100%") once. Returns immediately; the chip drives the click after the call returns. Use @ref tile_drive_h_is_playing to poll for completion.

tile_drive_h_play_double_tap

Studio
void tile_drive_h_play_double_tap(tile_t* tile)

Loads the sequencer with ROM library effect 10 ("Double Click — 100%"), a two-click effect, and triggers playback. The chip handles the inter-tap timing internally. Returns immediately; use @ref tile_drive_h_is_playing to poll.

tile_drive_h_play_alert

Studio
void tile_drive_h_play_alert(tile_t* tile)

Sequences three ROM-library effects: effect 14 ("Strong Buzz — 100%") → effect 56 ("Pulsing Sharp 1 — 100%") → effect 14. Returns immediately; use @ref tile_drive_h_is_playing to poll.

tile_drive_h_play_buzz

Studio
void tile_drive_h_play_buzz(tile_t* tile, uint16_t ms)

Switches into RTP (Real-Time Playback) mode, drives a constant full-amplitude signal for `ms` milliseconds, then stops the RTP stream and returns to internal-trigger mode. / @ref tile_drive_h_rtp_stop.

ms
[0..65535] Duration in milliseconds
  • Blocking call — does not return until the buzz completes. For longer non-blocking patterns, drive RTP directly via

tile_drive_h_is_calibrated

Studio
uint8_t tile_drive_h_is_calibrated(tile_t* tile)

Reads the STATUS register's DIAG_RESULT bit, which the auto- calibration engine populates on completion: 0 = converged (calibration produced valid A_CAL_COMP / A_CAL_BEMF values), 1 = failed. Only meaningful after a prior call to @ref tile_drive_h_calibrate.

Returns 1 if calibration converged, 0 otherwise

  • STATUS bits clear on read, so the result reflects the most recent calibration / diagnostic run.

Config

tile_drive_h_set_sequence_wait

Studio
void tile_drive_h_set_sequence_wait(tile_t* tile, uint8_t slot, uint8_t delay_steps)

The 8 sequencer slots can each be marked as either an effect (MSB=0, low 7 bits = waveform 1..123) or a wait time (MSB=1, low 7 bits × 10 ms = pause). This call rewrites slot @p slot with a wait of @p delay_steps × 10 ms (max 1270 ms). Use it after tile_drive_h_load_sequence() to insert pauses between effects, e.g. play 1, wait 200 ms, play 47. Slot is silently ignored if >= 8; delay_steps is clipped to 0x7F.

slot
[0..7] Slot index
delay_steps
[0..127] Wait length in 10 ms steps (0 = no wait, 127 = 1.27 s)

tile_drive_h_set_library

Studio
void tile_drive_h_set_library(tile_t* tile, drive_h_library_t library)

The DRV2605 ships with 6 ROM libraries: 1–5 are TS2200 ERM libraries (A–E), 6 is the LRA library. Library 0 is empty (silence). This call also updates the FEEDBACK_CTRL N_ERM_LRA bit so the chip drives the correct actuator type. The actuator is external (OUT± pads), so this must match what is wired: an LRA (coin / linear) uses DRIVE_H_LIB_LRA, an ERM (spinning mass) motor one of the ERM libraries.

library
Library (use DRIVE_H_LIB_* constants)

tile_drive_h_set_actuator_params

Studio
void tile_drive_h_set_actuator_params(tile_t* tile, uint8_t rated_voltage, uint8_t od_clamp, uint8_t fb_brake, uint8_t loop_gain)

Writes the four registers that the auto-calibration engine and smart-loop architecture consume: - rated_voltage (0x16): full-scale RMS drive level (closed-loop ref). - od_clamp (0x17): peak overdrive ceiling (also open-loop ref). - fb_brake (0x1A bits 6:4): feedback brake factor (0=1× .. 6=16×, 7=off). - loop_gain (0x1A bits 3:2): closed-loop gain (0=Low .. 3=Very high). Pass 0 for rated_voltage / od_clamp to leave that register untouched. From C, pass 0xFF for fb_brake / loop_gain to leave them untouched (Studio bounds them to their fields). Run tile_drive_h_calibrate() afterwards to update A_CAL_COMP / A_CAL_BEMF. Register-level escape hatch. For settings prefer tile_drive_h_set_actuator_voltage() (millivolts), tile_drive_h_set_brake_factor() and tile_drive_h_set_loop_gain().

rated_voltage
[0..255] RATED_VOLTAGE byte (0 = no change)
od_clamp
[0..255] OD_CLAMP byte (0 = no change)
fb_brake
[0..7] Feedback brake factor (drive_h_brake_t codes; 0xFF from C = no change)
loop_gain
[0..3] Loop gain (drive_h_loop_gain_t codes; 0xFF from C = no change)

tile_drive_h_set_brake_factor

Studio
void tile_drive_h_set_brake_factor(tile_t* tile, drive_h_brake_t factor)

Writes FEEDBACK_CTRL FB_BRAKE_FACTOR[6:4]: the feedback gain while braking, relative to the gain while driving. More braking stops the actuator faster (crisper clicks) at the cost of loop stability; the datasheet default (4x) suits most actuators. Only used in closed loop. The datasheet asks for this to be set before auto-calibration. tile_drive_h_calibrate() itself runs at 3x / Medium (TI's recommended calibration values) and restores this setting afterwards.

factor
Braking gain (drive_h_brake_t)

tile_drive_h_set_loop_gain

Studio
void tile_drive_h_set_loop_gain(tile_t* tile, drive_h_loop_gain_t gain)

Writes FEEDBACK_CTRL LOOP_GAIN[3:2]: how fast the loop drives the back-EMF (the actuator's speed) to the requested level. Higher gain settles faster and is less stable; Medium (the datasheet default) suits most actuators. Only used in closed loop. Like the brake factor, set it before calibrating.

gain
Loop gain (drive_h_loop_gain_t)

tile_drive_h_set_loop_mode

Studio
void tile_drive_h_set_loop_mode(tile_t* tile, uint8_t closed)

Closed loop (recommended for LRAs) enables smart-loop back-EMF feedback: automatic resonance tracking, overdrive, and braking, with full-scale amplitude referenced to RATED_VOLTAGE. Open loop drives blind: amplitude is referenced to OD_CLAMP, RATED_VOLTAGE is ignored, and LRA playback does NOT resonance-track on this part — the commutation frequency comes from DRIVE_TIME (see tile_drive_h_set_resonance_hz()). Applies to whichever actuator type is currently selected (set_library() / FEEDBACK_CTRL N_ERM_LRA).

closed
1 = closed-loop (smart-loop), 0 = open-loop
  • Switching to open loop makes OD_CLAMP the full-scale level: with init's 0x8C that is ~2.7 Vrms, stronger than closed loop.

tile_drive_h_set_actuator_voltage

Studio
void tile_drive_h_set_actuator_voltage(tile_t* tile, uint16_t rated_mv, uint16_t overdrive_mv)

The friendly-units version of tile_drive_h_set_actuator_params(): converts voltages to the RATED_VOLTAGE (0x16) and OD_CLAMP (0x17) register values using the DRV2605 datasheet equations (section 7.5.2, Eq. 2-5), honouring the currently selected actuator type (ERM vs LRA) and, for LRAs, the drive frequency currently programmed via tile_drive_h_set_resonance_hz(). - rated_mv: steady-state full-scale level (RMS for LRA, average for ERM). Closed-loop reference. - overdrive_mv: peak ceiling for overdrive/braking; also the full-scale reference in open-loop mode. Must be >= rated_mv; typically 1.3-1.5x for LRAs. Run tile_drive_h_calibrate() afterwards — the datasheet requires recalibration whenever these references change. above its rated voltage for long effects (play_buzz, RTP) heats it and shortens its life. The output never exceeds V_MOTOR, whatever is set here. The control defaults (2230 / 2700 mV) reproduce init's 0x56 / 0x8C at init's 238 Hz DRIVE_TIME.

rated_mv
[300..3600] Rated drive level in mV
overdrive_mv
[300..5000] Overdrive clamp in mV

tile_drive_h_set_resonance_hz

Studio
void tile_drive_h_set_resonance_hz(tile_t* tile, uint16_t hz)

Programs CONTROL1 DRIVE_TIME to half the LRA period — the datasheet-optimal value. In closed-loop mode this seeds the auto-resonance tracker (which then follows the real resonance); in open-loop mode it directly sets the commutation frequency. Read the actuator's actual resonance with tile_drive_h_get_resonance_hz() while driving in closed loop.

hz
[125..300] LRA resonant frequency in Hz

tile_drive_h_set_resonance_params

Studio
void tile_drive_h_set_resonance_params(tile_t* tile, uint8_t sample_time, uint8_t blanking_time, uint8_t idiss_time)

Writes Control2 (0x1C) bits for sample / blanking / current- dissipation timing. Default values (3 / 1 / 1) work for most coin-type LRAs at 175–235 Hz. Tune only if calibration fails to converge or the actuator runs at the edges of the 125–300 Hz window. init() writes the reset values (3 / 1 / 1). From C, pass 0xFF for any field to leave that register slice untouched (Studio bounds each to its 2-bit field). SAMPLE_TIME also feeds the LRA voltage maths in tile_drive_h_set_actuator_voltage().

sample_time
[0..3] Sample time (0 = 150 µs, 1 = 200, 2 = 250, 3 = 300 µs; 0xFF from C = no change)
blanking_time
[0..3] Blanking time code (0xFF from C = no change)
idiss_time
[0..3] Current-dissipation time code (0xFF from C = no change)

tile_drive_h_set_waveform_timing

Studio
void tile_drive_h_set_waveform_timing(tile_t* tile, int8_t overdrive, int8_t sustain_pos, int8_t sustain_neg, int8_t brake)

Adds signed offsets (in 5 ms steps) to the overdrive, sustain, and brake portions of every library effect. Offsets are 8-bit two's complement, so range is -640..+635 ms per knob. These offsets are only honoured in open-loop mode — closed-loop mode generates them automatically from back-EMF feedback.

overdrive
[-128..127] Overdrive Time Offset (0x0D, signed × 5 ms)
sustain_pos
[-128..127] Sustain-Time Positive Offset (0x0E, signed × 5 ms)
sustain_neg
[-128..127] Sustain-Time Negative Offset (0x0F, signed × 5 ms)
brake
[-128..127] Brake Time Offset (0x10, signed × 5 ms)

tile_drive_h_set_rtp_format

Studio
void tile_drive_h_set_rtp_format(tile_t* tile, uint8_t unsigned_, uint8_t bidir)

Selects how RTP_INPUT bytes are interpreted: - signed (default for closed-loop bidirectional): 0x80 = full reverse, 0x00 = mid-scale (no drive), 0x7F = full forward. - unsigned (recommended for closed-loop unidirectional and open-loop): 0x00 = no drive, 0xFF = full drive. Also exposes the BIDIR_INPUT bit (CONTROL2[7]) which selects unidirectional vs bidirectional input interpretation; tie this to the same convention as the format flag.

unsigned_
[0..1] 1 = unsigned data format, 0 = signed (default)
bidir
[0..1] 1 = bidirectional input (default), 0 = unidirectional

tile_drive_h_set_audio_params

Studio
void tile_drive_h_set_audio_params(tile_t* tile, uint8_t peak_time, uint8_t filter, uint8_t min_input, uint8_t max_input, uint8_t min_drive, uint8_t max_drive)

Configures the four ATV control registers: - ATV_CTRL (0x11): peak-detect time (0=10ms..3=40ms) and low-pass filter cutoff (0=100Hz..3=200Hz). - ATV_MIN_INPUT (0x12): minimum input level below which the envelope is gated (output silent). raw × 1.8/255 V. - ATV_MAX_INPUT (0x13): full-scale input level. raw × 1.8/255 V. - ATV_MIN_DRIVE (0x14): minimum output drive once unmuted. raw / 255 × 100 %. - ATV_MAX_DRIVE (0x15): maximum output drive at full input. raw / 255 × 100 %. Pass 0xFF for any field to leave it untouched. That makes 0xFF, the reset value of ATV_MAX_INPUT and ATV_MAX_DRIVE, unreachable once changed: use tile_drive_h_set_audio_envelope() and tile_drive_h_set_audio_levels() instead, which have no sentinel.

peak_time
[0..255] ATH_PEAK_TIME 0..3 (10/20/30/40 ms; 0xFF = no change)
filter
[0..255] ATH_FILTER 0..3 (100/125/150/200 Hz; 0xFF = no change)
min_input
[0..255] Minimum input gate (0xFF = no change)
max_input
[0..255] Full-scale input level (0xFF = no change)
min_drive
[0..255] Minimum output drive once active (0xFF = no change)
max_drive
[0..255] Full-scale output drive (0xFF = no change)

tile_drive_h_set_audio_envelope

Studio
void tile_drive_h_set_audio_envelope(tile_t* tile, drive_h_atv_peak_t peak_time, drive_h_atv_filter_t filter)

Writes ATV_CTRL (0x11): peak-detection time and low-pass cutoff. Reset values: 20 ms, 125 Hz.

peak_time
Peak-detection time (drive_h_atv_peak_t)
filter
Low-pass filter cutoff (drive_h_atv_filter_t)

tile_drive_h_set_audio_levels

Studio
void tile_drive_h_set_audio_levels(tile_t* tile, uint8_t min_input, uint8_t max_input, uint8_t min_drive, uint8_t max_drive)

Writes ATV_MIN_INPUT..ATV_MAX_DRIVE (0x12-0x15). Every value is written as given (no sentinel). Input levels are raw × 1.8 V / 255; drive levels raw / 255 × full scale. Reset values: 0x19 / 0xFF / 0x19 / 0xFF.

min_input
[0..255] Input level below which the output stays silent
max_input
[0..255] Input level that gives full drive
min_drive
[0..255] Output drive at the minimum input
max_drive
[0..255] Output drive at the full-scale input

Other

tile_drive_h_pwm_input_start

Studio
void tile_drive_h_pwm_input_start(tile_t* tile)

Sets MODE=3 with N_PWM_ANALOG=0. The chip accepts a 10–250 kHz PWM signal: duty cycle directly modulates output amplitude (50 % = no drive in bidirectional mode; 0 % = no drive in unidirectional mode). Useful for offloading waveform generation to a hardware timer or audio rendering pipeline. Call tile_drive_h_set_rtp_format() first if you need to change the unidirectional / bidirectional interpretation.

tile_drive_h_analog_input_start

Studio
void tile_drive_h_analog_input_start(tile_t* tile)

Sets MODE=3 with N_PWM_ANALOG=1. Reference voltage is 1.8 V: 0 V → 0 % drive, 0.9 V → 50 %, 1.8 V → 100 %. Useful for waveform synthesis from a DAC or analog signal source.

  • Pad 2 (TRIG) is a digital pad on the tile. The chip pin itself accepts 0–1.8 V analog, but the driving Core must output a clean analog level — Drive.H has no input filter or AC-coupling cap on TRIG.

tile_drive_h_pwm_input_stop

Studio
void tile_drive_h_pwm_input_stop(tile_t* tile)

Returns to internal-trigger mode (MODE=0). Same effect as tile_drive_h_audio_stop(); both modes share the IN/TRIG pin.

tile_drive_h_audio_start

Studio
void tile_drive_h_audio_start(tile_t* tile)

Sets MODE=4 (audio-to-vibe), N_PWM_ANALOG=1 (analog), and AC_COUPLE=1 (0.9 V common-mode bias on IN/TRIG). The chip envelope-detects the audio and drives haptic vibration at matching intensity.

  • The DRV2605 expects an AC-coupled line-level audio source (1.8 Vpp full-scale). Drive.H rev a does not include a series capacitor on pad 2 — users wanting audio-to-vibe must add their own external 1 µF AC-coupling cap between the audio source and pad 2.

tile_drive_h_audio_stop

Studio
void tile_drive_h_audio_stop(tile_t* tile)

Returns to internal-trigger mode (MODE=0) and clears the AC_COUPLE bit. Same physical effect as tile_drive_h_pwm_input_stop().

tile_drive_h_program_otp

uint8_t tile_drive_h_program_otp(tile_t* tile)

Writes the current contents of registers 0x16–0x1A (RATED_VOLTAGE, OD_CLAMP, A_CAL_COMP, A_CAL_BEMF, FEEDBACK_CTRL) to the DRV2605's nonvolatile OTP cells. After this, those values become the power-on defaults — the chip skips run-time calibration on subsequent boots. once per device. A bad programming run permanently mistunes the chip. NOT exposed to Studio by design. Pre-conditions: - Run tile_drive_h_calibrate() first and confirm pass. - VDD must be 4.0–4.4 V at the moment of programming (datasheet section 7.5.7). Lower VDD silently corrupts the cells. Returns 1 if the OTP_STATUS bit reads 1 after programming, 0 if the burn failed or OTP was already programmed.

Returns 1 on success, 0 on failure / already-programmed

tile_drive_h_get_otp_status

Studio
uint8_t tile_drive_h_get_otp_status(tile_t* tile)

Returns 1 if the chip's OTP cells have already been programmed (registers 0x16–0x1A boot from OTP rather than chip defaults).

Returns 1 if OTP is programmed, 0 if unprogrammed

Driver gaps · 3

Chip capabilities this driver doesn’t expose yet.

nicheOTP waveform burningThe DRV2605 can burn custom waveforms into one-time-programmable memory. This is implemented in firmware (tile_drive_h_program_otp()) but intentionally NOT exposed to Studio: it permanently and irreversibly modifies the chip. Driver-deferred by policy, not a hardware gap — call it from C if you really need it.
nicheMinor control bitsDriver-deferred: LRA_DRIVE_MODE (drive once or twice per cycle), SUPPLY_COMP_DIS (supply-voltage compensation), NG_THRESH (PWM / analog noise gate), BRAKE_STABILIZER, STARTUP_BOOST, BEMF_GAIN, LIBRARY_SEL.HI_Z (outputs high-impedance while idle) and MODE.DEV_RESET have no setter. Reachable only by editing the driver; none is hardware-gated.
nicheHardware EN controlHardware-gated in part: the DRV2605 EN pin is on pad 3 with a 100 kΩ pull-up to V+ (pad 10), so the driver cannot toggle it over I2C. Use the STANDBY bit (tile_drive_h_standby()) or drive pad 3 from a Core GPIO. With EN low the chip still ACKs its address but ignores reads and writes (SLOS825E §7.4.1.3), so init fails on the device-ID check; registers are kept.

Enums

drive_h_trigger_t

DRIVE_H_TRIG_INTERNAL
Internal: fired over I2C (the GO bit)
DRIVE_H_TRIG_EDGE
Rising edge on the TRIG pad
DRIVE_H_TRIG_LEVEL
Level on the TRIG pad

drive_h_brake_t

DRIVE_H_BRAKE_1X
1x
DRIVE_H_BRAKE_2X
2x
DRIVE_H_BRAKE_3X
3x
DRIVE_H_BRAKE_4X
4x
DRIVE_H_BRAKE_6X
6x
DRIVE_H_BRAKE_8X
8x
DRIVE_H_BRAKE_16X
16x
DRIVE_H_BRAKE_OFF
Braking off

drive_h_loop_gain_t

DRIVE_H_LOOP_GAIN_LOW
Low
DRIVE_H_LOOP_GAIN_MEDIUM
Medium
DRIVE_H_LOOP_GAIN_HIGH
High
DRIVE_H_LOOP_GAIN_VERY_HIGH
Very high

drive_h_atv_peak_t

Audio-to-vibe peak-detection time (ATV_CTRL ATH_PEAK_TIME[3:2]). Reset: 20 ms.

DRIVE_H_ATV_PEAK_10MS
10 ms
DRIVE_H_ATV_PEAK_20MS
20 ms
DRIVE_H_ATV_PEAK_30MS
30 ms
DRIVE_H_ATV_PEAK_40MS
40 ms

drive_h_atv_filter_t

Audio-to-vibe low-pass filter (ATV_CTRL ATH_FILTER[1:0]). Reset: 125 Hz.

DRIVE_H_ATV_LPF_100HZ
100 Hz
DRIVE_H_ATV_LPF_125HZ
125 Hz
DRIVE_H_ATV_LPF_150HZ
150 Hz
DRIVE_H_ATV_LPF_200HZ
200 Hz

drive_h_library_t

ROM waveform library, which also sets the actuator type (ERM vs LRA).

DRIVE_H_LIB_EMPTY
Empty library (silence).
DRIVE_H_LIB_ERM_A
ERM motor: TS2200 Library A (fixed open-loop overdrive).
DRIVE_H_LIB_ERM_B
ERM motor: TS2200 Library B (no overdrive).
DRIVE_H_LIB_ERM_C
ERM motor: TS2200 Library C (no overdrive).
DRIVE_H_LIB_ERM_D
ERM motor: TS2200 Library D (no overdrive).
DRIVE_H_LIB_ERM_E
ERM motor: TS2200 Library E (no overdrive).
DRIVE_H_LIB_LRA
LRA (coin / linear actuator): LRA library, auto-resonance.

Constants

TILE_DRIVE_H_VERSION_MAJOR4
TILE_DRIVE_H_VERSION_MINOR4
TILE_DRIVE_H_VERSION_PATCH0
DRV2605L_I2C_ADDR_DEFAULT0x5A
DRV2605L_STATUS_DEFAULT0x60Expected default STATUS register value (DEVICE_ID = 3).
DRV2605L_CONTROL2_DEFAULT0xF5
DRV2605L_STATUS_DEVICE_ID0xE0Bits 7:5 — device ID
DRV2605L_STATUS_DIAG_RESULT0x08Bit 3 — diagnostic result
DRV2605L_STATUS_OVER_TEMP0x02Bit 1 — over-temperature
DRV2605L_STATUS_OC_DETECT0x01Bit 0 — overcurrent detect
DRV2605L_MODE_INTERNAL_TRIG0x00Internal trigger (I2C GO)
DRV2605L_MODE_EXT_EDGE0x01External trigger, edge mode
DRV2605L_MODE_EXT_LEVEL0x02External trigger, level mode
DRV2605L_MODE_PWM_ANALOG0x03PWM or analog input on TRIG
DRV2605L_MODE_AUDIO0x04Audio-to-vibe on TRIG
DRV2605L_MODE_RTP0x05Real-time playback
DRV2605L_MODE_DIAGNOSTICS0x06Actuator diagnostics
DRV2605L_MODE_CALIBRATION0x07Auto-calibration
DRV2605L_MODE_STANDBY0x40STANDBY bit (bit 6)
DRV2605L_SEQ_MAX8