BERGSONNE

Drive.A.2

Dual-channel audio output driver for the Drive.A.2 tile (DAC63202W smart DAC + 2x TPA2028D1 Class-D amplifiers). Supports I2C and SPI bus access via tiles_pal_t.

(DAC63202W smart DAC + 2x TPA2028D1 Class-D amplifiers). Supports I2C and SPI bus access via tiles_pal_t.

Examples

Quick start (I2C — DAC + amplifiers)

  #include "core_tiles.h"  // provides core_tiles_pal()

  tile_t dac;
  tiles_pal_t *hal = core_tiles_pal(&core_i2c1);
  tile_drive_a_2_init(hal, 0, &dac, NULL);
  if (tile_is_ready(&dac)) {
      tile_drive_a_2_set(&dac, 0, 2048);       // Ch 0 mid-scale
      tile_drive_a_2_amp_set_gain(&dac, 12);    // +12 dB both amps
  }

Quick start (SPI — DAC only, no amplifier control)

  #include "core_tiles.h"

  tile_t dac;
  tiles_pal_t *hal = core_tiles_pal(&core_spi1);
  tile_drive_a_2_init(hal, 0, &dac, NULL);  // instance = CS index
  tile_drive_a_2_set_mv(&dac, 0, 1500);     // 1.5 V on channel 0

API reference

Initialization

tile_drive_a_2_find

uint8_t tile_drive_a_2_find(tiles_pal_t *hal, uint8_t instance)

Check whether a DAC63202W is present on the bus.

hal
Platform HAL handle
instance
Instance index (see mapping table)

Returns 1 if device ACKs (I2C) or responds to WHO_AM_I (SPI), 0 otherwise

tile_drive_a_2_init

void tile_drive_a_2_init(tiles_pal_t *hal, uint8_t instance, tile_t *tile, const drive_a_2_cfg_t *cfg)

Resets the DAC, verifies DEVICE-ID, powers up both VOUT channels, configures gain, and (in I2C mode) probes and configures the amplifiers.

hal
Platform HAL handle (see core_tiles.h).
instance
Instance index (I2C: address variant, SPI: CS index)
tile
Pointer to tile handle (populated by this function)
cfg
Optional config, or NULL for defaults (1x VDD, 6 dB amp)

Lifecycle

tile_drive_a_2_sleep

Studio
void tile_drive_a_2_sleep(tile_t *tile)

Powers down both DAC VOUT channels (Hi-Z) and puts the amplifiers into software shutdown.

tile_drive_a_2_wake

Studio
void tile_drive_a_2_wake(tile_t *tile)

Powers up both DAC VOUT channels and re-enables the amplifiers. Restores cached gain settings.

tile_drive_a_2_reset

void tile_drive_a_2_reset(tile_t *tile)

All DAC registers return to defaults. tile->state becomes TILE_STATE_NONE; call init() again to reconfigure.

Runtime

tile_drive_a_2_set

Studio
void tile_drive_a_2_set(tile_t *tile, uint8_t channel, uint16_t value)

Set a DAC channel output by raw 12-bit code (0–4095).

tile
Tile handle
channel
0 or 1
value
12-bit DAC code (0 = 0V, 4095 = full-scale)

tile_drive_a_2_set_mv

Studio
void tile_drive_a_2_set_mv(tile_t *tile, uint8_t channel, uint16_t mv)

Computes the DAC code from the cached reference voltage and gain.

tile
Tile handle
channel
0 or 1
mv
Desired output in millivolts

tile_drive_a_2_get

Studio
uint16_t tile_drive_a_2_get(tile_t *tile, uint8_t channel)

Read back the current DAC code for a channel.

tile
Tile handle
channel
0 or 1

Returns 12-bit DAC code currently loaded

tile_drive_a_2_set_waveform

Studio
void tile_drive_a_2_set_waveform(tile_t *tile, uint8_t channel, drive_a_2_wave_t wave)

Sets FUNC-CONFIG-X in DAC-X-FUNC-CONFIG. The waveform oscillates between DAC-X-MARGIN-LOW and DAC-X-MARGIN-HIGH at the configured slew rate. Call start_waveform() to begin output.

tile
Tile handle
channel
0 or 1
wave
Waveform shape

