115 uint32_t
init(uint16_t OutputInputDevice, uint8_t Volume,
116 uint32_t AudioFreq) {
117 uint32_t counter = 0;
118 uint16_t output_device = OutputInputDevice & 0xFF;
119 uint16_t input_device = OutputInputDevice & 0xFF00;
120 uint16_t power_mgnt_reg_1 = 0;
138 if (output_device > 0) {
140 switch (output_device) {
219 if (input_device > 0) {
221 switch (input_device) {
330 if (output_device > 0)
385 power_mgnt_reg_1 |= 0x0303 | 0x3003;
386 counter +=
writeReg16(0x01, power_mgnt_reg_1);
454 if (input_device > 0)
459 power_mgnt_reg_1 |= 0x0013;
460 counter +=
writeReg16(0x01, power_mgnt_reg_1);
470 power_mgnt_reg_1 |= 0x0003;
471 counter +=
writeReg16(0x01, power_mgnt_reg_1);
510 static const struct {
514 {0x00,
"SW Reset / Chip ID"},
515 {0x01,
"Power Management (1)"},
516 {0x02,
"Power Management (2)"},
517 {0x03,
"Power Management (3)"},
518 {0x04,
"Power Management (4)"},
519 {0x05,
"Power Management (5)"},
520 {0x18,
"Left Line Input 1&2 Volume"},
521 {0x1A,
"Right Line Input 1&2 Volume"},
522 {0x1C,
"Left Output Volume"},
523 {0x1D,
"Right Output Volume"},
524 {0x22,
"Left OPGA Volume"},
525 {0x23,
"Right OPGA Volume"},
526 {0x26,
"Speaker Volume Left"},
527 {0x27,
"Speaker Volume Right"},
528 {0x28,
"Input Mixer (2)"},
529 {0x29,
"Input Mixer (3)"},
530 {0x2A,
"Input Mixer (4)"},
531 {0x2D,
"Output Mixer (1)"},
532 {0x2E,
"Output Mixer (2)"},
533 {0x36,
"Output Mixer (5)"},
534 {0x39,
"Antipop (1)"},
535 {0x51,
"Class W (1)"},
536 {0x54,
"DC Servo (1)"},
537 {0x60,
"Analogue HP (1)"},
538 {0x4C,
"Charge Pump (1)"},
539 {0x102,
"Clocking (1) - errata"},
540 {0x110,
"Write Sequencer Ctrl (1)"},
541 {0x200,
"AIF1 Clocking (1)"},
542 {0x208,
"Clocking (1)"},
543 {0x210,
"AIF1 Rate"},
544 {0x300,
"AIF1 Control (1)"},
545 {0x302,
"AIF1 Master/Slave"},
546 {0x410,
"AIF1 ADC1 Filters"},
547 {0x411,
"AIF1 ADC2 Filters"},
548 {0x420,
"AIF1 DAC1 Filters (1)"},
549 {0x422,
"AIF1 DAC2 Filters (1)"},
550 {0x440,
"AIF1 DRC1 (1)"},
551 {0x450,
"AIF1 DRC2 (1)"},
552 {0x601,
"AIF1 DAC1 Left Mixer Routing"},
553 {0x602,
"AIF1 DAC1 Right Mixer Routing"},
554 {0x604,
"AIF1 DAC2 Left Mixer Routing"},
555 {0x605,
"AIF1 DAC2 Right Mixer Routing"},
556 {0x606,
"DAC1 Left Mixer Routing"},
557 {0x607,
"DAC1 Right Mixer Routing"},
558 {0x608,
"DAC2 Left Mixer Routing"},
559 {0x609,
"DAC2 Right Mixer Routing"},
560 {0x610,
"DAC1 Left Volume"},
561 {0x611,
"DAC1 Right Volume"},
562 {0x612,
"DAC2 Left Volume"},
563 {0x613,
"DAC2 Right Volume"},
564 {0x620,
"Oversampling"},
566 {0x817,
"Clocking - errata"},
568 AD_LOGI(
"WM8994 register dump (%d registers):",
569 (
int)(
sizeof(regs) /
sizeof(regs[0])));
570 for (
auto &r : regs) {
580 uint32_t
play(uint16_t *pBuffer, uint16_t Size) {
581 uint32_t counter = 0;
592 uint32_t counter = 0;
606 uint32_t counter = 0;
627 uint32_t
stop(uint32_t CodecPdwnMode) {
628 uint32_t counter = 0;
669 uint32_t counter = 0;
671 AD_LOGD(
"setVolume: Volume=%d convertedvol=0x%X output_enabled=%d", Volume,
676 if (convertedvol > 0x3E) {
692 }
else if (Volume == 0) {
700 counter +=
writeReg16(0x1C, convertedvol | 0x140);
703 counter +=
writeReg16(0x1D, convertedvol | 0x140);
706 counter +=
writeReg16(0x26, convertedvol | 0x140);
709 counter +=
writeReg16(0x27, convertedvol | 0x140);
718 counter +=
writeReg16(0x400, convertedvol | 0x100);
721 counter +=
writeReg16(0x401, convertedvol | 0x100);
724 counter +=
writeReg16(0x404, convertedvol | 0x100);
727 counter +=
writeReg16(0x405, convertedvol | 0x100);
739 uint32_t counter = 0;
769 uint32_t counter = 0;
853 uint32_t counter = 0;
902 uint32_t counter = 0;
918 uint8_t reg_be[2] = {(uint8_t)(reg >> 8), (uint8_t)(reg & 0xFF)};
919 uint8_t value_be[2] = {(uint8_t)(value >> 8), (uint8_t)(value & 0xFF)};
926 uint8_t reg_be[2] = {(uint8_t)(reg >> 8), (uint8_t)(reg & 0xFF)};
927 uint8_t value_be[2] = {0, 0};
930 return ((uint16_t)value_be[0] << 8) | value_be[1];
944#ifdef VERIFY_WRITTENDATA
946 result = (
readReg16(Reg) == Value) ? 0 : 1;
971 uint16_t mask = 0xFFFF, uint8_t maxRetries = 20,
972 uint32_t retryDelayMs = 25) {
973 for (uint8_t attempt = 0; attempt < maxRetries; attempt++) {
975 if ((
readReg16(reg) & mask) == (value & mask)) {
977 AD_LOGD(
"writeReg16Verified: reg=0x%X stuck after %d retries", reg,
985 "writeReg16Verified: reg=0x%X never retained 0x%X after %d retries",
986 reg, value, maxRetries);
991 return volume > 100 ? 100 : (uint8_t)((volume * 63) / 100);
994 return volume >= 100 ? 239 : (uint8_t)((volume * 240) / 100);
#define AD_LOGD(...)
Definition Logger.h:12
#define AD_LOGI(...)
Definition Logger.h:13
#define AD_LOGE(...)
Definition Logger.h:15
Header-only driver class for the WM8994 audio codec chip.
Definition WM8994.h:61
static constexpr uint16_t INPUT_DEVICE_INPUT_LINE_2
Definition WM8994.h:81
static constexpr uint8_t wm8994VolumeConvert(uint8_t volume)
Definition WM8994.h:990
uint16_t readReg16(uint16_t reg)
Reads back a register value over I2C (see writeReg's note on byte order)
Definition WM8994.h:925
static constexpr uint16_t OUTPUT_DEVICE_HEADPHONE
Definition WM8994.h:75
static constexpr int CODEC_PDWN_HW
Definition WM8994.h:87
AudioFrequency
Definition WM8994.h:63
@ AUDIO_FREQUENCY_22K
Definition WM8994.h:69
@ AUDIO_FREQUENCY_32K
Definition WM8994.h:68
@ AUDIO_FREQUENCY_96K
Definition WM8994.h:65
@ AUDIO_FREQUENCY_44K
Definition WM8994.h:67
@ AUDIO_FREQUENCY_16K
Definition WM8994.h:70
@ AUDIO_FREQUENCY_8K
Definition WM8994.h:72
@ AUDIO_FREQUENCY_192K
Definition WM8994.h:64
@ AUDIO_FREQUENCY_11K
Definition WM8994.h:71
@ AUDIO_FREQUENCY_48K
Definition WM8994.h:66
uint32_t init(uint16_t OutputInputDevice, uint8_t Volume, uint32_t AudioFreq)
Initializes the audio codec and the control interface.
Definition WM8994.h:115
uint8_t writeReg16(uint16_t Reg, uint16_t Value)
Writes a single data value to a codec register.
Definition WM8994.h:939
uint32_t output_enabled
Definition WM8994.h:1000
void setAddress(int addr)
Defines the I2C device address.
Definition WM8994.h:101
static constexpr uint16_t OUTPUT_DEVICE_BOTH
Definition WM8994.h:76
uint32_t setFrequency(uint32_t AudioFreq)
Sets new frequency.
Definition WM8994.h:852
uint32_t setOutputMode(uint8_t Output)
Switch dynamically (while audio file is played) the output target (speaker or headphone).
Definition WM8994.h:768
uint32_t readId()
Get the WM8994 ID.
Definition WM8994.h:504
uint32_t resume()
Resumes playing on the audio codec.
Definition WM8994.h:605
int i2c_addr
Definition WM8994.h:999
static constexpr uint8_t DEFAULT_VOLMIN
Definition WM8994.h:82
bool is_cold_startup
Definition WM8994.h:1004
static constexpr uint8_t DEFAULT_VOLSTEP
Definition WM8994.h:84
static constexpr uint16_t INPUT_DEVICE_DIGITAL_MICROPHONE_2
Definition WM8994.h:79
static constexpr uint16_t INPUT_DEVICE_INPUT_LINE_1
Definition WM8994.h:80
uint32_t setVolume(uint8_t Volume)
Sets higher or lower the codec volume level.
Definition WM8994.h:668
uint32_t pause()
Pauses playing on the audio codec.
Definition WM8994.h:591
static constexpr uint16_t INPUT_DEVICE_DIGITAL_MICROPHONE_1
Definition WM8994.h:78
void setWire(i2c_bus_handle_t handle)
Defines the I2C bus instance to be used.
Definition WM8994.h:98
static constexpr uint16_t OUTPUT_DEVICE_SPEAKER
Definition WM8994.h:74
static constexpr uint8_t volumeInConvert(uint8_t volume)
Definition WM8994.h:993
static constexpr int AUDIO_MUTE_ON
Definition WM8994.h:89
void deinit()
Deinitializes the audio codec.
Definition WM8994.h:499
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,...
Definition WM8994.h:970
static constexpr uint16_t OUTPUT_DEVICE_AUTO
Definition WM8994.h:77
void dumpRegisters()
Definition WM8994.h:509
uint32_t reset()
Resets wm8994 registers.
Definition WM8994.h:901
uint32_t setMute(uint32_t Cmd)
Enables or disables the mute feature on the audio codec.
Definition WM8994.h:738
i2c_bus_handle_t i2c_handle
Definition WM8994.h:998
static constexpr int AUDIO_RESUME
Definition WM8994.h:86
static constexpr int CODEC_PDWN_SW
Definition WM8994.h:88
static constexpr int WM8994_ADDR
Definition WM8994.h:93
uint32_t play(uint16_t *pBuffer, uint16_t Size)
Start the audio Codec play feature.
Definition WM8994.h:580
static constexpr uint8_t DEFAULT_VOLMAX
Definition WM8994.h:83
uint32_t stop(uint32_t CodecPdwnMode)
Stops audio Codec playing. It powers down the codec.
Definition WM8994.h:627
void writeReg(uint16_t reg, uint16_t value)
Definition WM8994.h:917
static constexpr int AUDIO_PAUSE
Definition WM8994.h:85
uint32_t input_enabled
Definition WM8994.h:1001
static constexpr int AUDIO_MUTE_OFF
Definition WM8994.h:90
static constexpr uint32_t WM8994_ID
Definition WM8994.h:91
static constexpr uint16_t WM8994_CHIPID_ADDR
Definition WM8994.h:92
Namespace for audio driver components.
Definition AudioBoard.h:5
void delayMs(unsigned long ms)
Definition API_Delay.h:19
void * i2c_bus_handle_t
Definition DriverCommon.h:155