|
arduino-audio-driver
|
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 |
Header-only driver class for the WM8994 audio codec chip.
| enum AudioFrequency : uint32_t |
|
default |
|
inline |
Deinitializes the audio codec.
|
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.
|
inline |
Initializes the audio codec and the control interface.
| OutputInputDevice | can 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. |
| Volume | Initial volume level (from 0 (Mute) to 100 (Max)) |
| AudioFreq | Audio Frequency |
| 0 | if correct communication, else wrong communication |
|
inline |
Pauses playing on the audio codec.
|
inline |
Start the audio Codec play feature.
| 0 | if correct communication, else wrong communication |
|
inline |
Get the WM8994 ID.
|
inline |
Reads back a register value over I2C (see writeReg's note on byte order)
|
inline |
Resets wm8994 registers.
|
inline |
Resumes playing on the audio codec.
|
inline |
Defines the I2C device address.
|
inline |
Sets new frequency.
| AudioFreq | Audio frequency used to play the audio stream. |
| 0 | if correct communication, else wrong communication |
|
inline |
Enables or disables the mute feature on the audio codec.
| Cmd | AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the mute mode. |
| 0 | if correct communication, else wrong communication |
|
inline |
Switch dynamically (while audio file is played) the output target (speaker or headphone).
| Output | specifies the audio output target: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO |
| 0 | if correct communication, else wrong communication |
|
inline |
Sets higher or lower the codec volume level.
| Volume | a byte value from 0 to 255 (refer to codec registers description for more details). |
| 0 | if correct communication, else wrong communication |
|
inline |
Defines the I2C bus instance to be used.
|
inline |
Stops audio Codec playing. It powers down the codec.
| CodecPdwnMode | selects the power down mode.
|
| 0 | if correct communication, else wrong communication |
|
inlinestaticconstexpr |
|
inlinestaticconstexpr |
|
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*)®/&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.
|
inline |
Writes a single data value to a codec register.
| Reg | Register address |
| Value | Data to be written |
| 0 | on success, non-zero on verify failure |
|
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.
| mask | Only 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. |
| 0 | on success, non-zero if the value never stuck within retries. |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
protected |
|
protected |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
protected |
|
protected |
First-ever headphone power-up needs the longer (cold) sequencer delay; see the register 0x110 write in init() below.
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |
|
protected |
|
staticconstexpr |
|
staticconstexpr |
|
staticconstexpr |