arduino-audio-driver
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Attributes | List of all members
WM8994 Class Reference

Header-only driver class for the WM8994 audio codec chip. More...

#include <WM8994.h>

Public Types

enum  AudioFrequency : uint32_t {
  AUDIO_FREQUENCY_192K = 192000 , AUDIO_FREQUENCY_96K = 96000 , AUDIO_FREQUENCY_48K = 48000 , AUDIO_FREQUENCY_44K = 44100 ,
  AUDIO_FREQUENCY_32K = 32000 , AUDIO_FREQUENCY_22K = 22050 , AUDIO_FREQUENCY_16K = 16000 , AUDIO_FREQUENCY_11K = 11025 ,
  AUDIO_FREQUENCY_8K = 8000
}
 

Public Member Functions

 WM8994 ()=default
 
void deinit ()
 Deinitializes the audio codec.
 
void dumpRegisters ()
 
uint32_t init (uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
 Initializes the audio codec and the control interface.
 
uint32_t pause ()
 Pauses playing on the audio codec.
 
uint32_t play (uint16_t *pBuffer, uint16_t Size)
 Start the audio Codec play feature.
 
uint32_t readId ()
 Get the WM8994 ID.
 
uint16_t readReg16 (uint16_t reg)
 Reads back a register value over I2C (see writeReg's note on byte order)
 
uint32_t reset ()
 Resets wm8994 registers.
 
uint32_t resume ()
 Resumes playing on the audio codec.
 
void setAddress (int addr)
 Defines the I2C device address.
 
uint32_t setFrequency (uint32_t AudioFreq)
 Sets new frequency.
 
uint32_t setMute (uint32_t Cmd)
 Enables or disables the mute feature on the audio codec.
 
uint32_t setOutputMode (uint8_t Output)
 Switch dynamically (while audio file is played) the output target (speaker or headphone).
 
uint32_t setVolume (uint8_t Volume)
 Sets higher or lower the codec volume level.
 
void setWire (i2c_bus_handle_t handle)
 Defines the I2C bus instance to be used.
 
uint32_t stop (uint32_t CodecPdwnMode)
 Stops audio Codec playing. It powers down the codec.
 
void writeReg (uint16_t reg, uint16_t value)
 
uint8_t writeReg16 (uint16_t Reg, uint16_t Value)
 Writes a single data value to a codec register.
 
uint8_t writeReg16Verified (uint16_t reg, uint16_t value, uint16_t mask=0xFFFF, uint8_t maxRetries=20, uint32_t retryDelayMs=25)
 Writes a register and confirms (by reading it back) that the value actually stuck, retrying with a short wait if not. Some WM8994 output-path registers (HP volume/mixer routing/AIF mute) can silently ignore writes for a while during headphone bring-up while the analog bias/DC-servo domain is still settling - and that settling time isn't reliably bounded by any fixed delay we've found (WSEQ_BUSY, register 0x111 bit 8, clears almost instantly and doesn't reflect it - observed empirically to vary run-to-run even with a generous fixed pre-delay). This self-adapts to however long the chip actually needs on a given boot instead of gambling on one guessed number.
 

Static Public Member Functions

static constexpr uint8_t volumeInConvert (uint8_t volume)
 
static constexpr uint8_t wm8994VolumeConvert (uint8_t volume)
 

Static Public Attributes

static constexpr int AUDIO_MUTE_OFF = 0
 
static constexpr int AUDIO_MUTE_ON = 1
 
static constexpr int AUDIO_PAUSE = 0
 
static constexpr int AUDIO_RESUME = 1
 
static constexpr int CODEC_PDWN_HW = 1
 
static constexpr int CODEC_PDWN_SW = 2
 
static constexpr uint8_t DEFAULT_VOLMAX = 0xFF
 
static constexpr uint8_t DEFAULT_VOLMIN = 0x00
 
static constexpr uint8_t DEFAULT_VOLSTEP = 0x04
 
static constexpr uint16_t INPUT_DEVICE_DIGITAL_MICROPHONE_1 = 0x0100
 
static constexpr uint16_t INPUT_DEVICE_DIGITAL_MICROPHONE_2 = 0x0200
 
static constexpr uint16_t INPUT_DEVICE_INPUT_LINE_1 = 0x0300
 
static constexpr uint16_t INPUT_DEVICE_INPUT_LINE_2 = 0x0400
 
static constexpr uint16_t OUTPUT_DEVICE_AUTO = 0x0004
 
static constexpr uint16_t OUTPUT_DEVICE_BOTH = 0x0003
 
static constexpr uint16_t OUTPUT_DEVICE_HEADPHONE = 0x0002
 
static constexpr uint16_t OUTPUT_DEVICE_SPEAKER = 0x0001
 
static constexpr int WM8994_ADDR = 0x1A
 
static constexpr uint16_t WM8994_CHIPID_ADDR = 0x00
 
static constexpr uint32_t WM8994_ID = 0x8994
 

Protected Attributes

int i2c_addr = WM8994_ADDR
 
i2c_bus_handle_t i2c_handle = nullptr
 
uint32_t input_enabled = 0
 
bool is_cold_startup = true
 
uint32_t output_enabled = 0
 

Detailed Description

Header-only driver class for the WM8994 audio codec chip.

Author
Phil Schatzmann

Member Enumeration Documentation

◆ AudioFrequency

enum AudioFrequency : uint32_t
Enumerator
AUDIO_FREQUENCY_192K 
AUDIO_FREQUENCY_96K 
AUDIO_FREQUENCY_48K 
AUDIO_FREQUENCY_44K 
AUDIO_FREQUENCY_32K 
AUDIO_FREQUENCY_22K 
AUDIO_FREQUENCY_16K 
AUDIO_FREQUENCY_11K 
AUDIO_FREQUENCY_8K 

Constructor & Destructor Documentation

◆ WM8994()

WM8994 ( )
default

Member Function Documentation

◆ deinit()

void deinit ( )
inline

Deinitializes the audio codec.

◆ dumpRegisters()

void dumpRegisters ( )
inline

Reads back and logs (AD_LOGI) every register this driver writes to - useful to confirm a register actually retained a value instead of trusting a successful I2C ACK as proof.

◆ init()

uint32_t init ( uint16_t  OutputInputDevice,
uint8_t  Volume,
uint32_t  AudioFreq 
)
inline

Initializes the audio codec and the control interface.

Parameters
OutputInputDevicecan be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH, OUTPUT_DEVICE_AUTO, INPUT_DEVICE_DIGITAL_MICROPHONE_1, INPUT_DEVICE_DIGITAL_MICROPHONE_2, INPUT_DEVICE_INPUT_LINE_1 or INPUT_DEVICE_INPUT_LINE_2.
VolumeInitial volume level (from 0 (Mute) to 100 (Max))
AudioFreqAudio Frequency
Return values
0if correct communication, else wrong communication

◆ pause()

uint32_t pause ( )
inline

Pauses playing on the audio codec.

◆ play()

uint32_t play ( uint16_t *  pBuffer,
uint16_t  Size 
)
inline

Start the audio Codec play feature.

Note
For this codec no Play options are required.
Return values
0if correct communication, else wrong communication

◆ readId()

uint32_t readId ( )
inline

Get the WM8994 ID.

◆ readReg16()

uint16_t readReg16 ( uint16_t  reg)
inline

Reads back a register value over I2C (see writeReg's note on byte order)

◆ reset()

uint32_t reset ( )
inline

Resets wm8994 registers.

◆ resume()

uint32_t resume ( )
inline

Resumes playing on the audio codec.

◆ setAddress()

void setAddress ( int  addr)
inline

Defines the I2C device address.

◆ setFrequency()

uint32_t setFrequency ( uint32_t  AudioFreq)
inline

Sets new frequency.

Parameters
AudioFreqAudio frequency used to play the audio stream.
Return values
0if correct communication, else wrong communication

◆ setMute()

uint32_t setMute ( uint32_t  Cmd)
inline

Enables or disables the mute feature on the audio codec.

Parameters
CmdAUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the mute mode.
Return values
0if correct communication, else wrong communication

◆ setOutputMode()

uint32_t setOutputMode ( uint8_t  Output)
inline

Switch dynamically (while audio file is played) the output target (speaker or headphone).

Parameters
Outputspecifies the audio output target: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO
Return values
0if correct communication, else wrong communication

◆ setVolume()

uint32_t setVolume ( uint8_t  Volume)
inline

Sets higher or lower the codec volume level.

Parameters
Volumea byte value from 0 to 255 (refer to codec registers description for more details).
Return values
0if correct communication, else wrong communication

◆ setWire()

void setWire ( i2c_bus_handle_t  handle)
inline

Defines the I2C bus instance to be used.

◆ stop()

uint32_t stop ( uint32_t  CodecPdwnMode)
inline

Stops audio Codec playing. It powers down the codec.

Parameters
CodecPdwnModeselects the power down mode.
  • CODEC_PDWN_SW: only mutes the audio codec. When resuming from this mode the codec keeps the previous initialization (no need to re-Initialize the codec registers).
  • CODEC_PDWN_HW: Physically power down the codec. When resuming from this mode, the codec is set to default configuration (user should re-Initialize the codec in order to play again the audio stream).
Return values
0if correct communication, else wrong communication

◆ volumeInConvert()

static constexpr uint8_t volumeInConvert ( uint8_t  volume)
inlinestaticconstexpr

◆ wm8994VolumeConvert()

static constexpr uint8_t wm8994VolumeConvert ( uint8_t  volume)
inlinestaticconstexpr

◆ writeReg()

void writeReg ( uint16_t  reg,
uint16_t  value 
)
inline

Writes a 16-bit register value over I2C. WM8994 expects both the register address and the data value big-endian (MSB first) on the wire - (uint8_t*)&reg/&value would reinterpret the host's in-memory byte order instead (little-endian on Cortex-M), silently sending everything byte-swapped. Confirmed live: reading back the chip ID returned 0x9489 instead of 0x8994 - exactly its bytes swapped.

◆ writeReg16()

uint8_t writeReg16 ( uint16_t  Reg,
uint16_t  Value 
)
inline

Writes a single data value to a codec register.

Parameters
RegRegister address
ValueData to be written
Return values
0on success, non-zero on verify failure

◆ writeReg16Verified()

uint8_t writeReg16Verified ( uint16_t  reg,
uint16_t  value,
uint16_t  mask = 0xFFFF,
uint8_t  maxRetries = 20,
uint32_t  retryDelayMs = 25 
)
inline

Writes a register and confirms (by reading it back) that the value actually stuck, retrying with a short wait if not. Some WM8994 output-path registers (HP volume/mixer routing/AIF mute) can silently ignore writes for a while during headphone bring-up while the analog bias/DC-servo domain is still settling - and that settling time isn't reliably bounded by any fixed delay we've found (WSEQ_BUSY, register 0x111 bit 8, clears almost instantly and doesn't reflect it - observed empirically to vary run-to-run even with a generous fixed pre-delay). This self-adapts to however long the chip actually needs on a given boot instead of gambling on one guessed number.

Parameters
maskOnly these bits are compared on readback - needed for registers with a self-clearing "apply now" strobe bit (e.g. HPOUT1_VU, bit 8 of 0x1C/0x1D) that always reads back 0 even on a fully successful write, which would otherwise burn the whole retry budget on every call regardless of success.
Return values
0on success, non-zero if the value never stuck within retries.

Member Data Documentation

◆ AUDIO_MUTE_OFF

constexpr int AUDIO_MUTE_OFF = 0
staticconstexpr

◆ AUDIO_MUTE_ON

constexpr int AUDIO_MUTE_ON = 1
staticconstexpr

◆ AUDIO_PAUSE

constexpr int AUDIO_PAUSE = 0
staticconstexpr

◆ AUDIO_RESUME

constexpr int AUDIO_RESUME = 1
staticconstexpr

◆ CODEC_PDWN_HW

constexpr int CODEC_PDWN_HW = 1
staticconstexpr

◆ CODEC_PDWN_SW

constexpr int CODEC_PDWN_SW = 2
staticconstexpr

◆ DEFAULT_VOLMAX

constexpr uint8_t DEFAULT_VOLMAX = 0xFF
staticconstexpr

◆ DEFAULT_VOLMIN

constexpr uint8_t DEFAULT_VOLMIN = 0x00
staticconstexpr

◆ DEFAULT_VOLSTEP

constexpr uint8_t DEFAULT_VOLSTEP = 0x04
staticconstexpr

◆ i2c_addr

int i2c_addr = WM8994_ADDR
protected

◆ i2c_handle

i2c_bus_handle_t i2c_handle = nullptr
protected

◆ INPUT_DEVICE_DIGITAL_MICROPHONE_1

constexpr uint16_t INPUT_DEVICE_DIGITAL_MICROPHONE_1 = 0x0100
staticconstexpr

◆ INPUT_DEVICE_DIGITAL_MICROPHONE_2

constexpr uint16_t INPUT_DEVICE_DIGITAL_MICROPHONE_2 = 0x0200
staticconstexpr

◆ INPUT_DEVICE_INPUT_LINE_1

constexpr uint16_t INPUT_DEVICE_INPUT_LINE_1 = 0x0300
staticconstexpr

◆ INPUT_DEVICE_INPUT_LINE_2

constexpr uint16_t INPUT_DEVICE_INPUT_LINE_2 = 0x0400
staticconstexpr

◆ input_enabled

uint32_t input_enabled = 0
protected

◆ is_cold_startup

bool is_cold_startup = true
protected

First-ever headphone power-up needs the longer (cold) sequencer delay; see the register 0x110 write in init() below.

◆ OUTPUT_DEVICE_AUTO

constexpr uint16_t OUTPUT_DEVICE_AUTO = 0x0004
staticconstexpr

◆ OUTPUT_DEVICE_BOTH

constexpr uint16_t OUTPUT_DEVICE_BOTH = 0x0003
staticconstexpr

◆ OUTPUT_DEVICE_HEADPHONE

constexpr uint16_t OUTPUT_DEVICE_HEADPHONE = 0x0002
staticconstexpr

◆ OUTPUT_DEVICE_SPEAKER

constexpr uint16_t OUTPUT_DEVICE_SPEAKER = 0x0001
staticconstexpr

◆ output_enabled

uint32_t output_enabled = 0
protected

◆ WM8994_ADDR

constexpr int WM8994_ADDR = 0x1A
staticconstexpr

◆ WM8994_CHIPID_ADDR

constexpr uint16_t WM8994_CHIPID_ADDR = 0x00
staticconstexpr

◆ WM8994_ID

constexpr uint32_t WM8994_ID = 0x8994
staticconstexpr

The documentation for this class was generated from the following file: