arduino-audio-driver
Loading...
Searching...
No Matches
WM8731.h
Go to the documentation of this file.
1
8#pragma once
9
11#include "DriverCommon.h"
12#include "Platforms/API_I2C.h"
13#include "stdbool.h"
14
15namespace audio_driver {
16
18constexpr int WM8731_ADDR = 0x1A;
19
25class WM8731 {
26 public:
28 enum class Reg : uint8_t {
29 LeftLineIn = 0x00,
30 RightLineIn = 0x01,
31 LeftHeadphoneOut = 0x02,
32 RightHeadphoneOut = 0x03,
33 AnaloguePath = 0x04,
34 DigitalPath = 0x05,
35 PowerDown = 0x06,
36 Format = 0x07,
37 SamplingControl = 0x08,
38 Active = 0x09,
39 Reset = 0x0F,
40 };
41
43 enum LineIn : uint16_t {
45 LineInMute = 1 << 7,
46 LineInBoth = 1 << 8,
47 };
48
50 enum HeadphoneOut : uint16_t {
53 HeadphoneBoth = 1 << 8,
54 };
55
57 enum AnaloguePath : uint16_t {
58 MicBoost = 1 << 0,
59 MuteMic = 1 << 1,
61 Bypass = 1 << 3,
62 DacSelect = 1 << 4,
63 SideTone = 1 << 5,
65 };
66
68 enum DigitalPath : uint16_t {
71 DeEmphasis32k = 0x1 << 1,
72 DeEmphasis44_1k = 0x2 << 1,
73 DeEmphasis48k = 0x3 << 1,
74 DacSoftMute = 1 << 3,
76 };
77
79 enum PowerDown : uint16_t {
81 MicPowerDown = 1 << 1,
82 AdcPowerDown = 1 << 2,
83 DacPowerDown = 1 << 3,
87 PowerOff = 1 << 7,
88 };
89
91 enum Format : uint16_t {
94 FormatI2S = 0x2,
95 FormatDsp = 0x3,
97 WordLength16Bit = 0x0 << 2,
98 WordLength20Bit = 0x1 << 2,
99 WordLength24Bit = 0x2 << 2,
100 WordLength32Bit = 0x3 << 2,
101 WordLengthMask = 0x3 << 2,
103 LrSwap = 1 << 5,
104 MasterMode = 1 << 6,
106 };
107
109 enum SamplingControl : uint16_t {
110 UsbMode = 1 << 0,
112 SampleRateMask = 0xF << 2,
113 ClkInDiv2 = 1 << 6,
114 ClkOutDiv2 = 1 << 7,
115 };
116
118 enum ActiveControl : uint16_t {
119 Active = 1 << 0,
120 };
121
122 WM8731() = default;
123
125 void setWire(i2c_bus_handle_t handle) { i2c_handle = handle; }
126
128 void setAddress(int addr) { i2c_addr = addr; }
129
132 if (initialized) {
133 AD_LOGW("The WM8731 has already been initialized");
134 return RESULT_OK;
135 }
136 initialized = true;
137
138 // reset all registers to their default values
139 reset();
140
141 // power up the needed sections, power down the rest
143
144 // analogue path: select dac output, line input, no bypass, no mic
146 if (cfg->input_device != ADC_INPUT_NONE &&
148 cfg->input_device != ADC_INPUT_ALL) {
150 }
152
153 // digital path: enable high pass filter, no de-emphasis, unmuted
154 digital_path = 0;
156
157 // default headphone / line out volume (0dB)
158 setVoiceVolume(70);
159
160 // input volume (0dB)
163
164 // configure the digital audio interface and sample rate
166
167 // activate the digital core
168 setActive(true);
169 return RESULT_OK;
170 }
171
174 setActive(false);
175 // power down everything (standby)
177 initialized = false;
178 return RESULT_OK;
179 }
180
182 error_t ctrlStateActive(codec_mode_t mode, bool ctrl_state_active) {
183 return ctrl_state_active ? resume() : standby();
184 }
185
188 uint16_t format = 0;
189 switch (iface->fmt) {
190 case I2S_LEFT:
191 format |= FormatLeftJustified;
192 break;
193 case I2S_RIGHT:
194 format |= FormatRightJustified;
195 break;
196 case I2S_DSP:
197 format |= FormatDsp;
198 break;
199 case I2S_NORMAL:
200 default:
201 format |= FormatI2S;
202 break;
203 }
204
205 switch (iface->bits) {
207 format |= WordLength20Bit;
208 break;
210 format |= WordLength24Bit;
211 break;
213 format |= WordLength32Bit;
214 break;
216 default:
217 format |= WordLength16Bit;
218 break;
219 }
220
221 if (iface->mode == MODE_MASTER) {
222 format |= MasterMode;
223 }
224
225 writeReg(Reg::Format, format);
227 return RESULT_OK;
228 }
229
231 error_t setVoiceMute(bool enable) {
232 if (enable) {
234 } else {
235 digital_path &= ~DacSoftMute;
236 }
238 }
239
245 if (volume < 0) volume = 0;
246 if (volume > 100) volume = 100;
247 voice_volume = volume;
248 // register range 0x30 (-73dB) .. 0x7F (+6dB), 0..0x2F is also mute
249 uint16_t reg_value = (volume == 0)
250 ? 0x00
251 : 0x30 + ((volume * (0x7F - 0x30)) / 100);
252 error_t ret =
254 ret |= writeReg(Reg::RightHeadphoneOut, reg_value | HeadphoneBoth);
255 return ret;
256 }
257
259 error_t getVoiceVolume(int* volume) {
260 *volume = voice_volume;
261 return RESULT_OK;
262 }
263
265 error_t writeReg(Reg reg_addr, uint16_t value) {
266 uint16_t word =
267 ((static_cast<uint8_t>(reg_addr) & 0x7F) << 9) | (value & 0x1FF);
268 uint8_t data[2] = {(uint8_t)((word >> 8) & 0xFF), (uint8_t)(word & 0xFF)};
269 return i2c_bus_write_bytes(i2c_handle, i2c_addr, &data[0], 1, &data[1], 1);
270 }
271
274
276 error_t setActive(bool active) {
277 active_control = active ? Active : 0;
279 }
280
287
290
291 protected:
294 bool initialized = false;
295 uint16_t analogue_path = 0;
296 uint16_t digital_path = 0;
297 uint16_t power_down = 0;
298 uint16_t active_control = 0;
299 int voice_volume = 70;
300
303 output_device_t output_device) {
305 if (input_device == ADC_INPUT_NONE) {
307 }
308 if (output_device == DAC_OUTPUT_NONE) {
310 }
312 }
313
321 switch (rate) {
322 case RATE_8K:
323 return 0x06;
324 case RATE_32K:
325 return 0x18;
326 case RATE_44K:
327 return 0x20;
328 case RATE_88K:
329 return 0x28;
330 case RATE_96K:
331 return 0x08;
332 case RATE_48K:
333 default:
334 return 0x00;
335 }
336 }
337};
338
339} // namespace audio_driver
#define RESULT_OK
Definition DriverCommon.h:74
#define AD_LOGW(...)
Definition Logger.h:14
Header-only driver class for the WM8731 codec chip.
Definition WM8731.h:25
uint16_t active_control
Definition WM8731.h:298
error_t ctrlStateActive(codec_mode_t mode, bool ctrl_state_active)
Activate or standby the codec.
Definition WM8731.h:182
error_t resume(void)
Restores the power configuration that was active before standby.
Definition WM8731.h:289
void setAddress(int addr)
Defines the I2C device address.
Definition WM8731.h:128
error_t init(codec_config_t *cfg)
Initialize the WM8731 codec chip.
Definition WM8731.h:131
error_t deinit(void)
Deinitialize the WM8731 codec chip.
Definition WM8731.h:173
error_t setVoiceMute(bool enable)
Mute / unmute the DAC output.
Definition WM8731.h:231
uint16_t getSamplingControl(samplerate_t rate)
Determine the SamplingControl register value for the requested sample rate.
Definition WM8731.h:320
SamplingControl
Bit flags for the Sampling Control register.
Definition WM8731.h:109
@ UsbMode
Definition WM8731.h:110
@ BaseOversamplingRate
Definition WM8731.h:111
@ ClkInDiv2
Definition WM8731.h:113
@ SampleRateMask
Definition WM8731.h:112
@ ClkOutDiv2
Definition WM8731.h:114
int i2c_addr
Definition WM8731.h:293
error_t configI2S(codec_mode_t mode, I2SDefinition *iface)
Configure the digital audio interface format and sample rate.
Definition WM8731.h:187
error_t reset()
Reset all registers to their default values.
Definition WM8731.h:273
AnaloguePath
Bit flags for the Analogue Audio Path Control register.
Definition WM8731.h:57
@ Bypass
Definition WM8731.h:61
@ DacSelect
Definition WM8731.h:62
@ SideTone
Definition WM8731.h:63
@ MuteMic
Definition WM8731.h:59
@ SideToneAttenuationMask
Definition WM8731.h:64
@ InputSelectMic
Definition WM8731.h:60
@ MicBoost
Definition WM8731.h:58
DigitalPath
Bit flags for the Digital Audio Path Control register.
Definition WM8731.h:68
@ DeEmphasis32k
Definition WM8731.h:71
@ DeEmphasis48k
Definition WM8731.h:73
@ DacSoftMute
Definition WM8731.h:74
@ HighPassOnReset
Definition WM8731.h:75
@ DeEmphasisDisable
Definition WM8731.h:70
@ DeEmphasis44_1k
Definition WM8731.h:72
@ AdcHighPassDisable
Definition WM8731.h:69
Reg
WM8731 register addresses.
Definition WM8731.h:28
Format
Bit flags / values for the Digital Audio Interface Format register.
Definition WM8731.h:91
@ WordLength32Bit
Definition WM8731.h:100
@ WordLength24Bit
Definition WM8731.h:99
@ WordLength20Bit
Definition WM8731.h:98
@ LrSwapPolarity
Definition WM8731.h:102
@ FormatI2S
Definition WM8731.h:94
@ FormatRightJustified
Definition WM8731.h:92
@ FormatLeftJustified
Definition WM8731.h:93
@ FormatMask
Definition WM8731.h:96
@ FormatDsp
Definition WM8731.h:95
@ WordLengthMask
Definition WM8731.h:101
@ BitClockInvert
Definition WM8731.h:105
@ LrSwap
Definition WM8731.h:103
@ MasterMode
Definition WM8731.h:104
@ WordLength16Bit
Definition WM8731.h:97
error_t writeReg(Reg reg_addr, uint16_t value)
Write a value to a WM8731 register.
Definition WM8731.h:265
void setWire(i2c_bus_handle_t handle)
Defines the I2C bus instance to be used.
Definition WM8731.h:125
ActiveControl
Bit flags for the Active Control register.
Definition WM8731.h:118
@ Active
Definition WM8731.h:119
error_t setActive(bool active)
Activates / deactivates the digital audio interface.
Definition WM8731.h:276
i2c_bus_handle_t i2c_handle
Definition WM8731.h:292
error_t updatePower(input_device_t input_device, output_device_t output_device)
Powers up the input/output sections that are actually used.
Definition WM8731.h:302
LineIn
Bit flags for the Left/Right Line In registers.
Definition WM8731.h:43
@ LineInBoth
Definition WM8731.h:46
@ LineInVolMask
Definition WM8731.h:44
@ LineInMute
Definition WM8731.h:45
uint16_t analogue_path
Definition WM8731.h:295
error_t setVoiceVolume(int volume)
Set the headphone / line output volume.
Definition WM8731.h:244
HeadphoneOut
Bit flags for the Left/Right Headphone Out registers.
Definition WM8731.h:50
@ HeadphoneZeroCross
Definition WM8731.h:52
@ HeadphoneVolMask
Definition WM8731.h:51
@ HeadphoneBoth
Definition WM8731.h:53
int voice_volume
Definition WM8731.h:299
PowerDown
Bit flags for the Power Down Control register.
Definition WM8731.h:79
@ PowerOff
Definition WM8731.h:87
@ DacPowerDown
Definition WM8731.h:83
@ MicPowerDown
Definition WM8731.h:81
@ ClockOutPowerDown
Definition WM8731.h:86
@ AdcPowerDown
Definition WM8731.h:82
@ OutputPowerDown
Definition WM8731.h:84
@ LineInPowerDown
Definition WM8731.h:80
@ OscillatorPowerDown
Definition WM8731.h:85
error_t standby(void)
Powers down all sections (standby)
Definition WM8731.h:282
uint16_t digital_path
Definition WM8731.h:296
uint16_t power_down
Definition WM8731.h:297
error_t getVoiceVolume(int *volume)
Get the headphone / line output volume (0~100)
Definition WM8731.h:259
bool initialized
Definition WM8731.h:294
Namespace for audio driver components.
Definition AudioBoard.h:5
constexpr int WM8731_ADDR
7-bit I2C address (CSB pin low). If CSB is pulled high use 0x1B.
Definition WM8731.h:18
input_device_t
Definition DriverCommon.h:170
@ ADC_INPUT_ALL
Definition DriverCommon.h:175
@ ADC_INPUT_NONE
Definition DriverCommon.h:171
@ ADC_INPUT_LINE1
Definition DriverCommon.h:172
@ BIT_LENGTH_24BITS
Definition DriverCommon.h:240
@ BIT_LENGTH_20BITS
Definition DriverCommon.h:239
@ BIT_LENGTH_32BITS
Definition DriverCommon.h:241
@ BIT_LENGTH_16BITS
Definition DriverCommon.h:237
codec_mode_t
Definition DriverCommon.h:290
@ CODEC_MODE_BOTH
Definition DriverCommon.h:295
int error_t
Definition DriverCommon.h:150
output_device_t
Definition DriverCommon.h:186
@ DAC_OUTPUT_NONE
Definition DriverCommon.h:187
samplerate_t
Definition DriverCommon.h:213
@ RATE_44K
Definition DriverCommon.h:220
@ RATE_8K
Definition DriverCommon.h:214
@ RATE_88K
Definition DriverCommon.h:223
@ RATE_32K
Definition DriverCommon.h:219
@ RATE_96K
Definition DriverCommon.h:224
@ RATE_48K
Definition DriverCommon.h:221
@ I2S_RIGHT
Definition DriverCommon.h:253
@ I2S_DSP
Definition DriverCommon.h:254
@ I2S_LEFT
Definition DriverCommon.h:252
@ I2S_NORMAL
Definition DriverCommon.h:251
@ MODE_MASTER
Definition DriverCommon.h:205
void * i2c_bus_handle_t
Definition DriverCommon.h:155
I2S interface parameters for the audio codec.
Definition DriverCommon.h:384
i2s_format_t fmt
Definition DriverCommon.h:386
samplerate_t rate
Definition DriverCommon.h:387
i2s_master_slave_t mode
Definition DriverCommon.h:385
sample_bits_t bits
Definition DriverCommon.h:388
Top-level codec configuration passed to the audio driver at init.
Definition DriverCommon.h:397
output_device_t output_device
Definition DriverCommon.h:399
I2SDefinition i2s
Definition DriverCommon.h:400
input_device_t input_device
Definition DriverCommon.h:398