tile_drive_a_2_start_waveform

Studio
void tile_drive_a_2_start_waveform(tile_t *tile, uint8_t channel)

Start waveform generation on a channel.

tile
Tile handle
channel
0 or 1

tile_drive_a_2_stop_waveform

Studio
void tile_drive_a_2_stop_waveform(tile_t *tile, uint8_t channel)

Stop waveform generation on a channel.

tile
Tile handle
channel
0 or 1

tile_drive_a_2_amp_set_gain

Studio
void tile_drive_a_2_amp_set_gain(tile_t *tile, int8_t gain_db)

Both TPA2028D1 amplifiers share I2C address 0x58, so this write affects both channels simultaneously. No-op in SPI mode.

tile
Tile handle
gain_db
Gain in dB (-28 to +30). Clamped if out of range.

tile_drive_a_2_amp_get_gain

Studio
int8_t tile_drive_a_2_amp_get_gain(tile_t *tile)

Read the current amplifier fixed gain.

tile
Tile handle

Returns Gain in dB (-28 to +30), or 0 if amp not available

tile_drive_a_2_amp_enable

Studio
void tile_drive_a_2_amp_enable(tile_t *tile)

No-op in SPI mode.

tile_drive_a_2_amp_disable

Studio
void tile_drive_a_2_amp_disable(tile_t *tile)

No-op in SPI mode.

tile_drive_a_2_amp_set_agc

Studio
void tile_drive_a_2_amp_set_agc(tile_t *tile, const drive_a_2_agc_cfg_t *cfg)

Writes all AGC registers (attack, release, hold, fixed gain, limiter, compression, noise gate, max gain). Affects both amps. No-op in SPI mode.

tile
Tile handle
cfg
AGC configuration

tile_drive_a_2_amp_read_status

Studio
uint8_t tile_drive_a_2_amp_read_status(tile_t *tile)

Check bit 3 (FAULT) for short-circuit and bit 2 (Thermal) for over-temperature. Write 0 to the respective bit to clear.

tile
Tile handle

Returns Raw register 0x01 value, or 0 if amp not available

tile_drive_a_2_read_status

Studio
uint16_t tile_drive_a_2_read_status(tile_t *tile)

Contains DEVICE-ID, VERSION-ID, NVM CRC status, and DAC busy flags.

tile
Tile handle

Returns 16-bit GENERAL-STATUS value

tile_drive_a_2_play_tone

Studio
void tile_drive_a_2_play_tone(tile_t *tile, drive_a_2_channel_t channel, uint16_t freq_hz, uint16_t ms)

