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 0API 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiouint16_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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studioint8_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
Studiovoid tile_drive_a_2_amp_enable(tile_t *tile)No-op in SPI mode.
tile_drive_a_2_amp_disable
Studiovoid tile_drive_a_2_amp_disable(tile_t *tile)No-op in SPI mode.
tile_drive_a_2_amp_set_agc
Studiovoid 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
Studiouint8_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
Studiouint16_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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiovoid 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
Studiouint16_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
Studiovoid 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.
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_MAJOR | 3 | |
| TILE_DRIVE_A_2_VERSION_MINOR | 1 | |
| TILE_DRIVE_A_2_VERSION_PATCH | 0 | |
| DAC63202W_I2C_ADDR_DEFAULT | 0x49 | A0 → VDD (default) |
| DAC63202W_I2C_ADDR_GND | 0x48 | A0 → GND |
| DAC63202W_I2C_ADDR_SDA | 0x4A | A0 → SDA |
| DAC63202W_I2C_ADDR_SCL | 0x4B | A0 → SCL |
| TPA2028D1_I2C_ADDR | 0x58 | Fixed (both amps) |

