BERGSONNE

Drive.DC.H

H-bridge DC motor driver for the Drive.DC.H tile (rev a).

Embeds the TI DRV8214, a full H-bridge motor driver with integrated current sensing, stall detection, and voltage/speed regulation.

Datasheet

Examples

Quick start

  #include "core_tiles.h"

  tile_t motor;
  tile_drive_dc_h_init(core_tiles_pal(&core_i2c3), 0, &motor, NULL);
  if (tile_is_ready(&motor)) {
      tile_drive_dc_h_forward(&motor);   // drive forward
      core_delay_ms(2000);
      tile_drive_dc_h_brake(&motor);     // slow-decay brake
  }

API reference

Initialization

tile_drive_dc_h_find

uint8_t tile_drive_dc_h_find(tiles_pal_t* hal, uint8_t instance)

Check whether a DRV8214 is present on the I2C bus.

hal
Platform HAL handle
instance
Instance index (0-8, see mapping table)

Returns 1 if device ACKs, 0 otherwise

tile_drive_dc_h_init

void tile_drive_dc_h_init(tiles_pal_t* hal, uint8_t instance, tile_t* tile, const drive_dc_h_cfg_t *cfg)

Verifies device presence, configures I2C bridge control in PWM mode, sets regulation parameters, and enables the output stage in coast state (motor not spinning). Call forward() or reverse() to start the motor.

hal
Platform HAL handle
instance
Instance index (0-8, see mapping table)
tile
Pointer to tile handle (populated by this function)
cfg
Optional config, or NULL for defaults

Lifecycle

tile_drive_dc_h_sleep

Studio
void tile_drive_dc_h_sleep(tile_t* tile)

Clears EN_OUT in CONFIG0. The device remains on the I2C bus and registers are accessible, but no current flows through the motor. OVP protection remains active in sleep.

tile
Pointer to tile handle

tile_drive_dc_h_wake

Studio
void tile_drive_dc_h_wake(tile_t* tile)

Sets EN_OUT in CONFIG0. The bridge returns to the last commanded state (coast/brake/forward/reverse).

tile
Pointer to tile handle

Runtime

tile_drive_dc_h_forward

Studio
void tile_drive_dc_h_forward(tile_t* tile)

Drive motor forward (OUT1=H, OUT2=L).

tile
Pointer to tile handle

tile_drive_dc_h_reverse

Studio
void tile_drive_dc_h_reverse(tile_t* tile)

Drive motor in reverse (OUT1=L, OUT2=H).

tile
Pointer to tile handle

tile_drive_dc_h_brake

Studio
void tile_drive_dc_h_brake(tile_t* tile)

Motor is actively held. Current recirculates through the low-side FETs, providing strong braking force.

tile
Pointer to tile handle

tile_drive_dc_h_coast

Studio
void tile_drive_dc_h_coast(tile_t* tile)

Motor freewheels. No braking force is applied. This is the initial state after init().

tile
Pointer to tile handle

tile_drive_dc_h_set_target

Studio
void tile_drive_dc_h_set_target(tile_t* tile, uint8_t value)

In voltage mode: sets target motor terminal voltage. With VM_GAIN_SEL=0: value * 15700/255 mV (61.6 mV/bit) With VM_GAIN_SEL=1: value * 3920/255 mV (15.4 mV/bit) In speed mode: sets target ripple speed. Target speed = value * W_SCALE rad/s.

tile
Pointer to tile handle
value
Target setpoint (0-255)

tile_drive_dc_h_get_fault

Studio
uint8_t tile_drive_dc_h_get_fault(tile_t* tile)

Contains FAULT[7], STALL[5], OCP[4], OVP[3], TSD[2], NPOR[1], CNT_DONE[0]. Use the DRV8214_FAULT_* masks to decode individual bits.

tile
Pointer to tile handle

Returns Raw fault byte (0 = no faults)

tile_drive_dc_h_clear_fault

Studio
void tile_drive_dc_h_clear_fault(tile_t* tile)

Sets CLR_FLT in CONFIG0. Clears FAULT, OCP, OVP, TSD, and NPOR bits. The CLR_FLT bit is self-clearing.

tile
Pointer to tile handle

tile_drive_dc_h_is_stalled

Studio
uint8_t tile_drive_dc_h_is_stalled(tile_t* tile)

Check if a motor stall condition is active.

tile
Pointer to tile handle

Returns 1 if STALL bit is set, 0 otherwise

tile_drive_dc_h_get_voltage_mv

Studio
uint16_t tile_drive_dc_h_get_voltage_mv(tile_t* tile)

Reads the VMTR register. The reading is proportional to the voltage across OUT1-OUT2 terminals. Valid while driving.

tile
Pointer to tile handle

Returns Motor voltage in mV (e.g. 3300 = 3.3 V)

tile_drive_dc_h_get_current_ma

Studio
uint16_t tile_drive_dc_h_get_current_ma(tile_t* tile)

Reads the IMTR register and converts using the current CS_GAIN_SEL setting. The reading reflects the current flowing through the low-side FETs during drive or brake.

tile
Pointer to tile handle

Returns Motor current in mA

tile_drive_dc_h_get_speed

Studio
uint8_t tile_drive_dc_h_get_speed(tile_t* tile)

Returns the raw SPEED register from the ripple counting algorithm. Value is proportional to motor speed but requires motor-specific calibration for RPM conversion.

tile
Pointer to tile handle

Returns Raw speed estimate (0-255)

tile_drive_dc_h_get_speed_rpm

Studio
uint32_t tile_drive_dc_h_get_speed_rpm(tile_t* tile)

Converts the chip's ripple-speed estimate to shaft RPM using the live W_SCALE setting and the configured ripples-per-rev, making it the exact inverse of the set_speed_rpm() target conversion. Accuracy depends on the motor profile (see set_motor_params()); without INV_R/KMC calibration the estimate is approximate.

tile
Pointer to tile handle

Returns Estimated shaft speed in revolutions per minute

tile_drive_dc_h_get_ripple_count

Studio
uint16_t tile_drive_dc_h_get_ripple_count(tile_t* tile)

Returns the total number of commutation ripples counted since the last clear. Proportional to rotor position.

tile
Pointer to tile handle

Returns Ripple count (0-65535)

tile_drive_dc_h_clear_ripple_count

Studio
void tile_drive_dc_h_clear_ripple_count(tile_t* tile)

Sets CLR_CNT in CONFIG0. Also clears CNT_DONE flag. The CLR_CNT bit is self-clearing.

tile
Pointer to tile handle

tile_drive_dc_h_set_speed_rpm

Studio
void tile_drive_dc_h_set_speed_rpm(tile_t* tile, uint32_t rpm, drive_dc_h_direction_t direction)

Switches the chip into speed-regulation mode (REG_CTRL=10b), writes WSET_VSET so the internal PI loop targets `rpm` for the given motor, and engages the bridge in `direction`. Returns immediately — the chip ramps the motor to the target speed autonomously and is_running() / get_speed() report progress.

tile
Initialised tile handle
rpm
Target shaft speed in revolutions per minute
direction
DRIVE_DC_H_DIR_FORWARD or DRIVE_DC_H_DIR_REVERSE
  • The driver picks the finest W_SCALE (24/40/64/128) whose 8-bit WSET range still reaches the requested speed, so low targets get the best granularity the chip offers: the RPM step is `60 × W_SCALE / ripples_per_rev`, e.g. 120 RPM at ripples_per_rev=12 for targets below ~30 600 RPM. WSET is clamped at 0xFF for targets beyond the coarsest scale, and a nonzero request never rounds down to a stop.
  • The conversion depends on the ripples-per-rev value from the init config (or set_motor_params()), and closed-loop accuracy depends on the ripple-counter calibration (INV_R, KMC) from `motor_mohm` / `kv_uv_per_rpm`. If those aren't set, speed regulation falls back to chip defaults and the RPM target is approximate. Provide a full motor profile — at init or via set_motor_params() — for accurate low-RPM control.

tile_drive_dc_h_move_distance

Studio
void tile_drive_dc_h_move_distance(tile_t* tile, uint16_t ripples, drive_dc_h_direction_t direction)

Closed-loop step: programs RC_THR for the requested ripple count, clears the ripple counter, engages the bridge in `direction`, then polls until either CNT_DONE fires or the motor stalls. On completion the bridge is put into slow-decay brake — the motor is actively held at the new position, not coasting.

tile
Initialised tile handle
ripples
Number of ripples to advance (0–65472)
direction
DRIVE_DC_H_DIR_FORWARD or DRIVE_DC_H_DIR_REVERSE
  • This call BLOCKS until the move completes or the motor stalls. Worst-case wall-time depends on motor speed + load; budget accordingly. There is no built-in timeout beyond the chip's own stall detector — use a separate watchdog or @ref tile_drive_dc_h_wait_for_stop with a timeout if you need a hard upper bound.
  • On completion the bridge is left in BRAKE (slow decay, both low-side FETs on). Call @ref tile_drive_dc_h_coast afterwards if you'd rather let the motor freewheel.
  • Ripple counts are coarse (integer commutation ticks, not encoder counts). Resolution = 1/ripples_per_rev of a revolution — typically 1/12 turn. Don't expect sub-degree positioning.

tile_drive_dc_h_is_running

Studio
uint8_t tile_drive_dc_h_is_running(tile_t* tile)

Returns 1 when the bridge is in forward or reverse drive (any non-zero, non-brake combination of IN1/IN2 in I²C bridge mode). Returns 0 when braking, coasting, sleeping, in pad-control mode, or not yet ready.

tile
Initialised tile handle

Returns 1 if driving, 0 otherwise

tile_drive_dc_h_wait_for_stop

Studio
uint8_t tile_drive_dc_h_wait_for_stop(tile_t* tile, uint32_t timeout_ms)

Polls the 16-bit ripple counter at ~10 ms cadence. Returns 1 when two successive samples (≥30 ms apart) report the same count — i.e., the rotor is mechanically stationary. Returns 0 if `timeout_ms` elapses first. Useful after @ref tile_drive_dc_h_brake when you want to know the motor has actually settled rather than just "the bridge has been commanded to brake".

tile
Initialised tile handle
timeout_ms
Maximum time to wait, in milliseconds

Returns 1 if the rotor settled before timeout, 0 on timeout

Config

tile_drive_dc_h_set_control_mode

Studio
void tile_drive_dc_h_set_control_mode(tile_t* tile, drive_dc_h_control_mode_t mode)

In I²C mode (default after init), forward/reverse/brake/coast control the bridge. In either pad-control mode, the chip ignores I²C bridge bits and tracks pads 2/3 directly: - PAD_PHEN — pad 2 = EN (PWM), pad 3 = PH (direction) - PAD_IN1IN2 — pad 2 = IN1, pad 3 = IN2 (independent half-bridges) Monitoring (voltage, current, fault, ripple count) keeps working over I²C in all modes. Switching to a pad mode disables I²C bridge calls (forward/reverse/etc) — they'll log an error and no-op.

tile
Pointer to tile handle
mode
Bridge control source (DRIVE_DC_H_CTRL_*)

tile_drive_dc_h_set_regulation_mode

Studio
void tile_drive_dc_h_set_regulation_mode(tile_t* tile, drive_dc_h_reg_mode_t mode)

Writes REG_CTRL bits in REG_CTRL0. After switching, set_target() is interpreted in the new loop's units (voltage code, speed code, etc.). Speed mode requires ripple counting to be enabled — the driver automatically sets EN_RC=1 when SPEED is selected.

tile
Pointer to tile handle
mode
Regulation mode (DRIVE_DC_H_REG_*)