Configures DAC margins for full-scale swing, sets a sine waveform, and uses the on-chip parametric generator together with a software-tuned slew rate / code step to approximate `freq_hz` (audio range 50–5000 Hz works well; the chip's function generator is rough at the high end). The amplifier is unmuted for the duration of the tone and restored to its prior mute state on return.

tile
Initialised tile handle
channel
DRIVE_A_2_CH_LEFT, _RIGHT, or _BOTH
freq_hz
Tone frequency in Hz (1–20000 useful range)
ms
Duration in milliseconds
  • Blocks for `ms` milliseconds via `hal->delay_ms`.

tile_drive_a_2_play_silence

Studio
void tile_drive_a_2_play_silence(tile_t *tile, drive_a_2_channel_t channel, uint16_t ms)

Stops any active waveform on `channel`, parks the DAC code at mid-scale (= zero differential at the amp input), and blocks for `ms` milliseconds. Useful to insert a precise gap between tones without toggling the amp shutdown — the amp stays alive but draws minimal idle current with no signal.

tile
Initialised tile handle
channel
DRIVE_A_2_CH_LEFT, _RIGHT, or _BOTH
ms
Duration in milliseconds
  • Blocks for `ms` milliseconds via `hal->delay_ms`.

tile_drive_a_2_play_chirp

Studio
void tile_drive_a_2_play_chirp(tile_t *tile, drive_a_2_channel_t channel, uint16_t start_hz, uint16_t end_hz, uint16_t ms)

Software sine-LUT chirp delivered through `set` (raw DAC code) at ~8 kHz update rate. Frequency advances linearly across `ms`. For ascending sweeps pass start < end; for descending, start > end. The amp is unmuted for the duration and restored to its prior mute state on return.

tile
Initialised tile handle
channel
DRIVE_A_2_CH_LEFT, _RIGHT, or _BOTH
start_hz
Initial frequency in Hz
end_hz
Final frequency in Hz
ms
Sweep duration in milliseconds
  • Blocks for `ms` milliseconds via `hal->delay_ms`.

tile_drive_a_2_set_volume_pct

Studio
void tile_drive_a_2_set_volume_pct(tile_t *tile, drive_a_2_channel_t channel, uint8_t pct)

Linear mapping from `pct` to the TPA2028D1's full -28 dB to +30 dB programmable range: gain_db = -28 + (pct × 58) / 100 0 % → -28 dB (near-mute), 50 % → +1 dB, 100 % → +30 dB. The mapping is intentionally linear-in-dB rather than perceptually weighted; for finer dB control use @ref tile_drive_a_2_amp_set_gain directly. Because both amps share an I²C address, the channel argument is accepted for symmetry with the rest of the tier-2 API but the write lands on both physical amps.

tile
Initialised tile handle
channel
DRIVE_A_2_CH_LEFT, _RIGHT, or _BOTH (advisory)
pct
0–100 percent (clamped if out of range)

tile_drive_a_2_mute

Studio
void tile_drive_a_2_mute(tile_t *tile, drive_a_2_channel_t channel)

Stashes the current fixed-gain register so a later @ref tile_drive_a_2_unmute restores it byte-exact, then puts the amp pair into software shutdown (SWS=1). Both physical amps mute regardless of `channel` (shared I²C address).

tile
Initialised tile handle
channel
DRIVE_A_2_CH_LEFT, _RIGHT, or _BOTH (advisory)

tile_drive_a_2_unmute

Studio
void tile_drive_a_2_unmute(tile_t *tile, drive_a_2_channel_t channel)

Re-applies the gain that was active at the time of @ref tile_drive_a_2_mute and clears software shutdown (SWS=0). If the channel was never muted by this driver instance the call still wakes the amp using whatever gain is currently in the register.

tile
Initialised tile handle
channel
DRIVE_A_2_CH_LEFT, _RIGHT, or _BOTH (advisory)

Config

tile_drive_a_2_set_gain

Studio
void tile_drive_a_2_set_gain(tile_t *tile, uint8_t channel, drive_a_2_gain_t gain)

Automatically enables the internal reference when an internal-reference gain is selected, and updates the cached Vref for set_mv() calculations.

tile
Tile handle
channel
0 or 1
gain
One of the drive_a_2_gain_t values

tile_drive_a_2_set_slew_rate

Studio
void tile_drive_a_2_set_slew_rate(tile_t *tile, uint8_t channel, drive_a_2_slew_t slew)

Programs SLEW-RATE-X bits[3:0] in DAC-X-FUNC-CONFIG. Affects both slewed direct-output updates and the on-chip function generator's frequency. The default is no-slew — outputs settle as fast as the analog stage allows. Use a slower slew to soften zero-crossings for capacitive / inductive loads, or to dial in a target waveform frequency together with set_code_step() and set_margins().

tile
Tile handle
channel
0 or 1
slew
Slew-rate code (drive_a_2_slew_t value 0–15)

tile_drive_a_2_set_code_step

Studio
void tile_drive_a_2_set_code_step(tile_t *tile, uint8_t channel, drive_a_2_step_t step)

Programs CODE-STEP-X bits[6:4] in DAC-X-FUNC-CONFIG. Larger steps give faster ramps / higher waveform frequencies at the cost of coarser resolution.

tile
Tile handle
channel
0 or 1
step
Code-step code (drive_a_2_step_t value 0–7)

tile_drive_a_2_set_margins

Studio
void tile_drive_a_2_set_margins(tile_t *tile, uint8_t channel, uint16_t low, uint16_t high)

Writes DAC-X-MARGIN-HIGH and DAC-X-MARGIN-LOW. The function generator oscillates between these levels, and they also serve as the thresholds for the chip's window / hysteresis comparator modes. Values are 12-bit DAC codes; high must be > low.

tile
Tile handle
channel
0 or 1
low
12-bit DAC code for the lower bound (0–4095)
high
12-bit DAC code for the upper bound (0–4095)

tile_drive_a_2_set_phase

Studio
void tile_drive_a_2_set_phase(tile_t *tile, uint8_t channel, drive_a_2_phase_t phase)

Programs PHASE-SEL-X bits[12:11] in DAC-X-FUNC-CONFIG. Take effect the next time start_waveform() is called. Use phase = 90° on one channel and 0° on the other to drive a quadrature pair.

tile
Tile handle
channel
0 or 1
phase
Phase offset (drive_a_2_phase_t)

tile_drive_a_2_set_waveform_params

Studio
void tile_drive_a_2_set_waveform_params(tile_t *tile, uint8_t channel, drive_a_2_wave_t wave, drive_a_2_step_t step, drive_a_2_slew_t slew)

Convenience helper that sets up the waveform shape, full-scale margins (0 → 4095), code step, and slew rate in one call. The resulting frequency is approximately: f_triangle = 1 / (2 × time_step × ceil((margin_high − margin_low) / code_step)) f_sawtooth = 1 / ( time_step × ceil((margin_high − margin_low) / code_step + 1)) Call start_waveform() to begin output once configured. For fine-grained control, call set_margins() / set_code_step() / set_slew_rate() / set_waveform() / set_phase() individually.

tile
Tile handle
channel
0 or 1
wave
Waveform shape (drive_a_2_wave_t)
step
Code-step (drive_a_2_step_t)
slew
Time per step (drive_a_2_slew_t)

tile_drive_a_2_nvm_save

Studio
void tile_drive_a_2_nvm_save(tile_t *tile)

Triggers NVM-PROG in COMMON-TRIGGER. The DAC's user-programmable registers (gain, margins, slew, waveform shape, COMMON-CONFIG, etc. — see datasheet "highlighted gray" rows) are committed to non-volatile storage and become the new power-on defaults. Blocking: holds the bus busy for the NVM write cycle. Limited write endurance — TI specs ~1000 cycles. Use only for one-time factory tuning, not for runtime configuration storage.

tile
Tile handle

tile_drive_a_2_nvm_reload

Studio
void tile_drive_a_2_nvm_reload(tile_t *tile)

Triggers NVM-RELOAD in COMMON-TRIGGER. Restores the saved power-on configuration without a full reset — equivalent to the load that happens automatically on POR. Blocks until the reload completes. Note that this resets the cached gain / vref state in the driver: call set_gain() afterwards if you need set_mv() to work correctly.

tile
Tile handle

Advanced

tile_drive_a_2_read_reg

Studio
uint16_t tile_drive_a_2_read_reg(tile_t *tile, uint8_t reg)

Escape hatch for advanced users wanting to touch registers the driver doesn't expose. Caller is responsible for not bricking the chip — most useful registers have typed setters above.

tile
Tile handle
reg
Register address (7-bit)

Returns 16-bit register value

tile_drive_a_2_write_reg

Studio
void tile_drive_a_2_write_reg(tile_t *tile, uint8_t reg, uint16_t value)

Write any 16-bit DAC63202W register.

tile
Tile handle
reg
Register address (7-bit)
value
16-bit value to write (big-endian on the wire)

Driver gaps · 2

Chip capabilities this driver doesn’t expose yet.

advancedDAC PWM-output mode (FBx pins)The DAC63202W FB0 / FB1 pins (package balls B2 / C2) can be configured as comparator / PWM outputs for driving external power-stage gates. On the Drive.A.2 tile these pins are tied to the on-board TPA2028D1 amplifier inputs (closed-loop voltage- output feedback) and are NOT routed to any tile-connector pad — so even if the driver enabled PWM mode, no Core GPIO could observe or use the output. Closing this gap requires a tile hardware revision that breaks FBx out to a pad.
nichePer-amp independent controlThe tile carries 2× TPA2028D1 amps wired to a single shared I²C bus, and the TPA2028D1 has a fixed factory I²C address (0x58) — any write at 0x58 is acknowledged by both amps simultaneously. Independent left / right gain, AGC, or shutdown therefore can't be achieved in software; closing this gap requires either an I²C-mux on the tile or amp ICs with selectable addresses.

Enums

drive_a_2_gain_t

DAC output voltage gain setting.

DRIVE_A_2_GAIN_1X_EXT
1x, external VREF pin
DRIVE_A_2_GAIN_1X_VDD
1x, VDD as reference (default)
DRIVE_A_2_GAIN_1P5X_INT
1.5x, internal 1.21V → 0–1.815V
DRIVE_A_2_GAIN_2X_INT
2x, internal 1.21V → 0–2.42V
DRIVE_A_2_GAIN_3X_INT
3x, internal 1.21V → 0–3.63V
DRIVE_A_2_GAIN_4X_INT
4x, internal 1.21V → 0–4.84V

drive_a_2_wave_t

Built-in waveform shapes for the DAC function generator.

DRIVE_A_2_WAVE_TRIANGLE
Triangular wave
DRIVE_A_2_WAVE_SAWTOOTH
Sawtooth (ramp up)
DRIVE_A_2_WAVE_INV_SAW
Inverse sawtooth (ramp down)
DRIVE_A_2_WAVE_SINE
Sine wave
DRIVE_A_2_WAVE_OFF
Function generation disabled

drive_a_2_slew_t

Slew-rate control (time per code step) for the DAC.

DRIVE_A_2_SLEW_NONE
No slew (default) — immediate update
DRIVE_A_2_SLEW_4_US
DRIVE_A_2_SLEW_8_US
DRIVE_A_2_SLEW_12_US
DRIVE_A_2_SLEW_18_US
DRIVE_A_2_SLEW_27_US
DRIVE_A_2_SLEW_41_US
DRIVE_A_2_SLEW_61_US
DRIVE_A_2_SLEW_91_US
DRIVE_A_2_SLEW_137_US
DRIVE_A_2_SLEW_239_US
DRIVE_A_2_SLEW_419_US
DRIVE_A_2_SLEW_733_US
DRIVE_A_2_SLEW_1282_US
DRIVE_A_2_SLEW_2564_US
DRIVE_A_2_SLEW_5128_US

drive_a_2_step_t

Code-step size (LSBs per slewed update tick) for the DAC.

DRIVE_A_2_STEP_1_LSB
1 LSB per step (default — finest)
DRIVE_A_2_STEP_2_LSB
DRIVE_A_2_STEP_3_LSB
DRIVE_A_2_STEP_4_LSB
DRIVE_A_2_STEP_6_LSB
DRIVE_A_2_STEP_8_LSB
DRIVE_A_2_STEP_16_LSB
DRIVE_A_2_STEP_32_LSB

drive_a_2_phase_t

Phase offset for the function generator (sine / triangle).

DRIVE_A_2_PHASE_0
0° (default)
DRIVE_A_2_PHASE_120
120°
DRIVE_A_2_PHASE_240
240°
DRIVE_A_2_PHASE_90
90° (quadrature)

drive_a_2_comp_t

Amplifier compression ratio.

DRIVE_A_2_COMP_1_1
1:1 — compression off
DRIVE_A_2_COMP_2_1
2:1
DRIVE_A_2_COMP_4_1
4:1 (default)
DRIVE_A_2_COMP_8_1
8:1

drive_a_2_channel_t

Logical channel selector for the tier-2 runtime helpers (`play_tone`, `set_volume_pct`, `mute`, …).

DRIVE_A_2_CH_LEFT
DAC0 / left amp logically
DRIVE_A_2_CH_RIGHT
DAC1 / right amp logically
DRIVE_A_2_CH_BOTH
Both DAC channels (amp writes still hit both)

Constants

TILE_DRIVE_A_2_VERSION_MAJOR3
TILE_DRIVE_A_2_VERSION_MINOR1
TILE_DRIVE_A_2_VERSION_PATCH0
DAC63202W_I2C_ADDR_DEFAULT0x49A0 → VDD (default)
DAC63202W_I2C_ADDR_GND0x48A0 → GND
DAC63202W_I2C_ADDR_SDA0x4AA0 → SDA
DAC63202W_I2C_ADDR_SCL0x4BA0 → SCL
TPA2028D1_I2C_ADDR0x58Fixed (both amps)