arduino-audio-driver
Loading...
Searching...
No Matches
CS43L22.h
Go to the documentation of this file.
1
36/* Define to prevent recursive inclusion -------------------------------------*/
37#pragma once
38
39/* Includes ------------------------------------------------------------------*/
40//#include "../Common/audio.h"
41#include <stdint.h>
42#include "stdbool.h"
43#include "stddef.h"
44#include "DriverCommon.h"
45#include "Platforms/API_I2C.h"
47
48namespace audio_driver {
49
55class CS43L22 {
56 public:
68 static constexpr uint8_t OUTPUT_DEVICE_SPEAKER = 1;
69 static constexpr uint8_t OUTPUT_DEVICE_HEADPHONE = 2;
70 static constexpr uint8_t OUTPUT_DEVICE_BOTH = 3;
71 static constexpr uint8_t OUTPUT_DEVICE_AUTO = 4;
72 static constexpr uint8_t DEFAULT_VOLMIN = 0x00;
73 static constexpr uint8_t DEFAULT_VOLMAX = 0xFF;
74 static constexpr uint8_t DEFAULT_VOLSTEP = 0x04;
75 static constexpr int AUDIO_PAUSE = 0;
76 static constexpr int AUDIO_RESUME = 1;
77 static constexpr int CODEC_PDWN_HW = 1;
78 static constexpr int CODEC_PDWN_SW = 2;
79 static constexpr int AUDIO_MUTE_ON = 1;
80 static constexpr int AUDIO_MUTE_OFF = 0;
81 static constexpr uint8_t CS43L22_REG_ID = 0x01;
82 static constexpr uint8_t CS43L22_REG_POWER_CTL1 = 0x02;
83 static constexpr uint8_t CS43L22_REG_POWER_CTL2 = 0x04;
84 static constexpr uint8_t CS43L22_REG_CLOCKING_CTL = 0x05;
85 static constexpr uint8_t CS43L22_REG_INTERFACE_CTL1 = 0x06;
86 static constexpr uint8_t CS43L22_REG_INTERFACE_CTL2 = 0x07;
87 static constexpr uint8_t CS43L22_REG_PASSTHR_A_SELECT = 0x08;
88 static constexpr uint8_t CS43L22_REG_PASSTHR_B_SELECT = 0x09;
89 static constexpr uint8_t CS43L22_REG_ANALOG_ZC_SR_SETT = 0x0A;
90 static constexpr uint8_t CS43L22_REG_PASSTHR_GANG_CTL = 0x0C;
91 static constexpr uint8_t CS43L22_REG_PLAYBACK_CTL1 = 0x0D;
92 static constexpr uint8_t CS43L22_REG_MISC_CTL = 0x0E;
93 static constexpr uint8_t CS43L22_REG_PLAYBACK_CTL2 = 0x0F;
94 static constexpr uint8_t CS43L22_REG_PASSTHR_A_VOL = 0x14;
95 static constexpr uint8_t CS43L22_REG_PASSTHR_B_VOL = 0x15;
96 static constexpr uint8_t CS43L22_REG_PCMA_VOL = 0x1A;
97 static constexpr uint8_t CS43L22_REG_PCMB_VOL = 0x1B;
98 static constexpr uint8_t CS43L22_REG_BEEP_FREQ_ON_TIME = 0x1C;
99 static constexpr uint8_t CS43L22_REG_BEEP_VOL_OFF_TIME = 0x1D;
100 static constexpr uint8_t CS43L22_REG_BEEP_TONE_CFG = 0x1E;
101 static constexpr uint8_t CS43L22_REG_TONE_CTL = 0x1F;
102 static constexpr uint8_t CS43L22_REG_MASTER_A_VOL = 0x20;
103 static constexpr uint8_t CS43L22_REG_MASTER_B_VOL = 0x21;
104 static constexpr uint8_t CS43L22_REG_HEADPHONE_A_VOL = 0x22;
105 static constexpr uint8_t CS43L22_REG_HEADPHONE_B_VOL = 0x23;
106 static constexpr uint8_t CS43L22_REG_SPEAKER_A_VOL = 0x24;
107 static constexpr uint8_t CS43L22_REG_SPEAKER_B_VOL = 0x25;
108 static constexpr uint8_t CS43L22_REG_CH_MIXER_SWAP = 0x26;
109 static constexpr uint8_t CS43L22_REG_LIMIT_CTL1 = 0x27;
110 static constexpr uint8_t CS43L22_REG_LIMIT_CTL2 = 0x28;
111 static constexpr uint8_t CS43L22_REG_LIMIT_ATTACK_RATE = 0x29;
112 static constexpr uint8_t CS43L22_REG_OVF_CLK_STATUS = 0x2E;
113 static constexpr uint8_t CS43L22_REG_BATT_COMPENSATION = 0x2F;
114 static constexpr uint8_t CS43L22_REG_VP_BATTERY_LEVEL = 0x30;
115 static constexpr uint8_t CS43L22_REG_SPEAKER_STATUS = 0x31;
116 static constexpr uint8_t CS43L22_REG_TEMPMONITOR_CTL = 0x32;
117 static constexpr uint8_t CS43L22_REG_THERMAL_FOLDBACK = 0x33;
118 static constexpr uint8_t CS43L22_REG_CHARGE_PUMP_FREQ = 0x34;
119 static constexpr uint8_t CODEC_STANDARD = 0x04;
120 static constexpr uint8_t CS43L22_ID = 0xE0;
121 static constexpr uint8_t CS43L22_ID_MASK = 0xF8;
122 static constexpr uint8_t CS43L22_CHIPID_ADDR = 0x01;
123 static constexpr uint8_t cs43l22VolumeConvert(uint8_t volume) {
124 return volume > 100 ? 255 : (uint8_t)((volume * 255) / 100);
125 }
126 CS43L22() = default;
127
129 void setWire(i2c_bus_handle_t handle) { i2c_handle = handle; }
130
132 void setAddress(uint16_t addr) { device_addr = addr; }
133
138 uint32_t init(uint16_t outputDevice, uint8_t volume, uint32_t audioFreq) {
139 uint32_t counter = 0;
140
141 /* Keep Codec powered OFF */
142 counter += writeReg(CS43L22_REG_POWER_CTL1, 0x01);
143
144 /*Save Output device for mute ON/OFF procedure*/
145 switch (outputDevice) {
147 output_dev = 0xFA;
148 break;
149
151 output_dev = 0xAF;
152 break;
153
155 output_dev = 0xAA;
156 break;
157
159 output_dev = 0x05;
160 break;
161
162 default:
163 output_dev = 0x05;
164 break;
165 }
166
168
169 /* Clock configuration: Auto detection */
170 counter += writeReg(CS43L22_REG_CLOCKING_CTL, 0x81);
171
172 /* Set the Slave Mode and the audio Standard */
174
175 /* Set the Master volume */
176 counter += setVolume(volume);
177
178 /* If the Speaker is enabled, set the Mono mode and volume attenuation level
179 */
180 if (outputDevice != OUTPUT_DEVICE_HEADPHONE) {
181 /* Set the Speaker Mono mode */
182 counter += writeReg(CS43L22_REG_PLAYBACK_CTL2, 0x06);
183
184 /* Set the Speaker attenuation level */
185 counter += writeReg(CS43L22_REG_SPEAKER_A_VOL, 0x00);
186 counter += writeReg(CS43L22_REG_SPEAKER_B_VOL, 0x00);
187 }
188
189 /* Additional configuration for the CODEC. These configurations are done to
190 reduce the time needed for the Codec to power off. If these configurations are
191 removed, then a long delay should be added between powering off the Codec and
192 switching off the I2S peripheral MCLK clock (which is the operating clock for
193 Codec). If this delay is not inserted, then the codec will not shut down
194 properly and it results in high noise after shut down. */
195
196 /* Disable the analog soft ramp */
197 counter += writeReg(CS43L22_REG_ANALOG_ZC_SR_SETT, 0x00);
198 /* Disable the digital soft ramp */
199 counter += writeReg(CS43L22_REG_MISC_CTL, 0x04);
200 /* Disable the limiter attack level */
201 counter += writeReg(CS43L22_REG_LIMIT_CTL1, 0x00);
202 /* Adjust Bass and Treble levels */
203 counter += writeReg(CS43L22_REG_TONE_CTL, 0x0F);
204 /* Adjust PCM volume level */
205 counter += writeReg(CS43L22_REG_PCMA_VOL, 0x0A);
206 counter += writeReg(CS43L22_REG_PCMB_VOL, 0x0A);
207
208 /* Return communication control value */
209 return counter;
210 }
211
213 void deinit() {}
214
216 uint32_t readID() {
217 uint8_t reg = CS43L22_CHIPID_ADDR;
218 uint8_t value = 0;
219 i2c_bus_read_bytes(i2c_handle, device_addr, &reg, 1, &value, 1);
220 return (uint32_t)(value & CS43L22_ID_MASK);
221 }
222
225 uint32_t play(uint16_t* pBuffer, uint16_t size) {
226 uint32_t counter = 0;
227
228 if (is_stop == 1) {
229 /* Enable the digital soft ramp */
230 counter += writeReg(CS43L22_REG_MISC_CTL, 0x06);
231
232 /* Enable Output device */
233 counter += setMute(AUDIO_MUTE_OFF);
234
235 /* Power on the Codec */
236 counter += writeReg(CS43L22_REG_POWER_CTL1, 0x9E);
237 is_stop = 0;
238 }
239
240 /* Return communication control value */
241 return counter;
242 }
243
245 uint32_t pause() {
246 uint32_t counter = 0;
247
248 /* Pause the audio file playing */
249 /* Mute the output first */
250 counter += setMute(AUDIO_MUTE_ON);
251
252 /* Put the Codec in Power save mode */
253 counter += writeReg(CS43L22_REG_POWER_CTL1, 0x01);
254
255 return counter;
256 }
257
259 uint32_t resume() {
260 uint32_t counter = 0;
261 /* Resumes the audio file playing */
262 /* Unmute the output first */
263 counter += setMute(AUDIO_MUTE_OFF);
264
265 delayMs(10);
266
268
269 /* Exit the Power save mode */
270 counter += writeReg(CS43L22_REG_POWER_CTL1, 0x9E);
271
272 return counter;
273 }
274
277 uint32_t stop(uint32_t cmd) {
278 uint32_t counter = 0;
279
280 /* Mute the output first */
281 counter += setMute(AUDIO_MUTE_ON);
282
283 /* Disable the digital soft ramp */
284 counter += writeReg(CS43L22_REG_MISC_CTL, 0x04);
285
286 /* Power down the DAC and the speaker (PMDAC and PMSPK bits)*/
287 counter += writeReg(CS43L22_REG_POWER_CTL1, 0x9F);
288
289 is_stop = 1;
290 return counter;
291 }
292
296 uint32_t setVolume(uint8_t volume) {
297 uint32_t counter = 0;
298 uint8_t convertedvol = cs43l22VolumeConvert(volume);
299
300 if (convertedvol > 0xE6) {
301 /* Set the Master volume */
302 counter += writeReg(CS43L22_REG_MASTER_A_VOL, convertedvol - 0xE7);
303 counter += writeReg(CS43L22_REG_MASTER_B_VOL, convertedvol - 0xE7);
304 } else {
305 /* Set the Master volume */
306 counter += writeReg(CS43L22_REG_MASTER_A_VOL, convertedvol + 0x19);
307 counter += writeReg(CS43L22_REG_MASTER_B_VOL, convertedvol + 0x19);
308 }
309
310 return counter;
311 }
312
314 uint32_t setFrequency(uint32_t audioFreq) { return 0; }
315
319 uint32_t setMute(uint32_t cmd) {
320 uint32_t counter = 0;
321
322 /* Set the Mute mode */
323 if (cmd == AUDIO_MUTE_ON) {
324 counter += writeReg(CS43L22_REG_POWER_CTL2, 0xFF);
325 counter += writeReg(CS43L22_REG_HEADPHONE_A_VOL, 0x01);
326 counter += writeReg(CS43L22_REG_HEADPHONE_B_VOL, 0x01);
327 } else /* AUDIO_MUTE_OFF Disable the Mute */
328 {
329 counter += writeReg(CS43L22_REG_HEADPHONE_A_VOL, 0x00);
330 counter += writeReg(CS43L22_REG_HEADPHONE_B_VOL, 0x00);
332 }
333 return counter;
334 }
335
340 uint32_t setOutputMode(uint8_t output) {
341 uint32_t counter = 0;
342
343 switch (output) {
346 0xFA); /* SPK always ON & HP always OFF */
347 output_dev = 0xFA;
348 break;
349
352 0xAF); /* SPK always OFF & HP always ON */
353 output_dev = 0xAF;
354 break;
355
358 0xAA); /* SPK always ON & HP always ON */
359 output_dev = 0xAA;
360 break;
361
364 0x05); /* Detect the HP or the SPK automatically */
365 output_dev = 0x05;
366 break;
367
368 default:
370 0x05); /* Detect the HP or the SPK automatically */
371 output_dev = 0x05;
372 break;
373 }
374 return counter;
375 }
376
378 uint32_t reset() { return 0; }
379 uint8_t writeReg(uint8_t reg, uint8_t value) {
380 error_t rc = i2c_bus_write_bytes(i2c_handle, device_addr, &reg, 1, &value, 1);
381 return rc == RESULT_OK ? 0 : 1;
382 }
383
384 protected:
386 uint16_t device_addr = 0;
387 uint8_t is_stop = 1;
388 volatile uint8_t output_dev = 0;
389};
390
391} // namespace audio_driver
#define RESULT_OK
Definition DriverCommon.h:74
Header-only driver class for the CS43L22 codec chip.
Definition CS43L22.h:55
uint32_t setFrequency(uint32_t audioFreq)
Sets new frequency: not implemented for this codec, as it is automatically detected by the codec.
Definition CS43L22.h:314
static constexpr uint8_t cs43l22VolumeConvert(uint8_t volume)
Definition CS43L22.h:123
static constexpr uint8_t CS43L22_REG_PASSTHR_A_VOL
Definition CS43L22.h:94
static constexpr uint8_t CS43L22_REG_PLAYBACK_CTL1
Definition CS43L22.h:91
static constexpr uint8_t CS43L22_REG_PCMA_VOL
Definition CS43L22.h:96
uint32_t stop(uint32_t cmd)
Definition CS43L22.h:277
static constexpr int CODEC_PDWN_HW
Definition CS43L22.h:77
AudioFrequency
Definition CS43L22.h:57
@ AUDIO_FREQUENCY_22K
Definition CS43L22.h:63
@ AUDIO_FREQUENCY_32K
Definition CS43L22.h:62
@ AUDIO_FREQUENCY_96K
Definition CS43L22.h:59
@ AUDIO_FREQUENCY_44K
Definition CS43L22.h:61
@ AUDIO_FREQUENCY_16K
Definition CS43L22.h:64
@ AUDIO_FREQUENCY_8K
Definition CS43L22.h:66
@ AUDIO_FREQUENCY_192K
Definition CS43L22.h:58
@ AUDIO_FREQUENCY_11K
Definition CS43L22.h:65
@ AUDIO_FREQUENCY_48K
Definition CS43L22.h:60
static constexpr uint8_t CS43L22_REG_MASTER_A_VOL
Definition CS43L22.h:102
uint32_t init(uint16_t outputDevice, uint8_t volume, uint32_t audioFreq)
Definition CS43L22.h:138
static constexpr uint8_t CODEC_STANDARD
Definition CS43L22.h:119
static constexpr uint8_t CS43L22_REG_BATT_COMPENSATION
Definition CS43L22.h:113
static constexpr uint8_t CS43L22_REG_SPEAKER_STATUS
Definition CS43L22.h:115
static constexpr uint8_t CS43L22_REG_PASSTHR_GANG_CTL
Definition CS43L22.h:90
static constexpr uint8_t CS43L22_REG_SPEAKER_A_VOL
Definition CS43L22.h:106
uint32_t readID()
Get the CS43L22 ID.
Definition CS43L22.h:216
static constexpr uint8_t CS43L22_REG_HEADPHONE_B_VOL
Definition CS43L22.h:105
uint32_t resume()
Resumes playing on the audio codec.
Definition CS43L22.h:259
static constexpr uint8_t CS43L22_REG_OVF_CLK_STATUS
Definition CS43L22.h:112
static constexpr uint8_t CS43L22_REG_TEMPMONITOR_CTL
Definition CS43L22.h:116
static constexpr uint8_t CS43L22_REG_VP_BATTERY_LEVEL
Definition CS43L22.h:114
static constexpr uint8_t DEFAULT_VOLMIN
Definition CS43L22.h:72
static constexpr uint8_t DEFAULT_VOLSTEP
Definition CS43L22.h:74
static constexpr uint8_t OUTPUT_DEVICE_BOTH
Definition CS43L22.h:70
uint32_t setVolume(uint8_t volume)
Definition CS43L22.h:296
static constexpr uint8_t CS43L22_REG_PASSTHR_B_VOL
Definition CS43L22.h:95
volatile uint8_t output_dev
Definition CS43L22.h:388
static constexpr uint8_t CS43L22_ID
Definition CS43L22.h:120
uint32_t setMute(uint32_t cmd)
Definition CS43L22.h:319
static constexpr uint8_t CS43L22_REG_CLOCKING_CTL
Definition CS43L22.h:84
uint32_t pause()
Pauses playing on the audio codec.
Definition CS43L22.h:245
static constexpr uint8_t CS43L22_REG_BEEP_TONE_CFG
Definition CS43L22.h:100
static constexpr uint8_t OUTPUT_DEVICE_AUTO
Definition CS43L22.h:71
uint8_t writeReg(uint8_t reg, uint8_t value)
Definition CS43L22.h:379
static constexpr uint8_t CS43L22_REG_PCMB_VOL
Definition CS43L22.h:97
static constexpr uint8_t CS43L22_REG_TONE_CTL
Definition CS43L22.h:101
uint16_t device_addr
Definition CS43L22.h:386
void setWire(i2c_bus_handle_t handle)
Defines the I2C bus instance to be used.
Definition CS43L22.h:129
static constexpr uint8_t OUTPUT_DEVICE_SPEAKER
Definition CS43L22.h:68
static constexpr uint8_t CS43L22_REG_INTERFACE_CTL2
Definition CS43L22.h:86
static constexpr uint8_t CS43L22_REG_PASSTHR_B_SELECT
Definition CS43L22.h:88
static constexpr uint8_t CS43L22_REG_THERMAL_FOLDBACK
Definition CS43L22.h:117
static constexpr int AUDIO_MUTE_ON
Definition CS43L22.h:79
void deinit()
Deinitializes the audio codec.
Definition CS43L22.h:213
static constexpr uint8_t CS43L22_REG_LIMIT_CTL2
Definition CS43L22.h:110
static constexpr uint8_t CS43L22_REG_BEEP_FREQ_ON_TIME
Definition CS43L22.h:98
uint32_t reset()
Resets cs43l22 registers.
Definition CS43L22.h:378
static constexpr uint8_t CS43L22_REG_MISC_CTL
Definition CS43L22.h:92
i2c_bus_handle_t i2c_handle
Definition CS43L22.h:385
static constexpr uint8_t CS43L22_REG_HEADPHONE_A_VOL
Definition CS43L22.h:104
static constexpr int AUDIO_RESUME
Definition CS43L22.h:76
uint32_t setOutputMode(uint8_t output)
Definition CS43L22.h:340
static constexpr uint8_t CS43L22_REG_INTERFACE_CTL1
Definition CS43L22.h:85
static constexpr uint8_t CS43L22_REG_LIMIT_ATTACK_RATE
Definition CS43L22.h:111
static constexpr int CODEC_PDWN_SW
Definition CS43L22.h:78
static constexpr uint8_t CS43L22_ID_MASK
Definition CS43L22.h:121
static constexpr uint8_t DEFAULT_VOLMAX
Definition CS43L22.h:73
static constexpr uint8_t CS43L22_REG_BEEP_VOL_OFF_TIME
Definition CS43L22.h:99
static constexpr uint8_t CS43L22_REG_CHARGE_PUMP_FREQ
Definition CS43L22.h:118
uint8_t is_stop
Definition CS43L22.h:387
static constexpr uint8_t CS43L22_REG_PLAYBACK_CTL2
Definition CS43L22.h:93
static constexpr uint8_t CS43L22_REG_MASTER_B_VOL
Definition CS43L22.h:103
static constexpr uint8_t CS43L22_REG_PASSTHR_A_SELECT
Definition CS43L22.h:87
static constexpr uint8_t CS43L22_REG_SPEAKER_B_VOL
Definition CS43L22.h:107
uint32_t play(uint16_t *pBuffer, uint16_t size)
Definition CS43L22.h:225
static constexpr int AUDIO_PAUSE
Definition CS43L22.h:75
static constexpr int AUDIO_MUTE_OFF
Definition CS43L22.h:80
static constexpr uint8_t CS43L22_REG_ID
Definition CS43L22.h:81
static constexpr uint8_t CS43L22_REG_POWER_CTL2
Definition CS43L22.h:83
static constexpr uint8_t CS43L22_REG_LIMIT_CTL1
Definition CS43L22.h:109
static constexpr uint8_t CS43L22_REG_ANALOG_ZC_SR_SETT
Definition CS43L22.h:89
static constexpr uint8_t CS43L22_REG_CH_MIXER_SWAP
Definition CS43L22.h:108
static constexpr uint8_t CS43L22_CHIPID_ADDR
Definition CS43L22.h:122
static constexpr uint8_t CS43L22_REG_POWER_CTL1
Definition CS43L22.h:82
static constexpr uint8_t OUTPUT_DEVICE_HEADPHONE
Definition CS43L22.h:69
void setAddress(uint16_t addr)
Defines the I2C device address.
Definition CS43L22.h:132
Namespace for audio driver components.
Definition AudioBoard.h:5
void delayMs(unsigned long ms)
Definition API_Delay.h:19
int error_t
Definition DriverCommon.h:150
void * i2c_bus_handle_t
Definition DriverCommon.h:155