tile_drive_dc_h_set_current_regulation_mode

Studio
void tile_drive_dc_h_set_current_regulation_mode(tile_t* tile, drive_dc_h_imode_t mode)

Selects when the chip's internal current loop folds back to keep motor current under the ITRIP threshold. ITRIP itself is set by the combination of CS_GAIN_SEL (set_current_sense_gain) and the internal 500 mV VREF (INT_VREF=1, fixed by this driver since the external VREF pin isn't routed on the Drive.DC.H tile).

tile
Pointer to tile handle
mode
Current regulation mode (DRIVE_DC_H_IMODE_*)

tile_drive_dc_h_set_current_sense_gain

Studio
void tile_drive_dc_h_set_current_sense_gain(tile_t* tile, uint8_t code)

Programs CS_GAIN_SEL[2:0] in RC_CTRL0. Lower max-current ranges give finer current resolution but lower R_DS(on) headroom; higher ranges support larger motors but coarser get_current_ma() steps. Codes: 0 = 4 A, 1 = 2 A, 2 = 1 A, 3 = 0.5 A, 4 = 0.25 A, 5 = 0.125 A Also affects ITRIP when current regulation is enabled.

tile
Pointer to tile handle
code
CS_GAIN_SEL code (0-5)

tile_drive_dc_h_set_stall_enabled

Studio
void tile_drive_dc_h_set_stall_enabled(tile_t* tile, uint8_t enabled)

Toggles EN_STALL in CONFIG0. When disabled, the STALL bit in the fault register won't latch and is_stalled() always returns 0. Useful while tuning the inrush time for a new motor.

tile
Pointer to tile handle
enabled
1 = stall detection on, 0 = off

tile_drive_dc_h_set_inrush_time_ms

Studio
void tile_drive_dc_h_set_inrush_time_ms(tile_t* tile, uint16_t ms)

Programs CONFIG1/CONFIG2 with a 16-bit count of 102.4 µs ticks, giving up to ~6.7 s. During the blanking window after a drive command, the stall detector ignores motor current — necessary because real motors draw several × steady-state during startup. Tune for the slowest motor you want to drive.

tile
Pointer to tile handle
ms
Inrush blanking time in milliseconds (0 - 6710)

tile_drive_dc_h_set_stall_recovery

Studio
void tile_drive_dc_h_set_stall_recovery(tile_t* tile, drive_dc_h_stall_recovery_t mode)

In LATCH mode, hitting a stall turns the bridge off until either clear_fault() is called or the chip is power-cycled. In REPORT mode the chip flags STALL but keeps driving — useful for haptics or actuators that legitimately stall against an end-stop.

tile
Pointer to tile handle
mode
DRIVE_DC_H_STALL_LATCH or DRIVE_DC_H_STALL_REPORT

tile_drive_dc_h_set_ripple_threshold

Studio
void tile_drive_dc_h_set_ripple_threshold(tile_t* tile, uint16_t count)

The chip raises CNT_DONE when the running ripple count reaches (count × scale). Useful for "rotate N counts then stop" patterns: watch the CNT_DONE bit in get_fault(), then call coast(). Internal threshold is 10-bit; the driver picks the smallest scale (×2, ×8, ×16, or ×64) that fits `count`.

tile
Pointer to tile handle
count
Threshold count (0 - 65472, larger = coarser scale)

tile_drive_dc_h_set_ripple_filter_gain

Studio
void tile_drive_dc_h_set_ripple_filter_gain(tile_t* tile, uint8_t code)

Programs FLT_GAIN_SEL[1:0] in RC_CTRL0. Scales the magnitude of detected ripples before the counter — increase if get_ripple_count() undercounts, decrease if it spuriously counts noise. Codes: 0 = ×2, 1 = ×4 (default), 2 = ×8, 3 = ×16

tile
Pointer to tile handle
code
FLT_GAIN_SEL code (0-3)

tile_drive_dc_h_set_motor_params

