Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: DISCO_L4R9I-LCD-demo
cs42l51.c
00001 /** 00002 ****************************************************************************** 00003 * @file cs42l51.c 00004 * @author MCD Application Team 00005 * @brief This file provides the CS42L51 Audio Codec driver. 00006 ****************************************************************************** 00007 * @attention 00008 * 00009 * <h2><center>© Copyright (c) 2017 STMicroelectronics. 00010 * All rights reserved.</center></h2> 00011 * 00012 * This software component is licensed by ST under BSD 3-Clause license, 00013 * the "License"; You may not use this file except in compliance with the 00014 * License. You may obtain a copy of the License at: 00015 * opensource.org/licenses/BSD-3-Clause 00016 * 00017 ****************************************************************************** 00018 */ 00019 00020 /* Includes ------------------------------------------------------------------*/ 00021 #include "cs42l51.h" 00022 00023 /** @addtogroup BSP 00024 * @{ 00025 */ 00026 00027 /** @addtogroup Components 00028 * @{ 00029 */ 00030 00031 /** @addtogroup CS42L51 00032 * @brief This file provides a set of functions needed to drive the 00033 * CS42L51 audio codec. 00034 * @{ 00035 */ 00036 00037 /** @defgroup CS42L51_Exported_Variables 00038 * @{ 00039 */ 00040 00041 /* Audio codec driver structure initialization */ 00042 AUDIO_DrvTypeDef cs42l51_drv = 00043 { 00044 cs42l51_Init, 00045 cs42l51_DeInit, 00046 cs42l51_ReadID, 00047 00048 cs42l51_Play, 00049 cs42l51_Pause, 00050 cs42l51_Resume, 00051 cs42l51_Stop, 00052 00053 cs42l51_SetFrequency, 00054 cs42l51_SetVolume, 00055 cs42l51_SetMute, 00056 cs42l51_SetOutputMode, 00057 cs42l51_Reset, 00058 }; 00059 00060 /** 00061 * @} 00062 */ 00063 00064 /** @defgroup CS42L51_Private_Types 00065 * @{ 00066 */ 00067 00068 /** 00069 * @} 00070 */ 00071 00072 /** @defgroup CS42L51_Private_Defines 00073 * @{ 00074 */ 00075 /* Uncomment this line to enable verifying data sent to codec after each write 00076 operation (for debug purpose) */ 00077 #if !defined (VERIFY_WRITTENDATA) 00078 #define VERIFY_WRITTENDATA 00079 #endif /* VERIFY_WRITTENDATA */ 00080 /** 00081 * @} 00082 */ 00083 00084 /** @defgroup CS42L51_Private_Macros 00085 * @{ 00086 */ 00087 00088 /** 00089 * @} 00090 */ 00091 00092 /** @defgroup CS42L51_Private_Variables 00093 * @{ 00094 */ 00095 00096 static uint8_t Is_CS42L51_Initialized = 0; 00097 static uint8_t Is_CS42L51_Stop = 1; 00098 00099 static uint16_t CS42L51_Device = OUTPUT_DEVICE_HEADPHONE; 00100 00101 /** 00102 * @} 00103 */ 00104 00105 /** @defgroup CS42L51_Private_Functions 00106 * @{ 00107 */ 00108 static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value); 00109 /** 00110 * @} 00111 */ 00112 00113 /** @addtogroup CS42L51_Exported_Functions 00114 * @{ 00115 */ 00116 00117 /** 00118 * @brief Initialize the audio codec and the control interface. 00119 * @param DeviceAddr: Device address on communication bus. 00120 * @param Device: Can be combination values of OUTPUT_DEVICE_HEADPHONE and 00121 * INPUT_DEVICE_MIC1. 00122 * @param Volume: Initial output volume level (from 0 (-100dB) to 100 (0dB)). 00123 * @param AudioFreq: Initial audio frequency (currently not used). 00124 * @retval 0 if correct communication, else wrong communication. 00125 */ 00126 uint32_t cs42l51_Init(uint16_t DeviceAddr, uint16_t Device, uint8_t Volume, uint32_t AudioFreq) 00127 { 00128 uint32_t counter = 0; 00129 uint8_t Value; 00130 00131 /* Check if codec is already initialized */ 00132 if(Is_CS42L51_Initialized == 0) 00133 { 00134 /* Initialize the Control interface of the Audio Codec */ 00135 AUDIO_IO_Init(); 00136 00137 Is_CS42L51_Initialized = 1; 00138 } 00139 else 00140 { 00141 /* Set all power down bits to 1 exept PDN to mute ADCs and DACs*/ 00142 counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x7E); 00143 Value = AUDIO_IO_Read(DeviceAddr, 0x03); 00144 counter += CODEC_IO_Write(DeviceAddr, 0x03, (Value | 0x0E)); 00145 00146 /* Disable zero cross and soft ramp */ 00147 Value = AUDIO_IO_Read(DeviceAddr, 0x09); 00148 counter += CODEC_IO_Write(DeviceAddr, 0x09, (Value & 0xFC)); 00149 00150 /* Power control : Enter standby (PDN = 1) */ 00151 Value = AUDIO_IO_Read(DeviceAddr, 0x02); 00152 counter += CODEC_IO_Write(DeviceAddr, 0x02, (Value | 0x01)); 00153 } 00154 00155 /* Mic Power and Speed Control : Auto detect on, Speed mode SSM, tri state off, MCLK divide by 2 off */ 00156 Value = AUDIO_IO_Read(DeviceAddr, 0x03); 00157 counter += CODEC_IO_Write(DeviceAddr, 0x03, ((Value & 0x0E) | 0xA0)); 00158 00159 /* Interface control : Loopback off, Slave, I2S (SDIN and SOUT), Digital mix off, Mic mix off */ 00160 counter += CODEC_IO_Write(DeviceAddr, 0x04, 0x0C); 00161 00162 /* Mic control : ADC single volume off, ADCB boost off, ADCA boost off, MicBias on AIN3B/MICIN2 pin, MicBias level 0.8xVA, MICB boost 16db, MICA boost 16dB */ 00163 counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x00); 00164 00165 /* ADC control : ADCB HPF off, ADCB HPF freeze off, ADCA HPF off, ADCA HPF freeze off, Soft ramp B off, Zero cross B off, Soft ramp A off, Zero cross A off */ 00166 counter += CODEC_IO_Write(DeviceAddr, 0x06, 0x00); 00167 00168 /* ADC Input Select, Invert and Mute : AIN1B to PGAB, AIN3A to PreAmp to PGAA, ADCB invert off, ADCA invert off, ADCB mute on, ADCA mute off */ 00169 counter += CODEC_IO_Write(DeviceAddr, 0x07, 0x32); 00170 00171 /* DAC output control : HP Gain to 1, Single volume control off, PCM invert signals polarity off, DAC channels mute on */ 00172 counter += CODEC_IO_Write(DeviceAddr, 0x08, 0xC3); 00173 00174 /* DAC control : Signal processing to DAC, Freeze off, De-emphasis off, Analog output auto mute off, DAC soft ramp */ 00175 counter += CODEC_IO_Write(DeviceAddr, 0x09, 0x42); 00176 00177 /* ALCA and PGAA Control : ALCA soft ramp disable on, ALCA zero cross disable on, PGA A Gain 0dB */ 00178 counter += CODEC_IO_Write(DeviceAddr, 0x0A, 0xC0); 00179 00180 /* ALCB and PGAB Control : ALCB soft ramp disable on, ALCB zero cross disable on, PGA B Gain 0dB */ 00181 counter += CODEC_IO_Write(DeviceAddr, 0x0B, 0xC0); 00182 00183 /* ADCA Attenuator : 0dB */ 00184 counter += CODEC_IO_Write(DeviceAddr, 0x0C, 0x00); 00185 00186 /* ADCB Attenuator : 0dB */ 00187 counter += CODEC_IO_Write(DeviceAddr, 0x0D, 0x00); 00188 00189 /* ADCA mixer volume control : ADCA mixer channel mute on, ADCA mixer volume 0dB */ 00190 counter += CODEC_IO_Write(DeviceAddr, 0x0E, 0x80); 00191 00192 /* ADCB mixer volume control : ADCB mixer channel mute on, ADCB mixer volume 0dB */ 00193 counter += CODEC_IO_Write(DeviceAddr, 0x0F, 0x80); 00194 00195 /* PCMA mixer volume control : PCMA mixer channel mute off, PCMA mixer volume 0dB */ 00196 counter += CODEC_IO_Write(DeviceAddr, 0x10, 0x00); 00197 00198 /* PCMB mixer volume control : PCMB mixer channel mute off, PCMB mixer volume 0dB */ 00199 counter += CODEC_IO_Write(DeviceAddr, 0x11, 0x00); 00200 00201 /* PCM channel mixer : AOUTA Left, AOUTB Right */ 00202 counter += CODEC_IO_Write(DeviceAddr, 0x18, 0x00); 00203 00204 if(Device & OUTPUT_DEVICE_HEADPHONE) 00205 { 00206 Value = VOLUME_CONVERT(Volume); 00207 /* AOUTA volume control : AOUTA volume */ 00208 counter += CODEC_IO_Write(DeviceAddr, 0x16, Value); 00209 /* AOUTB volume control : AOUTB volume */ 00210 counter += CODEC_IO_Write(DeviceAddr, 0x17, Value); 00211 } 00212 00213 /* Store device */ 00214 CS42L51_Device = Device; 00215 00216 /* Return communication control value */ 00217 return counter; 00218 } 00219 00220 /** 00221 * @brief Deinitialize the audio codec. 00222 * @param None 00223 * @retval None 00224 */ 00225 void cs42l51_DeInit(void) 00226 { 00227 /* Deinitialize Audio Codec interface */ 00228 AUDIO_IO_DeInit(); 00229 00230 Is_CS42L51_Initialized = 0; 00231 } 00232 00233 /** 00234 * @brief Get the CS42L51 ID. 00235 * @param DeviceAddr: Device address on communication Bus. 00236 * @retval The CS42L51 ID 00237 */ 00238 uint32_t cs42l51_ReadID(uint16_t DeviceAddr) 00239 { 00240 uint8_t Value; 00241 00242 if(Is_CS42L51_Initialized == 0) 00243 { 00244 /* Initialize the Control interface of the Audio Codec */ 00245 AUDIO_IO_Init(); 00246 00247 Value = AUDIO_IO_Read(DeviceAddr, CS42L51_CHIPID_ADDR); 00248 Value = (Value & CS42L51_ID_MASK); 00249 00250 /* Deinitialize Audio Codec interface */ 00251 AUDIO_IO_DeInit(); 00252 } 00253 else 00254 { 00255 Value = AUDIO_IO_Read(DeviceAddr, CS42L51_CHIPID_ADDR); 00256 Value = (Value & CS42L51_ID_MASK); 00257 } 00258 00259 return((uint32_t) Value); 00260 } 00261 00262 /** 00263 * @brief Start the audio Codec play feature. 00264 * @note For this codec no Play options are required. 00265 * @param DeviceAddr: Device address on communication Bus. 00266 * @retval 0 if correct communication, else wrong communication 00267 */ 00268 uint32_t cs42l51_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size) 00269 { 00270 uint32_t counter = 0; 00271 uint8_t Value; 00272 00273 if(Is_CS42L51_Stop == 1) 00274 { 00275 /* Unmute output device */ 00276 counter += cs42l51_SetMute(DeviceAddr, AUDIO_MUTE_OFF); 00277 00278 if(CS42L51_Device & OUTPUT_DEVICE_HEADPHONE) 00279 { 00280 /* DAC control : Signal processing to DAC, Freeze off, De-emphasis off, Analog output auto mute off, DAC soft ramp */ 00281 counter += CODEC_IO_Write(DeviceAddr, 0x09, 0x42); 00282 00283 /* Power control 1 : PDN_DACA, PDN_DACB disable. */ 00284 Value = AUDIO_IO_Read(DeviceAddr, 0x02); 00285 counter += CODEC_IO_Write(DeviceAddr, 0x02, (Value & 0x9F)); 00286 } 00287 00288 if(CS42L51_Device & INPUT_DEVICE_MIC1) 00289 { 00290 /* Power control 1 : PDN_PGAA, PDN_ADCA disable. */ 00291 Value = AUDIO_IO_Read(DeviceAddr, 0x02); 00292 counter += CODEC_IO_Write(DeviceAddr, 0x02, (Value & 0xF5)); 00293 00294 /* Mic Power and Speed Control : PDN_MICA, PDN_MIC_BIAS disable. */ 00295 Value = AUDIO_IO_Read(DeviceAddr, 0x03); 00296 counter += CODEC_IO_Write(DeviceAddr, 0x03, (Value & 0xF9)); 00297 } 00298 00299 /* Power control : Exit standby (PDN = 0) */ 00300 Value = AUDIO_IO_Read(DeviceAddr, 0x02); 00301 counter += CODEC_IO_Write(DeviceAddr, 0x02, (Value & 0xFE)); 00302 00303 Is_CS42L51_Stop = 0; 00304 } 00305 00306 /* Return communication control value */ 00307 return counter; 00308 } 00309 00310 /** 00311 * @brief Pause playing on the audio codec. 00312 * @param DeviceAddr: Device address on communication Bus. 00313 * @retval 0 if correct communication, else wrong communication 00314 */ 00315 uint32_t cs42l51_Pause(uint16_t DeviceAddr) 00316 { 00317 uint32_t counter = 0; 00318 00319 /* Pause the audio file playing */ 00320 /* Mute the output first */ 00321 counter += cs42l51_SetMute(DeviceAddr, AUDIO_MUTE_ON); 00322 00323 return counter; 00324 } 00325 00326 /** 00327 * @brief Resume playing on the audio codec. 00328 * @param DeviceAddr: Device address on communication Bus. 00329 * @retval 0 if correct communication, else wrong communication 00330 */ 00331 uint32_t cs42l51_Resume(uint16_t DeviceAddr) 00332 { 00333 uint32_t counter = 0; 00334 00335 /* Unmute the output */ 00336 counter += cs42l51_SetMute(DeviceAddr, AUDIO_MUTE_OFF); 00337 00338 return counter; 00339 } 00340 00341 /** 00342 * @brief Stop audio Codec playing. It powers down the codec. 00343 * @param DeviceAddr: Device address on communication Bus. 00344 * @param CodecPdwnMode: selects the power down mode (currently not used). 00345 * @retval 0 if correct communication, else wrong communication 00346 */ 00347 uint32_t cs42l51_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode) 00348 { 00349 uint32_t counter = 0; 00350 uint8_t Value; 00351 00352 /* Set all power down bits to 1 exept PDN to mute ADCs and DACs*/ 00353 counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x7E); 00354 Value = AUDIO_IO_Read(DeviceAddr, 0x03); 00355 counter += CODEC_IO_Write(DeviceAddr, 0x03, (Value | 0x0E)); 00356 00357 /* Disable zero cross and soft ramp */ 00358 Value = AUDIO_IO_Read(DeviceAddr, 0x09); 00359 counter += CODEC_IO_Write(DeviceAddr, 0x09, (Value & 0xFC)); 00360 00361 /* Power control : Enter standby (PDN = 1) */ 00362 Value = AUDIO_IO_Read(DeviceAddr, 0x02); 00363 counter += CODEC_IO_Write(DeviceAddr, 0x02, (Value | 0x01)); 00364 00365 Is_CS42L51_Stop = 1; 00366 return counter; 00367 } 00368 00369 /** 00370 * @brief Set higher or lower the codec volume level. 00371 * @param DeviceAddr: Device address on communication Bus. 00372 * @param Volume: output volume level (from 0 (-100dB) to 100 (0dB)). 00373 * @retval 0 if correct communication, else wrong communication 00374 */ 00375 uint32_t cs42l51_SetVolume(uint16_t DeviceAddr, uint8_t Volume) 00376 { 00377 uint32_t counter = 0; 00378 uint8_t convertedvol = VOLUME_CONVERT(Volume); 00379 00380 /* AOUTA volume control : AOUTA volume */ 00381 counter += CODEC_IO_Write(DeviceAddr, 0x16, convertedvol); 00382 /* AOUTB volume control : AOUTB volume */ 00383 counter += CODEC_IO_Write(DeviceAddr, 0x17, convertedvol); 00384 00385 return counter; 00386 } 00387 00388 /** 00389 * @brief Set new frequency. 00390 * @param DeviceAddr: Device address on communication Bus. 00391 * @param AudioFreq: Audio frequency used to play the audio stream. 00392 * @retval 0 if correct communication, else wrong communication 00393 */ 00394 uint32_t cs42l51_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq) 00395 { 00396 return 0; 00397 } 00398 00399 /** 00400 * @brief Enable or disable the mute feature on the audio codec. 00401 * @param DeviceAddr: Device address on communication Bus. 00402 * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the 00403 * mute mode. 00404 * @retval 0 if correct communication, else wrong communication 00405 */ 00406 uint32_t cs42l51_SetMute(uint16_t DeviceAddr, uint32_t Cmd) 00407 { 00408 uint32_t counter = 0; 00409 uint8_t Value; 00410 00411 /* Read DAC output control register */ 00412 Value = AUDIO_IO_Read(DeviceAddr, 0x08); 00413 00414 /* Set the Mute mode */ 00415 if(Cmd == AUDIO_MUTE_ON) 00416 { 00417 /* Mute DAC channels */ 00418 counter += CODEC_IO_Write(DeviceAddr, 0x08, (Value | 0x03)); 00419 } 00420 else /* AUDIO_MUTE_OFF Disable the Mute */ 00421 { 00422 /* Unmute DAC channels */ 00423 counter += CODEC_IO_Write(DeviceAddr, 0x08, (Value & 0xFC)); 00424 } 00425 return counter; 00426 } 00427 00428 /** 00429 * @brief Switch dynamically (while audio file is played) the output target 00430 * (speaker, headphone, etc). 00431 * @note This function is currently not used (only headphone output device). 00432 * @param DeviceAddr: Device address on communication Bus. 00433 * @param Output: specifies the audio output device target. 00434 * @retval 0 if correct communication, else wrong communication 00435 */ 00436 uint32_t cs42l51_SetOutputMode(uint16_t DeviceAddr, uint8_t Output) 00437 { 00438 return 0; 00439 } 00440 00441 /** 00442 * @brief Reset CS42L51 registers. 00443 * @param DeviceAddr: Device address on communication Bus. 00444 * @retval 0 if correct communication, else wrong communication 00445 */ 00446 uint32_t cs42l51_Reset(uint16_t DeviceAddr) 00447 { 00448 if(Is_CS42L51_Initialized == 1) 00449 { 00450 /* Deinitialize Audio Codec interface */ 00451 AUDIO_IO_DeInit(); 00452 00453 /* Initialize the Control interface of the Audio Codec */ 00454 AUDIO_IO_Init(); 00455 } 00456 return 0; 00457 } 00458 00459 /** 00460 * @} 00461 */ 00462 00463 /** @addtogroup CS42L51_Private_Functions 00464 * @{ 00465 */ 00466 00467 /** 00468 * @brief Write and optionally read back a single data. 00469 * @param Addr: I2C address 00470 * @param Reg: Reg address 00471 * @param Value: Data to be written 00472 * @retval None 00473 */ 00474 static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value) 00475 { 00476 uint32_t result = 0; 00477 00478 AUDIO_IO_Write(Addr, Reg, Value); 00479 00480 #ifdef VERIFY_WRITTENDATA 00481 /* Verify that the data has been correctly written */ 00482 result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1; 00483 #endif /* VERIFY_WRITTENDATA */ 00484 00485 return result; 00486 } 00487 00488 /** 00489 * @} 00490 */ 00491 00492 /** 00493 * @} 00494 */ 00495 00496 /** 00497 * @} 00498 */ 00499 00500 /** 00501 * @} 00502 */ 00503 00504 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Wed Jul 13 2022 19:15:17 by
