arduino-audio-driver
Loading...
Searching...
No Matches
CS42L51.h
Go to the documentation of this file.
1
16#pragma once
17
18#include <stdint.h>
19
21#include "DriverCommon.h"
22#include "Platforms/API_Delay.h"
23#include "Platforms/API_I2C.h"
24
25namespace audio_driver {
26
27/******************************************************************************/
28/****************************** REGISTER MAPPING ******************************/
29/******************************************************************************/
65
66/******************************************************************************/
67/*************************** Codec User types *******************************/
68/******************************************************************************/
69
71enum CS42L51Status : int32_t {
74};
75
77enum CS42L51InputDevice : uint32_t {
84};
85
87enum CS42L51OutputDevice : uint32_t {
90};
91
106
114
116enum CS42L51PowerDownMode : uint8_t {
119};
120
126
128enum CS42L51Mute : uint8_t {
131};
132
139
141static constexpr uint8_t CS42L51_ID = 0xD8;
142static constexpr uint8_t CS42L51_ID_MASK = 0xF8;
143
149class CS42L51 {
150 public:
151 CS42L51() = default;
152
154 void setWire(i2c_bus_handle_t handle) { i2c_handle = handle; }
155
157 void setAddress(uint16_t addr) { device_addr = addr; }
158
166 uint32_t init(uint32_t inputDevice, uint32_t outputDevice, uint8_t volume,
167 uint32_t audioFreq) {
168 uint32_t ret = 0;
169 uint8_t tmp;
170
171 if (is_initialized == 0) {
172 /* Set the device in standby mode */
174 tmp |= 0x01U;
175 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
176
177 /* Set all power down bits to 1 */
178 tmp = 0x7FU;
179 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
181 tmp |= 0x0EU;
183
184 is_initialized = 1;
185 } else {
186 /* Set all power down bits to 1 except PDN to mute ADCs and DACs*/
187 tmp = 0x7EU;
188 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
190 tmp |= 0x0EU;
192
193 /* Disable zero cross and soft ramp */
195 tmp &= 0xFCU;
196 ret += writeReg(CS42L51_DAC_CTRL, tmp);
197
198 /* Power control : Enter standby (PDN = 1) */
200 tmp |= 0x01U;
201 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
202 }
203
204 /* Mic Power and Speed Control : Auto detect on, Speed mode SSM, tri state
205 * off, MCLK divide by 2 off */
207 tmp = ((tmp & 0x0EU) | 0xA0U);
209
210 /* Interface control : Loopback off, Slave, I2S (SDIN and SOUT), Digital
211 * mix off, Mic mix off */
212 tmp = 0x0CU;
213 ret += writeReg(CS42L51_INTERFACE_CTRL, tmp);
214
215 /* Mic control : ADC single volume off, ADCB boost off, ADCA boost off,
216 * MicBias on AIN3B/MICIN2 pin, MicBias level 0.8xVA, MICB boost 32db,
217 * MICA boost 32dB */
218 tmp = 0x03U;
219 ret += writeReg(CS42L51_MIC_CTRL, tmp);
220
221 /* ADC control : ADCB HPF on, ADCB HPF freeze off, ADCA HPF on, ADCA HPF
222 * freeze off, Soft ramp B on, Zero cross B on, Soft ramp A on, Zero cross
223 * A on */
224 tmp = 0xAFU;
225 ret += writeReg(CS42L51_ADC_CTRL, tmp);
226
227 /* DAC output control : HP Gain to 1, Single volume control off, PCM
228 * invert signals polarity off, DAC channels mute on */
229 tmp = 0xC3U;
231
232 /* DAC control : Signal processing to DAC, Freeze off, De-emphasis off,
233 * Analog output auto mute off, DAC soft ramp */
234 tmp = 0x42U;
235 ret += writeReg(CS42L51_DAC_CTRL, tmp);
236
237 /* ALCA and PGAA Control : ALCA soft ramp disable on, ALCA zero cross
238 * disable on, PGA A Gain +8dB */
239 tmp = 0xD0U;
240 ret += writeReg(CS42L51_ALCA_PGAA_CTRL, tmp);
241
242 /* ALCB and PGAB Control : ALCB soft ramp disable on, ALCB zero cross
243 * disable on, PGA B Gain +8dB */
244 ret += writeReg(CS42L51_ALCB_PGAB_CTRL, tmp);
245
246 if ((inputDevice & CS42L51_IN_LINE1) == CS42L51_IN_LINE1) {
247 /* ADCA/ADCB Attenuator : -10dB */
248 tmp = 0xF6U;
249 } else {
250 /* ADCA/ADCB Attenuator : 0dB */
251 tmp = 0x00U;
252 }
253 /* ADCA Attenuator */
255 /* ADCB Attenuator */
257
258 /* ADCA mixer volume control : ADCA mixer channel mute on, ADCA mixer
259 * volume 0dB */
260 tmp = 0x80U;
262 /* ADCB mixer volume control : ADCB mixer channel mute on, ADCB mixer
263 * volume 0dB */
265
266 /* PCMA mixer volume control : PCMA mixer channel mute off, PCMA mixer
267 * volume 0dB */
268 tmp = 0x00U;
270 /* PCMB mixer volume control : PCMB mixer channel mute off, PCMB mixer
271 * volume 0dB */
273 /* PCM channel mixer : AOUTA Left, AOUTB Right */
275
276 if ((outputDevice & CS42L51_OUT_HEADPHONE) == CS42L51_OUT_HEADPHONE) {
277 tmp = volumeConvert(volume);
278 /* AOUTA volume control : AOUTA volume */
279 ret += writeReg(CS42L51_AOUTA_VOL_CTRL, tmp);
280 /* AOUTB volume control : AOUTB volume */
281 ret += writeReg(CS42L51_AOUTB_VOL_CTRL, tmp);
282 }
283
284 /* ALC enable and attack rate : ALCB and ALCA enable, fastest attack */
285 tmp = 0x40U;
287
288 /* Store current devices */
289 current_devices = (outputDevice | inputDevice);
290
291 return ret;
292 }
293
295 void deinit() { is_initialized = 0; }
296
298 uint32_t readID() {
299 uint8_t value = readReg(CS42L51_CHIP_ID);
300 return static_cast<uint32_t>(value & CS42L51_ID_MASK);
301 }
302
304 uint32_t play() {
305 uint32_t ret = 0;
306 uint8_t tmp;
307
309 /* Unmute the output first */
311
312 /* DAC control : Signal processing to DAC, Freeze off, De-emphasis off,
313 * Analog output auto mute off, DAC soft ramp */
314 tmp = 0x42U;
315 ret += writeReg(CS42L51_DAC_CTRL, tmp);
316
317 /* Power control 1 : PDN_DACA, PDN_DACB disable. */
319 tmp &= 0x9FU;
320 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
321 }
322
324 /* ADC Input Select, Invert and Mute : AIN1B to PGAB, AIN1A to PGAA,
325 * ADCB invert off, ADCA invert off, ADCB mute off, ADCA mute off */
326 tmp = 0x00U;
328
329 /* Power control 1 : PDN_PGAA, PDN_PGAA, PDN_ADCB, PDN_ADCA disable. */
331 tmp &= 0xF9U;
332 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
333
334 /* Mic Power and Speed Control : PDN_MICA, PDN_MICB, PDN_MIC_BIAS
335 * disable. */
337 tmp &= 0xFFU;
339 }
340
342 /* ADC Input Select, Invert and Mute : AIN1B to PGAB, AIN3A to PreAmp to
343 * PGAA, ADCB invert off, ADCA invert off, ADCB mute on, ADCA mute off */
344 tmp = 0x32U;
346
347 /* Power control 1 : PDN_PGAA, PDN_ADCA disable. */
349 tmp &= 0xF5U;
350 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
351
352 /* Mic Power and Speed Control : PDN_MICA, PDN_MIC_BIAS disable. */
354 tmp &= 0xF9U;
356 }
357
359 /* Power control 1 : PDN_PGAB, PDN_ADCB disable. */
361 tmp &= 0xEBU;
362 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
363
364 /* Mic Power and Speed Control : PDN_MICB, PDN_MIC_BIAS disable. */
366 tmp &= 0xF5U;
368 }
369
370 /* Power control : Exit standby (PDN = 0) */
372 tmp &= 0xFEU;
373 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
374
375 return ret;
376 }
377
379 uint32_t pause() { return setMute(CS42L51_MUTE_ON); }
380
382 uint32_t resume() { return setMute(CS42L51_MUTE_OFF); }
383
387 uint32_t stop(uint32_t cmd) {
388 uint32_t ret = 0;
389 uint8_t tmp;
390
391 /* Mute the output first */
392 ret += setMute(CS42L51_MUTE_ON);
393
394 if (cmd == CS42L51_PDWN_SW) {
395 /* Only output mute required*/
396 } else /* CS42L51_PDWN_HW */
397 {
398 /* Set all power down bits to 1 except PDN to mute ADCs and DACs*/
399 tmp = 0x7EU;
400 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
402 tmp |= 0x0EU;
404
405 /* Disable zero cross and soft ramp */
407 tmp &= 0xFCU;
408 ret += writeReg(CS42L51_DAC_CTRL, tmp);
409
410 /* Power control : Enter standby (PDN = 1) */
412 tmp |= 0x01U;
413 ret += writeReg(CS42L51_PWR_CTRL_1, tmp);
414 }
415
416 return ret;
417 }
418
422 uint32_t setVolume(uint8_t volume) {
423 uint32_t ret = 0;
424 uint8_t convertedvol = volumeConvert(volume);
425
426 /* AOUTA volume control : AOUTA volume */
427 ret += writeReg(CS42L51_AOUTA_VOL_CTRL, convertedvol);
428 /* AOUTB volume control : AOUTB volume */
429 ret += writeReg(CS42L51_AOUTB_VOL_CTRL, convertedvol);
430
431 return ret;
432 }
433
435 uint8_t getVolume() {
436 uint8_t tmp = readReg(CS42L51_AOUTA_VOL_CTRL);
437 return volumeInvert(tmp);
438 }
439
441 uint32_t setFrequency(uint32_t audioFreq) { return 0; }
442
446 uint32_t setMute(uint32_t cmd) {
447 uint32_t ret = 0;
448 uint8_t tmp = readReg(CS42L51_DAC_OUTPUT_CTRL);
449
450 /* Set the Mute mode */
451 if (cmd == CS42L51_MUTE_ON) {
452 tmp |= 0x03U;
453 } else /* CS42L51_MUTE_OFF Disable the Mute */
454 {
455 tmp &= 0xFCU;
456 }
457
459
460 return ret;
461 }
462
465 uint32_t setOutputMode(uint32_t output) {
466 if (output != CS42L51_OUT_HEADPHONE) return CS42L51_ERROR;
467 return CS42L51_OK;
468 }
469
471 uint32_t reset() { return 0; }
472
473 uint8_t readReg(uint8_t reg) {
474 uint8_t value = 0;
475 i2c_bus_read_bytes(i2c_handle, device_addr, &reg, 1, &value, 1);
476 return value;
477 }
478
479 uint8_t writeReg(uint8_t reg, uint8_t value) {
480 i2c_bus_write_bytes(i2c_handle, device_addr, &reg, 1, &value, 1);
481 return 0;
482 }
483
485 inline constexpr uint8_t volumeConvert(uint8_t volume) {
486 return volume >= 100 ? static_cast<uint8_t>(0)
487 : static_cast<uint8_t>(volume * 2 + 56);
488 }
489
491 inline constexpr uint8_t volumeInvert(uint8_t reg) {
492 return reg == 0 ? static_cast<uint8_t>(100)
493 : static_cast<uint8_t>((reg - 56) / 2);
494 }
495
496 protected:
498 uint16_t device_addr = 0;
499 uint8_t is_initialized = 0;
501};
502
503} // namespace audio_driver
Header-only driver class for the CS42L51 codec chip.
Definition CS42L51.h:149
constexpr uint8_t volumeConvert(uint8_t volume)
Converts a volume in the range 0-100 to the codec's register value.
Definition CS42L51.h:485
uint32_t setFrequency(uint32_t audioFreq)
Sets new frequency.
Definition CS42L51.h:441
uint8_t is_initialized
Definition CS42L51.h:499
uint32_t stop(uint32_t cmd)
Definition CS42L51.h:387
uint32_t play()
Start the audio Codec play feature.
Definition CS42L51.h:304
uint8_t readReg(uint8_t reg)
Definition CS42L51.h:473
uint32_t init(uint32_t inputDevice, uint32_t outputDevice, uint8_t volume, uint32_t audioFreq)
Definition CS42L51.h:166
uint32_t readID()
Get the CS42L51 ID.
Definition CS42L51.h:298
uint32_t resume()
Resumes playing on the audio codec.
Definition CS42L51.h:382
uint32_t setVolume(uint8_t volume)
Definition CS42L51.h:422
uint32_t setMute(uint32_t cmd)
Definition CS42L51.h:446
uint32_t pause()
Pauses playing on the audio codec.
Definition CS42L51.h:379
uint8_t writeReg(uint8_t reg, uint8_t value)
Definition CS42L51.h:479
constexpr uint8_t volumeInvert(uint8_t reg)
Converts a codec register value back to a volume in the range 0-100.
Definition CS42L51.h:491
uint16_t device_addr
Definition CS42L51.h:498
uint8_t getVolume()
Get the output codec volume level.
Definition CS42L51.h:435
void setWire(i2c_bus_handle_t handle)
Defines the I2C bus instance to be used.
Definition CS42L51.h:154
void deinit()
Deinitializes the audio codec.
Definition CS42L51.h:295
uint32_t reset()
Resets cs42l51 registers.
Definition CS42L51.h:471
i2c_bus_handle_t i2c_handle
Definition CS42L51.h:497
uint32_t current_devices
Definition CS42L51.h:500
uint32_t setOutputMode(uint32_t output)
Definition CS42L51.h:465
void setAddress(uint16_t addr)
Defines the I2C device address.
Definition CS42L51.h:157
Namespace for audio driver components.
Definition AudioBoard.h:5
CS42L51Frequency
Audio frequencies.
Definition CS42L51.h:93
@ CS42L51_FREQUENCY_8K
Definition CS42L51.h:104
@ CS42L51_FREQUENCY_22K
Definition CS42L51.h:101
@ CS42L51_FREQUENCY_192K
Definition CS42L51.h:94
@ CS42L51_FREQUENCY_88K
Definition CS42L51.h:97
@ CS42L51_FREQUENCY_16K
Definition CS42L51.h:102
@ CS42L51_FREQUENCY_96K
Definition CS42L51.h:96
@ CS42L51_FREQUENCY_44K
Definition CS42L51.h:99
@ CS42L51_FREQUENCY_32K
Definition CS42L51.h:100
@ CS42L51_FREQUENCY_48K
Definition CS42L51.h:98
@ CS42L51_FREQUENCY_11K
Definition CS42L51.h:103
@ CS42L51_FREQUENCY_176K
Definition CS42L51.h:95
CS42L51Reg
Definition CS42L51.h:30
@ CS42L51_ALCB_PGAB_CTRL
Definition CS42L51.h:41
@ CS42L51_BEEP_FREQ_AND_TIMING_CFG
Definition CS42L51.h:48
@ CS42L51_ALC_ENABLE_AND_ATTACK_RATE
Definition CS42L51.h:58
@ CS42L51_ALCA_PGAA_CTRL
Definition CS42L51.h:40
@ CS42L51_DAC_OUTPUT_CTRL
Definition CS42L51.h:38
@ CS42L51_ADC_CTRL
Definition CS42L51.h:36
@ CS42L51_PWR_CTRL_1
Definition CS42L51.h:32
@ CS42L51_CHIP_ID
Definition CS42L51.h:31
@ CS42L51_INTERFACE_CTRL
Definition CS42L51.h:34
@ CS42L51_AOUTA_VOL_CTRL
Definition CS42L51.h:52
@ CS42L51_MIC_CTRL
Definition CS42L51.h:35
@ CS42L51_ADCA_MIXER_VOL_CTRL
Definition CS42L51.h:44
@ CS42L51_AOUTB_VOL_CTRL
Definition CS42L51.h:53
@ CS42L51_CHARGE_PUMP_FREQ
Definition CS42L51.h:63
@ CS42L51_NOISE_GATE_CFG_AND_MISC
Definition CS42L51.h:61
@ CS42L51_BEEP_CFG_AND_TONE_CFG
Definition CS42L51.h:50
@ CS42L51_ALC_THR
Definition CS42L51.h:60
@ CS42L51_MIC_PWR_SPEED_CTRL
Definition CS42L51.h:33
@ CS42L51_PCMA_MIXER_VOL_CTRL
Definition CS42L51.h:46
@ CS42L51_BEEP_OFF_TIME_AND_VOL
Definition CS42L51.h:49
@ CS42L51_LIMITER_RELEASE_RATE_REG
Definition CS42L51.h:56
@ CS42L51_STATUS
Definition CS42L51.h:62
@ CS42L51_ADCB_ATTENUATOR
Definition CS42L51.h:43
@ CS42L51_ADCX_INPUT_SELECT
Definition CS42L51.h:37
@ CS42L51_ALC_RELEASE_RATE
Definition CS42L51.h:59
@ CS42L51_ADCA_ATTENUATOR
Definition CS42L51.h:42
@ CS42L51_LIMITER_THR_SZC_DISABLE
Definition CS42L51.h:55
@ CS42L51_TONE_CTRL
Definition CS42L51.h:51
@ CS42L51_DAC_CTRL
Definition CS42L51.h:39
@ CS42L51_PCMB_MIXER_VOL_CTRL
Definition CS42L51.h:47
@ CS42L51_LIMITER_ATTACK_RATE_REG
Definition CS42L51.h:57
@ CS42L51_ADC_PCM_CHANNEL_MIXER
Definition CS42L51.h:54
@ CS42L51_ADCB_MIXER_VOL_CTRL
Definition CS42L51.h:45
static constexpr uint8_t CS42L51_ID
CS42L51 chip identification.
Definition CS42L51.h:141
CS42L51InputDevice
Audio input devices: can be combined with |.
Definition CS42L51.h:77
@ CS42L51_IN_NONE
Definition CS42L51.h:78
@ CS42L51_IN_MIC2
Definition CS42L51.h:80
@ CS42L51_IN_MIC1
Definition CS42L51.h:79
@ CS42L51_IN_LINE1
Definition CS42L51.h:81
@ CS42L51_IN_LINE3
Definition CS42L51.h:83
@ CS42L51_IN_LINE2
Definition CS42L51.h:82
CS42L51Mute
Mute commands.
Definition CS42L51.h:128
@ CS42L51_MUTE_ON
Definition CS42L51.h:130
@ CS42L51_MUTE_OFF
Definition CS42L51.h:129
CS42L51VolumeSelect
Volume input/output selection.
Definition CS42L51.h:122
@ CS42L51_VOLUME_OUTPUT
Definition CS42L51.h:124
@ CS42L51_VOLUME_INPUT
Definition CS42L51.h:123
CS42L51Status
Component status.
Definition CS42L51.h:71
@ CS42L51_OK
Definition CS42L51.h:72
@ CS42L51_ERROR
Definition CS42L51.h:73
CS42L51OutputDevice
Audio output devices: can be combined with |.
Definition CS42L51.h:87
@ CS42L51_OUT_HEADPHONE
Definition CS42L51.h:89
@ CS42L51_OUT_NONE
Definition CS42L51.h:88
static constexpr uint8_t CS42L51_ID_MASK
Definition CS42L51.h:142
CS42L51Protocol
Audio protocols.
Definition CS42L51.h:134
@ CS42L51_PROTOCOL_R_JUSTIFIED
Definition CS42L51.h:137
@ CS42L51_PROTOCOL_L_JUSTIFIED
Definition CS42L51.h:135
@ CS42L51_PROTOCOL_I2S
Definition CS42L51.h:136
CS42L51PowerDownMode
Codec stop / power down options.
Definition CS42L51.h:116
@ CS42L51_PDWN_SW
Definition CS42L51.h:118
@ CS42L51_PDWN_HW
Definition CS42L51.h:117
void * i2c_bus_handle_t
Definition DriverCommon.h:155
CS42L51Resolution
Audio resolutions (only applicable for CS42L51_PROTOCOL_R_JUSTIFIED)
Definition CS42L51.h:108
@ CS42L51_RESOLUTION_24B
Definition CS42L51.h:112
@ CS42L51_RESOLUTION_16B
Definition CS42L51.h:109
@ CS42L51_RESOLUTION_18B
Definition CS42L51.h:110
@ CS42L51_RESOLUTION_20B
Definition CS42L51.h:111