Studio
void tile_drive_dc_h_set_motor_params(tile_t* tile, uint16_t motor_mohm, uint16_t ripples_per_rev, uint16_t kv_uv_per_rpm)

Writes the DRV8214's ripple-counter calibration registers (INV_R, KMC and their scale fields) from physical motor parameters, and caches ripples-per-rev for the set_speed_rpm()/get_speed_rpm() conversions. Equivalent to supplying `motor_mohm`, `ripples_per_rev` and `kv_uv_per_rpm` in the init config — use this when the driver was initialised with defaults (e.g. from Studio) and you want accurate closed-loop speed control. Example (RS PRO 834-7644, direct drive): motor_mohm=6000, ripples_per_rev=12, kv_uv_per_rpm=187. chip defaults (no-op for INV_R/KMC). (poles × brush pairs; common: 3, 5, 6, 7, 12). 0 = default (12); clamped to 255. motor: 100-2000). 0 = skip KMC tuning.

tile
Initialised tile handle
motor_mohm
Winding resistance in milliohms. 0 = leave
ripples_per_rev
Commutation ripples per shaft revolution
kv_uv_per_rpm
Back-EMF constant in µV/RPM (typical small

Advanced

gapnSLEEP pin (hardware-gated)Chip's nSLEEP pin (~100 nA quiescent in sleep, ~1.3 mA active) is not routed to any tile pad in the Drive.DC.H rev-a layout (verify in kiln/definitions/Drive-DC-H-a.json — pads 1–10 are GND, EN/IN1, PH/IN2, I²C.CLK, I²C.DAT, NPROP, OUT1, OUT2, VM, V+; nSLEEP is strapped active on the PCB). sleep()/wake() only toggle the I²C-side EN_OUT bit; the chip itself can't reach its true quiescent floor. Closing this gap requires a tile hardware revision that routes nSLEEP to a connector pad.

Driver gaps · 1

Chip capabilities this driver doesn’t expose yet.

nicheAddress selection (factory variants)The DRV8214 derives its 7-bit I²C address from tri-level pins A0/A1, but the Drive.DC.H tile straps these to fixed values per factory variant: A30 (0x30), A31 (0x31), A33 (0x33), A34 (0x34 default). Address is chip-gated at order time, not runtime- settable. The 9-entry instance table in this driver covers the full chip address space, but only those four straps are sold — pick a tile variant per Drive.DC.H tile sharing a bus.

Enums

drive_dc_h_direction_t

Drive direction for the tier-2 helpers.

DRIVE_DC_H_DIR_FORWARD
OUT1=H, OUT2=L (matches forward()).
DRIVE_DC_H_DIR_REVERSE
OUT1=L, OUT2=H (matches reverse()).

Constants

TILE_DRIVE_DC_H_VERSION_MAJOR4
TILE_DRIVE_DC_H_VERSION_MINOR2
TILE_DRIVE_DC_H_VERSION_PATCH0
DRV8214_I2C_ADDR_DEFAULT0x34
DRV8214_CONFIG3_DEFAULT0x63Expected CONFIG3 register value at power-on.
DRV8214_FAULT_FAULT0x80Bit 7 — any fault active
DRV8214_FAULT_STALL0x20Bit 5 — motor stall
DRV8214_FAULT_OCP0x10Bit 4 — overcurrent
DRV8214_FAULT_OVP0x08Bit 3 — overvoltage
DRV8214_FAULT_TSD0x04Bit 2 — thermal shutdown
DRV8214_FAULT_NPOR0x02Bit 1 — power-on reset
DRV8214_FAULT_CNT_DONE0x01Bit 0 — ripple count done
DRIVE_DC_H_MODE_VOLTAGE0
DRIVE_DC_H_MODE_SPEED1
DRIVE_DC_H_MODE_RIPPLE_COUNT2
DRIVE_DC_H_MODE_PAD_PHEN3
DRIVE_DC_H_MODE_PAD_IN1IN24