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: Aprendendo Final_v3
cs43l22.c
00001 /** 00002 ****************************************************************************** 00003 * @file cs43l22.c 00004 * @author MCD Application Team 00005 * @version V2.0.2 00006 * @date 06-October-2015 00007 * @brief This file provides the CS43L22 Audio Codec driver. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00012 * 00013 * Redistribution and use in source and binary forms, with or without modification, 00014 * are permitted provided that the following conditions are met: 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 2. Redistributions in binary form must reproduce the above copyright notice, 00018 * this list of conditions and the following disclaimer in the documentation 00019 * and/or other materials provided with the distribution. 00020 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00021 * may be used to endorse or promote products derived from this software 00022 * without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00028 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00029 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 ****************************************************************************** 00036 */ 00037 00038 /* Includes ------------------------------------------------------------------*/ 00039 #include "cs43l22.h" 00040 00041 /** @addtogroup BSP 00042 * @{ 00043 */ 00044 00045 /** @addtogroup Components 00046 * @{ 00047 */ 00048 00049 /** @addtogroup CS43L22 00050 * @brief This file provides a set of functions needed to drive the 00051 * CS43L22 audio codec. 00052 * @{ 00053 */ 00054 00055 /** @defgroup CS43L22_Private_Types 00056 * @{ 00057 */ 00058 00059 /** 00060 * @} 00061 */ 00062 00063 /** @defgroup CS43L22_Private_Defines 00064 * @{ 00065 */ 00066 #define VOLUME_CONVERT(Volume) (((Volume) > 100)? 100:((uint8_t)(((Volume) * 255) / 100))) 00067 /* Uncomment this line to enable verifying data sent to codec after each write 00068 operation (for debug purpose) */ 00069 #if !defined (VERIFY_WRITTENDATA) 00070 /* #define VERIFY_WRITTENDATA */ 00071 #endif /* VERIFY_WRITTENDATA */ 00072 /** 00073 * @} 00074 */ 00075 00076 /** @defgroup CS43L22_Private_Macros 00077 * @{ 00078 */ 00079 00080 /** 00081 * @} 00082 */ 00083 00084 /** @defgroup CS43L22_Private_Variables 00085 * @{ 00086 */ 00087 00088 /* Audio codec driver structure initialization */ 00089 AUDIO_DrvTypeDef cs43l22_drv = 00090 { 00091 cs43l22_Init, 00092 cs43l22_DeInit, 00093 cs43l22_ReadID, 00094 00095 cs43l22_Play, 00096 cs43l22_Pause, 00097 cs43l22_Resume, 00098 cs43l22_Stop, 00099 00100 cs43l22_SetFrequency, 00101 cs43l22_SetVolume, 00102 cs43l22_SetMute, 00103 cs43l22_SetOutputMode, 00104 cs43l22_Reset, 00105 }; 00106 00107 static uint8_t Is_cs43l22_Stop = 1; 00108 00109 volatile uint8_t OutputDev = 0; 00110 00111 /** 00112 * @} 00113 */ 00114 00115 /** @defgroup CS43L22_Function_Prototypes 00116 * @{ 00117 */ 00118 static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value); 00119 /** 00120 * @} 00121 */ 00122 00123 /** @defgroup CS43L22_Private_Functions 00124 * @{ 00125 */ 00126 00127 /** 00128 * @brief Initializes the audio codec and the control interface. 00129 * @param DeviceAddr: Device address on communication Bus. 00130 * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, 00131 * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . 00132 * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) 00133 * @retval 0 if correct communication, else wrong communication 00134 */ 00135 uint32_t cs43l22_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) 00136 { 00137 uint32_t counter = 0; 00138 00139 /* Initialize the Control interface of the Audio Codec */ 00140 AUDIO_IO_Init(); 00141 00142 /* Keep Codec powered OFF */ 00143 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x01); 00144 00145 /*Save Output device for mute ON/OFF procedure*/ 00146 switch (OutputDevice) 00147 { 00148 case OUTPUT_DEVICE_SPEAKER: 00149 OutputDev = 0xFA; 00150 break; 00151 00152 case OUTPUT_DEVICE_HEADPHONE: 00153 OutputDev = 0xAF; 00154 break; 00155 00156 case OUTPUT_DEVICE_BOTH: 00157 OutputDev = 0xAA; 00158 break; 00159 00160 case OUTPUT_DEVICE_AUTO: 00161 OutputDev = 0x05; 00162 break; 00163 00164 default: 00165 OutputDev = 0x05; 00166 break; 00167 } 00168 00169 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, OutputDev); 00170 00171 /* Clock configuration: Auto detection */ 00172 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_CLOCKING_CTL, 0x81); 00173 00174 /* Set the Slave Mode and the audio Standard */ 00175 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_INTERFACE_CTL1, CODEC_STANDARD); 00176 00177 /* Set the Master volume */ 00178 counter += cs43l22_SetVolume(DeviceAddr, Volume); 00179 00180 /* If the Speaker is enabled, set the Mono mode and volume attenuation level */ 00181 if(OutputDevice != OUTPUT_DEVICE_HEADPHONE) 00182 { 00183 /* Set the Speaker Mono mode */ 00184 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_PLAYBACK_CTL2, 0x06); 00185 00186 /* Set the Speaker attenuation level */ 00187 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_SPEAKER_A_VOL, 0x00); 00188 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_SPEAKER_B_VOL, 0x00); 00189 } 00190 00191 /* Additional configuration for the CODEC. These configurations are done to reduce 00192 the time needed for the Codec to power off. If these configurations are removed, 00193 then a long delay should be added between powering off the Codec and switching 00194 off the I2S peripheral MCLK clock (which is the operating clock for Codec). 00195 If this delay is not inserted, then the codec will not shut down properly and 00196 it results in high noise after shut down. */ 00197 00198 /* Disable the analog soft ramp */ 00199 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_ANALOG_ZC_SR_SETT, 0x00); 00200 /* Disable the digital soft ramp */ 00201 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MISC_CTL, 0x04); 00202 /* Disable the limiter attack level */ 00203 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_LIMIT_CTL1, 0x00); 00204 /* Adjust Bass and Treble levels */ 00205 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_TONE_CTL, 0x0F); 00206 /* Adjust PCM volume level */ 00207 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_PCMA_VOL, 0x0A); 00208 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_PCMB_VOL, 0x0A); 00209 00210 /* Return communication control value */ 00211 return counter; 00212 } 00213 00214 /** 00215 * @brief Deinitializes the audio codec. 00216 * @param None 00217 * @retval None 00218 */ 00219 void cs43l22_DeInit(void) 00220 { 00221 /* Deinitialize Audio Codec interface */ 00222 AUDIO_IO_DeInit(); 00223 } 00224 00225 /** 00226 * @brief Get the CS43L22 ID. 00227 * @param DeviceAddr: Device address on communication Bus. 00228 * @retval The CS43L22 ID 00229 */ 00230 uint32_t cs43l22_ReadID(uint16_t DeviceAddr) 00231 { 00232 uint8_t Value; 00233 /* Initialize the Control interface of the Audio Codec */ 00234 AUDIO_IO_Init(); 00235 00236 Value = AUDIO_IO_Read(DeviceAddr, CS43L22_CHIPID_ADDR); 00237 Value = (Value & CS43L22_ID_MASK); 00238 00239 return((uint32_t) Value); 00240 } 00241 00242 /** 00243 * @brief Start the audio Codec play feature. 00244 * @note For this codec no Play options are required. 00245 * @param DeviceAddr: Device address on communication Bus. 00246 * @retval 0 if correct communication, else wrong communication 00247 */ 00248 uint32_t cs43l22_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size) 00249 { 00250 uint32_t counter = 0; 00251 00252 if(Is_cs43l22_Stop == 1) 00253 { 00254 /* Enable the digital soft ramp */ 00255 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MISC_CTL, 0x06); 00256 00257 /* Enable Output device */ 00258 counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_OFF); 00259 00260 /* Power on the Codec */ 00261 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x9E); 00262 Is_cs43l22_Stop = 0; 00263 } 00264 00265 /* Return communication control value */ 00266 return counter; 00267 } 00268 00269 /** 00270 * @brief Pauses playing on the audio codec. 00271 * @param DeviceAddr: Device address on communication Bus. 00272 * @retval 0 if correct communication, else wrong communication 00273 */ 00274 uint32_t cs43l22_Pause(uint16_t DeviceAddr) 00275 { 00276 uint32_t counter = 0; 00277 00278 /* Pause the audio file playing */ 00279 /* Mute the output first */ 00280 counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_ON); 00281 00282 /* Put the Codec in Power save mode */ 00283 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x01); 00284 00285 return counter; 00286 } 00287 00288 /** 00289 * @brief Resumes playing on the audio codec. 00290 * @param DeviceAddr: Device address on communication Bus. 00291 * @retval 0 if correct communication, else wrong communication 00292 */ 00293 uint32_t cs43l22_Resume(uint16_t DeviceAddr) 00294 { 00295 uint32_t counter = 0; 00296 volatile uint32_t index = 0x00; 00297 /* Resumes the audio file playing */ 00298 /* Unmute the output first */ 00299 counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_OFF); 00300 00301 for(index = 0x00; index < 0xFF; index++); 00302 00303 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, OutputDev); 00304 00305 /* Exit the Power save mode */ 00306 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x9E); 00307 00308 return counter; 00309 } 00310 00311 /** 00312 * @brief Stops audio Codec playing. It powers down the codec. 00313 * @param DeviceAddr: Device address on communication Bus. 00314 * @param CodecPdwnMode: selects the power down mode. 00315 * - CODEC_PDWN_HW: Physically power down the codec. When resuming from this 00316 * mode, the codec is set to default configuration 00317 * (user should re-Initialize the codec in order to 00318 * play again the audio stream). 00319 * @retval 0 if correct communication, else wrong communication 00320 */ 00321 uint32_t cs43l22_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode) 00322 { 00323 uint32_t counter = 0; 00324 00325 /* Mute the output first */ 00326 counter += cs43l22_SetMute(DeviceAddr, AUDIO_MUTE_ON); 00327 00328 /* Disable the digital soft ramp */ 00329 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MISC_CTL, 0x04); 00330 00331 /* Power down the DAC and the speaker (PMDAC and PMSPK bits)*/ 00332 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL1, 0x9F); 00333 00334 Is_cs43l22_Stop = 1; 00335 return counter; 00336 } 00337 00338 /** 00339 * @brief Sets higher or lower the codec volume level. 00340 * @param DeviceAddr: Device address on communication Bus. 00341 * @param Volume: a byte value from 0 to 255 (refer to codec registers 00342 * description for more details). 00343 * @retval 0 if correct communication, else wrong communication 00344 */ 00345 uint32_t cs43l22_SetVolume(uint16_t DeviceAddr, uint8_t Volume) 00346 { 00347 uint32_t counter = 0; 00348 uint8_t convertedvol = VOLUME_CONVERT(Volume); 00349 00350 if(Volume > 0xE6) 00351 { 00352 /* Set the Master volume */ 00353 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MASTER_A_VOL, convertedvol - 0xE7); 00354 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MASTER_B_VOL, convertedvol - 0xE7); 00355 } 00356 else 00357 { 00358 /* Set the Master volume */ 00359 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MASTER_A_VOL, convertedvol + 0x19); 00360 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_MASTER_B_VOL, convertedvol + 0x19); 00361 } 00362 00363 return counter; 00364 } 00365 00366 /** 00367 * @brief Sets new frequency. 00368 * @param DeviceAddr: Device address on communication Bus. 00369 * @param AudioFreq: Audio frequency used to play the audio stream. 00370 * @retval 0 if correct communication, else wrong communication 00371 */ 00372 uint32_t cs43l22_SetFrequency(uint16_t DeviceAddr, uint32_t AudioFreq) 00373 { 00374 return 0; 00375 } 00376 00377 /** 00378 * @brief Enables or disables the mute feature on the audio codec. 00379 * @param DeviceAddr: Device address on communication Bus. 00380 * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the 00381 * mute mode. 00382 * @retval 0 if correct communication, else wrong communication 00383 */ 00384 uint32_t cs43l22_SetMute(uint16_t DeviceAddr, uint32_t Cmd) 00385 { 00386 uint32_t counter = 0; 00387 00388 /* Set the Mute mode */ 00389 if(Cmd == AUDIO_MUTE_ON) 00390 { 00391 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0xFF); 00392 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_HEADPHONE_A_VOL, 0x01); 00393 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_HEADPHONE_B_VOL, 0x01); 00394 } 00395 else /* AUDIO_MUTE_OFF Disable the Mute */ 00396 { 00397 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_HEADPHONE_A_VOL, 0x00); 00398 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_HEADPHONE_B_VOL, 0x00); 00399 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, OutputDev); 00400 } 00401 return counter; 00402 } 00403 00404 /** 00405 * @brief Switch dynamically (while audio file is played) the output target 00406 * (speaker or headphone). 00407 * @note This function modifies a global variable of the audio codec driver: OutputDev. 00408 * @param DeviceAddr: Device address on communication Bus. 00409 * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER, 00410 * OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO 00411 * @retval 0 if correct communication, else wrong communication 00412 */ 00413 uint32_t cs43l22_SetOutputMode(uint16_t DeviceAddr, uint8_t Output) 00414 { 00415 uint32_t counter = 0; 00416 00417 switch (Output) 00418 { 00419 case OUTPUT_DEVICE_SPEAKER: 00420 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0xFA); /* SPK always ON & HP always OFF */ 00421 OutputDev = 0xFA; 00422 break; 00423 00424 case OUTPUT_DEVICE_HEADPHONE: 00425 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0xAF); /* SPK always OFF & HP always ON */ 00426 OutputDev = 0xAF; 00427 break; 00428 00429 case OUTPUT_DEVICE_BOTH: 00430 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0xAA); /* SPK always ON & HP always ON */ 00431 OutputDev = 0xAA; 00432 break; 00433 00434 case OUTPUT_DEVICE_AUTO: 00435 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0x05); /* Detect the HP or the SPK automatically */ 00436 OutputDev = 0x05; 00437 break; 00438 00439 default: 00440 counter += CODEC_IO_Write(DeviceAddr, CS43L22_REG_POWER_CTL2, 0x05); /* Detect the HP or the SPK automatically */ 00441 OutputDev = 0x05; 00442 break; 00443 } 00444 return counter; 00445 } 00446 00447 /** 00448 * @brief Resets cs43l22 registers. 00449 * @param DeviceAddr: Device address on communication Bus. 00450 * @retval 0 if correct communication, else wrong communication 00451 */ 00452 uint32_t cs43l22_Reset(uint16_t DeviceAddr) 00453 { 00454 return 0; 00455 } 00456 00457 /** 00458 * @brief Writes/Read a single data. 00459 * @param Addr: I2C address 00460 * @param Reg: Reg address 00461 * @param Value: Data to be written 00462 * @retval None 00463 */ 00464 static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value) 00465 { 00466 uint32_t result = 0; 00467 00468 AUDIO_IO_Write(Addr, Reg, Value); 00469 00470 #ifdef VERIFY_WRITTENDATA 00471 /* Verify that the data has been correctly written */ 00472 result = (AUDIO_IO_Read(Addr, Reg) == Value)? 0:1; 00473 #endif /* VERIFY_WRITTENDATA */ 00474 00475 return result; 00476 } 00477 00478 /** 00479 * @} 00480 */ 00481 00482 /** 00483 * @} 00484 */ 00485 00486 /** 00487 * @} 00488 */ 00489 00490 /** 00491 * @} 00492 */ 00493 00494 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Wed Jul 13 2022 07:24:52 by
